코딩 연습/프로그래머스

프로그래머스 level1 문제들(정답률60%~70%)

blackbearwow 2023. 9. 24. 17:51

- [1차] 비밀지도

숫자를 이진 문자열로 바꾸는 방법은 두가지가 있다. "{0:b}".format(37)과 같이 .format을 사용하는 것과 bin()내장함수를 사용하는 방법이 있다. https://stackoverflow.com/questions/699866/python-int-to-binary-string 

def solution(n, arr1, arr2):
    answer = []
    for y in range(n):
        row1 = "{:b}".format(arr1[y]).rjust(n,"0")
        row2 = "{:b}".format(arr2[y]).rjust(n,"0")
        row = ''
        for x in range(n):
            if row1[x] == '0' and row2[x] == '0':
                row += ' '
            else:
                row += '#'
        answer.append(row)
    return answer

- 문자열 내 마음대로 정렬하기

python sort에서 key를 잘 다룰수 있는가를 묻는 문제이다.

key는 함수 또는 lambda로 정의할 수 있고, 정렬 기준이 여러개일 때는 튜플로 정해주자.

def solution(strings, n):
    answer = sorted(strings, key=lambda x: (x[n], x))
    return answer

- K번째수

python의 슬라이싱과 sort()메소드를 사용하면 쉽게 구할 수 있다.

def solution(array, commands):
    answer = []
    for command in commands:
        sliceNum = array[command[0] - 1 : command[1]]
        sliceNum.sort()
        print(sliceNum)
        answer.append(sliceNum[command[2] - 1])
    return answer

- 두 개 뽑아서 더하기

모두 더하고 집합으로 만들었다가 정렬하면 되는 문제이다.

def solution(numbers):
    answer = []
    for i in range(len(numbers) - 1):
        for k in range(i + 1, len(numbers)):
            answer.append(numbers[i]+numbers[k])
    return sorted(list(set(answer)))

- 2016년

딕션어리로 날짜수를 정한 후 주어진 날짜에 더한 뒤 1월1일과의 날짜수 차이 mod 7을 구하면 알 수 있다.

def solution(a, b):
    days = {1:31, 2:29, 3:31, 4:30, 5:31, 6:30,
           7:31, 8:31, 9:30, 10:31, 11:30, 12:31}
    for i in range(1, a):
        b += days[i]
    print(b)
    day = (b-1) % 7
    if day == 0: return "FRI"
    elif day == 1: return "SAT"
    elif day == 2: return "SUN"
    elif day == 3: return "MON"
    elif day == 4: return "TUE"
    elif day == 5: return "WED"
    elif day == 6: return "THU"
    return "FRI"

- 폰켓몬

def solution(nums):
    max = int(len(nums) / 2)
    pokemonSet = set(nums)
    if len(pokemonSet) < max:
        max = len(pokemonSet)
    return max

- 모의고사

순차적으로 돌아가며 몇번 맞았나 잘 세주기만 하면 된다. mod연산을 잘 활용하자.

def solution(answers):
    answer = []
    firstPerson = [1, 2, 3, 4, 5]
    secondPerson = [2, 1, 2, 3, 2, 4, 2, 5]
    thirdPerson = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    firstPersonCorrectNum = 0
    secondPersonCorrectNum = 0
    thirdPersonCorrectNum = 0
    for i in range(len(answers)):
        if answers[i] == firstPerson[i % len(firstPerson)]:
            firstPersonCorrectNum += 1
        if answers[i] == secondPerson[i % len(secondPerson)]:
            secondPersonCorrectNum += 1
        if answers[i] == thirdPerson[i % len(thirdPerson)]:
            thirdPersonCorrectNum += 1
    maxNum = max(firstPersonCorrectNum, secondPersonCorrectNum, thirdPersonCorrectNum)
    if firstPersonCorrectNum == maxNum:
        answer.append(1)
    if secondPersonCorrectNum == maxNum:
        answer.append(2)
    if thirdPersonCorrectNum == maxNum:
        answer.append(3)
    return answer

print(solution([1,2,3,4,5]))
print(solution([1,3,2,4,2]))

- 소수 만들기

3개 이상의 숫자 리스트에서 모든 3개 조합에서 소수인지 판단하여야 한다.

첫번째 숫자는 0번 인덱스부터 length-3까지 가능하고

두번째 숫자는 첫번째 숫자 인덱스 +1 부터 length-2까지 가능하고

세번째 숫자는 두번째 숫자 인덱스 +1 부터 length-1까지 가능하다.

for문을 사용해 모든 경우의 수를 만들어 해당 경우의 수가 소수인지 판별하면 된다.

def solution(nums):
    answer = 0
    for firstIndex in range(0, len(nums)-2):
        firstNum = nums[firstIndex]
        for secondIndex in range(firstIndex, len(nums)-2):
            for thirdIndex in range(secondIndex, len(nums)-2):
                firstNum = nums[firstIndex]
                secondNum = nums[secondIndex + 1]
                thirdNum = nums[thirdIndex + 2]
                if isPrime(firstNum + secondNum + thirdNum):
                    answer += 1
    return answer

def isPrime(num):
    count = 0
    for x in range(2, num):
        if num % x == 0:
            return False
    if count == 0:
        return True
    else:
        return False

print(solution([1,2,7,6,4]))

- 소수 찾기

1부터 n까지 나누어지는지 검사하여 소수를 판별하면 오래걸린다.

효율적 방법1 - 2부터 n-1까지 나누어지는지 판단해 나누어진다면, return False

