728x90

https://programmers.co.kr/learn/courses/30/lessons/72410

출처 : 프로그래머스

 

코딩테스트 연습 - 신규 아이디 추천

카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로

programmers.co.kr

def solution(new_id):
    answer = ''
    # 1단계 모든 대문자를 소문자로
    new_id = new_id.lower()
    id_must = ['-','_','.']

    # 2단계 알파벳 소문자, 숫자, 필요한 기호 빼고 삭제
    for i in new_id:
        if i in id_must or i.isalpha() or i.isdigit():
            answer += i

    # 3단계 연속된 . 하나의 .로
    cnt = 0
    for i in answer:
        if i == id_must[2]:
            cnt += 1
            if cnt == 2:
                answer = answer.replace("..", ".")
                cnt = 0

    # 4단계 .가 처음이나 마지막이면 제거
    if answer[0] == id_must[2]: # 처음
        if len(answer)>1: # 지울게 있어야 지움
            answer = answer[1:]
        else:
            answer = '.'
            
    if answer[-1] == id_must[2]: # 마지막
        answer = answer[:-1]

    # 5단계 빈 문자열이라면 a삽입
    if answer == "":
        answer += 'a'

    # 6단계 아이디 길이가 16자리 이상이면, 첫 15개 제외한 나머지 문자 제거
    if len(answer) >= 16:
        answer = answer.replace(answer[15:],"")
        if answer[-1] == id_must[2]: # 제거 후 마지막에 .이 있다면 제거
            answer = answer[:-1]

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

풀이

문자열 단계별 구현만 해주면 된다.

 

참고로 3단계는 이렇게 while 문으로도 가능하다.

while '..' in answer:
        answer = answer.replace('..', '.')

정규식으로 푸는 방법도 존재한다.

 

728x90

https://programmers.co.kr/learn/courses/30/lessons/81301

출처 : 프로그래머스

 

코딩테스트 연습 - 숫자 문자열과 영단어

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

programmers.co.kr

def solution(s):
    word = ['zero','one','two','three','four','five','six','seven','eight','nine']
    answer = ""
    alp = ""
    for i in s:
        if i.isdigit(): # 숫자인지
            answer += i
        else:
            alp += i
            if alp in word:
                answer += str(word.index(alp))
                alp = ""

    return int(answer)

풀이 1

숫자면 그냥 답에 추가해준다.

숫자가 아니라면 영문자 문자열에 넣다가 word에 저장해둔 값과 같은 값이 나온다면 word의 인덱스를 답에 넣어주고 영문자 리셋 ""한다.


def solution(s):
    words = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']

    for i in range(len(words)):
        s = s.replace(words[i], str(i))

    return int(s)

풀이 2

이건 다른 사람들 풀이이다..

replace를 썼다..

ㅠㅠ 대단한 사람들..

 


2021 카카오 채용연계형 인턴쉽 코딩테스트 문제다. 

728x90

출처 : 프로그래머스

 

https://programmers.co.kr/learn/courses/30/lessons/77484

 

코딩테스트 연습 - 로또의 최고 순위와 최저 순위

로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1 순위 당첨 내용 1 6개 번호가 모두 일치 2 5개 번호

programmers.co.kr

def solution(lottos, win_nums):
    ranking = [6, 6, 5, 4, 3, 2, 1] # 순위가 인덱스인 일치하는 개수 배열
    cnt = 0 # 당첨 개수
    for i in lottos:
        if i in win_nums:
            cnt += 1
    count0 = lottos.count(0) # 0 의 개수

    return [ranking[cnt+count0], ranking[cnt]]

풀이1

로또번호와 일치하는 개수 배열 ranking  : 순위를 인덱스로 한다.

 

def solution(lottos, win_nums):
    rank = {
        0: 6,
        1: 6,
        2: 5,
        3: 4,
        4: 3,
        5: 2,
        6: 1
    }
    return [ rank[len(set(lottos) & set(win_nums)) + lottos.count(0)], rank[len(set(lottos) & set(win_nums))]]

풀이2

딕셔너리를 활용한다.

두 배열의 공통값을 빠르게 구하는 방법

set(list1) & set(list2)

728x90

