Untitled

 avatar
unknown
plain_text
9 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