Skip to content
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
45 changes: 45 additions & 0 deletions solutions/nayoung/0129/[문제24]오픈채팅방.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
function solution(record) {
const answer = [];
// uid별 최종 닉네임을 저장할 객체
const nickByUid = {};

// record배열을 길이만큼 돌면서 uid와 닉네임 정보만 먼저 수집
for (let i = 0; i < record.length; i++) {
const line = record[i];
// 공백 기준으로 잘라서 첫 단어가 명령, 그 다음이 uid, 닉네임
const parts = line.split(" ");
const cmd = parts[0];
const uid = parts[1];

// Enter나 Change일 때만 닉네임이 있으니까 그때 nickByUid 갱신
if (cmd === "Enter" || cmd === "Change") {
const nick = parts[2];
nickByUid[uid] = nick;
}
}

// 다시 record를 돌면서 Enter/Leave인 경우만 메시지를 만든다
// 이때 nickByUid에 저장된 최종 닉네임을 씀
for (let j = 0; j < record.length; j++) {
const line2 = record[j];

const parts2 = line2.split(" ");
const cmd2 = parts2[0];
const uid2 = parts2[1];


if (cmd2 === "Enter") {
answer.push(nickByUid[uid2] + "님이 들어왔습니다.");
} else if (cmd2 === "Leave") {
answer.push(nickByUid[uid2] + "님이 나갔습니다.");
}
// "Change"는 메시지를 남기지 않으므로 아무것도 안 함
}

return answer;
}

// ========== 사용한 메서드 정리 ==========
// - String.prototype.split(" ") : 문자열을 공백 기준으로 나눠 배열로 만듦
// - Array.prototype.push(...) : 배열 맨 뒤에 값 추가
//- 객체 nickByUid[키] = 값 : 해시로 uid → 최종 닉네임 저장
88 changes: 88 additions & 0 deletions solutions/nayoung/0129/[문제25]베스트앨범.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// 주석 없는 버전
function solution(genres, plays) {
const answer = [];

const music = genres.reduce((arr, cur, index) => {
if (!arr[cur]) {
arr[cur] = { total: 0, song: [] };
}
arr[cur].song.push([index, plays[index]]);
arr[cur].total += plays[index];
return arr;
}, {});

const genreList = Object.keys(music).sort((a, b) => {
return music[b].total - music[a].total;
});

for (const genre of genreList) {
music[genre].song.sort((a, b) => {
if (b[1] !== a[1]) return b[1] - a[1];
return a[0] - b[0];
});

answer.push(music[genre].song[0][0]);
if (music[genre].song.length > 1) {
answer.push(music[genre].song[1][0]);
}
}

return answer;
}

//----------------------------------------------
// 주석 있는 버전

function solution(genres, plays) {
const answer = [];

// 1. reduce로 객체 생성 후 장르별 구조 정의
// reduce 사용
const music = genres.reduce((arr, cur, index) => {
// 해당 장르가 없으면 객체 생성
if(!arr[cur]){
arr[cur] = {
total : 0,
song : []
}
}
// song 안에 고유번호, 재생수 넣기
arr[cur].song.push([index, plays[index]])
// 장르별 총 재생 수 누적
arr[cur].total += plays[index];
return arr;
}, {}); // 의존성 까먹지 말기

// 2. 총 재생 수 많은 장르부터 정렬
// Object.keys(music)을 해주면 객체에서 배열로 바꿀 수 있음!
// a, b는 장르이름 => music[b].total = 해당 장르의 총 재생수
const genreList = Object.keys(music).sort((a, b) => {
return music[b].total - music[a].total
})

// 3. music객체 안에 있는 모든 장르를 하나씩 꺼내서 반복한다
for(const genre of genreList){
// 재생수 내림차순, 같으면 고유번호 오름차순
music[genre].song.sort((a, b) => {
// 이해하기 힘들었던 부분
// 재생수 제일 큰걸 맨 앞으로 정렬
if (b[1] !== a[1]) return b[1] - a[1];
// 재생수가 같을 경우 인댁스 작은게 앞으로
return a[0] - b[0];
});

// 장르별 제일 인기 있는 곡 고유번호 넣기
answer.push(music[genre].song[0][0]);

// 근데 노래의 갯수가 1개 이상이면 두번째 곡도 넣기
if(music[genre].song.length > 1){
answer.push(music[genre].song[1][0])
}
}

return answer; // 최종 결과 반환
}


// const in : 값을 꺼낼 때 사용
// for of : 키(인덱스, 프로퍼티명)을 꺼낼 때
57 changes: 57 additions & 0 deletions solutions/nayoung/0129/[문제26]신고결과받기.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 해당 문제는 못풀겠어서 gpt에게 강습?받은 코드입니다



