삼성SDS_백준14891_골드5_톱니바퀴 (구현_시뮬레이션)

RostoryT·2022년 10월 9일
0

Corporation_Coding Test

목록 보기
15/19

메모

  • 톱니바퀴 4개 일렬로

    • 1, 2, 3, 4번
    • 각각 8개의 톱니
      • 각 톱니는 N극 / S극
  • k번 회전

    • 1회 회전 시 톱니 위치가 좌/우로 한칸씩 이동
    • 시계방향 or 반시계방향(좌/우)
  • A를 회전시킬 때

    • 옆에 있는 톱니바퀴 B와 맞닿은 톱니의 극이 다르면 (A랑 B의 톱니가)

      • B는 A 반대방향으로 회전
    • 예를들어 다음과 같은 경우가 있으면

    • 두 톱니바퀴 맞닿은 부분이 초록색 점선일 때

      • 3번 톱니바퀴를 반시계(왼쪽)으로 회전(1칸)시키고 싶다.
      • 4번 톱니바퀴
        -> "(중요) 3번을 회전시키기 전에" 맞닿은 부분이 같은지 다른지를 체크한다!!
        -> 1. 같으면 회전 X
        -> 2. 다르면 3번의 반대 방향(오른쪽)으로 회전 (3-N, 4-S이므로)
        -> (주의할점) 4번 회전시켰는데 또 S면 "같은거" N 나올 때까지 돌려야할듯(여러 칸)
      • 2번 톱니바퀴
        -> 마찬가지로 수행
        -> 여기선 3번 톱니바퀴랑 맞닿은 부분이 S극으로 동일하기 때문에 회전 X
      • 1번은 2번이 회전하지 않았으므로 냅둠(처리할 필요가 있나 이거?)
  • 다음으로 1번이 시계(오른쪽)으로 회전시키고 싶다.
    • 2번 톱니바퀴
      -> 1번 회전시키기 전 맞닿은게 같은지 다른지 체크
      -> 회전시키자
    • 3번 톱니바퀴
      -> 2번이 회전했으므로 3번도 돌려야하는데,
      -> "(중요) 2번을 회전시키기 전에" 맞닿은게 같은지 다른지를 체크
      • 여기서 dfs처럼 해야하나??? (3번먼저-2번먼저-1번 이런느낌으로???)
    • 4번 톱니바퀴
      -> 3번이 회전했으므로 4번도 돌려야하는데,
      -> "(중요) 3번을 회전시키기 전에" 맞닿은게 같은지 다른지를 체크
      -> 3번 회전시키기 전에 4번과 맞닿은 부분이 동일하니까 회전 X

입출력 설명

입력

  1. 1번 톱니 상태
  2. 2번 톱니 상태
  3. 3번 톱니 상태
  4. 4번 톱니 상태
  • 톱니의 상태는 int값이고, 왼쪽부터 12시 방향 톱니부터 왼쪽순의 상태인거 (주의!!)
    • n극 : 0, s극 : 1 (사실 의미없음 0극 1극으로 생각)
  1. 회전할 횟수 k
  • 6번째 줄부터 k번 수행 ~> 회전방법 입력
  1. 회전시킬 톱니바퀴 번호, 왼/오방향
  • 1 : 오른쪽 // -1 : 왼쪽 <---- 이렇게 준 이유가 있을듯(주의!!)

    from collections import deque
    | help(deque) 하면
    | rotate(...)
    | Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.

출력

  • k번 회전시킨 이후 네 톱니바퀴의 점수 합 출력
    • 1번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 1점
    • 2번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 2점
    • 3번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 4점
    • 4번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 8점

중요 체크사항

  • 맞닿는 부분(체크해야할 위치)의 인덱스번호 (12시방향 톱니가 0번이니까)
    • 2번(좌), 6번(우)
    • 이걸 고려해야할지 모르겠으나,
      • 1번 바퀴는 2번만, 4번 바퀴는 6번만 체크하면 된다


