[우테코 프리코스] FE 김머핀의 1주차 회고록

Murpin·2022년 11월 7일
1

우테코프리코스

목록 보기
1/5

이번에 처음 지원해보는 우아한 테크 코스에서 프리코스를 참여하게 되었습니다.

[온보딩] 미션 수행

먼저 우아한테크코스 github에 초대되어 매 주차마다 미션을 진행하는데 1주차는 간단하게 문제를 7개를 풀어서 제출하는 것으로 진행하였다.
그리고 해당 문제를 풀면서 내가 함수 분할을 하거나 변수명을 결정하는 그런 방식에 대해서 나의 생각을 되짚어 보고 복기해보는 시간을 가져보았고 이를 정리하여 이번 글을 쓰게 됩니다.

문제 1


🚀 기능 요구 사항

포비와 크롱이 페이지 번호가 1부터 시작되는 400 페이지의 책을 주웠다. 책을 살펴보니 왼쪽 페이지는 홀수, 오른쪽 페이지는 짝수 번호이고 모든 페이지에는 번호가 적혀있었다. 책이 마음에 든 포비와 크롱은 페이지 번호 게임을 통해 게임에서 이긴 사람이 책을 갖기로 한다. 페이지 번호 게임의 규칙은 아래와 같다.

  1. 책을 임의로 펼친다.
  2. 왼쪽 페이지 번호의 각 자리 숫자를 모두 더하거나, 모두 곱해 가장 큰 수를 구한다.
  3. 오른쪽 페이지 번호의 각 자리 숫자를 모두 더하거나, 모두 곱해 가장 큰 수를 구한다.
  4. 2~3 과정에서 가장 큰 수를 본인의 점수로 한다.
  5. 점수를 비교해 가장 높은 사람이 게임의 승자가 된다.
  6. 시작 면이나 마지막 면이 나오도록 책을 펼치지 않는다.

포비와 크롱이 펼친 페이지가 들어있는 배열 pobi와 crong이 주어질 때, 포비가 이긴다면 1, 크롱이 이긴다면 2, 무승부는 0, 예외사항은 -1로 return 하도록 solution 메서드를 완성하라.

문제 정의

첫번째 문제에서는 각 pobi와 crong에 대하여 길이가 2인 배열 두개를 입력 받는데 이 값은 연속적이어야한다. (책을 생각했을때 왼쪽 페이지가 5이면 오른쪽은 6일 것이다)

그리고 이 두 개의 값에 대하여 연산의 횟수를 생각해보았을 때, 요구사항에서 2번과 3번은 각 페이지 값에 대하여 곱셈값과 덧셈값을 해주어야 한다.
왼쪽 페이지 연산 2+
오른족 페이지 연산 2+
그렇다면 유저 한 명에게는 선택할 수 있는 숫자의 경우가 4가지인가? 아니다.
2번과 3번을 자세히 읽어 보면 가장 큰 수를 구하는 것이므로
왼쪽에서 곱셈과 덧셈 값 중 가장 큰 수 하나
오른족에서 곱셈과 덧셈값 중 가장 큰 수 하나를 구하고서 비교한 이후 더 큰 값을 반환하면 된다.

처음 문제를 해결할 때 조건문을 써보니 depth가 굉장히 심해져 가독성이 떨어짐을 느꼈고 해당 부분을 함수로 분할하였다.

함수 정의

처음에는 페이지에서 곱셈 값과 덧셈 값을 계산해주고 더 큰 값을 반환하는 함수
calcPageLargerValue

다음은 왼쪽과 오른쪽 페이지의 최댓값을 비교하여 유저의 최댓값을 반환하는 함수
getUserMaxScore

이 두 가지로 분할하여 최댓값을 계산하는 과정에서 단순히 >, < 부등호등을 사용하는 것이 아닌 자바스크립트에 Math.max(...)를 활용하였다.
해당 함수는 괄호 안에 입력받는 숫자 중 가장 큰 수를 반환합니다.

  • Math.max(1 , 2)인 경우에는 2를 반환

그리고 최종적으로 결과 값에 대해서는 if … else 를 활용하여 결과값을 출력하였습니다.

함수로 분할할까 하였지만 결과 값에 대한 연산을 분리하는 것에 대해서 오히려 단순 조건문으로 이루어진 것인데 함수 분할의 의미의 필요성을 느끼지 못하여 그대로 작성하였습니다.

느낀 점

1번 문제에 대해서는 큰 막힘 없이 풀었고 함수를 분할하면서 분할하는 기준을 세워보는 것도 좋을 것 같다. 단순한 필요성을 느끼지 못했다 보다는 명확한 근거가 있다면 좋을 지도?!

문제 2


🚀 기능 요구 사항

