# 주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다.
# 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때,
# nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때
# 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.


def solution(nums):
    answer = 0

    i1 = 0
    i2 = 0

    loofVal = 0
    loofValFin = len(nums)-2
    loofValLen = len(nums)-1

    while loofVal < loofValFin:
        i1 = loofVal+1

        while i1 <= loofValFin:
            i2 = i1+1

            while i2 <= loofValLen:
                sumval = nums[loofVal]+nums[i1]+nums[i2]
                i=2
                isPrime = 0

                while i*i <= sumval :
                    if sumval%i == 0:
                        isPrime = 1
                    i += 1

                if isPrime == 0:
                    answer += 1

                i2 += 1
            i1 += 1
        loofVal += 1

    return answer

개발스토리

소수를 만드는 경우의 수를 모두 구현하지 않고 효율적으로 하는 방법을 생각해보느라 기간이 좀 더 걸렸다

결론은 그런 방법은 없다로 결론이 났다 이 판단은 나중에 다시보면 얼마든지 바뀔수있을거같다

모든 경우의 수를 만드니까 로직은 간단하다

1번째 선택 반복문

2번째 선택 반복문

3번째 선택 반복문

이 선택이 겹치지 않게하기위해서는 루프를 돌기전에 부모의 루프 값을 받아와서 ++를 진행한다

문제 요약

인형의 정보가 담긴 2차 배열을 받고 [[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]]

어떤 인덱스를 꺼낼지 적힌 매개변수를 받는데 [1,5,3,5,1,2,1,4]

꺼내서 담긴 바구니에 같은 인형의 정보가 두개가 쌓이면 두개를 터트려서 사라진다

다 꺼내고 남은 인형의 수를 return하도록 만들어보자

 
def solution(board, moves):
    arr = []
    answer = 0
    leng = len(board)

    for move in moves:
        i = 0
        while True:
            if i == leng:
                break
            if board[i][move-1] != 0:
                if len(arr) != 0:
                    if board[i][move-1] == arr[-1]:
                        arr.pop()
                        answer = answer+2
                    else:
                        arr.append(board[i][move-1])
                else:
                    arr.append(board[i][move-1])
                board[i][move-1] = 0
                break
            i = i+1

    return answer

 


개발스토리

처음문제를 보고 이해를 잘못했다 0번째 배열이 1번줄이 되는 방식으로 오해했다. 그러다가 다시 문제를 보고 0번째가 가장위의 줄을 나타내고 1번째 배열이 위에서 2번째줄을 나타내는 로직이었다

로직을 생각할때 크래인의 동작을 잘생각해보았다

1. 인형을 뽑을때 크래인은 비어있는 인형이 나오지 않을때까지 쭉 내려간다

2. 인형을 발견하면 인형을 꺼낸다 

3. 꺼내진 자리는 비어있음으로 표시를 바꾼다

 

이런 로직을 기반으로 코드를 구성했다 그래서 move의 수를 받아 i를 증가시키며 쭉 내려가면서 탐색하도록 했다

 

# 맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.

    # 1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
    # 2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
    # 3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
    # 4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
        # 4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
# 순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

n = [0,1,2,3,4,5,6,7,8,9]
n.insert(1,[["2"],["1","3","5"],["4","6","8"],["7","9","0"],["*","#"]])
n.insert(4,[["5"],["2","4","6","8"],["1","3","7","9","0"],["*","#"]])
n.insert(7,[["8"],["5","7","0","9"],["4","2","6","*","#"],["1","3"]])
n.insert(0,[["0"],["8","*","#"],["7","9","5"],["4","2","6"],["1","3"]])

