Python/online judge

Softeer [level2.전광판] | Python

구름솜:D 2024. 2. 2. 12:12
728x90

✏️ 문제

https://softeer.ai/practice/6268

 

Softeer - 현대자동차그룹 SW인재확보플랫폼

 

softeer.ai

 

 

✏️ 풀이방법

1. 2차원리스트(light)에 디지털 숫자(0~9)와 불이 들어오지 않았을 때를 표기할 수 있는 방법을 담는다. 0은 꺼져있는 전구, 1은 켜져있는 전구를 의미한다.

- 숫자로 담는 것 보다 문자열로 담는 것이 활용할 수 있는 메소드가 많기때문에 문자열로 담았다.

2. 전광판에 표시되는 디지털 숫자는 5개이기 때문에 두 자연수 a,b를 원소의 개수가 5개로 지정된 리스트에 담고 왼쪽부터 비어있는 자리는 '!로 대체해서 불이 들어오지 않은 것을 표기해준다.

- 예를 들어 자연수 1이면 ! ! ! ! 1로 표기해서 !는 전광판에 불이 들어오지 않은것을 알려준다.

3. 테스트 케이스가 여러개이기에 헷갈리지 않기 위해서 aboard,bboard에 하나의 케이스씩 실행 할 수 있도록 한다.

4. 2차원리스트(light)의 인덱스를 사용해서 디지털 숫자로 불이 켜져있는 곳을 확인한다. 불이 들어오지 않았을 때의 인덱스 값이 10이기 때문에 !로 표기한 것은 10으로 바꿔서 계산한다.

5. 각 테스트 케이스의 자연수에 해당하는 디지털 숫자로 바꿔 비교한 후 스위치를 눌러야하는 경우만 count한다. 

 

 

📌 코드

light =[['1','1','1','0','1','1','1'],
        ['0','0','0','0','0','1','1'],
        ['0','1','1','1','1','1','0'],
        ['0','0','1','1','1','1','1'],
        ['1','0','0','1','0','1','1'],
        ['1','0','1','1','1','0','1'],
        ['1','1','1','1','1','0','1'],
        ['1','0','1','0','0','1','1'],
        ['1','1','1','1','1','1','1'],
        ['1','0','1','1','1','1','1'],
        ['0','0','0','0','0','0','0']]
n = int(input())
for _ in range(n):
        a,b = map(lambda x:x.rjust(5,'!'),input().split())
        aboard, bboard = [], []
        cnt = 0
        for i in range(5):
                aboard.append(a[i])
                bboard.append(b[i])
                if '!' in aboard:
                        aboard[i] = '10'
                if '!' in bboard:
                        bboard[i] = '10'
                if aboard[i] != bboard[i]:
                        for k in range(7):
                                if light[int(aboard[i])][k] != light[int(bboard[i])][k]:
                                        cnt +=1
        print(cnt)

 

 

📌 결과

#입력
2
111 11
11 11111

#출력
2
6
#입력
2
1 2
9881 10724

#출력
5
11

 

 

🤔 시행착오.1

n = int(input())
ab = [list(map(list,input().split())) for _ in range(n)]
print(ab)
[[['1'], ['2']], [['9', '8', '8', '1'], ['1', '0', '7', '2', '4']]]

- 내가 원했던 것은 [ ['1', '2'],['9', '8', '8', '1','1', '0', '7', '2', '4']] 이런데 a,b가 구분될 수 있는 2차원의 불가능하고 이상한 구조를 그렸었다. 위처럼 실행하면 3차원 구조로 원소를 접근하는데 불편할 것 같았다.

 

 

🤔 시행착오.2

n = int(input())
ab = [list(map(int,format(input().split(), '05'))) for _ in range(n)]
print(ab)
    ab = [list(map(int,format(input().split(), '05'))) for _ in range(n)]
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported format string passed to list.__format__

- 전광판에 표기되는 숫자는 5개이기 때문에 불이 들어 오지 않는 곳을 format함수를 사용해서 0으로 채우려고 리스트에 변수를 입력하려고 했으나 format은 메소드로 문자열 객체에만 전달이 가능하다. 그래서 split()을 하면 리스트가 반환되기 때문에 리스트 객체로 잘못된 형식을 전달했다는 오류가 발생한다. 

 

* 아래와 같이 수정하면 정상실행이 가능하다.

n = int(input())
ab = [list(map(lambda x: format(int(x), '05'),input().split())) for _ in range(n)]
print(ab)
[['00001', '00002'], ['09881', '10724']]

 

 

 

🤔 시행착오.3

n = int(input())
ab = [list(map(int,input().split())) for _ in range(n)]
# 0은 꺼져있는 전구, 1은 켜져있는 전구
light =[[0,0,0,0,0,0,0],
        [0,0,0,0,0,1,1],
        [0,1,1,1,1,1,0],
        [0,0,1,1,1,1,1],
        [1,0,0,1,0,1,1],
        [1,0,1,1,1,0,1],
        [1,1,1,1,1,0,1],
        [1,0,1,0,0,1,1],
        [1,1,1,1,1,1,1],
        [1,0,1,1,1,1,1]]