출처: 프로그래머스

https://programmers.co.kr/learn/courses/30/lessons/92334

 

 

코딩테스트 연습 - 신고 결과 받기

문제 설명 신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다. 각 유저는 한 번에 한 명의

programmers.co.kr

def solution(id_list, report, k):
    answer = [0] * len(id_list)
    cnt = {id:0 for id in id_list} # id 별 신고된 횟수
    d = {id:[] for id in id_list} # 이용자 id 가 신고한 id들 딕셔너리

    for repo in set(report):
        rep = repo.split(' ') # 이용자id와 신고한 id 분리
        d[rep[0]].append(rep[1]) # 딕셔너리에서 이용자 id 키에 신고한 id들 추가
        cnt[rep[1]] += 1 # 신고횟수

    # print(d)
    for key,values in d.items():
        for val in values:
            if cnt[val] >= k: # 신고횟수가 k번 이상이면
                answer[id_list.index(key)] += 1
    # print(answer)
    return answer

풀이 

딕셔너리를 사용해 풀이했다.

문제 풀이에 필요한 딕셔너리와 답 배열이다.

이용자와 신고한 id가 같아서 헷갈리기에 정리를 잘 하고 코딩을 하자.

 

  • d = { 이용자 id : [신고한 id들...]}
  • cnt = { 신고당한 id : 신고당한 횟수 }
  • answer = [ id_list 순서대로 k번 이상 신고당한 유저를 신고한 회원들에게 메일 보낸 횟수 +1 ]

 

  • 각 유저는 한 번에 한 명의 유저를 신고할 수 있습니다.
    • 신고 횟수에 제한은 없습니다. 서로 다른 유저를 계속해서 신고할 수 있습니다.
    • 한 유저를 여러 번 신고할 수도 있지만, 동일한 유저에 대한 신고 횟수는 1회로 처리됩니다.

이 조건에서 한 유저가 한 유저를 계속 신고하는 것은 1회로 처리하기에 set(report)를 해준다.

이는 테스트케이스2를 보고 이해하면 된다.

 

공백 기준으로 set(report)를 잘라주고 만들어둔 d 딕셔너리에 삽입한다.

또, cnt 딕셔너리에 신고당한 id 별 신고 횟수를 적는다.

모두 딕셔너리에 넣고, cnt 딕셔너리에서 k번 이상 신고당한 유저들을 신고한 유저인 d 딕셔너리의 key를

answer에서 메일 보낸 횟수 +=1 해준다. 

 


* 딕셔너리 작성

cnt = {id:0 for id in id_list} # id 별 신고된 횟수
d = {id:[] for id in id_list} # 이용자 id 가 신고한 id들 딕셔너리

말이 쫌 길긴 하지만, 충분히 풀 수 있다.

카카오 2022 블라인드 코딩테스트 채용 문제라고 한다. 

728x90

출처 : 프로그래머스

https://programmers.co.kr/learn/courses/30/lessons/42626

 

코딩테스트 연습 - 더 맵게

매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같

programmers.co.kr

#include <string>
#include <vector>
#include <queue>
using namespace std;

int solution(vector<int> sco, int K) {
    int answer = 0;
    //우선순위큐 minheap생성
    priority_queue<int, vector<int>, greater<int>> pq(sco.begin(), sco.end());
    
    while(pq.size()>1 && pq.top()<K){
        //큐에 음식 2개이상있고, 가장 작은 스코빌 지수가 k보다 작을때
        int tmp1 = pq.top();
        pq.pop();
        int tmp2 = pq.top();
        pq.pop();
        int tmp3 = (tmp1+ (tmp2*2));
        pq.push(tmp3);
        answer ++; // 섞어주기
    }
    if (pq.top()>=K)
        return answer;
    else
        return -1;
}

 

 

1. 힙에 음식 넣고 오름차순 정렬한다.

2. 가장 작은 두 음식을 뽑고, 규칙에 맞게 섞는다. 섞은 음식을 다시 넣고 정렬한다.

3. 음식이 2개 이상 있고, 가장 작은 음식이 k보다 작을 때 계속 진행한다.

 

이는 우선순위 큐를 이용해 풀었다.

