1. 간단한 논리 연산
[문제 설명]
boolean 변수 x1, x2, x3, x4가 매개변수로 주어질 때, 다음의 식의 true/false를 return 하는 solution 함수를 작성해 주세요.
(x1 ∨ x2) ∧ (x3 ∨ x4)
[입출력 예]
| x1 | x2 | x3 | x4 | x5 |
| false | true | true | true | true |
| true | false | false | false | false |
[입출력 예 설명]
입출력 예 #1
- 예제 1번의 x1, x2, x3, x4로 식을 계산하면 다음과 같습니다.
(x1 ∨ x2) ∧ (x3 ∨ x4) ≡ (F ∨ T) ∧ (T ∨ T) ≡ T ∧ T ≡ T
따라서 true를 return 합니다.
입출력 예 #2
- 예제 2번의 x1, x2, x3, x4로 식을 계산하면 다음과 같습니다.
(x1 ∨ x2) ∧ (x3 ∨ x4) ≡ (T ∨ F) ∧ (F ∨ F) ≡ T ∧ F ≡ F
따라서 false를 return 합니다.
[∨과 ∧의 진리표]
| x | y | x ∨ y | x ∧ y |
| T | T | T | T |
| T | F | T | F |
| F | T | T | F |
| F | F | F | F |
[답변]
function solution(x1, x2, x3, x4) {
return (x1 || x2) && (x3 || x4);
}
💡 진리표를 보니 ∨는 or, ∧는 and 연산자길래 요렇게 풀어보았다.
2. 주사위 게임 3 ⭐⭐⭐⭐⭐
[문제 설명]
1부터 6까지 숫자가 적힌 주사위가 네 개 있습니다. 네 주사위를 굴렸을 때 나온 숫자에 따라 다음과 같은 점수를 얻습니다.
- 네 주사위에서 나온 숫자가 모두 p로 같다면 1111 × p점을 얻습니다.
- 세 주사위에서 나온 숫자가 p로 같고 나머지 다른 주사위에서 나온 숫자가 q(p ≠ q)라면 (10 × p + q)2 점을 얻습니다.
- 주사위가 두 개씩 같은 값이 나오고, 나온 숫자를 각각 p, q(p ≠ q)라고 한다면 (p + q) × |p - q|점을 얻습니다.
- 어느 두 주사위에서 나온 숫자가 p로 같고 나머지 두 주사위에서 나온 숫자가 각각 p와 다른 q, r(q ≠ r)이라면 q × r점을 얻습니다.
- 네 주사위에 적힌 숫자가 모두 다르다면 나온 숫자 중 가장 작은 숫자 만큼의 점수를 얻습니다.
네 주사위를 굴렸을 때 나온 숫자가 정수 매개변수 a, b, c, d로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.
[제한사항]
a, b, c, d는 1 이상 6 이하의 정수입니다.
[입출력 예]
| a | b | c | d | result |
| 2 | 2 | 2 | 2 | 2222 |
| 4 | 1 | 4 | 4 | 1681 |
| 6 | 3 | 3 | 6 | 27 |
| 2 | 5 | 2 | 6 | 30 |
| 6 | 4 | 2 | 5 | 2 |
[입출력 예 설명]
입출력 예 #1
- 예제 1번에서 네 주사위 숫자가 모두 2로 같으므로 1111 × 2 = 2222점을 얻습니다. 따라서 2222를 return 합니다.
입출력 예 #2
- 예제 2번에서 세 주사위에서 나온 숫자가 4로 같고 나머지 다른 주사위에서 나온 숫자가 1이므로 (10 × 4 + 1)2 = 412 = 1681점을 얻습니다. 따라서 1681을 return 합니다.
입출력 예 #3
- 예제 3번에서 a, d는 6으로, b, c는 3으로 각각 같으므로 (6 + 3) × |6 - 3| = 9 × 3 = 27점을 얻습니다. 따라서 27을 return 합니다.
입출력 예 #4
- 예제 4번에서 두 주사위에서 2가 나오고 나머지 다른 두 주사위에서 각각 5, 6이 나왔으므로 5 × 6 = 30점을 얻습니다. 따라서 30을 return 합니다.
입출력 예 #5
- 예제 5번에서 네 주사위 숫자가 모두 다르고 나온 숫자 중 가장 작은 숫자가 2이므로 2점을 얻습니다. 따라서 2를 return 합니다.
[답변]
function solution(a, b, c, d) {
const diceNumbers = [a, b, c, d];
if (new Set(diceNumbers).size === 1) {
return 1111 * a;
}
if (new Set(diceNumbers).size === 2) {
const [p, q] = [...new Set(diceNumbers)];
let count = 0;
for (let i = 0; i < diceNumbers.length; i++) {
for (let j = i + 1; j < diceNumbers.length; j++) {
if (diceNumbers[i] === diceNumbers[j]) {
count++;
}
}
}
if (count === 3) {
let pCount = 0, qCount = 0;
diceNumbers.forEach((n) => {
n === p ? pCount++ : qCount++;
});
return pCount > qCount ? Math.pow(10 * p + q, 2) : Math.pow(10 * q + p, 2);
} else if (count === 2) {
return (p + q) * Math.abs(p - q);
}
}
if (new Set(diceNumbers).size === 3) {
const [p, q, r] = [...new Set(diceNumbers)];
let pCount = 0, qCount = 0;
diceNumbers.forEach((n) => {
n === p && pCount++;
n === q && qCount++;
});
if (pCount === 2) {
return q * r;
} else if (qCount === 2) {
return p * r;
} else {
return p * q;
}
}
return Math.min(...diceNumbers);
}
💡 코딩 기초트레이닝 124문제 중 정답률이 두번째로 낮은 문제였다....... 처음에 술술 풀려서 오? 좀 잘하는 듯 했는데, 정답 제출하니 20%의 테스트케이스가 틀렸다...🤦♀️ 눈물 좔좔... 눈에 불을 켜고 오류를 찾아서 겨우 풀었다! 새로운 걸 많이 사용해봤음.
[풀이 과정]
1️⃣ 네 주사위에서 나온 숫자가 모두 p로 같다면 1111 × p점을 얻습니다.
if (new Set(diceNumbers).size === 1) {
return 1111 * a;
}
new Set()에 주사위 값을 담은 배열을 전달하여 Set을 생성하고 size가 1인지 확인한다.
Set은 중복된 값을 허용하지 않으므로 숫자 네개가 모두 같으면 1을 반환하기 때문!
size가 1이면 모든 숫자가 p로 같기 때문에 1111 * a를 return 해준다.
2️⃣ 세 주사위에서 나온 숫자가 p로 같고 나머지 다른 주사위에서 나온 숫자가 q(p ≠ q)라면 (10 × p + q)2 점을 얻습니다.
3️⃣ 주사위가 두 개씩 같은 값이 나오고, 나온 숫자를 각각 p, q(p ≠ q)라고 한다면 (p + q) × |p - q|점을 얻습니다.
if (new Set(diceNumbers).size === 2) {
const [p, q] = [...new Set(diceNumbers)];
let count = 0;
for (let i = 0; i < diceNumbers.length; i++) {
for (let j = i + 1; j < diceNumbers.length; j++) {
if (diceNumbers[i] === diceNumbers[j]) {
count++;
}
}
}
if (count === 3) {
let pCount = 0, qCount = 0;
diceNumbers.forEach((n) => {
n === p ? pCount++ : qCount++;
});
return pCount > qCount ? Math.pow(10 * p + q, 2) : Math.pow(10 * q + p, 2);
} else if (count === 2) {
return (p + q) * Math.abs(p - q);
}
}
이부분에서 약간 애를 먹었다. 2, 3번 보기 모두 size가 2로 출력되기 때문에 안에 조건문을 하나 더 추가해야 했다.
count 변수를 생성하고, for문을 돌려 중복값을 count해 3개의 주사위가 같은 지 / 2개의 주사위가 같은 지 구분했다.
3개의 주사위가 같으면 (10 * p + q)²를 return 해줘야 하는데, 구조분해할당을 하며 p와 q의 값이 순서대로 들어가 있기 때문에 3개의 같은 주사위와 나머지 하나의 주사위를 구분해줘야 했다. 역시 여기서도 엄청난 실패를 경험...
forEach문을 돌려 배열의 값 n이 p와 같으면 pCount를, q와 같으면 qCount를 +1 하고, 두 값을 비교해서 더 큰 값에 10을 곱해주도록... 했다... 그리고 Math.pow() 함수를 사용해 제곱한 값을 return 해주었다.
2개의 주사위가 같으면 (p + q) * |p - q|를 return 해줘야 하는데, 반례로 음수값이 나와 테스트에 실패했었다!
JavaScript에서 절대값을 반환하는 Math.abs()함수를 사용하여 절대값으로 출력해주면 3번 완료.
4️⃣ 어느 두 주사위에서 나온 숫자가 p로 같고 나머지 두 주사위에서 나온 숫자가 각각 p와 다른 q, r(q ≠ r)이라면 q × r점을 얻습니다.
if (new Set(diceNumbers).size === 3) {
const [p, q, r] = [...new Set(diceNumbers)];
let pCount = 0, qCount = 0;
diceNumbers.forEach((n) => {
n === p && pCount++;
n === q && qCount++;
});
if (pCount === 2) {
return q * r;
} else if (qCount === 2) {
return p * r;
} else {
return p * q;
}
}
2번과 같이 같은 주사위가 p가 되어야 하는데, 입력된 순서대로 들어가있기 때문에 반례의 경우 테스트 실패한다.
그래서 얘도 pCount와 qCount를 이용하여 개수를 세어 비교하여 풀었다.
5️⃣ 네 주사위에 적힌 숫자가 모두 다르다면 나온 숫자 중 가장 작은 숫자 만큼의 점수를 얻습니다.
return Math.min(...diceNumbers);
전개연산자(...)와 Math.min()함수를 사용해 가장 작은 값을 출력해줬다.
📌 new Set() : 고유한 값들의 집합을 나타내는 내장 객체. 중복된 값을 허용하지 않으며, 값들의 순서는 유지되지 않는다.
배열과 같은 이터러블 객체를 전달할 수 있음.
- add() : 값 추가
- has() : Set에 특정 값이 있는 지 확인
- delete() : 값 삭제
- clear() : 초기화
- size 속성 : Set의 크기 반환
[다른 답변]
function solution(a, b, c, d) {
if (a === b && a === c && a === d) return 1111 * a
if (a === b && a === c) return (10 * a + d) ** 2
if (a === b && a === d) return (10 * a + c) ** 2
if (a === c && a === d) return (10 * a + b) ** 2
if (b === c && b === d) return (10 * b + a) ** 2
if (a === b && c === d) return (a + c) * Math.abs(a - c)
if (a === c && b === d) return (a + b) * Math.abs(a - b)
if (a === d && b === c) return (a + b) * Math.abs(a - b)
if (a === b) return c * d
if (a === c) return b * d
if (a === d) return b * c
if (b === c) return a * d
if (b === d) return a * c
if (c === d) return a * b
return Math.min(a, b, c, d)
}
💡 노가다긴 하지만 보기는 훨씬 좋은 것 같다. 어려웠지만 재밌었던 문제!
3. 글자 이어 붙여 문자열 만들기
[문제 설명]
문자열 my_string과 정수 배열 index_list가 매개변수로 주어집니다. my_string의 index_list의 원소들에 해당하는 인덱스의 글자들을 순서대로 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.
[답변]
function solution(my_string, index_list) {
var answer = '';
index_list.forEach(n => answer += my_string[n]);
return answer;
}
💡 forEach 활용
[답변 2]
function solution(my_string, index_list) {
return index_list.map(i => my_string[i]).join('')
}
💡 map() 활용
4. 9로 나눈 나머지
[문제 설명]
음이 아닌 정수를 9로 나눈 나머지는 그 정수의 각 자리 숫자의 합을 9로 나눈 나머지와 같은 것이 알려져 있습니다.
이 사실을 이용하여 음이 아닌 정수가 문자열 number로 주어질 때, 이 정수를 9로 나눈 나머지를 return 하는 solution 함수를 작성해주세요.
[답변]
function solution(number) {
let arr = String(number).split('');
let sum = arr.reduce((acc, curr)=> Number(acc) + Number(curr));
return sum % 9;
}
💡 number를 배열로 만들어주고, reduce를 활용해 각 자리의 값을 더해주었다. Number로 형변환 해주고 return
[답변2]
function solution(number) {
return [...number].reduce((acc, curr)=> Number(acc) + Number(curr)) % 9;
}
💡 생각해보니 전개연산자로 하면 되지 않나...? 라는 생각이 들어 다시 풀어봤다. 훨씬 깔끔하고 좋은 듯. 뿌듯해
5. 문자열 여러 번 뒤집기
[문제 설명]
문자열 my_string과 이차원 정수 배열 queries가 매개변수로 주어집니다. queries의 원소는 [s, e] 형태로, my_string의 인덱스 s부터 인덱스 e까지를 뒤집으라는 의미입니다. my_string에 queries의 명령을 순서대로 처리한 후의 문자열을 return 하는 solution 함수를 작성해 주세요.
[답변]
function solution(my_string, queries) {
let arr = my_string.split('');
queries.forEach((query) => {
let [s, e] = query;
let reverse = arr.slice(s, e + 1).reverse();
arr.splice(s, reverse.length, ...reverse);
});
return arr.join('');
}
💡 헷갈렸다. 근데 어찌저찌 머리 굴려서 해결함
1. 일단 my_string을 .split()을 사용해 배열로 변경해준다.
2. 그리고 문자열을 뒤집을 부분을 .slice() 로 잘라서 새로운 배열을 만들고 .reverse() 를 사용해 뒤집어 변수에 담는다.
3. .splice 시작위치(s), 변경할 요소의 개수(reverse.length), 추가할 요소(...reverse) 로 arr 배열 내에 문자열을 완성시킨다.
4. arr.join('') 으로 배열을 문자열로 변경하여 return 해주면 끝
'프로그래머스 > Lv. 0 코딩 기초 트레이닝' 카테고리의 다른 글
| [프로그래머스] 코딩 기초 트레이닝 Day 10 / JS (0) | 2023.07.29 |
|---|---|
| [프로그래머스] 코딩 기초 트레이닝 Day 9 / JS (0) | 2023.07.28 |
| [프로그래머스] 코딩 기초 트레이닝 Day 7 / JS (0) | 2023.07.26 |
| [프로그래머스] 코딩 기초 트레이닝 Day 6 / JS (0) | 2023.07.25 |
| [프로그래머스] 코딩 기초 트레이닝 Day 5 / JS (0) | 2023.07.24 |