카카오 2차 - 2021

dasd412·2022년 2월 1일
0

코딩 테스트

목록 보기
1/71

전체 코드

import requests
import json
from collections import deque

x_auth_token="자신 문제의 토큰 참고"
url="https://kox947ka1a.execute-api.ap-northeast-2.amazonaws.com/prod/users"
dx=(-1,1,0,0)
dy=(0,0,-1,1)
INF=987654321
EMERGENCY_STANDARD=2


def start(problem):
    uri=url+"/start"
    return requests.post(uri,headers={'X-Auth-Token':x_auth_token, 'Content-Type':'application/json'},params={'problem':problem}).content

def locations(auth_key):
    uri=url+'/locations'
    return requests.get(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'}).content


def trucks(auth_key):
    uri=url+"/trucks"
    return requests.get(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'}).content

def simulate(auth_key,parameter):
    uri=url+'/simulate'
    return requests.put(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'},json={'commands':parameter}).content

def score(auth_key):
    uri=url+'/score'
    return requests.get(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'}).content


class Rent:
    def __init__(self,id,problem):
        if problem==1:
            self.bikes=4
        else:
            self.bikes=3
    
        self.id=id

    def has_bike(self)->bool:
        return self.bikes>0

    def __repr__(self):
        return "id:"+str(self.id)+", bikes:"+str(self.bikes)

    def update_bike(self,bikes_count):
        self.bikes=bikes_count

class Truck:
    def __init__(self,idx,x,y,territory):
        self.id=idx
        self.x=x
        self.y=y
        self.bikes=0
        self.command=[]
        #id list of rent 
        self.territory=territory
        #go or stop flag
        self.ongoing=False

    def __repr__(self):
        return " id : "+str(self.id) +" x :"+str(self.x)+" y: "+str(self.y)+" bikes : "+str(self.bikes)+" command: "+str(self.command)

    def has_space(self)->bool:
        return self.bikes<=20

    def ride_on(self):
        if self.has_space():
            self.bikes+=1
            self.command.append(5)
    
    def ride_off(self):
        if self.bikes>0:
            self.bikes-=1
            self.command.append(6)

    #get most bikes in trucks'own territory
    def get_most_area(self,rent_dict,rent_id_dict):
        most_id=-1
        most_count=-1

        for rent_id in self.territory:
            (x,y)=rent_id_dict[rent_id]
            bike_count=rent_dict[(x,y)].bikes
            if most_count<bike_count:
                most_count=bike_count
                most_id=rent_id

        return (most_id,most_count)

    #get min bikes in trucks'own territory
    def get_min_area(self,rent_dict,rent_id_dict):
        min_id=-1
        min_count=INF
        
        for rent_id in self.territory:
            (x,y)=rent_id_dict[rent_id]
            bike_count=rent_dict[(x,y)].bikes
            if min_count>bike_count:
                min_count=bike_count
                min_id=rent_id
        
        return (min_id,min_count)

    def BFS(self,start,end,rent_dict,rent_id_dict,length):

        area_responsible=[]

        for area in self.territory:
            dimension=rent_id_dict[area]
            area_responsible.append((dimension[0],dimension[1]))

        start_x,start_y=start
        end_x,end_y=end

        visited=[[False]*length for _ in range(length)]
        queue=deque()
        
        visited[start_x][start_y]=True
        queue.append((start_x,start_y,[]))

        while queue:
            x,y,command=queue.popleft()

            if x==end_x and y==end_y:
                
                return command

            for i in range(4):
                adjx=x+dx[i]
                adjy=y+dy[i]

                if adjx<0 or adjy<0 or adjx>=length or adjy>=length:
                    continue

                if (adjx,adjy) in area_responsible and visited[adjx][adjy]==False:
                    visited[adjx][adjy]=True

                    #i-> 0:north, 1:south, 2:west , 3:east
                    #command -> north:1, south:3, west:4, east:2
                    new_command=command[:]
                    if i==0:
                        new_command.append(1)
                    elif i==1:
                        new_command.append(3)
                    elif i==2:
                        new_command.append(4)
                    else:
                        new_command.append(2)
                    queue.append((adjx,adjy,new_command))
                    
                    

    #move current -> most ->min
    def move(self,most_id,min_id,rent_dict,rent_id_dict,length):
        self.ongoing=True

        current_x=self.x
        current_y=self.y

        most_x,most_y=rent_id_dict[most_id]
        min_x,min_y=rent_id_dict[min_id]

        ride_number=(rent_dict[(most_x,most_y)].bikes-rent_dict[(min_x,min_y)].bikes)//2
        if ride_number==0:
            ride_number+=1
        # print('ride',self.id,ride_number,(current_x,current_y),(most_x,most_y),(min_x,min_y))

        
        current_most_command=self.BFS((current_x,current_y),(most_x,most_y),rent_dict,rent_id_dict,length)
        # print('cmc',current_most_command)
        most_min_command=self.BFS((most_x,most_y),(min_x,min_y),rent_dict,rent_id_dict,length)
        # print('mmc',most_min_command)

        self.command.extend(current_most_command)

        for i in range(ride_number):
            if self.has_space():
                self.ride_on()
        
        self.command.extend(most_min_command)

        for i in range(ride_number):
            self.ride_off()

        #at end, insert stop command
        self.command.append(0)

        self.x=min_x
        self.y=min_y

    def pop_command(self):
        pop=[]

        #6 seconds*10 => 1 min
        for six_seconds in range(10):
            if len(self.command)>0:
                #FIFO
               pop.append(self.command.pop(0))
            else:
                #do nothing
                pop.append(0) 

        for cmd in pop:
            if cmd==0:
                self.ongoing=False
                break

        return pop

def simulate_problem1():

    start_response=start(1)
    auth_key=json.loads(start_response)['auth_key']
    
    Trucks=[]

    #ids of rent
    territory1=[2,3,4,8,9]
    territory2=[14,18,19,23,24]
    territory3=[0,1,5,6,10]
    territory4=[15,16,20,21,22]
    territory5=[7,11,12,13,17]

    territory_list=[territory1,territory2,territory3,territory4,territory5]

    for i in range(5):
        if i==0:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory1))
        elif i==1:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory2))
        elif i==2:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory3))
        elif i==3:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory4))
        else:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory5))
        
    rent_dict=dict()
    rent_id_dict=dict()

    rent_id=0
    j=0
    while j<5:
        i=4
        while i>=0:
            rent_dict[(i,j)]=Rent(rent_id,problem=1)
            rent_id_dict[rent_id]=(i,j)

            rent_id+=1
            i-=1
        j+=1
    


    # #start->10:00 am ~ end ->10:00 pm  , per one minute
    # 720 minute means 12 hour
    for times in range(720):
        print('times',times)
        #get rent status in server
        location_list=json.loads(locations(auth_key=auth_key))
        #update bikes of  rent objects
        for location in location_list['locations']:
            
            rent_id=location['id']
            located_bikes=location['located_bikes_count']
            rent_dict[rent_id_dict[rent_id]].update_bike(located_bikes)

        #get truck status in server
        truck_list=json.loads(trucks(auth_key=auth_key))
        
        for truck in truck_list['trucks']:
            truck_id=truck['id']
            location_id=truck['location_id']
            loaded_bikes_count=truck['loaded_bikes_count']
            


        # print('truck status ',truck_list['trucks'])
        # print()

        if times==0:
            Trucks[0].command=[1,1,1,1,0,0,0,0,0,0]
            Trucks[0].x=0
            Trucks[0].y=0

            Trucks[1].command=[1,1,1,1,2,2,2,2,0,0]
            Trucks[1].x=0
            Trucks[1].y=4

            Trucks[2].command=[0,0,0,0,0,0,0,0,0,0]
            Trucks[2].x=4
            Trucks[2].y=0

            Trucks[3].command=[2,2,2,2,0,0,0,0,0,0]
            Trucks[3].x=4
            Trucks[3].y=4

            Trucks[4].command=[2,2,1,1,0,0,0,0,0,0]
            Trucks[4].x=2
            Trucks[4].y=2

        else:
        #my strategy
            for truck_obj in Trucks:
                if truck_obj.ongoing==False:
                    (most_id,most_count)=truck_obj.get_most_area(rent_dict,rent_id_dict)
                    (min_id,min_count)=truck_obj.get_min_area(rent_dict,rent_id_dict)
                    # print(truck_obj.id, most_id, most_count,min_id,min_count)

                    if min_id==-1 or most_id==-1 or most_count==min_count or min_count>EMERGENCY_STANDARD:
                        continue
                
                    truck_obj.move(most_id,min_id,rent_dict,rent_id_dict,length=5)
                    # print('after',truck_obj)
            

        # #collect command and simulate
        command=[]
        for truck_obj in Trucks:
            pop=truck_obj.pop_command()
            command.append({'truck_id':truck_obj.id, "command":pop})

        # print('cmd',command)
        simulate_result=json.loads(simulate(auth_key=auth_key, parameter=command))
        print('simulate',simulate_result)
        print()


    result=json.loads(score(auth_key=auth_key))
    print('score',result["score"])

