2022우아한형제들_우테코

[우테코] 프리코스 1주차

chsua 2022. 12. 19. 19:47

저번 4기는 프리코스 전에 코딩테스트를 보았다고 한다. 그리고 프리코스를 3주간 진행했다.

아마 이 코딩테스트가 프리코스에 합쳐지며 프리코스가 4주가 된 것이 아닐까싶다.

1주차 프리코스는 그다지 어렵지는 않았다.

기본적인 코딩테스트랑 비슷했다고 생각이 든다.

 

오히려 어려웠던 것은 깃과 깃헙에 대해 알아야했고, 

파일을 다운받고 설치하는 등의 과정이었다.

시스템에 대해 잘 모르니까 많이 답답했다.

어느 누가 알려주는 것도 아니었고..

 

결국 우테코의 교육은 이런 느낌인 것 같다. 좋게 말하면 독립적인 교육, 다르게 말하면 방목형 교육.

문제에 있어서도 시스템에 있어서도 슬랙에 물어볼 수 없게 만들었는데 결국 이건 선발과정이다보니 여기서 오는 스트레스가 엄청났다.

잘하고 싶은 생각은 있는데 물어볼 플랫폼이 하나도 없고, 우테코에 같이 지원한 사람도 없으니 절벽 끝에 내몰린 기분이었다.

우태코 프리코스 내내 이런 기분이 들었다.

 

어쩌면 핑계이지만 그래서 다른 사람들 코드를 볼 여력도 없었다.

계속 내 코드를 구현하고 생각하는 거에만 매몰되었다.

조금 더 여유가 있었다면 다른 사람들의 코드를 볼 걸 하는 아쉬움도 크다.

