ASAC 빅데이터 분석가 과정 5일차 - 1 (24.12.10)
04_cotest
03_구현_카카오키패드
(이전 내용 포함)
프로그래머스 사이트
---> solution 함수!!!
---> 입력에 부분에 있어서는 굳이 변경을 잘 하지 않음!!!
def solution(numbers, hand):
answer = ''
##########
--> 문제에서 주어진 상황에 맞는 코드를 작성!!!!
입력 + 주어진 상황 + 요청한 출력!!!!!
참고) 외부 패키지 : 사용할 수 있는 리스트,,,
참고) 다른 기능적인 부분을 외부 함수를 만들어서 호출!!
##########
return answer
문제 이해를 위한 정리
- 엄지 손가락만 사용한다(왼엄, 오엄)
- 초기 위치 : L(*), R(#)
- 이동 경우 : LRUD움직(단, 대각선은 X, 수직 / 수평)
- 버튼의 종류에 따라서 case by case --> if
1) 1,4,7 : 무조건 왼손
2) 3,6,9 : 무존건 오른손
3) 2,5,8,0 : 가장 가까운 거리!!!! 거리???어떻게???
3-1) 거리가 다를 때 : 가까운 손
3-2) 거리가 같을 떄 : 어느손 잡이
결국 solution 함수 제출
입력 : numbers --> 누를 숫자들(리스트) [ 원소수 1~1000], 0~9
hand --> 무슨 손 잡이(문자열) ["left", "right"]
출력 : answer --> 문자열
입력으로 준 numbers에 해다하는 누른 손을 문자열!!!
L/R을 사용해서 이어진(공백없는)문자열!!!
거리 : 직교거리(가로로 얼마 + 세로로 얼마)
==> 대각선 거리X
==> 가로사이의 거리 + 세로 사이의 거리
==> 이거 최악의 경우1000개 지시사항 중에서 1/3 : 함수.
세팅 : 위치pos & 거리도 계산!!
=====> 키패드 평면 : 좌표화!!!!
큰 틀 : 눌러야 하는 버튼을 돌리면 됨!!!
for num in numbers:
if 1/4/7:
무조건 왼손
elif 3/6/9
무조건 오른손
else/elif 2/5/8/0
++ 양손에서의 이 버튼 사이의 거리!!!!
==> 여러번 사용될 것 같음!!!! 함수!!!!
( 입력 : 손의위치, 누를 버튼) --> 출력 : 직선거리
D_L, D_R
if 거리가 다를 때:
짧은 거리 거리 손을 선택!!!!
else: # 거리가 같을 때
hands 입력 변수의 정보를 사용!!!
==> 거리는 어떻게 할까??? 위치????
===> 문제에서는 대 놓고 좌표/ 축/ 기준 이런 말이 없음!!!
: 없으면 본인 편한대로 만들면 됨!!!!(숫자로 좌표!!!!)
: 숫자로 좌표 == 거리/ 위치
세팅 : 주어진 키패드 코드화 ==> 좌표!!! Dict
: 초기값이 *, # 를 포함한 0~9까지 버튼을 대상!!!!
: 키값 문자열, 값 (좌표)
===> 완벽한 개인 취향!!!!
key_pad = {
"1":[0,0], "2":[0,1], "3":[0,2],
"4":[1,0], "5":[1,1], "6":[1,2],
"7":[2,0], "8":[2,1], "9":[2,2],
"*":[3,0]
}
key_pad
(코테에서는 Dict을 선호하는 경향이 있다)
참고) 앞에서 처럼 리스트 중심의 인덱스로 한다면,,.,,
key_pad_list = ["1","2","3","4",..........]
pos_x = [0, 0, 0, 1,,,,,,,,,,,,]
pos_y = [0, 1, 2, 0,,,,,,,,,,,,]
pos = [[0,0], [0,1],[0,2] ]
# * 위치에 있을 때 좌표값은?
key_pad["*"][0], key_pad["*"][1]
temp_x, temp_y = key_pad["*"] (파이썬의 멀티 할당)
print(temp_x, temp_y)
+++ 추가적인 기능 : 거리구하는 부분 ==> 여러번 사용될 듯!!==> 함수!!!
==> 2/5/8/0 누를 때만 불러서 사용을 하려고 함!!!
입력 : 2개 키패드 위치( 눌러야 할 캐패드 번호, 현재 손 위치)
기능 : 입력 2개 위치 상에서 서로 L1/ 직선거리 / 맨하탄거리 방식으로 계산!!!
출력 : 그렇게 계산된 거리값
1-2, 2-1 : 다 양수로 나타나야 함!!!
==> abs() 함수 식을 사용해도 되고, if문으로 직접 구현해도 되고!!!! #abs() : 절대값 함수
==> 몰라도 그냥 하면 된다
def get_distance( number, pos):
# 입력으로 받은 number, pos변수 : 이 함수 내에서만 생존!!!!
key_pad = {"1":[0,0], "2":[0,1], "3":[0,2],"4":[1,0], "5":[1,1], "6":[1,2],
"7":[2,0], "8":[2,1], "9":[2,2],"*":[3,0], "0":[3,1], "#":[3,2]}
# 명시적으로 눌러야 할 버튼에 대한 값의 형 : 문자열로 형 변환!! (오류를 예방)
number = str(number)
pos = str(pos)
# 1) 눌러야 할 버튼의 좌표값 & 파이썬 멀티할당
x_number, y_number = key_pad[number]
# x_number = key_pad[number][0]
# y_number = key_pad[number][1]
# 2) 손의 위치에 대한 버튼의 좌표값 & 파이썬의 멀티할당
x_pos, y_pos = key_pad[pos]
# 3) 1번하고 2번 사이의 거리 ==> 수직거리!!!!! ===> abs함수,,,,,
abs_distance = abs(x_number - x_pos) + abs(y_number-y_pos)
# 최종 출력
return abs_distance
# 만든 기능이 잘 동작하는지 체크!!!
get_distance("5","3")
==> 큰 틀 : 입력으로 받은 numbers를 중심으로 롤링 : for
case1) 1/4/7 : 왼손
case2) 3/6/9 : 오른손
case3) 2/5/8/0 ===> 왼손과 오른손 사이의 거리 : get_distance()
d_l = get_distance(~~~)
d_r = get_distance(~~~)
case3-1) d_l == d_r : hand정보
case3-2) d_l != d_r : 가까운 거리의 손 ===> 부등식 처리!!!
d_l < d_r : 왼손
d_l > d_r : 오른손
#####꼭 혼자서 해보자!!#####(정답코드)
def get_distance( number, pos):
key_pad = {"1":[0,0], "2":[0,1], "3":[0,2],"4":[1,0], "5":[1,1], "6":[1,2],
"7":[2,0], "8":[2,1], "9":[2,2],"*":[3,0], "0":[3,1], "#":[3,2]}
number = str(number)
pos = str(pos)
x_number, y_number = key_pad[number]
x_pos, y_pos = key_pad[pos]
abs_distance = abs(x_number - x_pos) + abs(y_number-y_pos)
return abs_distance
def get_distance( number, pos):
key_pad = {"1":[0,0], "2":[0,1], "3":[0,2],"4":[1,0], "5":[1,1], "6":[1,2],
"7":[2,0], "8":[2,1], "9":[2,2],"*":[3,0], "0":[3,1], "#":[3,2]}
number = str(number)
pos = str(pos)
x_number, y_number = key_pad[number]
x_pos, y_pos = key_pad[pos]
abs_distance = abs(x_number - x_pos) + abs(y_number-y_pos)
return abs_distance
def solution(numbers, hand):
answer = ''
########
# 1-1) 필요한 변수들을 세팅 : 왼손 위치, 오른손 위치 변수 & 초기화
left_pos = "*"
right_pos = "#"
# 1-2) 필요한 변수 세팅 : 무슨손 잡이인지 --> 입력 : left/right --> 출력:L/R
if hand =="right":
hand = "R"
elif hand =="left": #양손잡이 조건이 없기 때문에 else 생략(코테 문제 특징!)
hand = "L"
#########
# 2) 본격적으로 눌러야 할 버튼 롤링!!!!!
for num in numbers:
# 2-1) 무조건 왼손 : 1/4/7
if num in [1,4,7]: # num==1 or num==4
answer += "L"
# ++ 왼손으로 눌렀으니, 왼손의 위치를 갱신!!!!***
left_pos = num
# 2-2) 무조건 오른손 : 3/6/9
elif num in [3,6,9]:
answer += "R"
# ++ 오른손으로 눌렀으니,,,오른손의 위치를 갱신!!!
right_pos = num
# 2-3) 판단 : 2/5/8/0/
elif num in [2,5,8,0]:
# 각 손과의 거리를 계산!!! & 거리 담당 변수가 필요!!!
dis_left = get_distance(num, left_pos)
dis_right = get_distance(num,right_pos )
# 2-3-1) 거리가 왼쪽이 짧을 때
if dis_left < dis_right:
answer += "L"
left_pos = num
# 2-3-2) 거리가 오른쪽이 짧을 때
elif dis_left > dis_right:
answer += "R"
right_pos = num
# 2-3-3) 거리가 동일 할 때
elif dis_left == dis_right:
answer += hand
# ===> 무슨손 잡이냐에 따라서...갱신할 손의 위치가 선택!!!
if hand =="R":
right_pos = num
elif hand =="L":
left_pos = num
########
return answer
a = [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5]
b = "right"
solution(a,b) # LRLLLRLLRRL //LRLLLRLLRRL
##### 코드 정리
def get_distance( number, pos):
key_pad = {"1":[0,0], "2":[0,1], "3":[0,2],"4":[1,0], "5":[1,1], "6":[1,2],
"7":[2,0], "8":[2,1], "9":[2,2],"*":[3,0], "0":[3,1], "#":[3,2]}
number = str(number)
pos = str(pos)
x_number, y_number = key_pad[number]
x_pos, y_pos = key_pad[pos]
abs_distance = abs(x_number - x_pos) + abs(y_number-y_pos)
return abs_distance
def solution(numbers, hand):
answer = ''
left_pos = "*"
right_pos = "#"
if hand =="right":
hand = "R"
elif hand =="left":
hand = "L"
for num in numbers:
if num in [1,4,7]: # num==1 or num==4
answer += "L"
left_pos = num
elif num in [3,6,9]:
answer += "R"
right_pos = num
elif num in [2,5,8,0]:
dis_left = get_distance(num, left_pos)
dis_right = get_distance(num,right_pos )
if dis_left < dis_right:
answer += "L"
left_pos = num
elif dis_left > dis_right:
answer += "R"
right_pos = num
elif dis_left == dis_right:
answer += hand
if hand =="R":
right_pos = num
elif hand =="L":
left_pos = num
return answer
04_정렬_코테용기본
주제 : 정렬!!!
==> 코테용 vs 실제 대면 면접 / 기본적인 내용들과 차이점!!!!
코테용 : 정렬과 관련된 개별적인 알고리즘이 주된 내용이 아님!!!!
==> 정렬만의 문제는 거의 없음!!!!
단, 마지막이나 중간에 1~2줄 정도 필요할 때 사용!!!
==> 핵심 : 내가 원하는 대로 정렬 규칙을 세팅!!!!
+ 필요한 자료형들을 구성/설정!!!!
( 정렬을 하기 위한 필요한 정보들을 어떻게 세팅!! )
실제 대면 면접 : 기본적인 정렬 알고리즘 차이점 & 코드로 구현!!!
==> 파이썬으로 구현하면 10줄 내외!!!!
==> for / index / 규칙 : 코드를 작성하는 기본기 파악하기 용이!!!
==> 알고리즘 효율성& 특징
*** 코테상에서는 알고리즘 중요한 것이 아니라!!!
==> 문제에서 제시한 기준대로 정렬할 수 있도록 구현!!!!!!
==> 정렬을 위한 정보들을 어떻게 세팅할지가 중요!!!!!!!!!
### 파이썬을 가지고 정렬하는 기본적인 기능 ###
파이썬을 가지고 정렬하는 경우 : 크게 2가지 방법
1) 리스트.sort() 메서드 : 원본이 날라감!!!!!!!
2) 파이썬 자체의 sorted() 함수 : 원본이 그대로 유지가 됨!!!!
변경된 결과를 따로 할당/연결!!!!
===> 공통점 : 둘 다 사용법이 동일함!!!!!
**** 중요한 점 ****
위의 2가지 방식을 사용할 때 : 문제에서 요구하는 대로 정렬 기준 작성!!!!
===> 특별한 정렬 기준에 대해서 : lambda 함수로 규칙을 기술!!!
+ 코테에서는 문제 상황/조건 각양각생 ==> 연습!!!!!!!
+++ 이러한 정렬을 하기 위해서 편한 자료형/값들을 주어진 문제에서
어떻게 세팅을 할 것인가가!!중요한 부분!!!!!
정렬 : "기준"을 가지고, 기준에 맞춰서 순서를 정리!!!!
==> 기준 : 위치, 값의 크기, 알파벳, 문자순, 성적순 ,,,,,,,,,,
참고 : 단순 순서상 재배치 : reverse()메서드/ reversed()함수
--> 주의!!!) 값의 크기 기준X , 단순 위치 기준 역순!!!!!
a = [15,22,8, 79, 10]
a
a.reverse()
a # ===> 리스트는 변경에 대한 메서드 : 원본이 바로 변경!!!!
값을 기준으로 정렬 : .sort()메서드, sorted()파이썬 기본 함수
sorted(a) # 원소의 값의 크기 기준 정렬 : 오름차순
b = sorted(a) # sorted()함수를 사용해서 변경된 값을 사용하려면 재할당!!!
b
a.sort() # 바로 정렬 기준이 a에 적용 --> 할당이 필요X
a # ==> 원본이 뭐였지;;;;;;;
정리)
파이썬의 리스트.sort() 메서드 : 원본이 바로 변경!!!
파이썬의 기본 함수 sorted() : 원본이 유지가 됨!!
변경된 값을 사용하기 위해서는 재할당!!!
+ opt) 값에 대한 정렬 기준 : 오름/ 내림차순
--> reverse = False : 오름차순
reverse = True : 내림차순
#FM적인 방법
a = [15,22,8, 79, 10]
a
a.sort(reverse =True) # 값의 크기 기준 : 내림차순
a
a.sort(reverse =False) # 값의 크기 기준 : 오름차순==>기본값
a
a = [15,22,8, 79, 10]
a
sorted( a, reverse=True) # 값 기준 내림차순
sorted( a, reverse=False) # 값 기준 오름차순
#정리
포지션 중심으로 뒤짚기 : reverse()메서드, reversed()함수
기준으로 정렬을 오름/내림 차순 : reverse파라미터 =T/F==> .sort(), sorted()
#목적 : 내가 원하는 정렬 기준을 만들어서 하자!!!!!!! ***
str_list = ["좋은하루","good morning", "굿모닝","niceday"]
str_list
참고) 수업 진행을 위해서 원본을 유지를 하는 sorted만 사용을 하겠습니다.
.sort() 메서드가 동일하므로!!!!!
sorted(str_list) # --> 기본 정렬 : 값 & 오름차순
==> 컴퓨터의 코드값을 기준으로,,,영어가 한글보다 앞의 숫자로 할당을 했기에..
(한글보다 영어가 먼저인 이유 : 코드값)
ord("g")
ord("n")
ord("굿")
sorted(str_list, reverse=True) # 값을 기준 / 내림차순
**********************************************************************
*** 원하는 기준대로 정렬 하는 것에 표현 : lambda 함수!!!!!!***
**********************************************************************
// lmabda 함수 정리 !!!! + sorted 함 정리!!!
str_list
ex) 글자의 앞글자 1개만 가지고 정렬을 하려고 함!!!!
===> 그 외의 글자들은 신경안 쓸께요!!!(그냥 원본 순서대로)
sorted( str_list, key=lambda x:x[0] )
ex) 특이하게 글자의 2번째 글자 1개만 가지고 정렬을 하겠습니다!!!
==> 그 외의 글자들은 신경 안 쓸께요!!!(그냥 원본 순서대로)
+++ 내가 직접 기준을 만들어야 함!!!!
sorted( str_list, key=lambda x:x[1] )
ex) 특별하게 글자의 길이순서대로 정렬해주세요!!!
===> 이것도 특별기준 : 내가 직접 만들어 내야 함!!!!!
sorted( str_list, key = lambda x: len(x))
===> 위의 코드 : 기준만 작성을 했고, 어느 순서인지 생략!!!
기본이 오름차순 Default!!!
ex) 특별하게 글자의 길이에 대해서 내림차순으로 정렬해주세요!!!!
(FM적인 방법)
sorted( str_list, key = lambda x: len(x), reverse=True)
오름/내림 방향성에 대해서 FM적으로는 reverse 파라미터 T/F
AM적으로으로 간단하게 +/-부호!!!!!
===> 조건이 여러개가 있는 경우에 대해서, 각 조건별로 방향성을 다 다르게 부여!!!
sorted( str_list, key = lambda x: +len(x) ) #오름차순
sorted( str_list, key = lambda x: -len(x) ) #내림차순
구체적인 예 : 이름,성적 자료형에 대해서 정렬!!!
zumsu_list = [ ("A",0), ("B",1), ("C",5), ("D",3), ("E",5)]
zumsu_list
--> 그냥 정렬해줘!!!
sorted(zumsu_list)
--> 정렬 기준 : 이름 중심으로 정렬을 해주세요!!!
sorted(zumsu_list, key=lambda x: x[0])
--> 정렬 기준 : 성적순으로 정렬을 해주세요!!!!
sorted(zumsu_list, key=lambda x: x[1])
*** 중요!!!!
==> 내가 기준을 지정하지 않는 상황에서 동일한 순서가 발생하면!!!!!
"원본의 순서를 그대로 유지를 한다!!!!!!!"
==> 성적이 제일 높은 친구를 앞으로 오게 해주시고,,
성적이 낮은 친구들을 뒤로 정렬해주세요!!!!
---> 성적이라는 기준을 내림차순: FM--> reverse=True
AM --> -부호
sorted(zumsu_list, key=lambda x: x[1], reverse=True)
sorted(zumsu_list, key=lambda x: -x[1])
# 조금 더 유사한 값들이 있는 경우로 세팅!!! 이름 - 성적!!!
zumsu_list = [
("A",0), ("B",5), ("AA",3),
("C",5),("B",1), ("Z", 5),
("D",3), ("E",5)
]
zumsu_list
--> 그냥 정렬해줘!!!!
sorted(zumsu_list)
결과 : 이름 순서대로 오름차순으로 정렬!!!!!사전순!!!!
혹, 이름이 같은 경우가 생기면,,,,뒤에 값을 기준(성적) 오름차순
--> 결론 : 기준대로 다 순서대로 오름차순 일괄 적용을 함!!!!!
정렬 : 명확하게 정렬의 기준을 제시!!!!
==> 정렬의 1기준 : 이름 순서
(혹, 정렬 1기준이 같다면(동명이인), 그냥 원본 순서대로)
sorted( zumsu_list, key = lambda x: x[0])
--> 코드적으로 정렬 기준에 안 쓰이면,,, 원본 순서를 유지!!!
정렬 : 아무것도 안 한 sorted()하고 동일하게 나오게 key, lamdba로 구현
: 1번 정렬 기준 : 이름(오름차순)
: 2번 정렬 기준 : 성적(오름차순)
===> lambda함수에 기술!!!!
여러개의 정렬 기준을 작성을 하는 과정에서는 순서, () 표현!!!
sorted( zumsu_list, key=lambda x: (x[0], x[1] ))
*****
#보통 코테 혼재된 방향성을 사용하는 경우가 있음!!!
1정렬 기준 : 이름(오름차순)
2정렬 기준 : 성적(내림차순)
그 외에는 원본 순서대로 유지해주세요!!!!
sorted( zumsu_list, key=lambda x: (x[0], -x[1] ))
#참고 : reverse 파라미터로 하게 되면???
====> 모든 정렬 기준들이 다 같은 방향으로 움직이게 됨!!!!!!
sorted( zumsu_list, key=lambda x: (x[0], x[1] ), reverse=True)
sorted( zumsu_list, key=lambda x: (x[0], x[1] ), reverse=False)
### 코테용 입장에서 정렬 : 위의 예제들에서 이름/성적 예시!!!!ㄲ
# ===> 가장 기본적인 형식!!!
# (이름은 오름차순, 성적은 내림차순....)
# +++ 정렬 기준에 안 적으면,,,,,원본 순서가 유지가 된다!!!!!!
05_정렬_실패율
문제를 읽으면서 끄적.;;
문제의 핵심 : 실패율의 정의대로 구해서---> 내림차순!!! : 정렬?
==> 정렬의 기준 : 실패율!!
실패율 정의 = 스테이지를 실패한 수 / 스테이지에 도전자수
case by case : 도전자 유저수 == 0 : 실패율 0 정의
도전자 유저수 != 0 : 실패율 계산...
==> 정렬을 할 때 : 실패율(내림차순) ---> 스테이지 번호(오름차순)
입력 : N --> 전체 게임의 스테이지의 수
stages --> 이 게임 유저들이 현재 어느 스테이지에 있는지 정보(리스트)
출력 : 실패율 계산 --> 실패율에 대한 정렬(내림차순)
--> 스테이지 번호만 리스트로 제출!!!!!
stages : 길이 1~20000까지
값 1~~ N+1
N+1의미 : N스테이지까지 다 클리어한 유저!!!!!
예시1)
N = 5
stages = [2, 1, 2, 6, 2, 4, 3, 3]
1stage
도전자 : 8명 --> stages의 원소의 수 8 ==> 8명이 이 게임에 참가
실패자 : 1명 --> 지금 1번에 있는 친구 수 ===> 값이 1인 갯수
실패율 : 1/8
2stage
도전자 : 7명 = 8 - 1 ( 1스테이지 도전자 - 1스테이지 실패자)
실패자 : 3명 --> 지금 2번에 있는 친구 수 ==> 값이 2인 갯수
실패율 : 3/7
3stage
도전자 : 4명 = 7 - 3 ( 2스테이지 도전자 - 2스테이지 실패자)
실패자 : 2명 --> 지금 3번에 있는 친구 수 ==> 값이 3인 갯수
실패율 : 2/4
4stage
도전자 : 2명 = 4 - 2 ( 3스테이지 도전자 - 3번 스테이지 실패자)
실패자 : 1명 --> 지금 4번에 있는 친구 수 ==> 값이 4인 갯수
실패율 : 1/2
5stage
도전자 : 1명 = 2 - 1 ( 4스테이지 도전자 - 4번 스테이지 실패자)
실패자 : 0명 ---> 지금 5번에 있는 친구 수 ==> 값이 5인 갯수
실패율 : 0/1
#####################################################
스테이지별로 실패율 정렬!!!!( 혹, 값이 같다면,,,작은 스테이지 번호!!!!!)
1F = 0.125
2F = 0.428
3F = 0.5
4F = 0.5
5F = 0
---> 3 --> 4 ---> 2 ---> 1 ---> 5
===> 생각의 시작 : i번째 stage에서 어찌될까에 대한 규칙화!!!!!
i-stages 에서
도전자 : (i-1)stage 도전자 - (i-1)stage의 실패자 ==> i-stage 도전자!!!
실패자 : 값이 i인 것들의 갯수!!!!
실패율 : i_F = i_실패자/i_도전수
==> i_도전자 수 ==0 : i_F = 0
!=0 : i_F = i_실패자/i_도전수
===> i=1에서는 i-1=0번째 스테이지 ==> 총 도전자!!!!!/ 유저 수
+++ 필요한 정보 : ( i-stage, i_F)
예시2)
N = 4
stages = [4,4,4,4,4] //[4,1,2,3]
1stage
도전자 : 5
실패자 : 0
1F = 0
2stage
도전자 : 5
실패자 : 0
2fF = 0
3stage
도전자 : 5
실패자 : 0
3F = 0
4stage
도전자 : 5
실패자 : 5
4F = 1
--> 4-->1->2->3
정렬의 위한 자료 정리
==> [스테이지 번호, 그 스테이지 실패율] // [ 이름, 성적]
[(1, 1_f), (2,2_f), (3, 3_f) .....]
중요사항
===> 출력에서 정렬을 사용을 해야함!!!!!
정렬1기준) 실패율 : 내림차순
정렬2기준) 스테이지 번호 : 오름차순
-----> 기준별로 방향성이 따로 따로이니,,,,+/-로 하는게 나을 듯!!!!
+++ sorted(), .sort() +++ key + lambda + (+/-)
====> 정렬&출력에 필요한 정보 : 스테이지번호, 실패율
====> [(1, 1_f), (2,2_f), (3, 3_f) .....]
[ [1, 1/8], [2, 3/7], [3, 0.5], [4, 0.5], [5, 0]]
--> [[3, 0.5], [4, 0.5],[2, 3/7],[1, 1/8], [5, 0] ]
===> [3,4,2,1,5]
참고!!!) 정렬에 대한 대상이 오로지 리스트만 가능할까?
==> No!!!
Dict로 정렬이 가능함!!!!!!
참고) 저는 dict로 진행을 해보겠습니다.
= {1:1/8, 2:3/7, 3:2/4, 4:1/2, 5:0}
t
===> 정렬의 1기준 : value
2기준 : key
t.items()
temp = sorted( t.items(), key=lambda x: ( -x[1], x[0] ) )
temp
# temp를 최종 출력용으로 정리하면 : LC
[i[0] for i in temp]
b = []
for i in temp:
b.append(i[0])
b
# 참고) 실패자의 수 : 필터링 & 카운팅!!!!
# m1) 리스트의 메서드 : .count()
[2, 1, 2, 6, 2, 4, 3, 3].count(2)
# m2) 필터링 & 카운팅 ==> LC
a = [2, 1, 2, 6, 2, 4, 3, 3]
len([ i for i in a if i ==2])
# m3) 꾸역꾸역 하자!!!!
cnt = 0
a = [2, 1, 2, 6, 2, 4, 3, 3]
for i in a:
if i == 2:
cnt += 1
print(cnt)
#### 저는 여기서는 dict로 해보겠습니다..
# dict
a_dict = {}
a_dict
a_dict["a"] = 100
a_dict
a_dict["a"] = 200 # 값의 변경
a_dict
a_dict["b"] = 999 # 값의 추가
a_dict
def solution(N, stages):
answer = []
######
# 1) 필요한 정보들을 세팅!!!!
# 1-1) 정렬을 위한 기본 정보처리 : dict ---> k:스테이지번호, v:실패율
fail_dict = {} # --> 스테이지를 돌아가면서,,,계산 결과를 추가!!!!
# 1-2) 최초 도전자에 대한 수 ==> 각 스테이지별로 돌아가면서 갱신!!!
num_people = len(stages) # --> 갱신 : i_stage의 도전자수 & 처음에는 1번스테이지 도전자 초기화
# 2) 큰 구조 : 스테이지를 돌아가면서 실패율 계산!!!!
# ===> 1,2,3,,,,,N 숫자 중심 롤링 : range(1, N+1,1)
for i_stage in range(1, N+1):
# 2-1) i번째 스테이지에서 할 일
# 2-1-1) i번째 스테이지에서 실패자 수 : 카운팅(필터링)==> .count()
fail_num = stages.count( i_stage )
# len( [ i for i in stages if i ==i_stage])
# 2-2-2) 실패율!!! case by case
if num_people > 0: # 1명 이상의 참가자 존재 --> 계산
fail_dict[i_stage] = fail_num / num_people
else: # 0명의 참가자 존재 => 정의 0
fail_dict[i_stage] = 0
# cf) 리스트로,,, fail_list.append([i_stage, fail_num / num_people])
# 2-2-3) 다음 라운드의 참가자에 대한 정보 : 갱신!!!!!
num_people -= fail_num
# ---> fail_dict = {1:1/8, 2:3/7, 3:2/4, 4:1/2, 5:0}
#-------------------------------------------------
# 3) 출력을 위한 정리 & 정렬!!!!!
# --> 정렬1기준 : 실패율 & 내림차순
# 정렬2기준 : 스테이지번호 & 오름차순
# fail_dict.items() : [ (1,1/8) , (2,3/7), (3, 0.5), (4,0.5), (5,0) ]
# key : x ==> (2, 3/7)
fail_list = sorted( fail_dict.items(), key=lambda x:( -x[1], x[0]) )
# [(3, 0.5), (4, 0.5), (2, 0.42857142857142855), (1, 0.125), (5, 0)]
# 4) 최종 제출 양식 : 정렬된 stage 번호를 리스트로 전달...
answer = [ fail_info[0] for fail_info in fail_list]
# [3,4,2,1,5]
######
return answer
# test
a = 5
b = [2, 1, 2, 6, 2, 4, 3, 3]# // [3,4,2,1,5]
solution(a,b)
# test
a = 4
b = [4,4,4,4,4] # // [4,1,2,3]
solution(a,b)
# 코드 정리
def solution(N, stages):
answer = []
fail_dict = {} # --> 스테이지를 돌아가면서,,,계산 결과를 추가!!!!
num_people = len(stages) # --> 갱신 : i_stage의 도전자수 & 처음에는 1번스테이지 도전자 초기화
for i_stage in range(1, N+1):
fail_num = stages.count( i_stage )
if num_people > 0: # 1명 이상의 참가자 존재 --> 계산
fail_dict[i_stage] = fail_num / num_people
else: # 0명의 참가자 존재 => 정의 0
fail_dict[i_stage] = 0
num_people -= fail_num
fail_list = sorted( fail_dict.items(), key=lambda x:( -x[1], x[0]) )
answer = [ fail_info[0] for fail_info in fail_list]
return answer
//자료형과 정보들을 어떻게 처리할 것인지
//코드를 어떻게 간결하게 만들 것인지
## 정리
1. 정렬에 대한 내용이 메인이 아님!!!!
==> 다른 여러 알고리즘. 주제와 함께 섞여서 최종 제출부분으로 처리!!!!
: 위의 예제는 그냥 주어진 문제를 구현하는 부분에 + 정렬
==> 이러한 기본적인 정렬을 하지 못하면,,,다하고 틀리느는 일이 있으니 꼭!!!
2. 정렬을 하기 위한 세팅을 어떻게 할지 : 스스로 결정& 판단!!!
==> 그 부분에 맞춰서, 코드 & 문법을 적당히 사용해야 함!!!!
==> 이 문제 정도는 기본 연습 레벨로 생각을 하고,,
최근의 경향은 기본 구성이 좀 복잡하게& 꼼꼼하게 해야하는 것으로 업글!!!
==> ref: https://school.programmers.co.kr/learn/courses/30/lessons/92341?language=python3
최근에는 그래도 하 난이도의 문제이지만, 이정도의 길이&지저분함을 생각하고