Phone Directory

kata programming

مساله:

John یک نسخه پشتیبان از دفترچه تلفن شخصی قدیمی خود را به در قالب یک فایل متنی نگه می دارد. در هر سطر فایل او می تواند شماره تلفن (با فرم +X-abc-def-ghij که X مخفف یک یا دو رقم است)، نام مربوطه که بین <و> است و آدرس را پیدا کند.

متأسفانه همه چیز مخلوط است، همه چیز همیشه در یک ترتیب نیست. بخشهایی از خطوط با کاراکترهای غیر الفبایی (به جز شماره تلفن و نام) به هم ریخته شده است.

نمونه هایی از خطوط دفتر تلفن John :

“/+1-541-754-3010 156 Alphand_St. <J Steeve>\n”

” 133, Green, Rd. <E Kustur> NY-56423 ;+1-541-914-3010!\n”

“<Anastasia> +48-421-674-8974 Via Quirinal Roma\n”

شما می توانید برنامه ای برای کمک به John بنویسید که خطوط دفترچه تلفن را بگیرد و همچنین شماره تلفن num را بگیرد، سپس رشته ای به فرمت روبرو را نمایش دهد: “Phone => num, Name => name, Address => adress”

مثال ها:

s = "/+1-541-754-3010 156 Alphand_St. <J Steeve>\n 133, Green, Rd. <E Kustur> NY-56423 ;+1-541-914-3010!\n"

phone(s, "1-541-754-3010") should return "Phone => 1-541-754-3010, Name => J Steeve, Address => 156 Alphand St."

اگر افراد زیادی برای یک شماره تلفن وجود داشته باشند، عبارت روبرو را برگردانید: “Error => Too many people: num”

یا اگر شماره num در دفترچه تلفن موجود نباشد، عبارت روبرو را برگردانید: “Error => Not found: num”


John keeps a backup of his old personal phone book as a text file. On each line of the file he can find the phone number (formated as +X-abc-def-ghij where X stands for one or two digits), the corresponding name between < and > and the address.

Unfortunately everything is mixed, things are not always in the same order; parts of lines are cluttered with non-alpha-numeric characters (except inside phone number and name).

Examples of John’s phone book lines:

"/+1-541-754-3010 156 Alphand_St. <J Steeve>\n"

" 133, Green, Rd. <E Kustur> NY-56423 ;+1-541-914-3010!\n"

"<Anastasia> +48-421-674-8974 Via Quirinal Roma\n"

Could you help John with a program that, given the lines of his phone book and a phone number num returns a string for this number : "Phone => num, Name => name, Address => adress"

Examples:

s = "/+1-541-754-3010 156 Alphand_St. <J Steeve>\n 133, Green, Rd. <E Kustur> NY-56423 ;+1-541-914-3010!\n"

phone(s, "1-541-754-3010") should return "Phone => 1-541-754-3010, Name => J Steeve, Address => 156 Alphand St."

It can happen that there are many people for a phone number num, then return : "Error => Too many people: num"

or it can happen that the number num is not in the phone book, in that case return: "Error => Not found: num"

Notes

Codewars stdout doesn’t print part of a string when between < and >

You can see other examples in the test cases.