방법 및 알고리즘

  • 뭐 rotate()함수 쓰면 돌리는건 될거같은데

  • recursive하게 연쇄적으로 돌려줘야하는게 조금 관건이네

    • 그리고 dfs처럼 회전이 발생한 바퀴로부터 가장 먼 바퀴부터 체크하고 돌려야 안꼬일듯
      • 회전시키기 전을 체크해야되니까
  • 대충 이렇게 접근하려 했는데

    • 완성본코드는 많이 다르긴함
    • 근데틀림
def turn_wheel(wheel_idx, direction):
    # 양옆 바퀴를 체크해야함 (이때 걔랑 맞닿는 부분) + 1234번에 따라 체크할 상대가 다름
    if wheel_idx == 0:
        # 다른 극이면 --> 옆 바퀴를 회전시킨다. --> 회전시키기 전에 걔의 옆에꺼를 체크해야한다!!!
        if wheels[wheel_idx][2] != wheels[wheel_idx+1][6]:
            turn_wheel(wheel_idx+1, direction * (-1))         # 옆 바퀴 인덱스랑 방향 반대로 넘겨줌 (중요)            
        else:
            옆에 바퀴는 회전시키지 않음
        돌아와서 wheel_idx를 direction방향으로 회전
        
    elif wheel_idx == 1 or wheel_idx == 2:    
        # 왼쪽 바퀴 확인
        # 다른 극이면 --> 옆 바퀴를 회전시킨다. --> 회전시키기 전에 걔의 옆에꺼를 체크해야한다!!!
        if wheels[wheel_idx][6] != wheels[wheel_idx-1][2]:
            turn_wheel(wheel_idx-1, direction * (-1))         # 옆 바퀴 인덱스랑 방향 반대로 넘겨줌 (중요)
        else:
            옆에 바퀴는 회전시키지 않음
        돌아와서 wheel_idx를 direction방향으로 회전
            
        # 오른쪽 바퀴 확인
        # 다른 극이면 --> 옆 바퀴를 회전시킨다. --> 회전시키기 전에 걔의 옆에꺼를 체크해야한다!!!
        if wheels[wheel_idx][2] != wheels[wheel_idx+1][6]:
            turn_wheel(wheel_idx+1, direction * (-1))         # 옆 바퀴 인덱스랑 방향 반대로 넘겨줌 (중요)
        else:
            옆에 바퀴는 회전시키지 않음
        돌아와서 wheel_idx를 direction방향으로 회전
            
            
    else:
        마찬가지로 진행

for k
    처음으로 회전시킬 바퀴를 회전하기 전에!!
    turn_wheel(turn[0], turn[1])
    # (필요없을듯??) 끝나고 돌아와서 wheels[turn[0]]을 rotate(turn[1])에 대해 한칸 돌려   <-- 이때 rotate() 파라미터 음수면 왼쪽으로임
    
answer = 0
if wheels[0][0] == 1:    answer += 1
if wheels[1][0] == 1:    answer += 2
if wheels[2][0] == 1:    answer += 4
if wheels[3][0] == 1:    answer += 8
print(answer)

솔루션 코드 - 내가 푼 (틀림)

  • 위에 수도코드형태로 쓴거 활용한건데
    • 너무 누더기 코드임ㅋ
    • 그리고 결정적으로 틀림
    • 테케 1,2는 맞는데 3에서 나가리됨
    • 어디서 잘못한듯
    • 아래 블로그 링크 넣어놨는데, 훨씬 심플하게 갈 수 있다
      • 내가 생각한거랑 같은 흐름이긴 한데, 내가 어디서 실수한듯
from collections import deque

''' 애초에 처음 돌릴때랑 그 다음부터 연쇄적으로 돌릴 때 구분했어야함'''
''' 처음 돌릴 때 2,3번째면 양옆을 다 봐야하는데, 그 다음부턴 한쪽방향으로만 쭉 가야함 => 안그럼 리커전 깊어져서 에러'''