def solution(numbers, hand):
    answer = ''
    Lpo = "*"
    Rpo = "#"
    LpoCoun = 10
    RpoCoun = 10

    for i in numbers:

        if i == 1 or i == 4 or i == 7:
            answer = answer+"L"
            Lpo = str(i)
        if i == 3 or i == 6 or i == 9:
            answer = answer+"R"
            Rpo = str(i)

        if i == 2 or i == 5 or i == 8 or i == 0:

            # 거리 받아오기
            count = 0
            for j in n[i]:
                if Lpo in j:
                    LpoCoun = count
                if Rpo in j:
                    RpoCoun = count
                count=count+1

            # 거리에 따라 조건
            if LpoCoun < RpoCoun:
                answer = answer+"L"
                Lpo = str(i)

            elif LpoCoun > RpoCoun:
                answer = answer+"R"
                Rpo = str(i)

            elif LpoCoun == RpoCoun:
                if hand == "right":
                    answer = answer+"R"
                    Rpo = str(i)
                elif hand == "left":
                    answer = answer+"L"
                    Lpo = str(i)

    return answer

# 1. 누를 번호를 받는다
# 2. 번호에 맞는 손으로 누른다 (초기값인 * #은 그냥 움직인다)
# 2-1. 147은 무조건 왼손 369는 무조건 오른손 (거리생각x)
# 2-2. 2480은 양손의 거리를 받아서 거리가 가까운 손이 움직인다
# 2-3. 누를때마다 양손가락의 위치를 저장한다

# aa1 = solution([1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5], "right")
aa2 = solution([7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2], "left")
# aa3 = solution([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], "right")

 


 

개발스토리

 

문제를 읽고 코드로 옮기는데 생각보다 많은 시간이 걸렸다. 구글에서 푸는 방법을 검색해서 정석대로 푸는것보다 나의 생각으로 푸는것이 훨씬 오래걸리지만 다음에 비슷한 유형의 문제를 만났을때 더욱 빠르게 풀 수 있을거라는 생각에 끈질기게 생각했다.

양쪽 끝의 숫자들은 그냥 누르면 되니 큰 걱정거리가 아니었다. 문제는 중앙렬의 숫자를 입력할때였다.

1. 중앙렬을 입력할때는 양손의 위치를 알고 있어야한다.

2. 비교해서 더 가까운 거리를 누르고 같은 거리일때 오른손잡이인지 왼손잡이인지 판단하고 거기에 맞게 누른다.

 

로직은 간단했다. 거리를 어떻게 구해오는지만 해결이 된다면 쉬웠다. 몇일을 고민해서 거리를 구하는 방법을 찾았다.

거리에 따라 2중 배열을 만들고 그걸 풀면서 못찾을때마다 count의 수를 올리며 양손의 거리를 받아왔다.

 

양손의 거리를 받아오는 문제가 해결되니 비교구문으로 바로 처리했다.

조금 아쉬운 점이 손가락의 초기 세팅 값이 *, # 라서 이에 해당되는 거리도 구해야하는 바람에

int를 억지로 str으로 바꿔주면서 해서 중간에 혼란이 왔다.

# 네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.

# 다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.

# 1478 → "one4seveneight"
# 234567 → "23four5six7"
# 10203 → "1zerotwozero3"

def solution(s):
 
    dic = {"zero":"0", "one":"1", "two":"2", "three":"3", "four":"4", "five":"5", "six":"6", "seven":"7", "eight":"8", "nine":"9" }
 
    # 문자 검색
    for d in dic:
        if d in s:
            s = s.replace(d,dic[d])

    answer = 0
    answer = int(s)
    return answer

결과 = solution("one4seveneight")

개발스토리

바꿀 딕셔너리를 for문으로 돌리고 s변수로 받은 문자열에 있는지 체크하고 있으면 d를 찾아서 d의 키로 찾은 값으로 replace 해주면서 변환해서 풀었다.

# 아이디의 길이는 3자 이상 15자 이하여야 합니다.
# 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
# 단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.

# 1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
# 2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
# 3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
# 4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.

# 5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
# 6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
#     만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
# 7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.


