coding 연습/프로그래머스

프로그래머스 level1 문제들(정답률50%이하)

blackbearwow 2023. 9. 24. 18:20

- 신규 아이디 추천

-처음에는 ord를 이용해 "2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다." 를 적용했지만, 정규표현식을 이용해 다시 프로그램을 짰다. 정규표현식 짱짱맨!

 

-다른 분들의 풀이법을 보니 for문을 사용해 정규표현식을 사용하지 않고 re.sub메소드를 이용해 엄청 간결하게 하셨다!

re.sub(patternreplstringcount=0flags=0)는 해당 string에서 정규식pattern에 해당하는 부분이 있다면 repl로 바꿔서 반환한다! 이렇게 좋은 함수가 있을줄이야...

import re

def solution(new_id):
    # step 1
    answer = new_id.lower()
    # step 2
    """p = re.compile("[a-zA-Z0-9-_.]+")
    for x in answer:
        if not p.match(x):
            answer = answer.replace(x, "")"""
    answer = re.sub('[^a-z0-9-_.]', "", answer)
    # step 3
    while True:
        index = answer.find("..")
        if index == -1:
            break
        answer = answer.replace("..", ".")
    # step 4
    answer = answer.strip(".")
    # step 5
    if answer == "":
        answer = "a"
    # step 6
    if len(answer) >= 16:
        answer = answer[:15]
        answer = answer.strip(".")
    # step 7
    if len(answer) == 2:
        answer = answer + answer[-1]
    elif len(answer) == 1:
        answer = answer * 3
    return answer

print("1234567890123456"[:15])
print(solution("4"))

- 햄버거 만들기

function solution(ingredient) {
    let answer = 0;
    let stack = [];
    // 순서대로 push하면서 lenght가 4 이상이면서 1(빵)을 push했을때 1231인지 확인
    for(const x of ingredient) {
        stack.push(x);
        if(stack.length >= 4 && x === 1) {
            let arr = stack.slice(stack.length-4, stack.length);
            if(arr.every((val, idx)=>val==[1, 2, 3, 1][idx])) {
                answer += 1;
                stack.length -= 4;
            }
        }
    }
    return answer;
}

- 성격 유형 검사하기

function solution(survey, choices) {
    var answer = '';
    const oneToFull = {
        R:["RT", 1], T:["RT",-1], C:["CF", 1], F:["CF",-1], 
        J:["JM", 1], M:["JM",-1], A:["AN", 1], N:["AN",-1]
    }
    const obj = {
        RT:0, CF:0, JM:0, AN:0
    }
    for(const i in survey) {
        let point = choices[i] - 4;
        let hyung = point < 0 ? survey[i][0] : survey[i][1];
        obj[oneToFull[hyung][0]] +=oneToFull[hyung][1] * Math.abs(point);
    }
    for(const key of Object.keys(obj)) {
        if(obj[key] < 0) answer += key[1];
        else answer += key[0];
    }
    return answer;
}

- 바탕화면 정리

function solution(wallpaper) {
    //y최소값, x최소값, y최대값+1, x최대값+1
    let xMin=100, yMin=100;
    let xMax=0, yMax=0;
    for(let y=0; y<wallpaper.length; y++) {
        console.log(wallpaper[y]);
        for(let x=0; x<wallpaper[y].length; x++) {
            if(wallpaper[y][x] === '#') {
                if(x < xMin)
                    xMin = x;
                if(xMax < x)
                    xMax = x;
                if(y < yMin)
                    yMin = y;
                if(yMax < y)
                    yMax = y;
            }
        }
    }
    return [yMin, xMin, yMax+1, xMax+1];
}

- 개인정보 수집 유효기간

month가 24 36등 12의 배수일 때, 12월로 해주어야 한다. 무작정 %12를 하면 0월이 되어버린다.

function solution(today, terms, privacies) {
    let answer = [];
    let [tYear, tMonth, tDay] = today.split('.');
    tYear = Number(tYear); tMonth = Number(tMonth); tDay = Number(tDay);
    //1. terms를 object형식으로 저장
    let temp = {};
    for(const x of terms) {
        temp[x.split(' ')[0]] = Number(x.split(' ')[1]);
    }
    terms = temp;
    //2. privacies마다 1일을 빼고 terms에 맞는 개월수를 더하고 12가 넘으면 년도를 올린다.
    for(let i=0; i<privacies.length; i++) {
        let [date, term] = privacies[i].split(' ');
        let [year, month, day] = date.split('.');
        year = Number(year); month = Number(month); day = Number(day);
        day -= 1;
        if(day < 1) {
            day += 28;
            month -= 1;
        }
        month += terms[term];
        if(month > 12) {
            if(month % 12 === 0) {
                year += month/12 - 1;
                month -= (month/12 - 1)*12;
            }
            else {
                year += Math.floor(month / 12);
                month %= 12;   
            }
        }
        //3. today와 privacies를 비교해 result를 구한다.
        if(year < tYear)
            answer.push(i+1);
        else if(year === tYear) {
            if(month < tMonth)
                answer.push(i+1);
            else if(month === tMonth) {
                if(day < tDay)
                    answer.push(i+1);
            }
        }
    }
    return answer;
}