def turn_wheel(wheel_idx, direction, gogo):    
    
    # 양옆 바퀴를 체크해야함 (이때 걔랑 맞닿는 부분) + 1234번에 따라 체크할 상대가 다름
    if wheel_idx == 0:
        # 1번 바퀴는 2번바퀴만 체크하고, 2번바퀴와 같은 톱니면 회전시킬 필요 X
        if wheels[wheel_idx][2] == wheels[wheel_idx+1][6]:
            return
            
    # 왼쪽 바퀴 확인            
    elif (wheel_idx == 1 or wheel_idx == 2) and gogo == "left":            
        if wheels[wheel_idx][6] != wheels[wheel_idx-1][2]:
            turn_wheel(wheel_idx-1, direction * (-1), "left")
            
    # 오른쪽 바퀴 확인
    elif (wheel_idx == 1 or wheel_idx == 2) and gogo == "right":
        if wheels[wheel_idx][2] != wheels[wheel_idx+1][6]:
            turn_wheel(wheel_idx+1, direction * (-1), "right")
        
    elif wheel_idx == 3:
        # 4번 바퀴는 3번바퀴만 체크하고, 3번바퀴와 같은 톱니면 회전시킬 필요 X
        if wheels[wheel_idx][6] == wheels[wheel_idx-1][2]:
            return
        
    #돌아와서 wheel_idx를 direction방향으로 회전
    wheels[wheel_idx].rotate(direction)
      


global wheels

wheels = []
for _ in range(4):
    wheel = deque(list(input()))
    wheels.append(wheel)

k = int(input())
num_k = [list(map(int, input().split())) for _ in range(k)]


# 회전시킬만큼 기기
for turn in turn_k:
    # index는 0부터 시작이므로 -1해줘야 안꼬임
    wheel_idx = turn[0]-1
    direction = turn[1]
    
    # 양옆 바퀴를 체크해야함 (이때 걔랑 맞닿는 부분) + 1234번에 따라 체크할 상대가 다름
    if wheel_idx == 0:
        # 다른 극이면 --> 옆 바퀴를 회전시킨다. --> 회전시키기 전에 걔의 옆에꺼를 체크해야한다!!!
        if wheels[wheel_idx][2] != wheels[wheel_idx+1][6]:
            turn_wheel(wheel_idx+1, direction * (-1), "right")         # 옆 바퀴 인덱스랑 방향 반대로 넘겨줌 (중요) 
                
    elif wheel_idx == 1 or wheel_idx == 2:    
        # 왼쪽 바퀴 확인 - 둘다확인
        if wheels[wheel_idx][6] != wheels[wheel_idx-1][2]:
            turn_wheel(wheel_idx-1, direction * (-1), "left")         # 옆 바퀴 인덱스랑 방향 반대로 넘겨줌 (중요)
            
        # 오른쪽 바퀴 확인 - 둘다확인
        if wheels[wheel_idx][2] != wheels[wheel_idx+1][6]:
            turn_wheel(wheel_idx+1, direction * (-1), "right")         # 옆 바퀴 인덱스랑 방향 반대로 넘겨줌 (중요)
        
    else:
        if wheels[wheel_idx][6] != wheels[wheel_idx-1][2]:
            turn_wheel(wheel_idx-1, direction * (-1), "left")         # 옆 바퀴 인덱스랑 방향 반대로 넘겨줌 (중요)
        
    #돌아와서 wheel_idx를 direction방향으로 회전
    wheels[wheel_idx].rotate(direction)
    
answer = 0
if wheels[0][0] == str(1):
    answer += 1
if wheels[1][0] == str(1):
    answer += 2
if wheels[2][0] == str(1):
    answer += 4
if wheels[3][0] == str(1):
    answer += 8
    
print(answer)
  • 2번테케 실행결과

  • 3번테케 실행결과 (틀림 ㅜㅜ)

솔루션 코드 - 블로그

profile
Do My Best

0개의 댓글