Q. 조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA

조이스틱을 각 방향으로 움직이면 아래와 같습니다.

▲ - 다음 알파벳 ▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로) ◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서) ▶ - 커서를 오른쪽으로 이동

예를 들어 아래의 방법으로 "JAZ"를 만들 수 있습니다.

- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다. - 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다. - 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다. 따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.

만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.

제한 사항

  • name은 알파벳 대문자로만 이루어져 있습니다.
  • name의 길이는 1 이상 20 이하입니다.

입출력 예

namereturn

"JEROEN" 56
"JAN" 23

 

틀린 정답)

def solution(name):
    answer = 0
    for i in name:
        if i != 'A' and 'Z':  
            if ord(i) <= 78:    #알파벳이 N보다 밑에 있을 때
                answer += ord(i) -65
            else:
                answer += 91 - ord(i)  #알파벳이 N보다 위에 있을 때
        else:
            answer += 1
    return answer + len(name) -1

우선 문제에서 조이스틱을 움직일 때 위로(A->Z)방향 아니면 아래로(Z->A)방향으로 움직일지를 결정해야하는 데 N을 기준으로 N보다 밑에 있으면 조이스틱을 위로, N보다 위에 있으면 조이스틱을 아래로 움직이는게 최단값을 반환할 수 있다. 

A= 0, B= 1....N=13 그리고 거꾸로 계산을 하면 Z=1, Y=2, X=3...O=12, N=13이 된다.

알파벳을 아스키코드로 바꾼 후 차이만큼을 빼서 answer에 추가하고 다음 문자로 이동하는 만큼을 더해주면 되는데...

왜 ..... 'JAN'이 23이지..? 24아닌가...?

 

누가...로직이 왜 틀렸는지 알려줘요...

'Algorithm' 카테고리의 다른 글

programmers #정수삼각형  (0) 2021.08.22
백준 15829번 #Hashing  (0) 2021.08.22
백준 10829번 #이진수변환  (0) 2021.08.21
programmers #[1차] 비밀지도  (0) 2021.08.19
백준 5692번 #팩토리얼 진법  (0) 2021.08.17

 

Q.

위와 같은 삼각형의 꼭대기에서 바닥까지 이어지는 경로 중, 거쳐간 숫자의 합이 가장 큰 경우를 찾아보려고 합니다. 아래 칸으로 이동할 때는 대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동 가능합니다. 예를 들어 3에서는 그 아래칸의 8 또는 1로만 이동이 가능합니다.

삼각형의 정보가 담긴 배열 triangle이 매개변수로 주어질 때, 거쳐간 숫자의 최댓값을 return 하도록 solution 함수를 완성하세요.

 

제한사항

  • 삼각형의 높이는 1 이상 500 이하입니다.
  • 삼각형을 이루고 있는 숫자는 0 이상 9,999 이하의 정수입니다.

입출력 예

triangle                      result

[[7], [3, 8], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]] 30

 

 

def solution(triangle):
    for i in range(1, len(triangle)):   #위에서부터 2번째 줄
        for j in range(i+1):            #항
            if j == 0:                  #맨 왼쪽 값인 경우
                triangle[i][j] += triangle[i-1][j]
            elif j == i:                #맨 오른쪽 값인 경우
                triangle[i][j] += triangle[i-1][j-1]
            else:                       #왼쪽 위, 오른쪽 위에 애들 중 큰값을 더해주기
                triangle[i][j] += max(triangle[i-1][j-1], triangle[i-1][j])
    
    return max(triangle[-1])            #가장 마지막 줄의 최댓값

 

점화식으로 생각하면 접근이 좀 편했다.

삼각형이 한줄 씩 밑으로 내려가면서 큰 수인 수를 더해주면 되는데 일반항으로 표현해보자.

 

이전까지 더한 최댓값이 M이라고 하고 내가 [i][j]번째 배열이라고 하면 나보다 왼쪽 위 [i-1][j-1] 이나 오른쪽 위 [i-1][j] 중에서 더 큰놈을 더해주면 계속 최대가 될 것이다. 

 

[i][j] += M +  [i-1][j-1]  or  M + [i-1][j]

 