if __name__=="__main__":
    simulate_problem1()

해설

1.서버와의 통신을 위한 코드를 작성한다.

가장 먼저 해야할 일은, 서버와의 통신을 위한 코드 작성이다.

파이썬에서 rest 통신을 하려면 requests 모듈을, json 처리작업을 하려면 json 모듈을 import해야 한다.

참고로,프로그래머스 과제관에 있는 해당 문제에 실제로 들어가보면, 자신에게 발급된 토큰이 있을 것이다. 이 토큰은 개인마다 다르므로 자신의 토큰 문자열을 복사해서 풀어야 한다.

그리고 문제에 있는 url은 문자열로 복사해서 풀면 된다. 직접 링크로 들어가보면 오류가 뜨는 데, 무시하고 문자열로 복사해서 풀자.

어쨋든, API 설명을 읽고 requests모듈과 json모듈을 활용하여 서버와 통신하는 함수들을 작성한다. 실제로 실행해서 response의 content를 출력해보면, API 설명에 나와있는 response를 확인할 수 있다.

여기서 start()함수의 인자인 problem은 문제의 번호를 뜻한다. 내 코드는 1만 있으니까, 1번 시나리오에 대해서만 푼 코드이다. 2번까지 풀려면 start(2)도 호출할 필요가 있다.

