[SWEA][D4][#01240] 단순 2진 암호코드

작성:    

업데이트:

카테고리:

태그: , ,

출처

학습용 포스트입니다. 본 포스트가 문제가 될 시 수정 또는 삭제하겠습니다.


문제 생략


My Sol

dictA = {
    '0001101': 0,
    '0011001': 1,
    '0010011': 2,
    '0111101': 3,
    '0100011': 4,
    '0110001': 5,
    '0101111': 6,
    '0111011': 7,
    '0110111': 8,
    '0001011': 9
}

def find1():
    # 위쪽부터, 오른쪽부터 1 조회
    for i in range(4, H, 5):
        for j in range(W-1, 50, -1):
            if mat[i][j]:
                return i, j


T = int(input())
for tc in range(1, T+1):
    H, W = map(int, input().split())
    mat = [list(map(int, input())) for _ in range(H)]

    si, sj = find1()
    barcode = mat[si][sj-56+1:sj+1]
    arr = []
    for i in range(8):
        lst = barcode[i*7:i*7+7]
        lst2 = [str(i) for i in lst]
        txt = ''.join(lst2)
        arr.append(dictA[txt])


    sumodd = 0
    for i in range(0, 8, 2):
        sumodd += arr[i]

    sumeven = 0
    for i in range(1, 8, 2):
        sumeven += arr[i]

    ssum = sumodd*3 + sumeven
    ret = 0 if ssum%10 else sumodd+sumeven
    print(f'#{tc} {ret}')

바코드의 세로 길이는 최소 5이므로, 입력으로 받아준 2차원 배열을 위에서 4번째부터 5의 간격으로 한 줄씩 조회를 한다. 이 때 바코드의 코드는 왼쪽은 0의 개수가 1개부터 3개까지 유동적이지만, 오른쪽은 반드시 1로 끝나므로, 왼쪽부터 조회해서 배열을 슬라이싱으로 처리하겠다. 때문에 위쪽부터 한 라인씩 내려오면서 오른쪽부터 왼쪽으로 조회하는 함수 find1()을 작성하였다. 1을 발견하면 해당 좌표를 반환하고 함수를 종료한다.

이 좌표를 받아 해당 좌표부터 왼쪽으로 56개의 수를 barcode 리스트에 담고, 이를 다시 슬라이싱으로 7개씩 8세트로 나누어 문자열로 치환한다. 이 치환한 문자열은 딕셔너리의 key로 이용하는데, 암호코드는 특별한 규칙 없이 임의로 배치되었기 때문에 딕셔너리를 사용하기로 하였다. 해당하는 2진수 7자리를 key로 하고, 10진수를 값으로 하여 이를 arr에 담는다. 모든 과정이 끝나면 8개의 숫자가 arr에 담기게 된다.

이를 홀수 번째 자릿수, 즉, 앞에서부터 짝수 인덱스는 sumodd에 합해 나중에 3배로 곱해주고, 홀수 인덱스는 sumeven에 합한다. 이를 더한 값을 ssum에 담는데, 만약 ssum이 10의 배수라면 암호이므로 sumodd와 sumeven을 더한 값을 출력하고, 10의 배수가 아니라면 암호가 아니므로 0을 출력하면 되겠다.


결과

PASS

댓글남기기