이 값이 계속 밑으로 내려가며 누적을 시키자. 즉, 최댓값을 계속 배열에 덮어 씌우자! 

 

만약 내가 가장 왼쪽에 주어진 값이면 나랑 항이 같은 바로 위의 애를 더해주면 되고

(  [i][j] + [i-1][j]  )

내가 가장 오른쪽에 주어진 값이면 나보다 하나 항이 하나 더 앞에 있는 애들 더해주면 된다.

(  [i][j] + [i-1][j-1]   or   [i][j]  + [i-1][-1]   )

 

 

동적계획법 = 점화식!

 

근데 문제는 점화식을 세우는 것이 아니고 생각한 점화식을 코드로 옮기는거네 ㅎㅎㅎㅎㅎㅎ 

 

   

 

 

'Algorithm' 카테고리의 다른 글

programmers #조이스틱  (0) 2021.09.15
백준 15829번 #Hashing  (0) 2021.08.22
백준 10829번 #이진수변환  (0) 2021.08.21
programmers #[1차] 비밀지도  (0) 2021.08.19
백준 5692번 #팩토리얼 진법  (0) 2021.08.17

Q.네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.

  1. 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.
  2. 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
  3. "지도 1"과 "지도 2"는 각각 정수 배열로 암호화되어 있다.
  4. 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.

네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.

입력 형식

입력으로 지도의 한 변 크기 n 과 2개의 정수 배열 arr1, arr2가 들어온다.

  • 1 ≦ n ≦ 16
  • arr1, arr2는 길이 n인 정수 배열로 주어진다.
  • 정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2n - 1을 만족한다.

출력 형식

원래의 비밀지도를 해독하여 '#', 공백으로 구성된 문자열 배열로 출력하라.

입출력 예제

매개변수값

n 5
arr1 [9, 20, 28, 18, 11]
arr2 [30, 1, 21, 17, 28]
출력 ["#####","# # #", "### #", "# ##", "#####"]

매개변수값

n 6
arr1 [46, 33, 33 ,22, 31, 50]
arr2 [27 ,56, 19, 14, 14, 10]
출력 ["######", "### #", "## ##", " #### ", " #####", "### # "]

 

최종 코드)

def solution(n, arr1, arr2):
    bin_list = []

    for i in range(0, len(arr1)):
        bin_list.append(bin(arr1[i] | arr2[i])[2:].zfill(n))

    for i in range(n):
        bin_list[i] = bin_list[i].replace('1','#').replace('0',' ')
    
    return bin_list

 

 

