[Python] 코딩 도장 - 전화번호

Updated:

코딩 도장 사이트의 문제를 직접 풀어본 내용을 정리하여 올립니다.

코딩 도장에서 여러 문제를 확인할 수 있습니다.

난이도 순으로 차근차근 풀어보려 합니다.


[문제: 전화번호] - Lv.2

회사원들은 외우기 좋은 전화번호를 갖고 싶어한다.

전화번호를 외우기 쉽도록 만드는 한 방법은 기억하기 좋은 단어나 구절이 되도록 하는 것이다.

예를 들어, 워털루 대학의 전화는 TUT-GLOP으로 전화를 걸 수 있다. 때때로 번호의 일부만이 단어를 쓰기 위해 사용될 수 있다.

Gino에서 피자를 주문하기 위해 310-GINO로 전화를 거는 식이다.

전화번호를 외우기 좋도록 하는 또다른 방법은 숫자들을 기억하기 좋은 방법으로 묶는 것이다.

3-10-10-10 (Three-tens)으로 전화를 걸면 피자헛에 주문을 할 수 있다.

전화번호의 표준형은 세 번째 번호와 네 번째 번호 사이에 하이픈(-)을 삽입한 7개의 숫자로 구성되어 있다. (예: 888-1200).

전화기의 키패드는 다음과 같은 글자 대 숫자의 대응을 지닌다.

A, B, C -> 2
D, E, F -> 3
G, H, I -> 4
J, K, L -> 5
M, N, O -> 6
P, R, S -> 7
T, U, V -> 8
W, X, Y -> 9

Q와 Z에 대한 대응관계는 존재하지 않는다.

하이픈은 전화기에 입력되지 않으며 필요에 따라 추가되거나 빠질 수 있다.

TUT-GLOP의 표준형은 888-4567이고, 310-GINO의 표준형은 310-4466, 3-10-10-10의 표준형은 310-1010이다.

만약 어떤 두 전화번호가 같은 표준형을 지니면 그들은 같은 번호이다.

여러분의 회사는 지역 회사원들의 전화번호를 정리하고 있다.

품질 관리 과정의 일환으로, 여러분은 정리된 전화번호부의 번호 중에 같은 것이 둘 이상 있지 않은지 확인하고 싶다.

Input

입력은 하나의 테스트 케이스로 구성된다.

입력의 첫 줄은 전화번호의 갯수(<=100,000)로 이뤄져 있다.

남은 줄들은 전화번호부 내의 전화번호들이 한 줄에 하나씩 들어 있다.

각 전화번호는 십진 숫자들과 대문자(Q,Z 제외), 하이픈으로 구성된 문자열로 이뤄져 있다.

문자열 내에서 정확히 7개의 문자들이 숫자 또는 알파벳 문자이다.

Output

한 번 이상 등장한 전화번호들이 출력을 구성한다.

각 줄은 표준형으로 표현된 전화번호와 출현 횟수가 하나의 공백 문자로 구분되어 있다.

출력되는 전화 번호들은 증가하는 사전식 순서로 되어 있어야 한다.

만약 입력으로 들어온 전화번호 중에 중복이 없다면 “No duplicates.”를 출력한다.

Sample Input

12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279

Sample Output

310-1010 2
487-3279 4
888-4567 3

출처: https://codingdojang.com/scode/441?answer_mode=hide


[풀이]

txt = "ABCDEFGHIJKLMNOPRSTUVWXY"
a = txt.maketrans("ABCDEFGHIJKLMNOPRSTUVWXY", "222333444555666777888999")

N = input()
telephone = [input().translate(a).replace("-","") for i in range(int(N))]
telephone = sorted(telephone, key=lambda x: int(x))

telephone2 = {x[:3] + "-" + x[3:]:0 for x in telephone}

for i in telephone:
    key = str(i)[:3] + "-" + str(i)[3:]
    telephone2[key] += 1

print("-"*30)
for key, value in telephone2.items():
    if value == 1:
        value = "No duplicates."
    print(key, value)
12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279
------------------------------
310-1010 2
310-4466 No duplicates.
487-3279 4
888-1200 No duplicates.
888-4567 3
967-1111 No duplicates.

알파벳을 숫자로 변경하는 방법은 translate()를 사용하였다.

그리고 입력받은 문자열을 하이폰을 제거하고 리스트 형태로 정렬하였다.

그 후 사전을 만들어서 해당 값의 갯수를 확인하는 방식을 사용했다.


[추천 풀이]

def main(input):
    AZ = "ABCDEFGHIJKLMNOPRSTUVWXY"
    table = {}
    for a in range(0, 8):
        for c in AZ[a*3:a*3+3]:
            table[c] = str(a+2)

    result = {}
    for line in input.split()[1:]:
        source = line.strip().replace("-", "")
        transformed = "".join(([table.get(x, x) for x in list(source)]))
        result[transformed] = result.get(transformed, 0) + 1

    for print_line in sorted(result.keys()):
        print( print_line[:3]+"-"+print_line[3:],\
            (result[print_line] if result[print_line] else "No duplicates."))
    
main("12 4873279 ITS-EASY 888-4567 3-10-10-10 888-GLOP TUT-GLOP 967-11-11 310-GINO F101010 888-1200 -4-8-7-3-2-7-9- 487-3279")
310-1010 2
310-4466 1
487-3279 4
888-1200 1
888-4567 3
967-1111 1

큰 맥락은 비슷한데 알파벳을 바꾸는 방법을 이 분은 사전을 사용하였다.

그리고 여기서 get()함수로 값이 없을 경우 반환하는 값을 지정해서 조금 더 간편하게 사용한 것 같다.

나의 코드에서도 key만 가지고 있는 사전을 만든 후 값을 추가해주었는데 이렇게 짜면 훨씬 줄일 수 있겠다.

Leave a comment