DEV Community

Discussion on: Daily Challenge #67- Phone Directory

Collapse
 
peledzohar profile image
Zohar Peled

Not sure about most efficient, but here's one way to do it using c#.
A more efficient way would be to first parse the entire text into objects, and then only search the already parsed text.

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {
        var s = @"/+1-541-754-3010 156 Alphand_St. <J Steeve>
            133, Green, Rd. <E Kustur> NY-56423 ;+1-541-914-3010!
            <Anastasia> +48-421-674-8974 Via Quirinal Roma
            <Too many> some text +48-421-674-8974 ";

        Console.WriteLine(phone(s, "1-541-754-3010"));  // return J Steeve
        Console.WriteLine(phone(s, "1-541-914-3010"));  // return E Kustur
        Console.WriteLine(phone(s, "48-421-674-8974")); // return Error => Too many people: nb
        Console.WriteLine(phone(s, "48-421-674-1234")); // return Error => Not found: nb
    }

    static string phone(string phoneBook, string phoneNumber)
    {
        var entries = new Dictionary<string, PhoneBookEntry>();
        var lines = phoneBook.Split('\n');
        foreach(var line in lines)
        {
            if(PhoneBookEntry.TryParse(line, out PhoneBookEntry entry) && entry.Phone == phoneNumber)
            {
                if(entries.ContainsKey(entry.Phone))
                {
                    return "Error => Too many people: nb";
                }
                entries[entry.Phone] = entry;
            }
        }
        if(entries.TryGetValue(phoneNumber, out PhoneBookEntry result))
        {
            return result.ToString();
        }
        return "Error => Not found: nb";
    }



    private class PhoneBookEntry
    {   
        private static Regex _phoneRe = new Regex(@"\+(\d{1,2}-\d{3}-\d{3}-\d{4})");
        private static Regex _nameRe = new Regex(@"<([^>]+)>");
        private static Regex _specialCharsRe = new Regex(@"[/!;]");

        private PhoneBookEntry(string phone, string address, string name)
        {
            Phone = phone;
            Address = address;
            Name = name;
        }

        public string Phone {get;}
        public string Address {get;}
        public string Name {get;}

        public static bool TryParse(string rawData, out PhoneBookEntry result)
        {
            result = null;
            var phoneMatch = _phoneRe.Match(rawData);
            if(phoneMatch.Success)
            {
                var nameMatch = _nameRe.Match(rawData);
                if(nameMatch.Success)
                {
                    var phone = phoneMatch.Groups[1].Value;
                    var name = nameMatch.Groups[1].Value;
                    var address = _specialCharsRe.Replace(_nameRe.Replace(_phoneRe.Replace(rawData, ""), ""), "").Trim();
                    result = new PhoneBookEntry(phone, address, name);
                    return true;
                }
            }

            return false;
        }

        public override string ToString()
        {
            return $"Phone => {Phone}, Name => {Name}, Address => {Address}";
        }            
    }
}

try it online