#13335

zzwwoonn·2022년 5월 5일
0

Algorithm

목록 보기
12/71

자 문제 끝까지 잘 읽었고, 문제 잘 이해했고, 예제 입력 1 2 3 전부 확인.

자 드가자 ㅡ

처음엔 슬라이딩 윈도우로 푸는 문제인가? (어디서 들어본 건 많음) 싶었다. 하지만 계속 손으로 따라 그려보니 배열로 시뮬레이션(구현)해보면 조건만 잘 넣어주면... 그냥 풀릴거 같은데? 싶었다. 그래서 무지성으로 대가리 먼저 박았다.

그 상태로 멈췄다. 도저히 정답이 안나온다. 예외가 뭐가 있는지를 모르겠다. 예제 입력은 다 맞게 나오는데... 이런 경우가 진짜 정말 ㅈ 아니 화가 난다.

패드 살거임. 나 짱구, 아무도 나 못말림. 나 진짜 진심.

계속 삽질(?) 아니지 예제는 다 맞췄자나? 삽질은 아니고 그냥 고민 ㅎ
계속 고민 하다가 정현이 형한테 코드를 보내줬고 조언을 좀 얻었다.

이전에 짰던 쓰레기같은 코드

carList = []
onRoad = []
n = w = L = i = cnt = sumW = totalCnt = 0
# 전역 변수로 다 놔두는거 안좋지만 print 함수 따로 만들어서 프로세스를 상세히 보기 위함

def processFunc():  
    global totalCnt, i, sumW, cnt

    while(1):
        if i > 0 and len(onRoad) == 0:
            break

        if cnt == w: # 다 기다린거 있으면 
            popValue = onRoad[0]
            onRoad.pop(0) # 젤 처음 들어온 트럭 빼주셈
            sumW -= popValue # 최대 무게 하중에서 그 트럭 무게 빼주셈
            
            if len(onRoad) == 0: 
                cnt = 0 # 도로 위가 다 비었으면 cnt = 0
            else: 
                cnt -= 1 # 도로 위에 좀 남아있으면 cnt -= 1

        if i >= n:
            pass # 트럭 전부다 도로위에 있거나 지나 갔거나 하면? 밑에 과정 해줄 필요가 없음 그냥 도로 위에 있는거 빠질 때까지 기다리면 됨
        else:
            oneValue = carList[i] # 이번에 다룰 차
            sumW += oneValue # 들어왔다 치고 무게 체크

            if sumW > L: # 무게가 최대 하중 넘으면?
                sumW -= oneValue # 무게 하중 체크하는거 고대로 다시 빼줘
            else:
                onRoad.append(oneValue) # 도로 위에 하나 올려주고
                # carList.pop(0) # 도로에 올라간 트럭은 빼주고
                i += 1 # 다음 트럭 들어오고
        cnt += 1 # 도로 위에 있는 트럭 cnt ++ , cnt 2가 되면 2번 기다렸다는거니까 다시 loop돌았을 때빼주면 댐
        totalCnt += 1 # while 1번 돌았으면 한타임 돌았다는거임

        printCheck()
        

def inputFunc():
    global n, w, L, carList

    n, w, L = map(int, input().split())
    carList = list(map(int, input().split()))


def printCheck():
    print("i = " , i, " cnt = ", cnt, " sumW = ", sumW ," totalCnt = ,", totalCnt)
    print(onRoad)
    
inputFunc()
processFunc()
print(totalCnt)

정현이 형 코드를 보고 내 코드를 봤을 때 (물론 c++이랑 python 이라 좀 다르겠지만?)

내가 찾은 문제점

  1. 전체적인 흐름을 생각하고 로직을 생각해서 뽝!!!!! 짜는 게 아니라 무턱대고 대가리부터 박으면서 코드를 쓰기 시작하니 이런 되도 않는 코드 (모든 예외의 상황을 변수로 다 잡아보려고 하는)가 나온 것 같다.