def solution(new_id):

    # 1단계 소문자 치환
    answer = new_id.lower()

    # 2단계 소문자 숫자 빼기 밑줄 마침표만 남기기
    char2 = 'abcdefghijklmnopqrstuvwxyz0123456789-_.'

    for i in answer:
        if (char2.find(i) < 0):
            answer = answer.replace(i,"")

    # 3단계 .. 두개를 . 하나로 치환
    i = 1
    ii=answer.count("..")
    while i < ii:
        ii=answer.count("..")
        answer = answer.replace("..", ".")

    # 4단계 양끝 . 제거
    answer = answer.strip(".")

    # 5단계 빈문자열일때 a 추가
    if (answer == ""): answer = "a"

    # 6단계 16자 이상 자르기
    answer = answer[0:15]
    # + 양끝제거 한번 더
    answer = answer.strip(".")

    # 7단계 2자이하면 마지막 문자를 길이가 3될때까지 반복
    if (len(answer) < 3):
        plus = answer[-1:]
        while len(answer) < 3:
            answer = answer + plus

    return answer

개발스토리

각 단계별로 나누지말고 한번에 하는 방법이 없을까 고민하다가 이런저런 시도는해보았지만 실패했다. 처음 코드를 다만들고나니 테스트 검증에 실패가 자꾸 나왔다. 원인을 분석하니 3단계에서 오류가 나왔다.

  점이 4개 있다고 가정했을때 한번 리플레이스를 거치면 두개를 하나로 만들면서 다시 두개가 된다. 이부분에서 문제가 되었다. 문자열의 ..을 세서 없을때까지 리플레이스를 진행하는 방식으로 변경했다. 여러 테스트를 진행하면서 비주얼 스튜디오 코드에서 지원하는 python preview 에서는 1000 스텝을 넘어서면 계산을 중단해버렸다. 처음에는 파이썬자체에서 1000스텝까지만 지원하는줄 알고 스텝을 줄이기 위해서 코드를 자꾸만 수정했었다. 스텝상관없이 지원되는 것을 나중에서야 알게 되었지만 스텝을 줄인다는 것이 시간 단축에 효과를 보이는거 같아서 좋은 경험을 했다.

# 일부 지워진 로또번호를 보고 최고순위와 최저순위를 맞추기
# 알아볼 수 없는 번호는 0으로 표기

def solution(lottos, win_nums):

    answer = [7] * 2

    for i in lottos:
        if i in win_nums:
            answer[0] -= 1
            answer[1] -= 1

    con = lottos.count(0)
    answer[0] -= con

    if answer[1] > 6:
        answer[1] = 6
    if answer[0] > 6:
        answer[0] = 6

    # [최고, 최저]
    return answer

solution([44, 1, 0, 0, 31, 25], [31, 10, 45, 1, 6, 19])

개발 스토리

 

문제를 이해하고 풀기 시작했을때 리턴 등수를 보고 배열의 값을 0부터 시작하는 것이 아니라 반대로 시작해야겠다고 생각했다. 배열을 돌며 있는지 체크하고 있으면 값을 각각 빼고 다빼고 나면 0숫자를 카운트해서 0번째 배열에 -값을 준다. 이렇게 하고 다풀고 끝난줄알았는데 다시보니 예외처리가 잘되지 않아서 다시 해주니 통과했다.


def solution(lottos, win_nums):

    rank=[6,6,5,4,3,2,1]

    cnt_0 = lottos.count(0)
    ans = 0 # 이걸 인덱스번호로 활용함
    for x in win_nums:
        if x in lottos:
            ans += 1
    return rank[cnt_0 + ans],rank[ans]

다른분들 풀이

다른분들 푼걸 봤더니 아주 특이하게 풀었다. 나는 접근을 각각 빼면서 접근하고 아예없을경우 예외 처리를 해주면서 풀었는데 여기는 등수에 더 주목했다. 등수를 우선 배열로 만들고 찾았을때 배열 번호를 더해주었다. 그리고 마지막에 배열 인덱스 값을 대입해서 리턴해서 마무리했다.

+ Recent posts