우선순위 큐를 이용하면 알아서 정렬된다.

 

곧... 12시 지났으니까 오늘 보는 코테만 끝나면 다시 파이썬으로 코테 준비하련다... c++ 좋은데 파이썬으로 계속 준비했어서 헷갈린다 ㅡㅡ

 


c++에서의 우선순위큐

priority_queue<int, vector<int>, greater<int>> pq; //minheap

priority_queue<int> pq; //maxheap

 

 

728x90

https://programmers.co.kr/learn/courses/30/lessons/43163

출처: 프로그래머스

 

코딩테스트 연습 - 단어 변환

두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다. 1. 한 번에 한 개의 알파벳만 바꿀 수

programmers.co.kr

#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int answer = 50;
bool visited[50]; //방문words

//begin과 한 글자만 다른 words 찾는 함수
bool oneDiff(string a, string b){
    int cnt_diff = 0;
    for(int i=0; i<b.size(); i++){
        if(a[i]!=b[i]){
            cnt_diff ++;
        }
    }
    if(cnt_diff == 1) //하나만 다르면
        return true;
    else
        return false;
}

void dfs(string begin, string target, vector<string> words, int idx){
   
    if(begin == target){ //종료조건
        answer = min(idx, answer);
        return; //종료
    }
    
    for(int i=0; i<words.size(); i++){
        //한글자만 다르고 아직 방문하지 않았으면
        if(oneDiff(begin, words[i]) && !visited[i]){
            visited[i] = true;
            dfs(words[i], target, words, idx+1);
            visited[i] = false; //dfs종료 후 돌아오면, 백트래킹
        }
    }
    return;
}

int solution(string begin, string target, vector<string> words) {

    dfs(begin, target, words,0);
    if(answer == 50){ //변환할 수 없으면 0
        answer = 0;
    }
    return answer;
}

최대 words의 길이가 50이니까 answer도 50, visited크기도 50으로 맞춘다.

이 말은 최대로 50번 변환할 수 있다는 것이다.

우리는 최단 횟수를 구해야 하기에 횟수 0부터 시작해서 50이랑 비교해서 최솟값을 구해낸다.

 

dfs로 풀이했다.

begin과 words에 있는 단어를 비교했을 때, 한 글자만 다른 단어만 방문 가능하다.

한 글자만 다른 것을 판별하는 함수를 따로 oneDiff()로 만들었다.

 

아직 방문하지 않았고 한 글자만 다른 단어만 방문 표시하고 다음 단계인 dfs 진행한다.

dfs가 종료되었을 때, 다시 백트래킹으로 visited [i]= true 했던 것을 visited[i] = false 처리해준다.


백트래킹...............

연습하자

728x90

출처: 프로그래머스

https://programmers.co.kr/learn/courses/30/lessons/43162?language=cpp 

 

코딩테스트 연습 - 네트워크

네트워크란 컴퓨터 상호 간에 정보를 교환할 수 있도록 연결된 형태를 의미합니다. 예를 들어, 컴퓨터 A와 컴퓨터 B가 직접적으로 연결되어있고, 컴퓨터 B와 컴퓨터 C가 직접적으로 연결되어 있

programmers.co.kr

#include <string>
#include <vector>
using namespace std;
bool visited[201]; //방문검사

void dfs(vector<vector<int>> &arr, int idx){
    visited[idx] = true;
    for(int i=0; i<arr[idx].size(); i++){
        if(arr[idx][i] == 1 && visited[i] == false){ //1이고 아직 방문하지 않은 컴
            // arr[idx][i] = 0;
            // visited[i] = true;
            dfs(arr, i); //dfs 진행
        }
    }
}

int solution(int n, vector<vector<int>> computers) {
    int answer = 0;
    for(int i=0; i<n; i++){
        if (visited[i]==false){
            dfs(computers,i); //dfs 진행
            answer++;
        }
    }
    return answer;
}

dfs로 풀이했다.

 

연결되어 있는 것이 1로 표시되어 있다.

dfs로 computers 벡터를 돌면서 인접한 1을 찾고 dfs진행이 끝나면 인접한 1 찾는 과정이 끝난 것이다.

끝날 때마다 answer++해준다.

+ Recent posts