import sys
sys.stdin = open("단순 2진 암호코드.txt")
# 패턴이 키 값이 되는 형태
pattern_dic = {
"0001101": 0,
"0011001": 1,
"0010011": 2,
"0111101": 3,
"0100011": 4,
"0110001": 5,
"0101111": 6,
"0111011": 7,
"0110111": 8,
"0001011": 9,
}
T = int(input())
for tc in range(1, T + 1):
# N: 배열의 세로 크기
# M: 배열의 가로 크기
N, M = map(int, input().split())
ARR = [input() for _ in range(N)]
# 배열을 탐색하며 1이 있는지 확인합니다.
start_r = -1
for i in range(N):
if "1" in ARR[i]:
start_r = i
break
# 7줄만 남기고 배열을 잘라내자
ARR = ARR[start_r:start_r + 7]
# 열 잘라내기
# 뒤에서부터 탐색
end_c = M
for i in range(M - 1, -1, -1):
# 모든 암호가 1로 끝나기 때문에, 맨 뒤를 확인한다.
if ARR[0][i] == "1":
end_c = i
break
# 우리가 찾아야 탐색해야 할 문자열
secret_text = ARR[0][end_c - 55:end_c + 1]
solve_list = []
for i in range(0, 56, 7):
temp_secret = secret_text[i:i + 7]
solve_list.append(pattern_dic[temp_secret])
# 검증 과정
confirm_number = 0
for i in range(8):
if (i + 1) % 2:
confirm_number += int(solve_list[i]) * 3
else:
confirm_number += int(solve_list[i])
# 검증 실패 시 0 출력
result = 0
if confirm_number % 10 == 0:
result = sum(solve_list)
print(f"#{tc} {result}")
암호 패턴에 해당하는 값을 대응시키기 위해 딕셔너리를 선언하였다.
키값으로 암호 문자열을 두어도 되고, 해독한 숫자로 해도 될 것 같지만 이 문제는 암호화 된 것을 풀어내는 과정으로 진행되고 있기 때문에 암호 패턴을 키값으로 설정하였다.
필요 없는 문자열은 잘라주었다.
행
동일한 암호 문자열이 몇 개의 행에 걸쳐 존재하는데, 해독을 위해서는 한 줄만 알아도 되기 때문에 암호 문자열에만 포함된 1을 찾아 해당 행만 남겨주었다.
열
암호 패턴이 0으로 시작하기 때문에, 앞에서부터 찾는 것은 다소 어려울 수 있다는 생각이 들었다.
살펴보니 모든 암호 패턴은 1로 끝나는 것을 확인할 수 있었고, 잘라낸 행을 뒤에서부터 탐색하여 1을 찾는 것으로 실제 암호 패턴의 위치를 찾을 수 있었다.
decryption = {
'0001101': 0,
'0011001': 1,
'0010011': 2,
'0111101': 3,
'0100011': 4,
'0110001': 5,
'0101111': 6,
'0111011': 7,
'0110111': 8,
'0001011': 9
}
T = int(input())
for tc in range(1, T + 1):
N, M = map(int, input().split())
arr = [input() for _ in range(N)]
code = ''
for i in range(N):
for j in range(M -1, -1, -1):
if arr[i][j] == '1':
code += arr[i][j - 55 : j + 1]
dcode= []
start, end = 0, 7
for i in range(8):
dcode.append(decryption[code[start:end]])
start += 7
end += 7
if ((dcode[0] + dcode[2] + dcode[4] + dcode[6]) * 3 + dcode[1] + dcode[3] + dcode[5] + dcode[7]) % 10 == 0:
print('#{} {}'.format(tc, sum(dcode)))
else:
print('#{} {}'.format(tc, 0))
T = int(input())
number = [
[0,0,0,1,1,0,1],
[0,0,1,1,0,0,1],
[0,0,1,0,0,1,1],
[0,1,1,1,1,0,1],
[0,1,0,0,0,1,1],
[0,1,1,0,0,0,1],
[0,1,0,1,1,1,1],
[0,1,1,1,0,1,1],
[0,1,1,0,1,1,1],
[0,0,0,1,0,1,1]
]
for tc in range(1,T+1):
N, M = map(int, input().split())
arr = []
# 행을 받아와서 1이 있는 행의 인덱스값 추출
for i in range(N):
arr += [list(map(int, ' '.join(input()).split()))]
if 1 in arr[i]:
ob_i = i
# 사용할 행만 따로 뽑기
data = list(arr[ob_i])
# 역순으로 방문하여 1이되는 열 인덱스 파악
for i in range(M-1,-1,-1):
if data[i] == 1:
ob_i = i
break
# 숫자 섹션을 나누어서 암호숫자와 대비, 숫자 찾기
num_res = []
data = data[ob_i-55:ob_i+1] # 해당 인덱스 추출
for i in range(0,56,7):
section = data[i:i+7] # 섹션 뽑기
for j in range(len(number)): # 암호숫자 비교
cnt = 0
for k in range(7):
if section[k] == number[j][k]:
cnt += 1
if cnt == 7: # 완전히 일치하면 저장
num_res += [j]
break
# 암호 유효성 판별
temp1 = 0 # 홀수자리 합
temp2 = 0 # 짝수자리 합
for i in range(7):
if i % 2:
temp2 += num_res[i]
else:
temp1 += num_res[i]
if (temp1*3+temp2+num_res[7]) % 10 or not (temp1+temp2+num_res[7]):
res = 0
else:
res = temp1+temp2+num_res[7]
print('#{} {}'.format(tc,res))
역순으로 열을 탐색하는 방법이 동일
암호 패턴 해석을 위해 이중배열을 선언한 것에서 차이를 발견할 수 있었다.
배열로 선언하다보니 암호숫자를 비교하는 과정에서 반복문이 여러번 사용되고 있는데, 개인적으로는 딕셔너리로 접근하는 것이 깔끔하다고 생각하지만 어느것이 우월하다 할 필요는 없을 듯 하다.