- 달리기 경주

Object를 사용해 선수를 찾는 시간복잡도를 줄이는게 핵심.

function solution(players, callings) {
    let playersObj = {}; //key:value => 이름:index
    for(let i=0; i<players.length; i++){
        playersObj[players[i]] = i;
    }
    for(let i=0; i<callings.length; i++){
        //1. index를 찾는다.
        //let index = players.findIndex((val)=>val==callings[i]);
        let index = playersObj[callings[i]];
        //2. 불린 선수와 앞 선수의 순서를 바꾸어준다.
        let temp = players[index-1];
        players[index-1] = players[index];
        players[index] = temp;
        //3. playersObj정보도 바꾸어준다.
        playersObj[callings[i]] -= 1;
        playersObj[players[index]] += 1;
    }
    return players;
}

- 공원 산책

function solution(park, routes) {
    // 가로 세로 구하기
    let height = park.length;
    let width = park[0].length;
    let currentX, currentY;
    // 시작지점 좌표 구하기
    for(let y=0; y<height; y++) {
        if(currentX === undefined) {
            for(let x=0; x<width; x++) {
                if(park[y][x] === 'S') {
                    currentX = x;
                    currentY = y;
                    break;
                }
            }
        }
    }
    // 루트를 확인하며 가능하다면 이동.
    for(let route of routes) {
        let [direction, distance] = route.split(' ');
        distance = Number(distance);
        if(direction === 'N') {
            if(currentY - distance >= 0) {
                if([...Array(distance).keys()].every((val)=>park[currentY-val-1][currentX]!='X')) {
                    currentY -= distance;
                }
            }
        }
        else if(direction === 'S') {
            if(currentY + distance < height) {
                if([...Array(distance).keys()].every((val)=>park[currentY+val+1][currentX]!='X')) {
                    currentY += distance;
                }
            }
        }
        else if(direction === 'W') {
            if(currentX - distance >= 0) {
                if([...Array(distance).keys()].every((val)=>park[currentY][currentX-val-1]!='X')) {
                    currentX -= distance;
                }
            }
        }
        else if(direction === 'E') {
            if(currentX + distance < width) {
                if([...Array(distance).keys()].every((val)=>park[currentY][currentX+val+1]!='X')) {
                    currentX += distance;
                }
            }
        }
    }
    return [currentY, currentX];
}

- 신고 결과 받기

def solution(id_list, report, k):
    idDict = {} # 누가 누구를 신고했는지 저장하는 dictionary
    reportedCount = {} # 누가 몇번 신고당했는지 저장하는 dictionary
    bannedId = [] # 어떤 id가 정지당했는지 저장
    answer = [] #처리 결과 메일을 받은 횟수

    # id와 해당 유저가 신고한 id를 저장하기 위한 dictionary생성
    for x in id_list:
        idDict[x] = set()
        reportedCount[x] = 0
    # 누가 누구를 신고했는지 저장
    for x in report:
        ids = x.split()
        idDict[ids[0]].add(ids[1])
    # 누가 몇번 신고당했는지 확인
    for x in reportedCount.keys():
        for y in idDict.keys():
            if x in idDict[y]:
                reportedCount[x] += 1
    # 정지당할 id를 저장
    for x in reportedCount.keys():
        if reportedCount[x] >= k:
            bannedId.append(x)
    # 메일 개수 저장
    for x in idDict.keys():
        i = 0
        for y in idDict[x]:
            if y in bannedId:
                i += 1
        answer.append(i)
        
    return answer

- [PCCP 기출문제] 1번 / 붕대 감기

def solution(bandage, health, attacks):
    maxH = health
    nextA = attacks.pop(0)
    continual = 0
    for i in range(attacks[-1][0]+1):
        # 공격당하면 피가 닳음
        if i == nextA[0]:
            health -= nextA[1]
            if attacks:
                nextA = attacks.pop(0)
            if health <= 0:
                return -1
            continual = 0
        # 그렇지 않으면 피 회복
        else:
            health += bandage[1]
            continual += 1
            if continual >= bandage[0]:
                health += bandage[2]
                continual = 0
            if health > maxH:
                health = maxH
    return health

- 가장 많이 받은 선물

def solution(friends, gifts):
    answer = 0
    fDict = {}
    scoreDict = {}
    for x in friends:
        fDict[x] = {}
        scoreDict[x] = 0
        for y in friends:
            if x != y:
                fDict[x][y] = 0
    for gift in gifts:
        [sender, receiver] = gift.split()
        fDict[sender][receiver] += 1
        scoreDict[sender] += 1
        scoreDict[receiver] -= 1
    for sender in friends:
        count = 0
        for receiver in friends:
            if sender != receiver:
                if fDict[sender][receiver] > fDict[receiver][sender]:
                    count += 1
                elif fDict[sender][receiver] == fDict[receiver][sender]:
                    if scoreDict[sender] > scoreDict[receiver]:
                        count += 1
        if count > answer:
            answer = count
    return answer