import requests
import json
from collections import deque

x_auth_token="자신 문제의 토큰 참고"
url="https://kox947ka1a.execute-api.ap-northeast-2.amazonaws.com/prod/users"
dx=(-1,1,0,0)
dy=(0,0,-1,1)
INF=987654321
EMERGENCY_STANDARD=2


def start(problem):
    uri=url+"/start"
    return requests.post(uri,headers={'X-Auth-Token':x_auth_token, 'Content-Type':'application/json'},params={'problem':problem}).content

def locations(auth_key):
    uri=url+'/locations'
    return requests.get(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'}).content


def trucks(auth_key):
    uri=url+"/trucks"
    return requests.get(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'}).content

def simulate(auth_key,parameter):
    uri=url+'/simulate'
    return requests.put(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'},json={'commands':parameter}).content

def score(auth_key):
    uri=url+'/score'
    return requests.get(uri,headers={"Authorization":auth_key,'Content-Type':'application/json'}).content

def simulate_problem1():
		#서버에게 1번 문제를 시작하겠다고 start(1)함수를 호출한다.
    start_response=start(1)
		#지급 받은 키. 서버와의 통신에 사용되는 모든 함수의 파라미터로 쓰인다. (세션 정보 같은 것으로 보면 된다.)
    auth_key=json.loads(start_response)['auth_key']

if __name__=="__main__":
    simulate_problem1()

2.문제 해결을 위한 전략을 세운다.

내가 세운 전략은 '각 트럭을 구역마다 배치한다'+'해당 구역에서 2개보다 적게 자전거가 있는 곳이 발생하면, 해당 구역 중 자전거가 가장 많은 곳에서 자전거를 가져온다 '

먼저, 각 트럭을 배치한 그림은 다음과 같다.

트럭이 총 5개이고, 맵도 5*5칸이기 때문에 위와 같이 분할했다.

만약 [14,18,19,23,24] 구역(위 그림의 연두색에 해당.) 중에서 14번 지점이 부족하다고 하자.

그리고 현재 트럭의 지점은 23번, 제일 많은 지점은 24번 지점이라 하자.

그러면 트럭의 경로는 '23번에서 24번으로 이동→ 24번에서 필요한 만큼 자전거 싣기 → 24번에서 14번으로 이동→14번 지점에 자전거 내리기 → 멈추기'가 된다.

주의할 점은, 처음에 모든 트럭이 0번 지점에 있다는 것이다. 따라서 맨 처음 1분에는 5개의 트럭을 각각의 구역으로 보내야 한다. 나는 임의로 0,4,12,20,24번 지점에 보냈다. (제일 먼 24번 지점까지 가는 것도 1분이 안 걸린다. 8칸만 가면 되므로 48초면 충분히 첫 1분 내에 24번에 도착할 수 있다.)

3.세운 전략에 맞게 클래스를 작성한다.

Rent 클래스는 각 지점의 자전거 대여소를 의미한다.

class Rent:
		#문제 번호에 따라 자전거 대여소의 초기 자전거 개수가 다르다.
    def __init__(self,id,problem):
        if problem==1:
            self.bikes=4
        else:
            self.bikes=3
    
        self.id=id

    def has_bike(self)->bool:
        return self.bikes>0

    def __repr__(self):
        return "id:"+str(self.id)+", bikes:"+str(self.bikes)

		#서버의 응답 결과(API함수인 locations()에 대한 리턴 값)로 데이터를 덮어씌우는 함수.
    def update_bike(self,bikes_count):
        self.bikes=bikes_count

트럭 클래스는 문제의 핵심이므로 제일 길다. 설명은 주석으로 작성하였다.

dx=(-1,1,0,0)
dy=(0,0,-1,1)
INF=987654321
EMERGENCY_STANDARD=2

class Truck:
    def __init__(self,idx,x,y,territory):
        self.id=idx #트럭의 id
        self.x=x #트럭의 x좌표
        self.y=y #트럭의 y좌표
        self.bikes=0 #트럭이 보유한 자전거 개수
        self.command=[] #트럭 객체에 담긴 '명령 행'
        self.territory=territory#트럭 객체가 담당하는 구역들
        self.ongoing=False#가고 있는 중인지, 멈춰 있는 지 나타내는 플래그

    def __repr__(self):
        return " id : "+str(self.id) +" x :"+str(self.x)+" y: "+str(self.y)+" bikes : "+str(self.bikes)+" command: "+str(self.command)

    def has_space(self)->bool:#최대 보유 개수인 20개를 넘는가 
        return self.bikes<=20

    def ride_on(self):#자전거를 태울 수 있으면 5번 명령(자전거 상차)을 명령 행에 담는다.
        if self.has_space():
            self.bikes+=1
            self.command.append(5)
    
    def ride_off(self):#자전거를 내릴 게 있으면 6번 명령(자전거 하차)를 명령 행에 담는다.
        if self.bikes>0:
            self.bikes-=1
            self.command.append(6)

    #트럭이 담당한 구역 중에서 가장 많이 자전거를 보유한 곳의 정보를 알아낸다.
		#rent_id_dict[대여소 id]=해당 대여소의 (x,y)좌표
		#rent_dict[(x,y)]= Rent 객체의 정보
    def get_most_area(self,rent_dict,rent_id_dict):
        most_id=-1
        most_count=-1

        for rent_id in self.territory:
            (x,y)=rent_id_dict[rent_id]
            bike_count=rent_dict[(x,y)].bikes
            if most_count<bike_count:
                most_count=bike_count
                most_id=rent_id

        return (most_id,most_count)

    #트럭이 담당한 구역 중에서 가장 적게 자전거를 보유한 곳의 정보를 알아낸다.
    def get_min_area(self,rent_dict,rent_id_dict):
        min_id=-1
        min_count=INF
        
        for rent_id in self.territory:
            (x,y)=rent_id_dict[rent_id]
            bike_count=rent_dict[(x,y)].bikes
            if min_count>bike_count:
                min_count=bike_count
                min_id=rent_id
        
        return (min_id,min_count)

		#BFS를 활용하여 start 지점 ~> end 지점까지 최단 거리로 갈 수 있는 
		#'경로의 궤적(trace)'을 얻는다. 
    def BFS(self,start,end,rent_dict,rent_id_dict,length):
				
				#트럭이 책임져야 하는 담당 구역들을 뜻한다.
        area_responsible=[]

        for area in self.territory:
            dimension=rent_id_dict[area]
            area_responsible.append((dimension[0],dimension[1]))

				#BFS를 위한 초기화 작업
        start_x,start_y=start
        end_x,end_y=end

        visited=[[False]*length for _ in range(length)]
        queue=deque()
        
        visited[start_x][start_y]=True
				#(x좌표,y좌표, [경로의 궤적]) 튜플을 담는다.
        queue.append((start_x,start_y,[]))

        while queue:
            x,y,command=queue.popleft()
						#도착했으면 경로의 궤적을 리턴한다. 
            if x==end_x and y==end_y:
                return command

						#4방향의 인접한 곳들을 살펴본다.
            for i in range(4):
                adjx=x+dx[i]
                adjy=y+dy[i]

								#범위를 벗어나면 스킵.
                if adjx<0 or adjy<0 or adjx>=length or adjy>=length:
                    continue
								#인접한 곳이 담당구역이고, 방문한 적 없으면 
                if (adjx,adjy) in area_responsible and visited[adjx][adjy]==False:
                    visited[adjx][adjy]=True
                    new_command=command[:]

										#북쪽이면 1번 커맨드를 담는다.
                    if i==0:
                        new_command.append(1)
										#남쪽이면 3번 커맨드를 담는다.
                    elif i==1:
                        new_command.append(3)
										#서쪽이면 4번을 담는다.
                    elif i==2:
                        new_command.append(4)
										#동쪽이면 2번을 담는다.
                    else:
                        new_command.append(2)

                    queue.append((adjx,adjy,new_command))
                    
                    

    #현재 지점 ~> 가장 많은 지점 ~>자전거 태우기 ~>가장 적은 지점 ~>자전거 내리기 ~>멈추기
    def move(self,most_id,min_id,rent_dict,rent_id_dict,length):

        self.ongoing=True#가는 중이라고 플래그를 변경한다.

        current_x=self.x
        current_y=self.y

        most_x,most_y=rent_id_dict[most_id]
        min_x,min_y=rent_id_dict[min_id]

				#태울 자전거의 수. (가장 많은 자전거의 수 - 가장 적은 자전거의 수 )//2
				#최소 1개는 태운다.
        ride_number=(rent_dict[(most_x,most_y)].bikes-rent_dict[(min_x,min_y)].bikes)//2
        if ride_number==0:
            ride_number+=1

        #현재 지점 ~> 가장 많은 지점으로 가는 경로의 궤적을 얻는다.
        current_most_command=self.BFS((current_x,current_y),(most_x,most_y),rent_dict,rent_id_dict,length)
        
				#가장 많은 지점 ~>가장 적은 지점으로 가는 경로의 궤적을 얻는다.
        most_min_command=self.BFS((most_x,most_y),(min_x,min_y),rent_dict,rent_id_dict,length)
        
				#현재 지점 ~> 가장 많은 지점으로 가는 명령을 담는다.
        self.command.extend(current_most_command)

		
				#태워야 하는 수 만큼 5번 명령을 담는다.
        for i in range(ride_number):
            if self.has_space():
                self.ride_on()

        #가장 많은 지점 ~>가장 적은 지점으로 가는 명령을 담는다.
        self.command.extend(most_min_command)
				
				#내려야 하는 수만큼 6번 명령을 담는다.
        for i in range(ride_number):
            self.ride_off()

        #끝나면 0번 명령을 담는다.즉, 멈춘다.
        self.command.append(0)

				#최종 좌표를 가장 적은 지점의 좌표로 미리 변경해 놓는다. 
        self.x=min_x
        self.y=min_y

		#10개의 명령을 꺼내는 함수
    def pop_command(self):
        pop=[]

        #6초 *10= 1분이므로 10개의 명령을 꺼내는 것이다.
        for six_seconds in range(10):
            if len(self.command)>0:
                #FIFO
               pop.append(self.command.pop(0))
            else:
                #do nothing
                pop.append(0) 

				#만약 멈추는 명령이 존재하면, 트럭 객체를 멈춤 상태로 변경한다.
        for cmd in pop:
            if cmd==0:
                self.ongoing=False
                break

        return pop

4.돌려보면서 시뮬레이션 및 디버깅한다.

아래 코드는 하드 코딩이 많이 되있다. 양해 바란다.

print()문을 활용하여 제대로 로직이 돌아가는 지 확인하였다.

def simulate_problem1():

    start_response=start(1)
    auth_key=json.loads(start_response)['auth_key']
    
    Trucks=[]

    #각 트럭이 담당할 구역들
    territory1=[2,3,4,8,9]
    territory2=[14,18,19,23,24]
    territory3=[0,1,5,6,10]
    territory4=[15,16,20,21,22]
    territory5=[7,11,12,13,17]

    territory_list=[territory1,territory2,territory3,territory4,territory5]
		
		#모든 트럭을 0번 구역에 생성하고, 각 담당 구역을 정해준다.
    for i in range(5):
        if i==0:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory1))
        elif i==1:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory2))
        elif i==2:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory3))
        elif i==3:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory4))
        else:
            Trucks.append(Truck(idx=i,x=4,y=0,territory=territory5))

    #rent_id_dict[대여소 id]=해당 대여소의 (x,y)좌표
		#rent_dict[(x,y)]= Rent 객체의 정보
    rent_dict=dict()
    rent_id_dict=dict()

    rent_id=0
    j=0
    while j<5:
        i=4
        while i>=0:
            rent_dict[(i,j)]=Rent(rent_id,problem=1)
            rent_id_dict[rent_id]=(i,j)

            rent_id+=1
            i-=1
        j+=1
    


    # #start->10:00 am ~ end ->10:00 pm
    # 12시간은 720분이고, 서버와의 통신은 '1분 단위'이므로 720회 반복한다.
    for times in range(720):
        print('times',times)

        #서버의 대여소 정보를 받는다.
        location_list=json.loads(locations(auth_key=auth_key))

        #대여소 객체들의 자전거 개수 정보를 업데이트 한다.
        for location in location_list['locations']:
            
            rent_id=location['id']
            located_bikes=location['located_bikes_count']
            rent_dict[rent_id_dict[rent_id]].update_bike(located_bikes)

        #서버의 트럭 정보를 받는다.
        truck_list=json.loads(trucks(auth_key=auth_key))
        
        for truck in truck_list['trucks']:
            truck_id=truck['id']
            location_id=truck['location_id']
            loaded_bikes_count=truck['loaded_bikes_count']
            


        # print('truck status ',truck_list['trucks'])
        # print()

				#처음 1분에는 트럭을 각각의 구역으로 배치시켜야 한다. (하드 코딩 양해바람.)
        if times==0:
						#첫 번쨰 트럭은 4번 지점으로 이동
            Trucks[0].command=[1,1,1,1,0,0,0,0,0,0]
            Trucks[0].x=0
            Trucks[0].y=0

						#두 번쨰 트럭은 24번 지점으로 이동
            Trucks[1].command=[1,1,1,1,2,2,2,2,0,0]
            Trucks[1].x=0
            Trucks[1].y=4

						#세 번째 트럭은 0번 지점으로 이동
            Trucks[2].command=[0,0,0,0,0,0,0,0,0,0]
            Trucks[2].x=4
            Trucks[2].y=0
						
						#네 번쨰 트럭은 20번 지점으로 이동
            Trucks[3].command=[2,2,2,2,0,0,0,0,0,0]
            Trucks[3].x=4
            Trucks[3].y=4

						#다섯 번쨰 트럭은 12번 지점으로 이동
            Trucks[4].command=[2,2,1,1,0,0,0,0,0,0]
            Trucks[4].x=2
            Trucks[4].y=2

        else:
						#트럭들의 상태를 확인한다. 
            for truck_obj in Trucks:
								#멈춰있는 상태면, 담당 구역 중 자전거가 가장 많은 곳과 가장 적은 곳의 정보를 알아낸다.
                if truck_obj.ongoing==False:
                    (most_id,most_count)=truck_obj.get_most_area(rent_dict,rent_id_dict)
                    (min_id,min_count)=truck_obj.get_min_area(rent_dict,rent_id_dict)
                    # print(truck_obj.id, most_id, most_count,min_id,min_count)
			
                    if min_id==-1 or most_id==-1 or most_count==min_count or min_count>EMERGENCY_STANDARD:
                        continue

							      #가장 적은 곳이 2개 이하라면 트럭을 움직이게 한다.          
                    truck_obj.move(most_id,min_id,rent_dict,rent_id_dict,length=5)
                    # print('after',truck_obj)
            

        # #collect command and simulate
        command=[]
        for truck_obj in Trucks:
						#각 트럭의 명령을 10개씩 빼내서 담는다. 
            pop=truck_obj.pop_command()
            command.append({'truck_id':truck_obj.id, "command":pop})

        # print('cmd',command)
        simulate_result=json.loads(simulate(auth_key=auth_key, parameter=command))
        print('simulate',simulate_result)
        print()

		#정상적으로 720번 수행되면 점수가 출력된다.
    result=json.loads(score(auth_key=auth_key))
    print('score',result["score"])

참고할 사항

1.위 코드는 1번 시나리오만 푼 것이다.

2.위 코드의 평가는 다음과 같다.

(점수:269.5304, 실패횟수:140개, 거리=606.8, 성공률= 약 90%)

3.아무 것도 하지 않을 경우 (커맨드가 0으로만 이루어진 경우)의 점수는 다음과 같다.

(점수:229.9391, 실패횟수:351개, 거리=0.0, 성공률= 약 75%)

4.이 문제에서 현재 또는 미래 시점의 '사용자의 요청'은 입력으로 주어지지 않는다. 문제에 다운로드할 수 있는 json 데이터들은 모두 '과거 요청 기록'일 뿐이다. 그리고 simulate()를 호출해서 얻을 수 있는 response에도 '실패 요청 횟수'만 있을 뿐이다.

profile
아키텍쳐 설계와 테스트 코드에 관심이 많음.

0개의 댓글