암호문을 좋아하는 괴짜 개발자 브라운이 이번에는 중복 문자를 이용한 새로운 암호를 만들었다. 예를 들어 “browoanoommnaon”이라는 암호문은 다음과 같은 순서로 해독할 수 있다.

  1. “browoanoommnaon”
  2. “browoannaon”
  3. “browoaaon”
  4. “browoon”
  5. “brown”

임의의 문자열 cryptogram이 매개변수로 주어질 때, 연속하는 중복 문자들을 삭제한 결과를 return 하도록 solution 메서드를 완성하라.

문제 정의

cryptogram이란 암호문이 존재하며,
그 암호문은 2번 이상 반복되는 문자열들을 제거하고 붙이고,
또 다시 2번이상 반복되는 문자열이 존재하지 않을 때까지 반복하면, 결국은 단일로 이루어진 단어가 나올 것이며 해당 단어를 출력하면 된다.

함수 정의

결국에는 두 번 이상 반복되는 것을 찾아서 공백으로 만들 수 있는 함수가 있다면 해당 함수를 반복을 돌리면서 없을 때 종료하는 것으로 문제를 해결할 수 있을 것 같았다.

처음에 생각한 것은 while문을 통해 반복문처리도 가능할 것 같다고 생각했지만, 자바스크립트 메서드를 활용하는 방식으로 더 생각해보았다.

그렇게 생각해낸 것이 정규표현식이다.

정규표현식을 통해 만약 a~z중 2번 이상 반복되는 문자열을 확인한다면, 해당 부분을 replace()를 통해 공백으로 바꿔주는 것을 반복하여 반복이 없어진 경우에 대해 최종 값을 반환하는 형태를 생각했다.

느낀점

정규표현식을 사용하니 굉장히 짧고 간단하게 작성할 수 있었다. 다음부터 문자열에 대한 자세를 정규표현식으로 접근해야겠다는 나름의 솔루션을 찾게 되었다.
하나 생긴 의문으로는 정규표현식의 경우에는 어떻게 탐색하는 탐색 방식에 대해 궁금증이 생겼다. (좋은 블로깅의 주제가 될 것 같다.)

문제 3


🚀 기능 요구 사항

배달이가 좋아하는 369게임을 하고자 한다. 놀이법은 1부터 숫자를 하나씩 대면서, 3, 6, 9가 들어가는 숫자는 숫자를 말하는 대신 3, 6, 9의 개수만큼 손뼉을 쳐야 한다.

숫자 number가 매개변수로 주어질 때, 1부터 number까지 손뼉을 몇 번 쳐야 하는지 횟수를 return 하도록 solution 메서드를 완성하라.

문제 정의

간단하게 369 게임이며, 만약 해당 숫자까지 1부터 올라가면서 3, 6, 9 가 해당 문자에 포함되어있는 횟수를 계산하여 반환하는 문제이다.

함수 정의

결국은 입력받은 숫자만큼 반복은 해야할 것이다.
그러한 반복이 되는 것에 대해서 3, 6, 9 가 포함된 횟수를 정규표현식을 통해 포함된 경우에 대해서만 3,6,9의 갯수를 계산하도록 하였다.
갯수 계산에 대해서는 match().length를 통해 계산하였다.

또한 계산에 있어서 1이나 2에서는 굳이 검사할 필요가 없기에 3부터 반복문을 검사하였다.

느낀점

정규표현식을 활용하여 강력한 문제 풀이가 가능했다. 번거롭게 더 함수를 작성할 생각이 들지 않았다. 하지만 정규표현식에 대한 초기 정의에서는 꽤나 번거롭기도 하였고 학습을 요구한다는 것을 느꼈다.

문제 4


🚀 기능 요구 사항

어느 연못에 엄마 말씀을 좀처럼 듣지 않는 청개구리가 살고 있었다. 청개구리는 엄마가 하는 말은 무엇이든 반대로 말하였다.

엄마 말씀 word가 매개변수로 주어질 때, 아래 청개구리 사전을 참고해 반대로 변환하여 return 하도록 solution 메서드를 완성하라.
| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
| — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
| Z | Y | X | W | V | U | T | S | R | Q | P | O | N | M | L | K | J | I | H | G | F | E | D | C | B | A |

문제 정의

영어 문장이 주워지면 모든 문자에 대해 문자를 변경하는데
변경하는 대상은 영어 소문자와 대문자이며, A ~ Z 를 Z ~ A 형식으로 변경하는 작업을 진행한다.
그리고 입력 받는 문장에 대해 영어에서만 처리가 이루어져야 한다.

함수 정의

먼저 알파벳인 영어에서 A~Z a-z 에 대한 탐색이 이루어져야하므로 탐색 정규표현식
ALPHABETICAL_REG_EXP