=> 아마 체스판 (이걸로 될까 안될까, 시간은 안넘칠까, 특별한 알고리즘이 있진 않을까와 같은 잡생각으로 몇 십분 몇 시간 째 짱구만 굴렸으나 결국 브루트포스가 정답이였다 라는 슬픈 얘기)을 풀고 나서의 영향인거 같다. 그냥 대가리부터 박는 건 역시 절대 안된다. 체스판처럼 풀어서도 안되고 트럭처럼 풀어서도 안된다. 하루 하루 느끼는 점이 정말.. 알차다..^^
( 어쩌면 정현이 형이 그걸 노리고 이 문제를 던져준 걸수도? )

  1. 트럭에서 pop(0) 이걸 적용 해볼 생각을 왜 못했을까?
    => 왜 굳이 굳이 i 로만 접근하려고 했나? 심지어 i 는 전역 변수로 선언해서 while loop 안에서 i++ 해가면서 루프를 성실하게 돌고있다. 많이 안풀어봐서 그렇다고.. 그렇게 자위하자.

  2. 큰 상관은 없지만 while(1) 하고 안에서 if 로 break 걸어주는게 아니라 while ( 다리 위에 트럭 ) 해주면 훨씬 간단하지 않은가? => 다리 위에 트럭이 없으면 반복문 종료 이것도.. 많이 안풀어봐서 잘 몰랐던걸로 ^^

그리고 어느 정도 문제점을 찾고 수정한 후 코드에 적용하였으나 Index Error 가 계속 나온다. Syntax 가 아닌게 어디냐고..^^ ㅎㅎ

4 2 10
7 4 5 6 을 입력으로 줬을 때

OnRoad 에 6 하나 들어있고 carList 에는 아무것도 없을 상황을 가정해보자.

마지막 차(6)가 도로 위에 올라가 있는 상황이다. carList에는 아무 것도 없으므로 값을 읽을 수 없다. -> index Error

바로 예외처리 해주시고
(끝나고나서 구글링을 통해 가장 짧은 코드를 찾아보니.. 이런 예외 처리도 필요없게 짜놨더라) 근데 이게 정답이 아닌건 아니자나? 나도 잘 풀었다고 생각함. 아무튼ㅡㅡ

내가 짠 맞췄습니다!! 코드

n, w, L = map(int, input().split())
carList = list(map(int, input().split()))
onRoad = [0] * w
# print(onRoad)

# sumW = 0
#  파이썬 내장 함수로 배열 안의 값들을 전부 합해주는 함수가 있다. 그걸 써본다
totalCnt = 0

while(onRoad):
    # 도로 위에 트럭이 없어질 때까지 ㄱ

    onRoad.pop(0) # 앞 자리 하나 비워

    if(carList):
        # 차가 있을 때
        oneValue = carList[0] # 이번에 다룰 차
    
        if sum(onRoad) + oneValue > L : # 무게 체크, 10보다 크면?
            # sum(배열) => 배열의 무게를 자동으로 계산해줌, 이걸 왜 몰랐을까? 알면서 안쓴건가
            onRoad.append(0)

        else: # 무게 체크, 10(w)보다 작으면? 
            onRoad.append(carList.pop(0)) # 2줄로 짤걸 한 줄로 줄여!!!!
            # carList에서 젤 앞에 있는 놈 -> truck 빼서 도로에 올려
    else:
        onRoad.append(0)
        if sum(onRoad) == 0:
            totalCnt += 1
            break
    
    # 한바퀴 돌리면 totalCnt ++
    totalCnt += 1
    # print(onRoad)
    # print("totalCnt = ", totalCnt)
    # input()

print(totalCnt)

추가로

이 문제랑은 좀 별개의 문제인데 조환규 교수님의 수업을 듣다보니 엘레강스한 코드~ 짧은 코드~ 보기 쉬운 코드~ 등등 좋은(?) 얘기, 조언 ,팁들을 많이 들었다. 그래서 그렇게 짜려고 노력도 많이 한다. 코드를 보면 알겠지만 지금까지도 그래왔다.

근데 중요한 건 에러가 난무한다. 전역 변수 스코프 에러가..

스코프를 완벽하게 이해하지 못하고 있는 건지..
(이건 절대 아닐거야. 그래야만 해. 코딩 얼마나 했는데? 이걸?)

파이썬에서의 스코프 동작 원리를 모르는 건지... (JS를 계속 공부하다보니 또 한번씩 헷갈리고 막 그런다. 그렇다 핑계다.)

물론 나도 이왕 코딩하고 알고리즘 문제 푸는거 다시 디버깅하기도 편하게 입력 함수, 실행 함수 나눠서 짜고 안에 세부적인 함수도 다 따로 빼주고 깔끔하고 엘레강스한 코드를 짜고 싶다. 정말 그렇다. 최대한으로 그렇게 해왔었다.

근데 지금 나는 너무나 미개한 까닭에 알고리즘 짜기도 빠듯한 시간에 이런 사소한 부분까지 신경쓰기엔 시간이 턱없이 부족하다.

결론은.

모든 문제에서 일단 “맞췄습니다!!” 부터 띄우고, 그 다음 다시 코드를 돌이켜 생각해보는 걸로 하자.

0개의 댓글