Untitled
unknown
plain_text
10 months ago
4.8 kB
13
Indexable
using System;
using System.Collections.Generic;
using System.Linq;
public enum AddResult { ok, not_member, already_exists }
public enum FindReport { ok, unknown_name }
public enum RemoveResult { ok, not_present }
public readonly record struct Person(string Name);
public readonly record struct Phone(string Number);
public class PhoneDB
{
private readonly HashSet<Person> _members;
private readonly Dictionary<Person, HashSet<Phone>> _telephones = new();
public PhoneDB(IEnumerable<Person> members)
{
_members = new HashSet<Person>(members);
}
private void AssertInvariant()
{
foreach (var p in _telephones.Keys)
{
if (!_members.Contains(p))
throw new InvalidOperationException("Invariant violated: dom(telephones) ā members");
}
}
public AddResult AddEntry(Person name, Phone number)
{
if (!_members.Contains(name))
return AddResult.not_member;
if (!_telephones.TryGetValue(name, out var phones))
{
phones = new HashSet<Phone>();
_telephones[name] = phones;
}
if (phones.Contains(number)) return AddResult.already_exists;
phones.Add(number);
AssertInvariant();
return AddResult.ok;
}
public (FindReport, IReadOnlyCollection<Phone>) DoFindPhones(Person name)
{
if (!_telephones.TryGetValue(name, out var phones) || phones.Count == 0)
return (FindReport.unknown_name, Array.Empty<Phone>());
return (FindReport.ok, phones.ToArray());
}
public RemoveResult RemoveEntry(Person name, Phone number)
{
if (!_telephones.TryGetValue(name, out var phones) || !phones.Remove(number))
return RemoveResult.not_present;
if (phones.Count == 0) _telephones.Remove(name);
AssertInvariant();
return RemoveResult.ok;
}
public void PrintState()
{
Console.WriteLine("\nš Current PhoneDB:");
foreach (var m in _members)
{
_telephones.TryGetValue(m, out var phones);
var list = phones != null && phones.Count > 0
? string.Join(", ", phones.Select(p => p.Number))
: "(none)";
Console.WriteLine($" - {m.Name}: {list}");
}
Console.WriteLine();
}
}
internal static class Program
{
private static void Main()
{
// STEP 1: Initialize members
Console.WriteLine("Enter initial members (comma-separated):");
var input = Console.ReadLine() ?? "";
var members = input.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Select(name => new Person(name))
.ToArray();
var db = new PhoneDB(members);
Console.WriteLine($"ā
PhoneDB initialized with {members.Length} members.\n");
// STEP 2: Command loop
Console.WriteLine("Commands:");
Console.WriteLine(" add <name> <number>");
Console.WriteLine(" find <name>");
Console.WriteLine(" remove <name> <number>");
Console.WriteLine(" list");
Console.WriteLine(" exit\n");
while (true)
{
Console.Write("> ");
var line = Console.ReadLine();
if (string.IsNullOrWhiteSpace(line)) continue;
var parts = line.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
var cmd = parts[0].ToLowerInvariant();
if (cmd == "exit") break;
switch (cmd)
{
case "add" when parts.Length == 3:
var addRes = db.AddEntry(new Person(parts[1]), new Phone(parts[2]));
Console.WriteLine($"ā {addRes}");
break;
case "find" when parts.Length == 2:
var (findRes, numbers) = db.DoFindPhones(new Person(parts[1]));
Console.WriteLine($"ā {findRes}");
if (findRes == FindReport.ok)
Console.WriteLine($"Numbers: {string.Join(", ", numbers.Select(n => n.Number))}");
break;
case "remove" when parts.Length == 3:
var removeRes = db.RemoveEntry(new Person(parts[1]), new Phone(parts[2]));
Console.WriteLine($"ā {removeRes}");
break;
case "list":
db.PrintState();
break;
default:
Console.WriteLine("ā Invalid command or arguments.");
break;
}
}
Console.WriteLine("š Exiting PhoneDB.");
}
}
Editor is loading...
Leave a Comment