탐색된 모든 수에 대하여 청개구리식으로 변경하는 함수 frogTranslation

이 두 개를 활용하여 계산하기로 하였습니다.
문자열에 대한 탐색으로는 정규표현식을 통해 하였는데 그렇다면 변경을 어떻게 할지를 고민하였고, 변경에 대한 replace()를 더 학습하였습니다
그리고 replace()에 두 번째 인자로 익명함수를 통하여 선택되는 문자에 대한 정보를 받을 수 있는 기능을 통하여 각 영어 문자에 변화를 주었습니다.
그리고 청개구리식 변환에서 아스키코드를 활용하여 계산을 하였습니다.
계산 과정에서 착각할 뻔 했던 부분은 영어의 아스키코드는 대문자와 소문자가 연속해 있지 않으며, 코드 변환 이후 다시 글자로 반환해주는 과정을 거쳐야 한다는 것이었습니다.
A~Z : 65 ~ 90
a-z: 97 ~ 122
91 ~ 96은 다른 문자

느낀점

문자 변형에 대해서 아스키코드를 사용해서 변경하였는데 이 것 말고는 딱히 다른 풀이법이 떠오르지 않았다. 그리고 또 이 문제에서 정규표현식이 활약하였다.
나름 깔끔한 풀이가 지속되고 있어서 기분은 좋았다.

문제 5


🚀 기능 요구 사항

계좌에 들어있는 돈 일부를 은행에서 출금하고자 한다. 돈 담을 지갑이 최대한 가볍도록 큰 금액의 화폐 위주로 받는다.

돈의 액수 money가 매개변수로 주어질 때, 오만 원권, 만 원권, 오천 원권, 천 원권, 오백원 동전, 백원 동전, 오십원 동전, 십원 동전, 일원 동전 각 몇 개로 변환되는지 금액이 큰 순서대로 배열에 담아 return 하도록 solution 메서드를 완성하라.

문제 정의

결국에는 들어오는 금액에 대해서 돈의 액수에서 가장 큰 지폐권부터 가질 수 있는 최대를 가지면서 계산하면 자연스럽게 최소의 지폐와 동전의 갯수를 가지게 될 것이다.

함수 정의

가장 먼저 떠오른 것은 해당 지폐권에 대한 정보를 담고 있는 정적인 데이터가 필요하다고 판단하여 해당 상수를 선언하여 사용하였다.
const STATIC_MONEY = [50000, 10000, 5000, 1000, 500, 100, 50, 10, 1];

두 번째로는 상수로 선언한 단위는 큰 순서대로 선언되었으니, 50000원부터 입력 받은 값을 나누어준 값을 answer 배열에 push하는 형태로 구현하였습니다.
결과적으로 큰 수를 먼저 나누게 되고, 마지막 1까지 나눈 수를 계산하는 것으로 결과가 마무리 됩니다.

느낀점

지폐의 단위를 먼저 선언하여 해당 값을 순서대로 계산을 먼저 생각해서 하였지만 마지막 1계산 이후 return을 0으로 설정하였는데 뭔가 쓰레기 값을 사용하게 된 것 같아 불편했다. 한번 더 함수를 깔끔하게 할 수 있도록 노력해야겠다.

문제 6


🚀 기능 요구 사항

우아한테크코스에서는 교육생(이하 크루) 간 소통 시 닉네임을 사용한다. 간혹 비슷한 닉네임을 정하는 경우가 있는데, 이러할 경우 소통할 때 혼란을 불러일으킬 수 있다.

혼란을 막기 위해 크루들의 닉네임 중 같은 글자가 연속적으로 포함 될 경우 해당 닉네임 사용을 제한하려 한다. 이를 위해 같은 글자가 연속적으로 포함되는 닉네임을 신청한 크루들에게 알려주는 시스템을 만들려고 한다.

신청받은 닉네임 중 같은 글자가 연속적으로 포함 되는 닉네임을 작성한 지원자의 이메일 목록을 return 하도록 solution 메서드를 완성하라.

문제 정의

입력의 경우에 대해서 닉네임과 이메일이 입력된다
입력된 사용자의 이름과 이메일이 저장되고 입력된 사용자들의 닉네임 중 2글자가 같은 경우에는 해당 유저의 이메일과 닉네임을 반환해야한다.
중복된 인원 두 명 모두 나와야한다.

함수 정의

먼저 닉네임에 대한 내용을 2글자씩 나누어서 저장해주는 함수 -setNicknameDirectory
검색 중인 닉네임이 저장된 nickNameDirectory에 있는 글자 중 2글자가 중복이 존재하는 지를 파악하는 함수 -isDuplicateNickname

