Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

온보딩 미션 시험 제출 #2

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/PROBLEM1.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,20 @@
| [97, 98] | [197, 198] | 0 |
| [131, 132] | [211, 212] | 1 |
| [99, 102] | [211, 212] | -1 |

- 제시된 입력 받기
- pobi와 crong의 [왼쪽 페이지, 오른쪽 페이지]를 컴퓨터로부터 입력받기
- (예외 2) 왼쪽 페이지는 홀수, 오른쪽 페이지는 짝수여야 함
- (예외 3) 오른쪽 페이지는 왼쪽 페이지보다 한 쪽수 많아야 함
- (예외 4) 시작 면이나 마지막 면이 나오면 안 됨
- 각각의 점수 계산하기
- 왼쪽 페이지 계산 시 가장 큰 수 구하기
- 오른쪽 페이지 계산 시 가장 큰 수 구하기
- 위 둘 중 큰 수를 구하여 내 점수로 하기
- 승패 나누기
- 각각의 점수를 비교
- 높은 사람이 이김
- 결과 출력하기
- pobi가 이기면 1 출력
- crong이 이기면 2 출력
- (예외)는 -1 출력
61 changes: 59 additions & 2 deletions src/problem1.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,63 @@
function problem1(pobi, crong) {
var answer;
/**
* 페이지의 기본 조건 검사
* @param {number[]} pages 누군가 핀 책의양쪽 페이지
* @returns {boolean} 검사에 통과한 경우 true를 반환
*/
// 예외처리
function checkException(pages) {
// 예외 1
if (pages[1] !== pages[0] + 1) {
return false;
}
// 예외 2
if (pages[0] % 2 !== 1 || pages[1] % 2 !== 0) {
return false;
}
// 예외 3
if (pages[0] === 1 || pages[1] === 400) {
return false;
}
return true;
}

function findMaxOfPageGame(page) {
const pageStringList = page.toString().split(""); // ["1", "3", "2"]
const pageNumberList = pageStringList.map((str) => parseInt(str)); //[1, 3, 2]

const addList = pageNumberList.reduce((num1, num2) => num1 + num2, 0);
const mulList = pageNumberList.reduce((num1, num2) => num1 * num2, 1);

return Math.max(addList, mulList);
}

function compareScore(pobi, crong) {
const pobiScore = pobi.map((page) => findMaxOfPageGame(page));
const crongScore = crong.map((page) => findMaxOfPageGame(page));

const bestValueOfPobi = Math.max(...pobiScore);
const bestValueOfCrong = Math.max(...crongScore);

const answer =
bestValueOfPobi > bestValueOfCrong
? 1
: bestValueOfPobi < bestValueOfCrong
? 2
: 0;
return answer;
}

/**
* PROBLEM1
* @param {number[]} pobi pobi가 핀 책의 양쪽 페이지
* @param {number[]} crong crong이 핀 책의 양쪽 페이지
* @returns {0 | 1 | 2 | -1}
*/
function problem1(pobi, crong) {
if (checkException(pobi) && checkException(crong)) {
return compareScore(pobi, crong);
} else {
return -1;
}
}

module.exports = problem1;
11 changes: 10 additions & 1 deletion src/problem2.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
function problem2(cryptogram) {
var answer;
const answer = reduceWord(cryptogram);
return answer;
}

function reduceWord(word) {
let new_word = word;
for (let i = 0; i < word.length; i++) {
//글자 수 만큼
new_word = new_word.replace(/([a-z])\1{1,}/g, "");
}
return new_word;
}

module.exports = problem2;
18 changes: 16 additions & 2 deletions src/problem3.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
function problem3(number) {
var answer;
return answer;
let counter = 0;
for (i = 1; i <= number; i++) {
counter += doClap(i);
}
return counter;
}

function doClap(number) {
const strNumList = number.toString().split("");
let claps = 0;
strNumList.forEach((num) => {
if (num === "3" || num === "6" || num === "9") {
claps++;
}
});
return claps;
}

module.exports = problem3;
21 changes: 19 additions & 2 deletions src/problem4.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
function problem4(word) {
var answer;
return answer;
let answer = [];
// 모든 글자에 대해
for (let i = 0; i < word.length; i++) {
const ascii = word.charCodeAt(i); // 아스키 코드로 변환 후
// 소문자는 대문자로
if (ascii >= 65 && ascii <= 90) {
answer.push(90 - ascii + 65);
}
// 대문자는 소문자로
if (ascii >= 97 && ascii <= 122) {
answer.push(122 - ascii + 97);
}
// 띄어쓰기는 그대로
if (ascii === 32) {
answer.push(32);
}
}
// 모든 아스키 코드를 문자로 변환 후 합치기
return answer.map((num) => String.fromCharCode(num)).join("");
}

module.exports = problem4;
24 changes: 22 additions & 2 deletions src/problem5.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
const MONEY_UNIT = [50000, 10000, 5000, 1000, 500, 100, 50, 10, 1];

function checkException(money) {
if (money < 1 || money > 1000000) {
return false;
}
return true;
}

function calculateMoney(money) {
const wallet = [];
MONEY_UNIT.forEach((unit) => {
wallet.push(parseInt(money / unit));
money = money % unit;
});
return wallet;
}

function problem5(money) {
var answer;
return answer;
if (!checkException) {
return -1;
}
return calculateMoney(money);
}

module.exports = problem5;
55 changes: 53 additions & 2 deletions src/problem6.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,57 @@
function problem6(forms) {
var answer;
return answer;
const formsObjectArray = convertToObjectArray(forms);
const uniqueWords = findUniqueWordsOfNickname(formsObjectArray);
return findEmailByDuplicatedName(formsObjectArray, uniqueWords).sort();
}

//들어온 리스트를 JS 오브젝트로 변환해주는 함수
function convertToObjectArray(forms) {
const array = [];
forms.map((element) => {
array.push({
email: element[0],
name: element[1],
});
});
return array;
}

//사용자들의 이름을 2글자 이상으로 잘개 쪼개어 중복이 없는 리스트로 반환해주는 함수
function findUniqueWordsOfNickname(formsObjectArray) {
let uniqueWords = new Set();
formsObjectArray.forEach((element) => {
const nickname = element.name;
//검사할 글자 갯수 제어
for (let i = 0; i < nickname.length; i++) {
//글자를 처음부터 끝까지 검사
for (let j = 0; j < nickname.length - i; j++) {
//글자를 잘라보기(for문 돌면서 1글자, 2글자, 3글자 ...)
const word = nickname.slice(j, j + i + 1);
//자른 글자의 갯수가 1 초과인 경우에만 Set함수에 추가를 시도함
if (word.length > 1) {
uniqueWords.add(word);
}
}
}
});
return Array.from(uniqueWords);
}

//단어 리스트를 중복 사용 하고 있는 사람을 찾아 이메일을 반환하는 함수
function findEmailByDuplicatedName(formsObjectArray, uniqueWords) {
let emails = new Set();
uniqueWords.forEach((word) => {
// 특정 단어가 포함된 이름을 찾아 객체를 배열로 만들기
const list = formsObjectArray.filter((form) => form.name.includes(word));
//찾은 결과가 1보다 크다면 중복 사용 중인 사람들로 간주하고
//emails 집합에 그 사람들의 email을 추가해줌
if (list.length > 1) {
list.map((element) => {
emails.add(element.email);
});
}
});
return Array.from(emails);
}

module.exports = problem6;
91 changes: 90 additions & 1 deletion src/problem7.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,95 @@
function problem7(user, friends, visitors) {
var answer;
let suggestedFriends = [];

// 주변인들의 친구 관계를 인간 중심으로 관계
const friendsObjectArray = []; // [{id: "donut", friends:{"...","...","..."}}, {}~]
friends.forEach((element) => {
// 양방향으로 추가해줘서 모든 id들이 빠짐 없이 객체의 중심이 될 수 있도록 함
handleFriend(friendsObjectArray, element[0], element[1]);
handleFriend(friendsObjectArray, element[1], element[0]);
});

// 친구들의 친구 목록 (점수 계산용이므로 중복 허용)
const relatedFriendsArray = checkFriendOfFriends(friendsObjectArray, user); //['andole', 'jun', 'andole', 'jun']
//추천 친구 포인트 계산
figurePoints(suggestedFriends, 10, relatedFriendsArray);

// 방문한 사람들의 친구 목록 (본인, 친구 제외된 목록)
const relatedVisitorsArray = checkVisitors( // ['bedi', 'bedi', 'bedi']
friendsObjectArray,
user,
visitors
);
//추천 친구 포인트 계산
figurePoints(suggestedFriends, 1, relatedVisitorsArray);

// 이 시점에서의 suggested friends
// 0 : {id: 'andole', points: 20}
// 1 : {id: 'jun', points: 20}
// 2 : {id: 'bedi', points: 3}

//포인트 순으로 정렬 한 다음, 아이디 순으로 정렬
suggestedFriends.sort(
(a, b) => b.points - a.points || a.id.localeCompare(b.id)
);

//최대 5명만 리턴
const answer = suggestedFriends.slice(0, 5).map((el) => el.id); //['andole', 'jun', 'bedi']
return answer;
}

function handleFriend(friendsObjectArray, from, to) {
const index = friendsObjectArray.findIndex((friend) => friend.id === from);
//검색 결과가 없다면 새 데이터 추가
if (index === -1) {
friendsObjectArray.push({
id: from,
friends: new Set().add(to),
});
} else {
friendsObjectArray[index].friends.add(to);
}
}

function checkFriendOfFriends(friendsObjectArray, user) {
const index = friendsObjectArray.findIndex((friend) => friend.id === user);
//사용자의 친구 목록을 찾아냄
const userFriends = Array.from(friendsObjectArray[index].friends);

//사용자의 친구들이 어떤 친구들을 가지고 있는지 찾아서 array에 추가해줌
let array = [];
userFriends.map((id) => {
const idx = friendsObjectArray.findIndex((friend) => friend.id === id);
return Array.from(friendsObjectArray[idx].friends).map((el) => {
array.push(el);
});
});
//추천 금지 명단에 추가해줄 목적으로 본인 사용자도 친구처럼 취급
userFriends.push(user);
//혹시 명단에 이미 친구인 사람이 있다면 제거해줌
return array.filter((id) => !userFriends.includes(id));
}

function checkVisitors(friendsObjectArray, user, visitors) {
const index = friendsObjectArray.findIndex((friend) => friend.id === user);
// 사용자의 친구 목록을 찾아냄
const userFriends = Array.from(friendsObjectArray[index].friends);
userFriends.push(user);
return visitors.filter((id) => !userFriends.includes(id));
}

function figurePoints(suggestedFriends, point, arr) {
arr.map((id) => {
const idx = suggestedFriends.findIndex((friend) => friend.id === id);
if (idx === -1) {
suggestedFriends.push({
id: id,
points: point,
});
} else {
suggestedFriends[idx].points += point;
}
});
}

module.exports = problem7;