효율적 방법2 - 2부터 int(sqrt(n))+1까지 나누어지는지 판단해 나누어진다면, return False

def solution(n):
    import math
    answer = 0
    for x in range(2, n+1):
        answer += IsPrimeNum(x)
    return answer

def IsPrimeNum(x):
    import math
    count = 1
    for i in range(2, int(math.sqrt(x))+1):
        if x % i == 0:
            return False
    return True

- 실패율

dict로 단계마다 실패확률을 저장, failRate라는 리스트에 실패 확률을 따로 저장해 둔 후 failRate를 내림차순으로 정렬 후 해당되는 dict를 찾아서 answer리스트에 추가해주면 된다.

def solution(N, stages):
    answer = []

    rateDict = {}
    failRate = []
    
    for x in range(1, N+1):
        challenge = 0
        notCleared = 0
        for stage in stages:
            if stage >= x:
                challenge += 1
            if stage == x:
                notCleared += 1 
        if challenge == 0:
            rateDict[x] = 0
        else:    
            rateDict[x] = notCleared/challenge
        failRate.append(rateDict[x])

    failRate = sorted(set(failRate), reverse=True)

    for rate in failRate:
        for d in rateDict.items():
            if d[1] == rate:
                answer.append(d[0])
    return answer

print(solution(5, [2, 1, 2, 6, 2, 4, 3, 3]))
print(solution(4, [4,4,4,4,4]))

failRate를 사용한 이유는 rateDict에서 values()를 기준으로 정렬할 수 없었기 때문이다. 그러나 sorted의 key와 lambda를 활용하면 failRate를 사용하지 않고도 values()를 기준으로 정렬가능하다.

def solution(N, stages):
    rateDict = {}

    for x in range(1, N+1):
        challenge = 0
        notCleared = 0
        for stage in stages:
            if stage >= x:
                challenge += 1
            if stage == x:
                notCleared += 1 
        if challenge == 0:
            rateDict[x] = 0
        else:
            rateDict[x] = notCleared/challenge

    answer = sorted(rateDict.keys(), key=lambda x: rateDict[x], reverse=True)
    
    return answer

print(solution(5, [2, 1, 2, 6, 2, 4, 3, 3]))

- 가장 가까운 같은 글자

function solution(s) {
    let answer = [];
    // alphabetObject에는 가장 나중에 나온 인덱스를 저장한다.
    let alphabetObject = {};
    for(let i=0; i<s.length; i++) {
        const alphabet = s[i];
        if(alphabetObject[alphabet] === undefined) {
            answer.push(-1);
            alphabetObject[alphabet] = i;
        }
        else {
            answer.push(i - alphabetObject[alphabet]);
            alphabetObject[alphabet] = i;
        }
    }
    return answer;
}

- 푸드 파이트 대회

function solution(food) {
    let answer = '';
    for(let i=1; i<food.length; i++) {
        answer += i.toString().repeat(Math.floor(food[i]/2));
    }
    answer = answer + '0' + answer.split('').reverse().join('');
    return answer;
}

- 콜라 문제

function solution(a, b, n) {
    let answer = 0;
    while(n >= a) {
        const dealCount = Math.floor(n/a);
        answer += dealCount * b;
        n = n - dealCount * a + dealCount * b;
    }
    return answer;
}

- 추억 점수

function solution(name, yearning, photo) {
    let answer = [];
    const photoScore = {};
    for(let i=0; i<name.length; i++) {
        photoScore[name[i]] = yearning[i];
    }
    answer = photo.map((val)=>{
        return val.map((val)=>photoScore[val]?photoScore[val]:0).reduce((total, value)=>total+value);
    })
    return answer;
}

- 명예의 전당 (1)

function solution(k, score) {
    let answer = [];
    let honor = [];
    for(let i=0; i<score.length; i++) {
        if(i<k) honor.push(score[i]);
        else if(honor[0] < score[i]){
            honor.shift();
            honor.push(score[i]);
        }
        honor.sort((a, b)=>a-b);
        answer.push(honor[0]);
    }
    return answer;
}

- 카드 뭉치

function solution(cards1, cards2, goal) {
    for(let i=0; i<goal.length; i++) {
        if(cards1[0] === goal[i])
            cards1.shift();
        else if(cards2[0] === goal[i])
            cards2.shift();
        else 
            return 'No';
    }
    return 'Yes';
}

- 과일 장수

function solution(k, m, score) {
    if(score.length < m)
        return 0;
    let answer = 0;
    score.sort((a, b)=>b-a);
    for(let i=0; i<=score.length-m; i+=m) {
        answer += m * score[i+m - 1];
    }
    return answer;
}

- 덧칠하기

function solution(n, m, section) {
    let answer = 1;
    let index = section[0] + m;
    for (const x of section) {
        if(index <= x) {
            answer += 1;
            index = x+m;
        }
    }
    return answer;
}

- 기사단원의 무기

약수를 구하는 방법으로 제곱근까지 세는 방법을 사용하였다. 

또다른 약수 개수 구하는 방법은, 소인수분해하여 지수에 1을 더하여 곱하는 방법도 있다.

function solution(number, limit, power) {
    let answer = [];
    for (let i=1; i<=number; i++) {
        //약수의 개수 구하기
        const sqrt = Math.sqrt(i);
        let count =0;
        for(let k=1; k<=Math.floor(sqrt); k++) {
            if(i % k == 0) count+=2;
        }
        if(Number.isInteger(sqrt)) count-=1;
        answer.push(count>limit?power:count);
    }
    return answer.reduce((total, val)=>total+val);
}