왕비를 피해 일곱 난쟁이들과 함께 평화롭게 생활하고 있던 백설공주에게 위기가 찾아왔다.
일과를 마치고 돌아온 난쟁이가 일곱 명이 아닌 아홉 명이었던 것이다.
아홉명의 난쟁이는 모두 자신이 "백설 공주와 일곱 난쟁이"의 주인공이라고 주장했다.
뛰어난 수학적 직관력을 가지고 있던 백설공주는, 다행스럽게도 일곱 난쟁이의 키의 합이 100이 됨을 기억해냈다.
아홉난쟁이의 키가 주어졌을 때, 백설공주를 도와 일곱 난쟁이를 찾는 프로그램을 작성하시오.
문제를 딱 보자마자 의식의 흐름대로 과정을 먼저 쓰고, 그 과정을 토대로 코드를 짜보기로 했다.
<script>
function solution(arr) {
let answer = [];
// 우선 9개의 배열 중에 인덱스 값으로 랜덤하게 7개를 뽑고
// 7개를 새로운 배열에 담는다. (거기다 중복 검사까지)
// 마지막에 모든 인덱스의 값을 더해서 100이 나오는지 까지 확인
// 7명을 뽑을 배열
let newArr = [];
// 7번만 반복해서 push하는 함수
const searchThere = function () {
for (let i = 0; i < 7; i++) {
let randomIndexValue = arr[Math.floor(Math.random() * 9)]; // 총 배열의 인덱스가 8이므로 0 ~ 8 사이를 랜덤으로 뽑는다. 그런데 겹치는 숫자가 있다?
// 랜덤으로 뽑은 값음 checkSameValue라는 함수로 검사해서...
if (checkSameValue(randomIndexValue)) {
// 같은 값이 있다면 i를 -1하여, 다시 랜덤값을 뽑음
i--;
} else {
// 없다면 배열에 넣음
newArr.push(randomIndexValue);
}
}
};
// 배열에 같은 인덱스가 존재하는지 확인하는 함수
const checkSameValue = function (randomIndexValue) {
return newArr.find((e) => {
if (e === randomIndexValue) {
return true;
} else {
return false;
}
});
};
// 최종적으로 나온 배열을 더하여 100이 나오는지 확인하는 함수 <= 뭔가 이상해서 일단 폐기
// const check100 = function () {
// newArr.reduce((prev, current) => {
// console.log("합계", prev);
// if (prev + current == 100) {
// answer = "200";
// } else {
// answer = "400";
// }
// });
// };
const check100 = function () {
let result = 0;
for (let i = 0; i < newArr.length; i++) {
result = result + newArr[i];
}
console.log("뽑은 배열의 합계", result);
if (result == 100) {
answer = newArr;
} else {
console.log("100이 아님! 배열 재생성 시작");
}
};
// 테스트 시작~
searchThere();
console.log("뽑은 배열", newArr);
check100();
if (answer.length !== 0) {
return answer;
} else {
return searchThere();
}
}
let arr = [20, 7, 23, 19, 10, 15, 25, 8, 13];
console.log(solution(arr));
</script>
코드량이 이게 맞나 싶다. 근데 가장 큰 문제는 따로 있다.
방금 확인하려다가 컴이 멈춰서 다시켰다...
return searchThere()
를 주석처리하고 해보면, 찾기는 찾아진다.
합계가 100이 아닐 시, 처음부터 돌아가기위해서 searchThere()
함수를 호출해서 무한루프가 걸린 것 같다.
저렇게 쓰는게 아닌건가?
searchThere()
을 리턴하면 soultution()
에 인자로 받은 arr
값이 초기화 되는걸까? 정확한 이유는 모르겠지만..
solution(arr)을 리턴했더니 문제가 해결되었다...
<script>
function solution(arr) {
let answer = [];
// 우선 9개의 배열 중에 인덱스 값으로 랜덤하게 7개를 뽑고
// 7개를 새로운 배열에 담는다. (거기다 중복 검사까지)
// 마지막에 모든 인덱스의 값을 더해서 100이 나오는지 까지 확인
// 7명을 뽑을 배열
let newArr = [];
// 7번만 반복해서 push하는 함수
const searchThere = function () {
for (let i = 0; i < 7; i++) {
let randomIndexValue = arr[Math.floor(Math.random() * 9)]; // 총 배열의 인덱스가 8이므로 0 ~ 8 사이를 랜덤으로 뽑는다. 그런데 겹치는 숫자가 있다?
// 랜덤으로 뽑은 값음 checkSameValue라는 함수로 검사해서...
if (checkSameValue(randomIndexValue)) {
// 같은 값이 있다면 i를 -1하여, 다시 랜덤값을 뽑음
i--;
} else {
// 없다면 배열에 넣음
newArr.push(randomIndexValue);
}
}
};
// 배열에 같은 인덱스가 존재하는지 확인하는 함수
const checkSameValue = function (randomIndexValue) {
return newArr.find((e) => {
if (e === randomIndexValue) {
return true;
} else {
return false;
}
});
};
// 중복되지 않는 7개를 뽑은 배열의 합이 100인지를 확인하는 함수
const check100 = function () {
let result = 0;
for (let i = 0; i < newArr.length; i++) {
result = result + newArr[i];
}
console.log("뽑은 배열의 합계", result);
if (result == 100) {
answer = newArr;
} else {
console.log("배열의 합이 100이 아님! (answer 초기화)");
answer = [];
}
};
// 테스트 시작~
searchThere();
console.log("뽑은 배열", newArr);
check100();
if (answer.length !== 0) {
return answer;
} else {
return solution(arr);
}
}
let arr = [20, 7, 23, 19, 10, 15, 25, 8, 13];
console.log(solution(arr));
</script>
아주 잘 찾아주는 모습이다 ㅋㅋ 😂
sum - ( arr[i] + arr[j] ) === 100
<script>
function solution(arr){
let answer=arr;
// 전체 합을 구함.
let sum=answer.reduce((a, b)=>a+b, 0);
// 2중 for문으로 2개의 인덱스 값을 더해서...
for(let i=0; i<8; i++){
for(let j=i+1; j<9; j++){
// 전체 합을 뺀 값이 100이라면
if((sum-(answer[i]+answer[j]))==100){
// 2개의 인덱스의 값을 지우고 배열을 리턴
answer.splice(j, 1);
answer.splice(i, 1);
}
}
}
return answer;
}
let arr=[20, 7, 23, 19, 10, 15, 25, 8, 13];
console.log(solution(arr));
</script>
존나 충격적이다.. 왜 전체에서 2개를 빼서 결국엔 100이 나와야 한다는 생각을 못했을까?
const fs = require('fs');
const input = require('fs')
.readFileSync('2309.txt')
.toString()
.trim()
.split('\n')
.map((item) => Number(item));
const over100 = input.reduce((acc, cur) => acc + cur) - 100;
const rst = [];
for (let i = 0; i < 9; i++) {
for (let j = 1 + i; j < 9; j++) {
if (input[i] + input[j] === over100) {
return input
.filter((item) => item !== input[i] && item !== input[j])
.sort(function (a, b) {
return a - b;
})
.map((item) => console.log(String(item)));
}
}
}