Skip to content

Commit 8291459

Browse files
Merge pull request #8 from codeisneverodd/codeisneverodd
[정기적 문제 풀이 추가 PR] 2022.03.30 정기적 문제 풀이 추가합니다!
2 parents ac6a0a8 + 8aca2be commit 8291459

File tree

8 files changed

+251
-5
lines changed

8 files changed

+251
-5
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
## 😁 **도움이 되셨다면** 오른쪽 상단 ↗ 의 ⭐️ **Star를 클릭**해 이 프로젝트를 응원해주세요!
99

1010
## 풀이 현황
11+
1112
풀이 완료로 표시된 Level의 폴더에 포함되지 않은 답안이 있다면
1213

1314
- [Issues](https://github.com/codeisneverodd/programmers-coding-test/issues) 에 제보해주세요. `New issue`를 누르고 제목과 내용을
@@ -25,9 +26,11 @@
2526
- 풀이 문제 수: 43문제(2022.03.28)
2627
- 풀이 완료 예상 시점: 2022년 4월 중
2728

28-
### Level 3
29+
### Level 3 👨🏻‍💻(풀이 중..)
2930

30-
풀이 완료 예상 시점: 2022년 8월 중
31+
- 전체 문제 수: 52문제
32+
- 풀이 문제 수: 5문제(2022.03.24)
33+
- 풀이 완료 예상 시점: 2022년 8월 중
3134

3235
### Level 4
3336

level-2/프린터.js

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function solution(priorities, location) {
1919
return answer;
2020
}
2121

22-
//정답 2 - codisneverodd
22+
//정답 2 - codeisneverodd
2323
function solution(priorities, location) {
2424
var answer = 0;
2525
let documents = priorities.map((priority, documentLocation) => [documentLocation, priority])
@@ -46,9 +46,9 @@ function solution(priorities, location) {
4646
//정답 3 - jaewon1676
4747
function solution(priorities, location) {
4848
var answer = 0;
49-
while(true){
49+
while (true) {
5050

51-
if (priorities[0] < Math.max(...priorities)){
51+
if (priorities[0] < Math.max(...priorities)) {
5252
if (location - 1 < 0) location = priorities.length
5353
priorities.push(priorities.shift())
5454
location--;
@@ -64,4 +64,53 @@ function solution(priorities, location) {
6464

6565
}
6666
return answer
67+
}
68+
69+
//정답 4 - codeisneverodd
70+
//shift를 사용하지 않고 queue를 구현한 풀이를 추가합니다.
71+
function solution(priorities, location) {
72+
let answer = 0;
73+
const printer = new Queue;
74+
priorities.forEach((priority, index) => {
75+
printer.enqueue([priority, index])
76+
})
77+
while (printer.size() > 0) {
78+
const check = printer.dequeue()
79+
const countHigherPriority = printer.queue.filter(x => x[0] > check[0]).length
80+
if (countHigherPriority > 0) {
81+
printer.enqueue(check)
82+
} else {
83+
answer += 1
84+
if (check[1] === location) break
85+
}
86+
87+
}
88+
return answer;
89+
}
90+
91+
class Queue {
92+
constructor() {
93+
this.queue = []
94+
this.front = 0
95+
this.rear = 0
96+
}
97+
98+
enqueue(value) {
99+
this.queue[this.rear++] = value
100+
}
101+
102+
dequeue() {
103+
const value = this.queue[this.front]
104+
delete this.queue[this.front]
105+
this.front += 1
106+
return value
107+
}
108+
109+
peek() {
110+
return this.queue(this.front)
111+
}
112+
113+
size() {
114+
return this.rear - this.front
115+
}
67116
}

level-2/후보키.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//https://github.com/codeisneverodd/programmers-coding-test
2+
//완벽한 정답이 아닙니다.
3+
//정답 1 - codeisneverodd
4+
function solution(relation) {
5+
//1. 가능한 조합을 1개~Attribute개수 만큼 찾는다.
6+
//2. 해당 개수의 조합이 키가 될 수 있는지 검사하고, 가능하면 후보키에 추가한다.
7+
//3. 단 추가하려고 할 때, 후보키에 있는 값이 자신의 부분 집합이 될 수 있으면 추가하지 않는다.
8+
const keys = []
9+
const totalAttrCount = relation[0].length
10+
const indexList = Array.from(Array(totalAttrCount), (x, index) => index) // [0,1,2,3 ... totalAttrCount-1]
11+
12+
//Fn for 2. 해당 조합으로 각 row의 attribute를 모았을 때 중복이 있는지를 반환하는 함수
13+
const isUnique = (relation, attrIndexComb) => {
14+
let result = Array.from(Array(relation.length), x => '')
15+
for (const attrIndex of attrIndexComb) {
16+
relation.forEach((row, rowIndex) => result[rowIndex] += row[attrIndex]) //Set를 이용해 중복 검사를 하기 위해 result에 string으로 넣음.
17+
}
18+
return result.length === [...new Set(result)].length
19+
}
20+
21+
//Fn for 3. keys에 현재 구한 검사할 조합의 부분집합이 존재하는지 반환, 단 keys에 들어있는 각 조합의 크기는 현재 검사할 조합의 크기보다 작다.
22+
const isMinimal = (attrComb) => {
23+
for (const key of keys) if (key.every(attr => attrComb.includes(attr))) return false
24+
return true
25+
}
26+
27+
//가능한 모든 조합을 검사
28+
for (let attrCount = 1; attrCount <= totalAttrCount; attrCount++) {
29+
const combinations = getCombinations(indexList, attrCount)
30+
for (const attrComb of combinations) {
31+
if (isMinimal(attrComb) && isUnique(relation, attrComb)) keys.push(attrComb)
32+
}
33+
}
34+
35+
return keys.length
36+
}
37+
38+
//Fn for 1. 조합을 반환하는 함수
39+
const getCombinations = (array, selectNumber) => {
40+
const result = [];
41+
if (selectNumber === 1) {
42+
return array.map((element) => [element]);
43+
}
44+
array.forEach((fixed, index, origin) => {
45+
const restCombinations = getCombinations(origin.slice(index + 1), selectNumber - 1);
46+
const attached = restCombinations.map((restCombination) => [fixed, ...restCombination]);
47+
result.push(...attached);
48+
});
49+
return result;
50+
}

level-3/가장-먼-노드.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//https://github.com/codeisneverodd/programmers-coding-test
2+
//완벽한 정답이 아닙니다.
3+
//정답 1 - codeisneverodd
4+
function solution(n, edge) {
5+
const graph = Array.from(Array(n + 1), () => [])
6+
for (const [src, dest] of edge) {
7+
graph[src].push(dest)
8+
graph[dest].push(src)
9+
}
10+
const distance = Array(n + 1).fill(0)
11+
distance[1] = 1
12+
const toBeSearched = [1]
13+
while (toBeSearched.length > 0) {
14+
const src = toBeSearched.shift()
15+
for (const dest of graph[src]) {
16+
if (distance[dest] === 0) {
17+
distance[dest] = distance[src] + 1
18+
toBeSearched.push(dest)
19+
}
20+
}
21+
}
22+
return distance.filter(x => x === Math.max(...distance))
23+
}

level-3/네트워크.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//https://github.com/codeisneverodd/programmers-coding-test
2+
//완벽한 정답이 아닙니다.
3+
//정답 1 - codeisneverodd
4+
function solution(n, computers) {
5+
let answer = 0
6+
const visited = new Array(n).fill(false)
7+
const newNetwork = (startComputer) => {
8+
//새로운 네트워크를 만들 시작 컴퓨터를 파라미터로 받는다.
9+
const toBeVisited = [startComputer]
10+
while (toBeVisited.length > 0) {
11+
//시작 컴퓨터로부터 방문 가능한 컴퓨터를 모두 방문하며 해당 컴퓨터의 visited를 true로 바꾼다
12+
const currentComputer = toBeVisited.pop()
13+
visited[currentComputer] = true
14+
for (let nextComputer = 0; nextComputer < n; nextComputer++) {
15+
if (!visited[nextComputer] && computers[currentComputer][nextComputer]) {
16+
toBeVisited.push(nextComputer)
17+
}
18+
}
19+
}
20+
}
21+
22+
for (let startComputer = 0; startComputer < n; startComputer++) {
23+
if (!visited[startComputer]) {
24+
newNetwork(startComputer)
25+
//새로운 네트워크를 생성할 때마다 정답을 1 증가시킨다.
26+
answer++
27+
}
28+
}
29+
return answer
30+
}

level-3/베스트앨범.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//https://github.com/codeisneverodd/programmers-coding-test
2+
//완벽한 정답이 아닙니다.
3+
//정답 1 - codeisneverodd
4+
function solution(genres, plays) {
5+
var answer = [];
6+
const songs = []
7+
const genreSumHash = {}
8+
const genreSumArr = []
9+
10+
//고유번호, 장르, 플레이수를 담은 songs
11+
genres.forEach((genre, id) => {
12+
songs.push({id: id, genre: genre, play: plays[id]})
13+
genreSumHash[genre] = genreSumHash[genre] === undefined ? plays[id] : genreSumHash[genre] + plays[id]
14+
})
15+
16+
//장르별 플레이수 합으로 정렬하기 위해 생성한 배열 genreSumArr
17+
for (const genre in genreSumHash) genreSumArr.push([genre, genreSumHash[genre]])
18+
genreSumArr.sort((a, b) => b[1] - a[1])
19+
20+
//각 장르안에서 각 노래의 play수가 높은 순으로 정렬하고 앞에서부터 2개까지 정답에 고유번호를 push
21+
for (const genre of genreSumArr) {
22+
const sorted = songs.filter(song => song.genre === genre[0]).sort((a, b) => b.play - a.play)
23+
for (let i = 0; i < 2 && i < sorted.length; i++) answer.push(sorted[i].id)
24+
}
25+
return answer;
26+
}
27+
28+
//정답 2 - codeisneverodd
29+
//Map과 고차함수를 적극적으로 이용한 풀이
30+
function solution(genres, plays) {
31+
const genreMap = new Map(); // {genre:{totalPlay:number, songs:[{play:number, id:number}, ...]}
32+
genres
33+
.map((genre, id) => [genre, plays[id]])
34+
.forEach(([genre, play], id) => {
35+
const data = genreMap.get(genre) || {totalPlay: 0, songs: []}
36+
genreMap.set(genre, {
37+
totalPlay: data.totalPlay + play,
38+
songs: [...data.songs, {play: play, id: id}]
39+
.sort((a, b) => b.play - a.play)
40+
.slice(0, 2)
41+
})
42+
})
43+
44+
return [...genreMap.entries()] //entries => [[genre, {totalPlay, songs}], ...]
45+
.sort((a, b) => b[1].totalPlay - a[1].totalPlay)
46+
.flatMap(item => item[1].songs) // [[songs], [songs]] => [songs, songs]
47+
.map(song => song.id)
48+
}

level-3/여행경로.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//https://github.com/codeisneverodd/programmers-coding-test
2+
//완벽한 정답이 아닙니다.
3+
//정답 1 - codeisneverodd
4+
function solution(tickets) {
5+
const routes = [] //최종 가능 루트들을 담을 배열
6+
const makeRoutes = (currentDepart, remainTickets, currentRoute) => {
7+
//현재 출발지, 남은 티켓들, 현재 까지 만든 루트를 기반으로 경로를 만들어 가는 재귀 함수
8+
if (remainTickets.length > 0) {
9+
remainTickets.forEach(([depart, nextDepart], index) => {
10+
if (depart === currentDepart)
11+
//현재 출발지와 같은 출발지를 가진 티켓이 있다면, 해당 티켓을 사용하고 해당 티켓의 도착지를 다음 출발지로 지정
12+
makeRoutes(
13+
nextDepart,
14+
[...remainTickets.slice(0, index), ...remainTickets.slice(index + 1)],
15+
[...currentRoute, currentDepart])
16+
})
17+
} else {
18+
//티켓을 모두 사용하면 최종 가능 루트에 포함
19+
routes.push([...currentRoute, currentDepart])
20+
}
21+
}
22+
makeRoutes("ICN", tickets, [])
23+
return routes.sort()[0]
24+
}

level-3/입국심사.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//https://github.com/codeisneverodd/programmers-coding-test
2+
//완벽한 정답이 아닙니다.
3+
//정답 1 - codeisneverodd
4+
function solution(n, times) {
5+
//최소로 걸릴 수 있는 시간 left, 최대로 걸릴 수 있는 시간 right
6+
let [left, right] = [1, Math.max(...times) * n]
7+
while (left <= right) {
8+
const mid = Math.floor((left + right) / 2)
9+
const sum = times.reduce((acc, time) => acc + Math.floor(mid / time), 0)
10+
//sum은 mid 시간 동안 처리 할 수 있는 사람의 수
11+
if (sum < n) {
12+
left = mid + 1
13+
} else {
14+
right = mid - 1
15+
}
16+
}
17+
// left 가 right를 넘어갔다는 것은 left가 n보다 크거나 같아져서 n명을 수용할 수 최소값이 되있다는 것이다.
18+
return left;
19+
}

0 commit comments

Comments
 (0)