diff --git "a/solutions/nayoung/0129/[\353\254\270\354\240\23424]\354\230\244\355\224\210\354\261\204\355\214\205\353\260\251.js" "b/solutions/nayoung/0129/[\353\254\270\354\240\23424]\354\230\244\355\224\210\354\261\204\355\214\205\353\260\251.js" new file mode 100644 index 0000000..f3f2c8e --- /dev/null +++ "b/solutions/nayoung/0129/[\353\254\270\354\240\23424]\354\230\244\355\224\210\354\261\204\355\214\205\353\260\251.js" @@ -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 → 최종 닉네임 저장 diff --git "a/solutions/nayoung/0129/[\353\254\270\354\240\23425]\353\262\240\354\212\244\355\212\270\354\225\250\353\262\224.js" "b/solutions/nayoung/0129/[\353\254\270\354\240\23425]\353\262\240\354\212\244\355\212\270\354\225\250\353\262\224.js" new file mode 100644 index 0000000..033a747 --- /dev/null +++ "b/solutions/nayoung/0129/[\353\254\270\354\240\23425]\353\262\240\354\212\244\355\212\270\354\225\250\353\262\224.js" @@ -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 : 키(인덱스, 프로퍼티명)을 꺼낼 때 diff --git "a/solutions/nayoung/0129/[\353\254\270\354\240\23426]\354\213\240\352\263\240\352\262\260\352\263\274\353\260\233\352\270\260.js" "b/solutions/nayoung/0129/[\353\254\270\354\240\23426]\354\213\240\352\263\240\352\262\260\352\263\274\353\260\233\352\270\260.js" new file mode 100644 index 0000000..474d93e --- /dev/null +++ "b/solutions/nayoung/0129/[\353\254\270\354\240\23426]\354\213\240\352\263\240\352\262\260\352\263\274\353\260\233\352\270\260.js" @@ -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; // 최종 결과 반환 +} diff --git "a/solutions/nayoung/0129/[\353\254\270\354\240\23427]\353\251\224\353\211\264\353\246\254\353\211\264\354\226\274.js" "b/solutions/nayoung/0129/[\353\254\270\354\240\23427]\353\251\224\353\211\264\353\246\254\353\211\264\354\226\274.js" new file mode 100644 index 0000000..c691457 --- /dev/null +++ "b/solutions/nayoung/0129/[\353\254\270\354\240\23427]\353\251\224\353\211\264\353\246\254\353\211\264\354\226\274.js" @@ -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; // 완성된 조합 배열 반환 +}