그랬다면 이후에 더 잘 짜서 낼 수 있었을텐데.. :(


아래는 제시된 문제였다.

총 7가지 기능을 구현해야 했다.

 

기능1 _ 포비와 크롱이의 페이지 게임

더보기
  • 기능1 _ 포비와 크롱이의 페이지 게임
    1. 책을 임의로 펼친다.
    2. 왼쪽 페이지 번호의 각 자리 숫자를 모두 더하거나, 모두 곱해 가장 큰 수를 구한다.
    3. 오른쪽 페이지 번호의 각 자리 숫자를 모두 더하거나, 모두 곱해 가장 큰 수를 구한다.
    4. 2~3 과정에서 가장 큰 수를 본인의 점수로 한다.
    5. 점수를 비교해 가장 높은 사람이 게임의 승자가 된다.
    6. 시작 면이나 마지막 면이 나오도록 책을 펼치지 않는다.
    포비와 크롱이 펼친 페이지가 들어있는 배열 pobi와 crong이 주어질 때, 포비가 이긴다면 1, 크롱이 이긴다면 2, 무승부는 0, 예외사항은 -1로 return 하도록 solution 메서드를 완성하라.
    • pobi와 crong의 길이는 2이다.
    • pobi와 crong에는 [왼쪽 페이지 번호, 오른쪽 페이지 번호]가 순서대로 들어있다.
    실행 결과 예시pobi crong result
    [97, 98] [197, 198] 0
    [131, 132] [211, 212] 1
    [99, 102] [211, 212] -1
  • 제한사항
  • 포비와 크롱이 페이지 번호가 1부터 시작되는 400 페이지의 책을 주웠다. 책을 살펴보니 왼쪽 페이지는 홀수, 오른쪽 페이지는 짝수 번호이고 모든 페이지에는 번호가 적혀있었다. 책이 마음에 든 포비와 크롱은 페이지 번호 게임을 통해 게임에서 이긴 사람이 책을 갖기로 한다. 페이지 번호 게임의 규칙은 아래와 같다.

 

내 제출 코드

function problem1(pobi, crong) {
    function splitNum(num) {
        num = num + "";
        let arrNum = num.split("");
        let plus = arrNum.map(x => +x).reduce((a, b) => a + b);
        let mul = arrNum.reduce((a, b) => a * b);
        return plus, mul;
    }

    function findMax(arr) {
        if (arr[0] + 1 !== arr[1]) return -1;
        return Math.max(splitNum(arr[0]), splitNum(arr[1]))
    }

    let pobiNum = findMax(pobi);
    let crongNum = findMax(crong);
    if ((pobiNum == -1) || (crongNum == -1)) return -1;
    else if (pobiNum > crongNum) return 1;
    else if (pobiNum < crongNum) return 2;
    else return 0; // pobiNum == crongNum
}

module.exports = problem1;

 

기능2_중복문자

더보기
  • 기능2_중복문자
    1. "browoanoommnaon"
    2. "browoannaon"
    3. "browoaaon"
    4. "browoon"
    5. "brown"
    임의의 문자열 cryptogram이 매개변수로 주어질 때, 연속하는 중복 문자들을 삭제한 결과를 return 하도록 solution 메서드를 완성하라.
    • cryptogram은 길이가 1 이상 1000 이하인 문자열이다.
    • cryptogram은 알파벳 소문자로만 이루어져 있다.
    실행 결과 예시
    cryptogram  result
    "browoanoommnaon" "brown"
    "zyelleyz" ""
  • 제한사항
  • 암호문을 좋아하는 괴짜 개발자 브라운이 이번에는 중복 문자를 이용한 새로운 암호를 만들었다. 예를 들어 "browoanoommnaon"이라는 암호문은 다음과 같은 순서로 해독할 수 있다.

 

내 제출코드

function problem2(cryptogram) {
    let newCryptogram = [];
    let inLen = cryptogram.length;
    let coLen = newCryptogram.length;

    function skip(cryptogram, newCryptogram) {
        for (let i = 0; i < cryptogram.length; i++) {
            if (cryptogram[i] != cryptogram[i + 1]) newCryptogram.push(cryptogram[i]);
            else i++;
        }
    }

    while (inLen != coLen) {
        skip(cryptogram, newCryptogram);
        coLen = newCryptogram.length
        cryptogram = []
        skip(newCryptogram, cryptogram);
        inLen = cryptogram.length;
        newCryptogram = [];
    }

    return cryptogram.join("");
}

 

기능3_369게임숫자

더보기
  • 기능3_369게임숫자
    • number가 매개변수로 주어질 때, 1부터 number까지 손뼉을 몇 번 쳐야 하는지 횟수를 return 하도록 solution 메서드를 완성하라.
      • number는 1 이상 10,000 이하인 자연수이다.
      실행 결과 예시
      number  result
      13 4
      33 14
  • 제한사항
  • 배달이가 좋아하는 369게임을 하고자 한다. 놀이법은 1부터 숫자를 하나씩 대면서, 3, 6, 9가 들어가는 숫자는 숫자를 말하는 대신 3, 6, 9의 개수만큼 손뼉을 쳐야 한다.

 

내 코드

function problem3(number) {
    let count = 0;

    for (let i = 1; i <= number; i++) {
        let arr = i + "";
        for (let j = 0; j < arr.length; j++) {
            if ((arr[j] == "3") || (arr[j] == "6") || (arr[j] == "9")) count++;
        }
    }
    return count;
}

 

기능4_반대로 말하기

더보기
  • 기능4_반대로 말하기
    • 어느 연못에 엄마 말씀을 좀처럼 듣지 않는 청개구리가 살고 있었다. 청개구리는 엄마가 하는 말은 무엇이든 반대로 말하였다.엄마 말씀 word가 매개변수로 주어질 때, 아래 청개구리 사전을 참고해 반대로 변환하여 return 하도록 solution 메서드를 완성하라.
    • 제한사항
      • word는 길이가 1 이상 1,000 이하인 문자열이다.
      • 알파벳 외의 문자는 변환하지 않는다.
      • 알파벳 대문자는 알파벳 대문자로, 알파벳 소문자는 알파벳 소문자로 변환한다.
      실행 결과 예시 
      word result
      "I love you" "R olev blf"

 

내 코드: 

function problem4(word) {
    let answer = [];
    let map = new Map();
    let alp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let alpRev = "zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA";
    for (let i = 0; i < 52; i++) {
        map.set(alp[i], alpRev[i]);
    }
    for (let j = 0; j < word.length; j++) {
        if (map.has(word[j])) answer.push(map.get(word[j]));
        else answer.push(word[j]);
    }

    return answer.join("");
}

 

기능5_돈 반환

더보기
  • 기능5_돈 반환
    • 계좌에 들어있는 돈 일부를 은행에서 출금하고자 한다. 돈 담을 지갑이 최대한 가볍도록 큰 금액의 화폐 위주로 받는다.
    • 돈의 액수 money가 매개변수로 주어질 때, 오만 원권, 만 원권, 오천 원권, 천 원권, 오백원 동전, 백원 동전, 오십원 동전, 십원 동전, 일원 동전 각 몇 개로 변환되는지 금액이 큰 순서대로 배열에 담아 return 하도록 solution 메서드를 완성하라.
    • 실행 결과 예시 
      money result
      50237 [1, 0, 0, 0, 0, 2, 0, 3, 7]
      15000 [0, 1, 1, 0, 0, 0, 0, 0, 0]
  • 제한사항
    • money는 1 이상 1,000,000 이하인 자연수이다.

내 코드: 

function problem5(money) {
    let answer = [0, 0, 0, 0, 0, 0, 0, 0, 0]

    while (money != 0) {
        if (money >= 50000) {
            money -= 50000;
            answer[0]++
        } else if (money >= 10000) {
            money -= 10000;
            answer[1]++
        } else if (money >= 5000) {
            money -= 5000;
            answer[2]++
        } else if (money >= 1000) {
            money -= 1000;
            answer[3]++
        } else if (money >= 500) {
            money -= 500;
            answer[4]++
        } else if (money >= 100) {
            money -= 100;
            answer[5]++
        } else if (money >= 50) {
            money -= 50;
            answer[6]++
        } else if (money >= 10) {
            money -= 10;
            answer[7]++
        } else {
            answer[8] = money;
            money = 0
        }
    }
    return answer;
}

 

기능6_유사닉네임 찾기

더보기
  • 기능6_유사닉네임 찾기
    • 우아한테크코스에서는 교육생(이하 크루) 간 소통 시 닉네임을 사용한다. 간혹 비슷한 닉네임을 정하는 경우가 있는데, 이러할 경우 소통할 때 혼란을 불러일으킬 수 있다. 혼란을 막기 위해 크루들의 닉네임 중 같은 글자가 연속적으로 포함 될 경우 해당 닉네임 사용을 제한하려 한다. 이를 위해 같은 글자가 연속적으로 포함되는 닉네임을 신청한 크루들에게 알려주는 시스템을 만들려고 한다.제한사항
    • 두 글자 이상의 문자가 연속적으로 순서에 맞추어 포함되어 있는 경우 중복으로 간주한다.
    • 크루는 1명 이상 10,000명 이하이다.
    • 이메일은 이메일 형식에 부합하며, 전체 길이는 11자 이상 20자 미만이다.
    • 신청할 수 있는 이메일은 email.com 도메인으로만 제한한다.
    • 닉네임은 한글만 가능하고 전체 길이는 1자 이상 20자 미만이다.
    • result는 이메일에 해당하는 부분의 문자열을 오름차순으로 정렬하고 중복은 제거한다.
    • 신청받은 닉네임 중 같은 글자가 연속적으로 포함 되는 닉네임을 작성한 지원자의 이메일 목록을 return 하도록 solution 메서드를 완성하라.
  • 실행 결과 예시 
    forms result
    [ ["mailto:jm@email.com", "제이엠"], ["mailto:jason@email.com", "제이슨"], ["mailto:woniee@email.com", "워니"], ["mailto:mj@email.com", "엠제이"], ["mailto:nowm@email.com", "이제엠"] ] ["mailto:jason@email.com", "mailto:jm@email.com", "mailto:mj@email.com"]

내 코드:

function problem6(forms) {
    let answer = new Set()
    let nameMap = new Map();

    for (let i = 0; i < forms.length; i++) {
        let [email, name] = forms[i] ;
        for (let j = 0; j < name.length - 1; j++) {
            let sliceName = name[j] + name[j + 1];
            if (nameMap.has(sliceName)) {
                answer.add(nameMap.get(sliceName));
                answer.add(email);
            } else nameMap.set(sliceName, email);
        }
    }
    let answerArr = [...answer];
    return answerArr.sort();
}

 

기능7_친구추천 알고리즘

더보기
  • 기능7_친구추천 알고리즘
    • 레벨 2의 팀 프로젝트 미션으로 SNS(Social Networking Service)를 만들고자 하는 팀이 있다. 팀에 속한 크루 중 평소 알고리즘에 관심이 많은 미스터코는 친구 추천 알고리즘을 구현하고자 아래와 같은 규칙을 세웠다.
      • 사용자와 함께 아는 친구의 수 = 10점
      • 사용자의 타임 라인에 방문한 횟수 = 1점
      사용자 아이디 user와 친구 관계를 담은 이차원 배열 friends, 사용자 타임 라인 방문 기록 visitors가 매개변수로 주어질 때, 미스터코의 친구 추천 규칙에 따라 점수가 가장 높은 순으로 정렬하여 최대 5명을 return 하도록 solution 메서드를 완성하라. 이때 추천 점수가 0점인 경우 추천하지 않으며, 추천 점수가 같은 경우는 이름순으로 정렬한다.
    • 제한사항
      • user는 길이가 1 이상 30 이하인 문자열이다.
      • friends는 길이가 1 이상 10,000 이하인 배열이다.
      • friends의 각 원소는 길이가 2인 배열로 [아이디 A, 아이디 B] 순으로 들어있다.
        • A와 B는 친구라는 의미이다.
        • 아이디는 길이가 1 이상 30 이하인 문자열이다.
      • visitors는 길이가 0 이상 10,000 이하인 배열이다.
      • 사용자 아이디는 알파벳 소문자로만 이루어져 있다.
      • 동일한 친구 관계가 중복해서 주어지지 않는다.
      • 추천할 친구가 없는 경우는 주어지지 않는다.
    • 실행 결과 예시
user friends visitors result
"mrko" [ ["donut", "andole"], ["donut", "jun"], ["donut", "mrko"],
["shakevan", "andole"], ["shakevan", "jun"],
["shakevan", "mrko"] ]
["bedi", "bedi", "donut", "bedi", "shakevan"] ["andole",
"jun", "bedi"]

 

내 코드:

function problem7(user, friends, visitors) {
    let input = friends;
    **let friend = new Map() ; //친구 map**
    let score = new Map() ;  // 점수판
    for (let i = 0; i < input.length; i++) {    //친구 - [친구] 맵 만들기 및 score판 설정
        let [first, sec] = input[i];
        score.set(first, 0);
        score.set(sec, 0);
        if (friend.has(first)) friend.get(first).push(sec);
        else friend.set(first, [sec]);
        if (friend.has(sec)) friend.get(sec).push(first);
        else friend.set(sec, [first]);
    }

    let userFriend = friend.get(user);  // user의 친구 구하기
    for (let j = 0; j < userFriend.length; j++) {  
        let friFri = friend.get(userFriend[j]);       //친구의 친구 구하기
        for (let k = 0; k < friFri.length; k++) {
            score.set(friFri[k], score.get(friFri[k]) + 10);  //친구의 친구 점수 추가
        }
    }

    for (let l = 0; l < visitors.length; l++) {     //방문친구 점수 추가
        if (score.has(visitors[l])) score.set(visitors[l], score.get(visitors[l]) + 1);
        else score.set(visitors[l], 1);
    }

    userFriend.forEach(x => score.set(x, -1));  // 기존 친구 점수 -1
    score.set(user, -1);     // 본인 점수 -1
    score = [...score].sort((a, b) => {   //점수별 내림차순 + 동일점수 오름차순
        if (b[1] === a[1]) {
            if (a[0] < b[0]) return -1
        } else return b[1] - a[1];
    });

    let answer = []
    **for (let i = 0; i < 5; i++) {
        if (score[i][1] <= 0) break;
        answer.push(score[i][0])
    }**
    return answer;
}

>> friend가 원래는 배열이었는데 그럼 너무 반복횟수가 많아져서 이걸 map으로 만들어줌
>> 마지막 answer을 원래는 shift()로 했는데 그럼 오래걸려서 for문으로 수정

 

 

 

 

내 미션 제출:

 

https://github.com/woowacourse-precourse/javascript-onboarding/pull/257/files

 

[온보딩] 최수현 미션 제출합니다. by chsua · Pull Request #257 · woowacourse-precourse/javascript-onboarding

 

github.com