import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class PhoneDir {

  public static String phone(String strng, String num) {
    List<String> contactList = Arrays.stream(strng.split("\\n")).map(line -> {
      String phone = line.substring(line.indexOf("+") + 1,line.indexOf(" ", line.indexOf("+")) > 0 ? line.indexOf(" ", line.indexOf("+")) : line.length()).replaceAll("[^0-9|-]+", "");
      String name = line.substring(line.indexOf("<") + 1, line.indexOf(">"));
      String address = line.replace("+" + phone, "").replace("<" + name + ">", "");
      return "Phone => " + phone + ", Name => " + name + ", Address => " + address.replaceAll("[^a-z|A-Z|.| |\\-|0-9|_]+", "").trim().replace("  ", " ").replace("  ", " ").replace("_", " ");
    }).filter(line -> line.startsWith("Phone => "+ num))
      .collect(Collectors.toList());

    if (contactList != null && contactList.size() > 0)
      return (contactList.size() > 1) ?  "Error => Too many people: " + num : contactList.get(0);
    return "Error => Not found: " + num;

  }
}
class PhoneDir {
    public static  String phone(String strng, String num) {
        String found = null;
        int count = 0;
        for (String entry : strng.split("\n"))
            if (entry.contains("+" + num)) {
                found = entry;
                count++;
            }
        
        // error cases
        if (count == 0) return "Error => Not found: " + num;
        if (count > 1) return "Error => Too many people: " + num;

        // process found entry
        String name = found.split("<|>")[1];
        String address = found
                .replace(name, "").replace(num, "") // only address left
                .replaceAll("[^A-Za-z0-9\\. -]", " ") // filter all unnecessary chars
                .trim().replaceAll(" +", " "); // reduce extra spaces

        return "Phone => " + num + ", Name => " + name + ", Address => " + address;
    }
}
import java.util.*;      
import java.util.regex.*;
class PhoneDir {
    public static  String phone(String strng, String num) {                                                 
        Pattern numPattern = Pattern.compile(".*(?<=\\+)"+num+".*");                                        
        String name = "", address;                                                                          
        String[] found = Arrays.stream(strng.trim().split("\n"))                                            
                               .filter(s -> numPattern.matcher(s).matches())                                                                           
                               .limit(2)                                                                    
                               .toArray(String[]::new);                                                                                                           
        if (found.length == 2) return "Error => Too many people: " + num;                                       
        if (found.length == 0) return "Error => Not found: " + num;                                             
                                                                                                            
        Matcher nameMatcher = Pattern.compile("<(.*)>").matcher(found[0]);                                  
        if (nameMatcher.find()) name = nameMatcher.group(1);                                                
                                                                                                            
        address = found[0].replaceAll(num + "|" + name, "")                                                 
                       .replaceAll("(?i)[^a-z0-9-. ]", " ")                                                 
                       .replaceAll(" +(?= )", "")                                                           
                       .trim();                                                                             
        return String.format("Phone => %s, Name => %s, Address => %s", num, name, address);                 
    }                                                                                                                                                                                                   
}
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

class PhoneDir {

    private static final Pattern PHONE = Pattern.compile("\\+\\d{1,2}-\\d{3}-\\d{3}-\\d{4}");
    private static final Pattern NAME = Pattern.compile(("<(.*)>"));
    private static final Pattern SPECIALS = Pattern.compile(("(\\:|\\,|\\?|\\*|\\$|!|\\\\|;|\\/)"));
    
    public static  String phone(String strng, String num) {
    
        List<String> filtered = filterByPhone(strng.split("\n"), "+" + num);
        
        if (filtered.size() == 1) {
            String line = filtered.get(0);
            Matcher nameMatcher = NAME.matcher(line);
            nameMatcher.find();
            String name = nameMatcher.group(1);
            line = nameMatcher.replaceAll("");
            line = PHONE.matcher(line).replaceAll("");
            line = SPECIALS.matcher(line).replaceAll("");
            String address = line.replaceAll("\\s{2,}|_", " ").trim();
            return String.format("Phone => %s, Name => %s, Address => %s", num, name, address);
            
        } else if (filtered.isEmpty()) {
            return String.format("Error => Not found: %s", num);
            
        } else {
            return String.format("Error => Too many people: %s", num);
        }
    }

    private static List<String> filterByPhone(String[] entries, String phone) {
        return Arrays.stream(entries).filter(e -> e.contains(phone)).collect(Collectors.toList());
    }
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
class PhoneDir {
    /**
     * 
     * @param num could send with + or without
     */
    public static String phone(String strng, String num) {
        List<String> found = Arrays.stream(strng.replace('_', ' ').split("\n")).filter(item -> item.contains(num.contains("+") ? num : "+" + num)).collect(Collectors.toList());
        if(found.size() > 1) return "Error => Too many people: " + num;
        else if(found.size() == 0) return "Error => Not found: " + num;
        StringBuilder result = new StringBuilder();
        result.append("Phone => ").append(num).append(", ");
        String name = found.get(0).substring(found.get(0).indexOf('<') + 1, found.get(0).indexOf('>'));
        result.append("Name => ").append(name).append(", ");
        result.append("Address => ").append(found.get(0).replace(num, "").replace(name, "").replaceAll("[^a-zA-Z0-9\\s-.]", "").replaceAll("\\s{2,}", " ").trim());

        return result.toString();
    }
}

دیدگاهتان را بنویسید