현재 검색 중인 닉네임에 대한 중복이 있는지를 검사하는 함수 - isDuplicateNowNickname

  • 이 함수의 경우에는 예외 상황을 생각했던 예를 들어 닉네임이 “김머판머판” 인 경우 닉네임을 2글자로 나누어서 저장하는 과정에서 중복으로 반환하는 경우가 있다.
  • 그래서 이를 방지하고자 넣은 함수이다.

중복이 일어난 닉네임과 이메일을 정답배열에 넣는 함수 - setAnswer

느낀점

여기서부터 조금 많이 구현에 대한 생각이 많아지고 브루트포스와 같은 무식한 방식으로 했다면 굉장히 오랜 시간이 걸렸을 것 같다. 마침 JS Object를 통해 키값을 통한 value 접근의 시간을 줄임으로써 실행시간에서 많은 손해를 보지 않고 해결할 수 있었던 문제 였다.

문제 7


🚀 기능 요구 사항

레벨 2의 팀 프로젝트 미션으로 SNS(Social Networking Service)를 만들고자 하는 팀이 있다. 팀에 속한 크루 중 평소 알고리즘에 관심이 많은 미스터코는 친구 추천 알고리즘을 구현하고자 아래와 같은 규칙을 세웠다.

  • 사용자와 함께 아는 친구의 수 = 10점
  • 사용자의 타임 라인에 방문한 횟수 = 1점

사용자 아이디 user와 친구 관계를 담은 이차원 배열 friends, 사용자 타임 라인 방문 기록 visitors가 매개변수로 주어질 때, 미스터코의 친구 추천 규칙에 따라 점수가 가장 높은 순으로 정렬하여 최대 5명을 return 하도록 solution 메서드를 완성하라. 이때 추천 점수가 0점인 경우 추천하지 않으며, 추천 점수가 같은 경우는 이름순으로 정렬한다.

문제 정의

먼저 user를 중심으로 생각해야한다. 중요한 것은 user와 관련이 있는자를 구분하는 것으로 시작한다.

점수를 주는 기준

  • user의 친구(friend)의 친구(other friend)이지만 user와 친구(friend)가 아닌 경우 10점
  • user의 친구가 아닌 경우, user의 타임라인 방문 회수 당 1점

탐색 순서의 경우에는 먼저 user의 친구(friend)들을 한명씩 살펴야한다.
그리고 user의 친구(friend)들의 친구들(other friend) 중에 user의 친구가 아닌 친구들은 모두 10점씩 부여해 준다.
10점이 부여되는 친구들은 타임라인에 몇회 방문했는지 계산하고 방문 횟수당 1점을 추가로 부여한다.
그렇게 최종적으로 결정된 인원은 정답 배열에 넣게되는데
만약 배열이 비어있는 경우에는 그대로 집어넣는다.
만약 숫자가 하나라도 있다면 그와 점수를 비교하고 더 높을경우 자리를 교환하고 낮을 경우 다음 자리로 이동한다.

그렇게 탐색과 정렬이 완성되면 결과값을 반환한다.

함수 정의

form에 입력되는 친구들에 대한 관계를 저장한다. 키값이 user에게 value로 친구들의 이름이 담긴 리스트를 갖게하고, 나머지 친구와 친구리스트 형태로 저장하는 함수 - updateFriendsList

만약 추천 리스트에 중복된 인원의 이름이 들어오는 지를 확인하는 함수 - isDuplicateRecommendFriendList

추천 리스트에 들어가는 인원들을 반환하는 함수 - getRecommendFriendList

추천 리스트에 들어가는 인원들의 순위를 정렬하고 저장하는 함수 - setRecommendFriendList

느낀점

개인적으로 가장 구현이 어려웠다. 마지막 문제여서 그런지 생각 보다 시간도 많이 쓰고 코드가 길어지게 된 부분이 컸다. 또한 인수들에 대한 네이밍도 중요하겠다고 생각하여 다양한 방식으로 시도를 해보았다. 시도는 좋았지만 그닥 퀄리티가 좋아보이지 않았다.
아무래도 더 좋은 구조를 생각할 수 있었을 텐데 너무 아쉽다. 앞으로 남은 기간 더 열심히 배우는 자세로 임해야겠다.

잎으로의 다짐


1주차에 대한 회고가 많이 늦어지고 있다. 좀 더 나의 성장을 위해 투자해야할 때이지 않은가 싶다. 이번 년도 연말 나의 학구열을 불태워서 이번 우테코 프리코스 기간 동안 성장할 것이다. 만약 합격 된다면 좋겠지만, 되지 않더라도 이 경험들이 나의 밑거름이 되어 더 멋있는 개발자로 성장하는 내가 될 것이다.

profile
모든 것에 배움을 얻고자합니다

0개의 댓글