본문 바로가기
개발공부/[코딩테스트_SWEA]

[SWEA 1242][Python][S/W 문제해결 응용] 1일차 - 암호코드 스캔

by 왜지? 2022. 12. 31.
반응형

코드

## SWEA 1242
T = int(input())
change_hex_to_bin = {'0':'0000', '1':'0001', '2':'0010', '3':'0011',
                 '4':'0100', '5':'0101', '6':'0110', '7':'0111',
                 '8':'1000', '9':'1001', 'A':'1010', 'B':'1011',
                 'C':'1100', 'D':'1101', 'E':'1110', 'F':'1111'}

## 맨 뒤에가 전부 1이기 때문에.. 뒤에서부터 코드를 인식하도록 함.
bar_code = {'112':0, '122':1, '221':2,'114':3, '231':4,'132':5, '411':6, '213':7, '312':8, '211':9}

for test_case in range(1,T+1):
    N,M = map(int, input().split())
    arry = [  list(input().strip()) for _ in range(N) ]
    bin_arry = ['']*N
    for i in range(N):
        for j in range(M):
            bin_arry[i] += change_hex_to_bin[arry[i][j]]
    result = 0
    visited = []
    temp_list = []

    ## 한줄씩 바코드 검사
    for i in range(N):
        n1 = n2 = n3 = 0
        if '1' not in bin_arry[i] :
            continue

        ## 뒤에서부터 검사 ( 뒤에 세자리로 구분 가능 )
        for j in range(M*4-1,-1,-1):
            if n2 == 0 and n3 == 0 and bin_arry[i][j]=='1':## 첫번째 1의 개수
                n1 += 1
            elif n1 and n3 == 0 and  bin_arry[i][j] == '0': ## 두번째 0의 개수
                n2 += 1
            elif n1 and n2 and bin_arry[i][j]=='1': ## 세번째 1의 개수
                n3 += 1
            elif n3 and bin_arry[i][j] == '0' :
                rate = min(n1,n2,n3)
                tmp = bar_code[ str(n1//rate)+str(n2//rate)+str(n3//rate) ]
                temp_list.append(tmp)
                n1=n2=n3=0
                if len(temp_list) == 8 :
                    check = ((temp_list[7]+temp_list[5]+temp_list[3]+temp_list[1])*3 + temp_list[0]+temp_list[2]+temp_list[4]+temp_list[6]) % 10
                    if temp_list not in visited :
                        if check == 0 :
                            result += sum(temp_list)
                        visited.append(temp_list)
                    temp_list = []
    print(f"#{test_case} {result}")

 

풀이

문제를 이해하는데 상당히 시간이 오래 걸렸다.

코딩테스트의 세계는 복잡하다... 

아래의 순서대로 코드를 작성했다. 

1. 16진수로 받은 input을 2진수로 바꿔준다. ( 2d list의 col길이가 x 4배만큼 증가한다. )

2. row 별로 for문을 돌면서 전체 row 중 '1'이 하나라도 있으면 바코드 분석을 한다. 

3. '1'이 포함된 row는 모든 column 들을 돌면서 암호코드의 길이를 측정한다.

4.문제에서 주어진 암호코드의 비율( 3:2:1:1, 2:2:2:1, .. )을 보면 뒤의 세자리만으로 모든 숫자가 구분이 가능하다.

5. n1 : 첫번째 구간 1의 수 / n2 : 2번째구간 0의 수 / n3 : 세번째 구간 1의 수 로 정의하고,  

6. row의 끝에서부터 탐색하여 암호코드의 n1,n2,n3를 업데이트 한다. ( 단순 개수가 아닌 비율로 비교해줘야한다. )

7. 모두 업데이트 되면 암호코드 길이가 8이 되는 지 확인한 후 올바른 암호코드인지 확인한다. ( 10의 배수 ) 

8. 올바른 암호코드라면 result 값에 더해준다. ( 동일한 row가 반복되기 때문에 중복 체크를 해줘야한다. )

반응형

댓글