cnt = 0
for i in range(n):
        a = list(map(int,format(ab[i][0], '05')))
        b = list(map(int,format(ab[i][1], '05')))
        for j in range(5):
                if a[j] != b[j]:
                        aboard = light[a[j]]
                        bboard = light[b[j]]
                        print(aboard, bboard)
                        for k in range(7):
                                if light[a[j]][k] != light[b[j]][k]:
                                        cnt += 1
                        print(cnt)

- 디지털 숫자 0과 불이 들어오지 않는 경우를 구분하지 않고 풀이해서 불이 들어오지 않는 경우가 다 0으로 계산되어 버렸다.

 

 

🤔 시행착오.4

n = int(input())
ab = [list(map(lambda x: x.zfill(5),input().split())) for _ in range(n)]
[['00001', '00002'], ['09881', '10724']]

- 처음에는 불이 꺼져있는 자리를 zfill을 사용해서 0으로 채우려고 했는데 이러면 숫자 0을 디지털 숫자로 표기했을 때랑 불이 꺼져있는 경우를 구분할 수 없는 문제가 생긴다. 그래서 rjust로 특정 문자('!')로 불이 꺼져있는 경우를 구분하기로 했다. 

- 이에 ab리스트 안의 리스트의 원소를 문자열로 받아서 문자열 함수를 사용할 수 있기에 디지털 숫자 표기도 문자열로 하는 것이 유리하다고 생각했다.

 

 

🤔 시행착오.5

light =[['1','1','1','0','1','1','1'],
        ['0','0','0','0','0','1','1'],
        ['0','1','1','1','1','1','0'],
        ['0','0','1','1','1','1','1'],
        ['1','0','0','1','0','1','1'],
        ['1','0','1','1','1','0','1'],
        ['1','1','1','1','1','0','1'],
        ['1','0','1','0','0','1','1'],
        ['1','1','1','1','1','1','1'],
        ['1','0','1','1','1','1','1'],
        ['0','0','0','0','0','0','0']]
n = int(input())
for _ in range(n):
        a,b = map(lambda x:x.rjust(5,'!'),input().split())
        aboard, bboard = [], []
        cnt = 0
        for i in range(5):
                aboard.append(a[i])
                bboard.append(b[i])
                if '!' in aboard:
                        a[i] = '10'
                if '!' in bboard:
                        b[i] = '10'
                if aboard[i] != bboard[i]:
                        for k in range(7):
                                 if light[int(aboard[i])][k] != light[int(bboard[i])][k]:
                                        cnt +=1
                        print(cnt)
    a[i] = '10'
    ~^^^
TypeError: 'str' object does not support item assignment

- 불이 들어오지 않는 것을 !로 표시한 것을 light의 인덱스를 활용하기 위해 '10'으로 변경해야하는 데 aboard리스트에 적용하려고 했는데 헷갈려가지고 a문자열에 바꾸려고해서 타입에러가 발생했다. 문자열은 interable한 객체가 아닌 변형 불가의 자료형이기 때문에 데이터를 바꿀 수 없어서 나타나는 에러이다. 

 

 

🔎 다른풀이

import sys
# 맨 위 idx를 0, 왼쪽을 1, 오른쪽을 2 아래를 3 ... 방식으로 숫자를 만들 경우 필요한 전구 미리 정의
num2lamp = {"0" : set([0, 1, 2, 4, 5, 6]),    
            "1" : set([2, 5]),    
            "2" : set([0, 2, 3, 4, 6]),    
            "3" : set([0, 2, 3, 5, 6]),    
            "4" : set([1, 2, 3, 5]),    
            "5" : set([0, 1, 3, 5, 6]),    
            "6" : set([0, 1, 3, 4, 5, 6]),    
            "7" : set([0, 1, 2, 5]),   
            "8" : set([0, 1, 2, 3, 4, 5, 6]),    
            "9" : set([0, 1, 2, 3, 5, 6]),    
            " " : set()}
# test case 수
test_case = int(input())
for _ in range(test_case):    
    num_a, num_b = input().split()    
# zero padding    
    num_a = num_a.rjust(5, " ")    
    num_b = num_b.rjust(5, " ")    
    count = 0    
for a, b in zip(num_a, num_b):        
# 같을 경우 개수 안 세도 됨        
    if a == b:            
        continue        
    else:            
    # a에만 있으면 꺼야함            
    off = len(num2lamp[a] - num2lamp[b])            
    # b에만 있으면 켜야함   
    on = len(num2lamp[b] - num2lamp[a])            
    count += int(on + off)    # 결과 출력                    
print(count)

- https://only-wanna.tistory.com/entry/파이썬-소프티어-전광판

-  전구를 리스트가 아닌 딕셔러니 형태로 저장했다.  

 

 

📝 메모

- 문제를 풀다보니 for문을 세 번 돌려야 할 것 같았다 그러면 시간복잡도가 비효율적일것같다는 생각에 다른 방법으로 풀 수 없을 까 고민했었다. 하지만 결국엔 3중 for문으로 풀었다. 근데 생각해 보면 제약조건에 보면 테스트케이스가 1000까지이다. 시간 복잡도는 테스트케이스가 많거나 주어지는 개수가 아주 많을 때 고려해야하는 것 같다.

- 그래도 시간 복잡도도 생각하고 이제 문제 내애서 힌트도 얻으려고 하는 걸 보니 코테를 푸는데 아주 조금씩 느리지만 천천히 성장하고 있는 것 같다