상세 컨텐츠

본문 제목

[PROGRAMMERS] 프로그래머스 코딩테스트 연습 > Level 2 & python3 문제풀이 ~ 11.04

취준/2. 코딩테스트

by ranlan 2021. 11. 5. 03:59

본문

728x90

업로드된 날짜와 제목의 날짜가 항상 하루 차이나는 이유는,, 내가 늘 새벽에 공부하기 때문,,

낮에는 캡스톤하느라 바빴구,, 밤에는 야구보다 시간 다가서 이제야 겨우 몇문제 풀고 포스팅하는 중,,⚾️

내일은 진짜 열심히 해야되는딩

 


 

오픈채팅방

코딩테스트 연습 > 2019 KAKAO BLIND RECRUITMENT > 오픈채팅방 https://programmers.co.kr/learn/courses/30/lessons/42888

 

코딩테스트 연습 - 오픈채팅방

오픈채팅방 카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다. 신입사원인 김크루는 카카오톡 오

programmers.co.kr

난이도는 나쁘지 않았음

나도 그렇고 대부분 아이디와 이름을 매칭하는 딕셔너리를 둔 듯하다. 아닌 경우도 있지만 그래도 가장 직관적이고 깔끔한듯!

 

1) 처음 생각한 코드

def solution(records):
    
    answer = [] 
    change_names = {} # 아이디: 이름
    records.reverse() # 순서 뒤집어줌
    records = [record.split() for record in records] # ' '로 나눈 리스트 반환

    for i in range(len(records)):
        record = records[i]
        act = record[0]
        id = record[1]

        if act == 'Change':
            if id in change_names.keys():
                continue # 이미 저장된 이름일 경우
            else
                change_names[id] = record[2] # 변경된 최근 이름 저장
        elif act == 'Enter': # 퇴장시에는 이름이 주어지지 않음
            if id not in change_names: # 이름 사전에 저장되어있지 않은 경우 저장
                change_names[id] = record[2]
            # 이름을 최근 이름으로 바꿔줌    
            records[i][2] = record[2] if id not in change_names.keys() else change_names[id]
    
    for record in records[::-1]:
        if record[0] == 'Change':
            continue
        elif record[0] == 'Enter':
            answer.append(record[2] + '님이 들어왔습니다.')
        elif record[0] == 'Leave':
            answer.append(change_names[record[1]] + '님이 나갔습니다.')

    return answer

records 리스트에서 Change 나올때의 이름이 최신임으로 반복문을 뒤에서부터 돌려야겠다는 생각

+ 혹시 변경은 안됐지만 누락된 이름이 있을까봐 Enter일때 딕셔너리에 아이디와 이름을 넣어줘야겠다는 생각

+ 이름 변경을 확인하는 첫번째 for문에서 변경된 이름으로 모두 바꿔줘야겠다는 생각..

 

2) 최종

문제를 통과하고나니 내 풀이가 완벽히 이해되고.. 지저분하다는걸 느껴서 수정

def solution(records):
    
    answer = [] 
    change_names = {} # 아이디: 이름
    records = [record.split() for record in records] # ' '으로 나눠서 리스트 반환

    # 첫번째 for문에서 굳이 이름을 바꾸지 않고 아이디 & 이름 정보만 저장
    for record in records:
        if record[0] == 'Change':
            change_names[record[1]] = record[2] # change 이름 변경
        elif record[0] == 'Enter': # 퇴장시에는 이름이 주어지지 않음
            change_names[record[1]] = record[2]
    
    for record in records:
        if record[0] == 'Change':
            continue
        elif record[0] == 'Enter':
            answer.append(change_names[record[1]] + '님이 들어왔습니다.')
        elif record[0] == 'Leave':
            answer.append(change_names[record[1]] + '님이 나갔습니다.')

    return answer

 

 

멀쩡한 사각형

코딩테스트 연습 > Summer/Winter Coding(2019) > 멀쩡한 사각형 https://programmers.co.kr/learn/courses/30/lessons/62048

 

코딩테스트 연습 - 멀쩡한 사각형

가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을

programmers.co.kr

직접 그림을 그려가며 머리를 좀 굴려야했던 문제ㅠㅠ

 

1) 처음 푼 풀이(통과X)

(모든 풀이에서 가로가 짧고 세로가 더 길다고 가정)

 

첫 풀이에서는 최소공배수와 최대공약수를 생각 안하고 그냥 기울기에만 초점을 맞췄다.

먼저 기울기가 정수로 나올때는 무조건 전체 사각형 수에서 세로 길이만큼 빼주면 됨

기울기가 정수가 아닐 경우, 사용하지 못하는 칸이 처음에는 무조건 2 * 가로(더 짧은 길이) 라고 생각했다.

기울기의 여러 경우를 생각해봤을때 고정적으로 2개가 아니라 기울기보다 큰 최소의 자연수라고 생각되어 수정했다.

def solution(w, h):
    total = w * h
    height, width = max(w, h), min(w, h)

    if height % width == 0:
        return total - h
    
    disable = math.ceil(height / width)
    return total - (disable * width)

 

2) 규칙을 못찾겠어서 다른 사람의 풀이 참고함

[참고] https://luv-n-interest.tistory.com/736

 

멀쩡한 사각형 원리, Python [프로그래머스]

문제 설명 가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를

luv-n-interest.tistory.com

요약

최소공배수 크기 만큼의 사각형 안에서 (가로+세로-1)개의 사각형이 사용 불가함으로

-> 전체 크기로 비율을 늘리면 사용 불가 사각형의 수는 최대공약수 * (가로/최대공약수 + 세로/최대공약수 - 1)

-> 결국  (가로 + 세로 - 최대공약수)  개가 사용 불가능한 사각형의 수가 된다..!

import math

def solution(w, h):
    total = w * h
    height, width = max(w, h), min(w, h)

    if height % width == 0:
        return total - height

    # 최소공배수 크기 사각형 안의 사용할 수 없는 사각형
    disable = height + width - math.gcd(height, width)

    return total - disable

최대공약수는 이미 정의되어있는 math 라이브러리의 gcd() 메서드 이용

 

이런 규칙 찾아내는 사람들은 참 대단한 것 같다,, 기울기도 좋은 풀이가 될 수 있었을 것 같은디 아쉽다.

근데 기울기를 이용해서 하는 것도 결국은 최대공약수, 최소공배수가 필요하긴 했을 듯 하당.

 

3) 더 짧은 코드

def solution(w,h):
    gcd = math.gcd(w, h) 
    answer = w * h - (w + h - gcd)
    return answer

내가 기울기가 정수일 때 따로 처리한 경우도 모두 계산 가능함

 

 

728x90

관련글 더보기

댓글 영역