[Softeer][21년 재직자 대회 예선] 전광판 문제
문제
전광판은 최대 다섯 자리의 자연수만을 표시할 수 있도록, 아래와 같이 육각형 모양의 전구 7×5=35개로 구성되어 있다.
각각의 전구에는 스위치가 달려 있다. 전구에 달려 있는 스위치를 누를 때, 그 전구가 켜져 있었다면 꺼지고, 그 전구가 꺼져 있었다면 켜진다.
지금 전광판에 자연수 A가 표시되어 있는데, 유가가 변동됨에 따라 전광판에 표시된 자연수를 B로 바꿔야 한다. 이러한 목표를 달성하기 위해 스위치를 최소 몇 번 눌러야 하는지를 구하는 프로그램을 작성하라.
제약조건
하나의 입력에서 1개 이상 1000개 이하의 테스트 케이스를 해결해야 한다.
A와 B는 한 자리 이상 다섯 자리 이하의 자연수이다.
A와 B는 숫자 0으로 시작하지 않는다.
A와 B는 서로 다르다.
입력형식
첫 번째 줄에 해결할 테스트 케이스의 수 T가 주어진다.
다음 T개의 줄에는 한 줄에 테스트 케이스 하나씩이 주어진다. 각각의 줄에는 두 자연수 A와 B가 공백 하나를 사이로 두고 주어진다.
각각의 테스트 케이스마다 순서대로, 스위치를 눌러야 하는 최소 횟수를 한 줄에 하나씩 출력한다.
2 1 2 9881 10724
5 11
입력예제2
2 111 11 11 11111
출력예제2
2 6

풀이
처음 문제를 봤을 때 스위치 변환 개수를 알기위해서는 각 숫자별(1~9)별 어떤 스위치를 켜고 끄는지 기록해야한다고 생각하여 8칸짜리 list에 1혹은0으로 표시하고자 생각했다.
이를 위해 숫자 list를 만들려면 9개 list에 내부에 list가 또 있는 형태를 만들어야하는데 이보다 이진법을 이용하기로 했다.
즉 7자리의 이진수로 표현하고 이를 num_dict에 이용한다.
테스트 케이스 T에 관해 한줄 한줄 테스트 케이스가 주어진다. 또한 A와 B는 한자리 이상 5자리 이하 자연수임으로
만일 1이 주어지는 경우 00001로 변경해야한다.
가장 중요한건 새롭게 추가된 0 즉, 1이 들어오면 00001인데 이때 추가된 0은 불이 모두 꺼진 상태이다.
이를 위해 .zfill()이 아닌 rjust를 이용한다.
마지막으로 두 숫자에 관해서 bulb가 몇개가 변했는가는
0*1 = 1혹은 1*0 =1 인 경우임으로 XOR연산을 적용한다.
그럼으로 코드는 아래와 같을 것이다.
import sys
num_bulb = {
'0': 0b1111110, # 0
'1': 0b0110000, # 1
'2': 0b1101101, # 2
'3': 0b1111001, # 3
'4': 0b0110011, # 4
'5': 0b1011011, # 5
'6': 0b1011111, # 6
'7': 0b1110010, # 7
'8': 0b1111111, # 8
'9': 0b1111011, # 9
' ': 0b0000000 # fill
}
T = int(input())
for _ in range(T):
a, b = input().split()
a = str(a).rjust(5, " ")
b = str(b).rjust(5, " ")
switch_count = 0
for i in range(5):
digit_a = a[i]
digit_b = b[i]
digit_a = num_bulb[digit_a]
digit_b = num_bulb[digit_b]
switch_count += bin(digit_a ^ digit_b).count('1')
print(switch_count)