def solution(n, arr1, arr2):
    bin_list = []

    for i in range(0, len(arr1)):
        bin_list.append(bin(arr1[i] | arr2[i])

우선 가장 제일 먼저 arr1 과 arr2를 bin 함수를 이용하여 2진수로 변환하고 비트연산 or을 한번에 진행하여 bin_list에 추가했다. 그런데 이대로 추가를 하면 bin 함수로 변환하면서 2진수 앞에 0b가 붙는다.

 

def solution(n, arr1, arr2):
    bin_list = []

    for i in range(0, len(arr1)):
        bin_list.append(bin(arr1[i] | arr2[i])[2:]

그래서 3번째(인덱스는 2)부터 슬라이싱하여 원하는 2진수 숫자만 뽑아 append 하였다.

그런데 이대로 return을 하면 문제가 길이가 파라미터 n가 같이 않은 변수들이 에러를 일으킨다.

 

def solution(n, arr1, arr2):
    bin_list = []

    for i in range(0, len(arr1)):
        bin_list.append(bin(arr1[i] | arr2[i])[2:].zfill(n))

문제에서는 변수의 길이와 n이 같아야하기 때문에 zill함수를 사용해서 앞에 0으로 채워주었다.

 

 

    for i in range(n):
        bin_list[i] = bin_list[i].replace('1','#').replace('0',' ')

그리고 replace함수를 사용해서 1 -> #, 0 -> ' ' 으로 바꿔주면 끝!!

 

 

 

카카오 입사 코딩테스트라고 해서 처음에 너무 쫄고 들어간 것같다. 물론 시험중에서 낮은 난이도에 해당하겠지만 그래도 두려움의 문턱을 넘을 수 있었다는 것에 크게 감동하고 있다! 계속 꾸준히 화이팅!!!

'Algorithm' 카테고리의 다른 글

백준 15829번 #Hashing  (0) 2021.08.22
백준 10829번 #이진수변환  (0) 2021.08.21
백준 5692번 #팩토리얼 진법  (0) 2021.08.17
백준 10872 #팩토리얼  (0) 2021.08.17
programmers #소수찾기  (0) 2021.08.10

Q. 한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.

각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.

 

제한사항

  • numbers는 길이 1 이상 7 이하인 문자열입니다.
  • numbers는 0~9까지 숫자만으로 이루어져 있습니다.
  • "013"은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.

입출력 예

numbers     /        return

"17" 3
"011" 2

 

 

import copy

def permutation(lst, strum, numbers):
    for i in range(len(numbers)):
        cns = copy.deepcopy(numbers)
        add_strum = strum + cns.pop(i)
        lst.append(int(add_strum))
        permutation(lst, add_strum, cns)

def prime_list(n):
    sieve = [True] * (n+1)
    m = int(n ** 0.5)
    if n <= 1:
        return False
    for i in range(2, m + 1):
        if sieve[i] == True:           # i가 소수인 경우
            for j in range(i+i, n+1, i): # i이후 i의 배수들을 False 판정
                sieve[j] = False
    #return [i for i in range(2, n) if sieve[i] == True]
    return sieve[-1]


def solution(numbers):
    num = []
    numbers = list(numbers)
    permutation(num, '', numbers)

    number_set = set(num)
    number_list = list(number_set)

    answer = 0
    for n in number_list:
        if prime_list(n):
            answer += 1
            print(n, answer)
    return answer

테스트 케이스 몇 개에서 시간초과로 실패가 떴다. 재귀함수가 디스크를 많이 잡아먹기도 하고 소수찾는 함수를 에라토스테네스 체를 사용해서 굴리는 시간이 많아가지고 그런 듯 하다. 그래서 제출은 squt이용해서 했고 개인적으로는 이 풀이가 더 마음에 들기때문에 이걸로 블로깅하겠다.

 

 

def prime_list(n):
    sieve = [True] * (n+1)
    m = int(n ** 0.5)
    if n <= 1:
        return False
    for i in range(2, m + 1):
        if sieve[i] == True:           # i가 소수인 경우
            for j in range(i+i, n+1, i): # i이후 i의 배수들을 False 판정
                sieve[j] = False
    return sieve[-1]

에라토스테네스 체를 만들기 위해서 True로만 차있는 리스트를 하나 만들었다.

반복문을  n까지 다 돌릴 필요는 없어서 n의 루트까지만 반복을 하고 처음의 i는 그대로 True, 그 이후에는 i의 배수들을 False로 바꿔서 리스트에 저장하기로 한다.

 

def permutation(lst, strum, numbers):
    for i in range(len(numbers)):
        cns = copy.deepcopy(numbers)
        add_strum = strum + cns.pop(i)
        lst.append(int(add_strum))
        permutation(lst, add_strum, cns)

재귀함수...처음에 코드를 짰을 때는 deepcopy를 하지 않았더니 1,2,3을 연결할 때, 두 자리 수까지 밖에 되지 않아서 애를 먹었다. 결국 deepcopy를 써서 str 형태로 수들을 연결하고 int로 변환하여 다시 permutation에 넣게끔 연습했다.

 

 

def solution(numbers):
    num = []
    numbers = list(numbers)
    permutation(num, '', numbers)

    number_set = set(num)
    number_list = list(number_set)

    answer = 0
    for n in number_list:
        if prime_list(n):
            answer += 1
            print(n, answer)
    return answer

펄뮤테이션 함수를 쓰고 난 후에 담겨진 리스트들의 요소가 중복이 있을 수 있으니 set로 하여 중복을 제거하고 소수가 맞는지 확인하여 갯수를 리턴하였다.

 

다시 공부해야할 부분은 재귀함수(예제 많이 풀어보기)!!

'Algorithm' 카테고리의 다른 글

백준 5692번 #팩토리얼 진법  (0) 2021.08.17
백준 10872 #팩토리얼  (0) 2021.08.17
programmers #다리를 지나는 트럭  (0) 2021.08.08
programmers #기능개발  (0) 2021.08.08
programmers #시저암호  (0) 2021.08.07

Q. 트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 다리에는 트럭이 최대 bridge_length대 올라갈 수 있으며, 다리는 weight 이하까지의 무게를 견딜 수 있습니다. 단, 다리에 완전히 오르지 않은 트럭의 무게는 무시합니다.

예를 들어, 트럭 2대가 올라갈 수 있고 무게를 10kg까지 견디는 다리가 있습니다. 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.

경과 시간다리를 지난 트럭다리를 건너는 트럭대기 트럭

0 [] [] [7,4,5,6]
1~2 [] [7] [4,5,6]
3 [7] [4] [5,6]
4 [7] [4,5] [6]
5 [7,4] [5] [6]
6~7 [7,4,5] [6] []
8 [7,4,5,6] [] []

따라서, 모든 트럭이 다리를 지나려면 최소 8초가 걸립니다.

solution 함수의 매개변수로 다리에 올라갈 수 있는 트럭 수 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭 별 무게 truck_weights가 주어집니다. 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.

 

제한조건

  • bridge_length는 1 이상 10,000 이하입니다.
  • weight는 1 이상 10,000 이하입니다.
  • truck_weights의 길이는 1 이상 10,000 이하입니다.
  • 모든 트럭의 무게는 1 이상 weight 이하입니다.

입출력 예

bridge_lengthweighttruck_weightsreturn

2 10 [7,4,5,6] 8
100 100 [10] 101
100 100 [10,10,10,10,10,10,10,10,10,10] 110

 

 

def solution(bridge_length, weight, truck_weights):
    num = len(truck_weights)
    que = []   #[트럭, 다리 위 위치] 로 된 2차원 리스트
    timer = 0
    finish = []   #다리를 건넌 트럭들
    while len(finish) < num:
        timer += 1   #루프를 돌때마다 시간을 +1
        sum = 0   #다리 위에 있는 트럭들의 무게 합
        if que:
            for i in range(len(que)):
                if que[i][0] == 0:
                    continue
                
                que[i][1] += 1   #트럭을 앞으로 한칸 이동
                if que[i][1] > bridge_length:   #트럭이 이동한 거리가 다리 길이보다 길면
                    finish.append(que[i][0])    #다리 통과
                    que[i] = [0,0]              #큐(다리)를 초기화
                else:
                    sum += que[i][0]            #다음 트럭의 무게를 우선 계산(올릴지/말지)
            if truck_weights and (sum + truck_weights[0]) <= weight:  #무게가 가능하다면
                que.append([truck_weights.pop(0),1])   #큐에 추가
        else:   #큐(다리)가 비어 있을 때 
            if truck_weights:   #대기하는 트럭이 있다면  
                que.append([truck_weights.pop(0),1])   #큐(다리)에 트럭을 올리고 앞으로 거리1 이동
    return timer

우선 내가 이해한 바로 코드에 설명을 부여했다.

이 문제를 처음 접했을 때 가장 난감했던 부분은 시간을 어떻게 재야하는 것인가였는데 스택처럼 시간을 재는 변수를 추가하면 되었다. 그리고 스택/큐는 while문을 많이 활용하는 듯 하다. 그래서 while을 돌 때마다 타임을 늘리면 시간 계산이 가능하다.

 

그리고 2차원 리스트 [트럭, 위치]를 한꺼번에 생각하는 것이 코드를 간략하게 쓸 수 있는 좋은 아이디어같다.

다른 문제들보다 가장 직관적으로 이해할 수 있는 풀이라고 생각해서 이 코드를 외우는 것으로 공부했다.

 

'Algorithm' 카테고리의 다른 글

백준 10872 #팩토리얼  (0) 2021.08.17
programmers #소수찾기  (0) 2021.08.10
programmers #기능개발  (0) 2021.08.08
programmers #시저암호  (0) 2021.08.07
programmers #체육복(정답아님)  (0) 2021.08.07

Q. 프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

 

제한 사항

  • 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
  • 작업 진도는 100 미만의 자연수입니다.
  • 작업 속도는 100 이하의 자연수입니다.
  • 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

입출력 예

progresses     /        speeds               /         return

[93, 30, 55] [1, 30, 5] [2, 1]
[95, 90, 99, 99, 80, 99] [1, 1, 1, 1, 1, 1] [1, 3, 2]

 

 

def solution(progresses, speeds):
    n = len(progresses) 
    day = [0]*n
    for i in range(n):
        day[i] = (100 - progresses[i]) // speeds[i]
        if (100 - progresses[i]) % speeds[i] !=0:
            day[i] += 1 
       
    stack = []
    answer = []
    stack.append(day.pop(0))
    while day:
        current = day.pop(0)
        if stack[0] >= current:
            stack.append(current)
        else:
            answer.append(len(stack))
            stack = [current]

        if not day:
            answer.append(len(stack))
            
    return answer

한 progress가 완성될 때 까지 걸리는 시간을 (100 - progress) // speeds로 계산하여 day 리스트에 추가한다. 만약 일수를 계산했을 때 나머지가 나온다면 하루를 더 연장시켜야하기 때문에 +1을 계산해준다.

 

예를 들어, 1번 테스트 케이스라고 가정해보자.

 

progresses = [93, 30, 55]

speeds = [1, 30, 5]

day = [7, 2, 9]

 

스택에 가장 day[0]을 추가한다.

그리고 그 다음 날 current = day[1]과 day[0]을 비교해서 day[1]이 작다면 배포를 기다려야 하기 때문에 stack에 추가.

아니라면 둘이 같이 배포할 수 있기 때문에 len(stack)를 정답에 넣어주고, 스택에 다음날과 비교해야할 current = day[1] 값을 넣어준다.

 

만약 day가 비어있다면 바로 스택의 길이만 출력!

 

 

 

스택/큐 문제는 아직도 익숙하지 않아 다른 사람의 풀이를 참고해서(거의 배꼈다) 공부했다. 이제 약간 어떤식으로 스택을 사용해야할지 알듯말듯... 우선 스택에 들어가있는 요소들과 비교할 변수가 추가로 더 필요하다는 것!

리스트에 append, remove 하는 것도 결국 스택인데 저건 쉽고 스택은 어려운게 참..,,

'Algorithm' 카테고리의 다른 글

programmers #소수찾기  (0) 2021.08.10
programmers #다리를 지나는 트럭  (0) 2021.08.08
programmers #시저암호  (0) 2021.08.07
programmers #체육복(정답아님)  (0) 2021.08.07
programmers #예산  (0) 2021.08.07

Q. 어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.제한 조건

  • 공백은 아무리 밀어도 공백입니다.
  • s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
  • s의 길이는 8000이하입니다.
  • n은 1 이상, 25이하인 자연수입니다.

입출력 예

"AB" 1 "BC"
"z" 1 "a"
"a B z" 4 "e F d"

 

 

def solution(s, n):
    answer = []
    for alp in s:
        if alp.isalpha():    #alp가 알파벳일 때
            if 65 <= ord(alp) <= 90:  # alp의 ASKII코드가 65~90사이일때,(대문자일때)
                if ord(alp)+n >90:    # n을 더한 값이 Z = 90 보다 크면
                    answer.append(chr(ord(alp)+n-26))  #한바퀴 돌아와야하기 때문에 알파벳의 갯수 26을 뺌
                else:
                    answer.append(chr(ord(alp)+n))
            else:                     # alp의 ASKII코드가 92~122사이일때,(소문자일때)
                if ord(alp)+n > 122:  
                    answer.append(chr(ord(alp)+n-26))
                else:
                    answer.append(chr(ord(alp)+n))
        else:
            answer.append(' ')        #공백은 ' '로 처리
            
    return ''.join(answer)

 

도무지 혼자 풀 수 없어서 다른 사람들의 풀이를 참고하여 새로운 함수 몇가지를 배우고 써봤다.

isalpha() : 알파벳인지 아닌지 구분 (T/F로 출력)

ord() : 알파벳을 ASKII코드로 변환  (대문자는 A~Z가 65~90, 소문자는 a~z가 97~122)

chr() : ASKII코드를 알파벳으로 변환

 

 

내가 알던 시저암호는 C = E(k , p) = (p + k)mod26  , 즉 알파벳의 갯수 26으로 나눈 나머지로 계산하는 거였는데 아스키코드로 바꿔서 연산하려니 나머지보다 빼기가 더 만만해보였다.

내일 다시 일어나서 %로 연산을 해보기로!

'Algorithm' 카테고리의 다른 글

programmers #다리를 지나는 트럭  (0) 2021.08.08
programmers #기능개발  (0) 2021.08.08
programmers #체육복(정답아님)  (0) 2021.08.07
programmers #예산  (0) 2021.08.07
programmers #2016년  (0) 2021.08.06

Q. 점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • 전체 학생의 수는 2명 이상 30명 이하입니다.
  • 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
  • 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

입출력 예

nlostreservereturn

5 [2, 4] [1, 3, 5] 5
5 [2, 4] [3] 4
3 [3] [1] 2

 

 

 

 

def solution(n, lost, reserve):
    cnt = n - len(lost)
    for i in lost:
        for j in reserve:
            if j == i-1 or j == i or j == i+1:
                cnt += 1
                reserve.remove(j)
                break
            elif j != i-1 and j != i and j != i+1:
                cnt += 0
    return cnt

딱 2개 테스트케이스에서 실패가 나는데 왜때문인지....체육복은 왜 훔쳐가는건지.....도둑놈들 망해라

'Algorithm' 카테고리의 다른 글

programmers #기능개발  (0) 2021.08.08
programmers #시저암호  (0) 2021.08.07
programmers #예산  (0) 2021.08.07
programmers #2016년  (0) 2021.08.06
programmers #완주하지 못한 선수  (0) 2021.08.05

Q. S사에서는 각 부서에 필요한 물품을 지원해 주기 위해 부서별로 물품을 구매하는데 필요한 금액을 조사했습니다. 그러나, 전체 예산이 정해져 있기 때문에 모든 부서의 물품을 구매해 줄 수는 없습니다. 그래서 최대한 많은 부서의 물품을 구매해 줄 수 있도록 하려고 합니다.

물품을 구매해 줄 때는 각 부서가 신청한 금액만큼을 모두 지원해 줘야 합니다. 예를 들어 1,000원을 신청한 부서에는 정확히 1,000원을 지원해야 하며, 1,000원보다 적은 금액을 지원해 줄 수는 없습니다.

부서별로 신청한 금액이 들어있는 배열 d와 예산 budget이 매개변수로 주어질 때, 최대 몇 개의 부서에 물품을 지원할 수 있는지 return 하도록 solution 함수를 완성해주세요.

제한사항

  • d는 부서별로 신청한 금액이 들어있는 배열이며, 길이(전체 부서의 개수)는 1 이상 100 이하입니다.
  • d의 각 원소는 부서별로 신청한 금액을 나타내며, 부서별 신청 금액은 1 이상 100,000 이하의 자연수입니다.
  • budget은 예산을 나타내며, 1 이상 10,000,000 이하의 자연수입니다.

입출력 예

dbudgetresult

[1,3,2,5,4] 9 3
[2,2,3,3] 10 4

 

 

def solution(d, budget):
    answer = 0    #예산을 받을 수 있는 부서의 수
    d.sort()      #최대한 많은 부서를 주어야하기 때문에 예산이 적은 부서들을 위주로 정렬
    sum = 0       #부서에게 지급될 예산의 합
    
    for i in d:   #루프를 돌려 각 부서들의 예산을 더해서 budget보다 작으면 루프 탈출
        if sum + i <= budget:  
            sum += i
            answer += 1
        else:
            break
    return answer

sum과 budget을 비교해서 처음 코드를 세웠는데 계속 몇 테스트케이스에서 에러가 났다. 그 이유는 문제를 제대로 안봐서..ㅎㅎ

'최대한 많은 부서' 라고 문제에 주어졌음에도 정렬을 하지 않았었다.

앞으로는 문제를 성심성의껏 읽기^^

 

 

 

다른 사람의 풀이

def solution(d, budget):
    d.sort()
    cnt = 0

    for i in d :
        budget -= i
        if budget < 0 :
               break
        cnt += 1
    return cnt

예산에서 부서들의 신청금액을 빼서 찾는 것도 괜찮은 방법이다! 거꾸로 연산 ㅇㅋㅇㅋ

 

 

 

def solution(d, budget):
    d.sort()
    while budget < sum(d):
        d.pop()
    return len(d)

pop은....흠...냐링...ㅎㅎㅎㅎㅎㅎㅎㅎㅎ 스택/큐 공부를 다시 한 후에 확인해보자!

'Algorithm' 카테고리의 다른 글

programmers #시저암호  (0) 2021.08.07
programmers #체육복(정답아님)  (0) 2021.08.07
programmers #2016년  (0) 2021.08.06
programmers #완주하지 못한 선수  (0) 2021.08.05
programmers #모의고사  (0) 2021.07.29

Q.

2016년 1월 1일은 금요일입니다. 2016년 a월 b일은 무슨 요일일까요? 두 수 a ,b를 입력받아 2016년 a월 b일이 무슨 요일인지 리턴하는 함수, solution을 완성하세요. 요일의 이름은 일요일부터 토요일까지 각각  SUN,MON,TUE,WED,THU,FRI,SAT 입니다. 예를 들어 a=5, b=24라면 5월 24일은 화요일이므로 문자열 "TUE"를 반환하세요.

 

제한 조건

  • 2016년은 윤년입니다.
  • 2016년 a월 b일은 실제로 있는 날입니다. (13월 26일이나 2월 45일같은 날짜는 주어지지 않습니다)

입출력 예

abresult

5 24 "TUE"

 

 

 

def solution(a, b):
    day = ['FRI','SAT','SUN','MON','TUE','WED','THU']
    month = [31,29,31,30,31,30,31,31,30,31,30,31]
    total = []
    cnt,date = 0,0
    
    for i in range(0,12):
        cnt=sum(month[0:i])
        total.append(cnt)
        
    if a == 1:
        date = b
    else:
        date = total[a-1] + b
        
    i = date%7
    answer = day[i-1]
    return answer

왠지 이 문제에서 핵심은 a월b일을 수로 바꿨을때 몇일이 되냐였던 것 같다.

달마다 요일이 달랐고 if문을 12번 쓸수는 없어서 우선 리스트를 이용해서 월들의 누적합을 구하고싶었다.

 

for문을 이용해서 누적합을 total리스트에 추가했다. 그리고 그 누적합에 b일도 더해서 총 일수를 구했다.

요일은 7개가 반복되니까 일수를 7로 나눈 나머지를 idx로 day리스트에서 찾게끔 했다.

 

처음에는 문제보고 좀 막막할 줄 알았는데 제한시간보다 더 일찍풀려서 당황쓰;

 

def solution(a, b):
    day = ['THU','FRI','SAT','SUN','MON','TUE','WED']
    month = [0,31,29,31,30,31,30,31,31,30,31,30,31]
 
    return day[(sum(month[0:a]) + b)%7]

 

대단하신 분의 팁으로 변수들을 줄이고 효율성을 살려 3줄로 풀이를 끝냈다..

와...대박....신기..재밌다..와..

 

day의 인덱스와 일수의 합을 7로 나누었을 때의 나머지를 같게 하려고 day 리스트에서 THU를 가장 먼저 넣었다.

누적합에 + b일만 추가하면 되기 때문에 변수로 잡았던 cnt도 없앴고 return에 바로 원하는 값을 집어넣었다.

 

 

 

다음 공부할 함수

zip()

'Algorithm' 카테고리의 다른 글

programmers #체육복(정답아님)  (0) 2021.08.07
programmers #예산  (0) 2021.08.07
programmers #완주하지 못한 선수  (0) 2021.08.05
programmers #모의고사  (0) 2021.07.29
programmers #K번째수  (0) 2021.07.22

+ Recent posts