function solution(id_list, report, k) {
const answer = []; // 최종 결과를 담을 배열

// 1. report 배열에서 중복 신고 제거 (Set 사용)
const reportSet = new Set(report); // 같은 "신고자 신고당한자"는 자동으로 한 번만 남음

// 2. 신고당한 사람별로 신고 횟수 세기 (Map 사용)
const reportedCount = new Map(); // key: 신고당한id, value: 신고당한 횟수

for (const entry of reportSet) { // 중복 제거된 신고 목록을 하나씩 돌면서
const parts = entry.split(" "); // ["신고자", "신고당한자"]
const reportedId = parts[1]; // 신고당한 사람

if (!reportedCount.has(reportedId)) { // 아직 카운트가 없으면
reportedCount.set(reportedId, 0); // 0으로 초기화
}
reportedCount.set(reportedId, reportedCount.get(reportedId) + 1); // 신고 횟수 증가
}

// 3. k번 이상 신고당한 사람을 정지 대상 Set으로 만들기
const suspended = new Set(); // 정지된 유저 id들을 저장하는 Set

for (const [id, count] of reportedCount) { // Map을 돌면서
if (count >= k) { // 신고 횟수가 k 이상이면
suspended.add(id); // 정지 대상에 추가
}
}

// 4. 각 유저가 받은 메일 수를 Map으로 관리
const mailCount = new Map(); // key: 유저id, value: 받은 메일 수

for (let i = 0; i < id_list.length; i++) {
mailCount.set(id_list[i], 0); // 모든 유저의 메일 수를 0으로 초기화
}

// 5. 신고 기록을 다시 돌면서, 정지된 사람을 신고한 유저에게 메일 +1
for (const entry of reportSet) {
const parts = entry.split(" "); // ["신고자", "신고당한자"]
const reporter = parts[0]; // 신고한 사람
const reported = parts[1]; // 신고당한 사람

if (suspended.has(reported)) { // 신고당한 사람이 정지 대상이면
mailCount.set(reporter, mailCount.get(reporter) + 1); // 신고자 메일 수 +1
}
}

// 6. id_list 순서대로 메일 받은 횟수를 answer에 넣기
for (let i = 0; i < id_list.length; i++) {
answer.push(mailCount.get(id_list[i])); // Map에서 값 꺼내서 결과 배열에 추가
}

return answer; // 최종 결과 반환
}
68 changes: 68 additions & 0 deletions solutions/nayoung/0129/[문제27]메뉴리뉴얼.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// 해당 문제는 못풀겠어서 gpt에게 강습?받은 코드입니다



function solution(orders, course) {
const answer = []; // 최종 결과를 담을 배열
const comboMap = new Map(); // 조합별 주문 횟수를 저장할 Map

// 모든 주문을 하나씩 돌면서
for (const order of orders) {
const sorted = order.split("").sort().join(""); // 주문을 사전순으로 정렬해서 통일

// 각 코스 길이에 대해 처리
for (const len of course) {
if (sorted.length < len) continue; // 주문 길이가 짧으면 이 코스는 건너뜀

const combos = getCombos(sorted, len); // 해당 길이의 조합들을 모두 구함

// 구한 조합들을 하나씩 카운트
for (const c of combos) {
comboMap.set(c, (comboMap.get(c) || 0) + 1); // 기존 값이 있으면 +1, 없으면 1로 시작
}
}
}

// 각 코스 길이별로 가장 많이 주문된 조합만 골라냄
for (const len of course) {
let max = 0; // 해당 코스 길이에서 최대 주문 횟수
const selected = []; // 최대 횟수를 가진 조합들을 담을 배열

// Map에 저장된 모든 조합을 돌면서
for (const [combo, count] of comboMap) {
if (combo.length === len && count >= 2) { // 길이가 맞고, 2번 이상 주문된 조합만 대상
if (count > max) { // 더 많이 주문된 조합을 찾으면
max = count; // 최대값 갱신
selected.length = 0; // 기존 결과 비우고
selected.push(combo); // 현재 조합 추가
} else if (count === max) { // 최대값과 같으면
selected.push(combo); // 같이 추가
}
}
}

answer.push(...selected); // 이 코스 길이에서 고른 조합들을 결과에 추가
}

return answer.sort(); // 최종 결과를 사전순으로 정렬해서 반환
}

// 문자열 str에서 len개를 뽑는 모든 조합을 만들어 배열로 반환하는 함수
function getCombos(str, len) {
const result = []; // 조합들을 담을 배열

// 재귀 함수: start는 시작 인덱스, path는 현재까지 만든 문자열
function dfs(start, path) {
if (path.length === len) { // 원하는 길이에 도달하면
result.push(path); // 결과 배열에 추가하고
return; // 더 이상 진행하지 않음
}

for (let i = start; i < str.length; i++) { // 시작 위치부터 끝까지 돌면서
dfs(i + 1, path + str[i]); // 다음 문자로 재귀 호출
}
}

dfs(0, ""); // 처음에는 인덱스 0, 빈 문자열부터 시작
return result; // 완성된 조합 배열 반환
}