나의 풀이
문제의 난이도보다 문제를 풀다 실수를 했는데 그것 때문에 시간을 너무 많이 잡아먹었다.
평소에는 처음 풀때는 좋은 변수명이 생각나지않아 대충 변수명을 하고 코테문제를 풀고 문제를 다시 리팩터링하면서
변수명을 고친다. 하지만 오늘 이렇게 하다가 변수명이 중복이 되어서 맞게 풀었는데 계속 틀린답이 나왔다.
for문을 작성할때 조건문에 var가아닌 let으로 선언하면 지역변수가 되기때문에 외부에 있는 변수와 같은이름을 할수있는데 이부분에서 문제가 발생하였다.
이제 처음 문제풀때부터 변수명을 고민하고 제대로 작성하자
1. 풀이
딱 보고 아 for문과 slice를 사용해서 10일단위로 끊으면서 want 제품과 할인 제품을 비교하면 될 것 같다 생각했다.
1) want 와 number을 하나의 객체로 만들기
const cut = 10
let result = 0
// 자주 사용하기에 want 배열과 number배열을 하나의 객체로 만들어 준다.
// wnat의 길이가 10이하이기 때문에 가독성을 위해 for문보다 reduce를 사용했다.
const wantBox = want.reduce((acc,cur,index) => {
acc[cur] = number[index]
return acc
},{})
2) 할인 상품 객체 만들기
for (let j = 0; j<=discount.length - cut; j++) {
// 할인 상품 10일 단위로 끊기
const seriesOfDiscountedGoods = discount.slice(j,j+cut)
let count = 0
// 10일 동안의 할인 상품과 수량이 들어있는 객체 만들기
const discountBox = seriesOfDiscountedGoods.reduce((acc,cur,index) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc
},{})
// 원하는 제품과 수량이 10일 동안의 할인 상품,수량과 일치하는지 확인
for (const goods in wantBox) {
// 원하는 상품이 없거나 수량이 일치하지 않으면 early return
if(!discountBox[goods]) break
if(wantBox[goods] !== discountBox[goods]) break
count += 1
// 원하는 제품과 수량이 10일간 마트 할인과 일치하다면 result += 1
if(count === want.length){
result += 1
break
}
}
}
return result
slice를 통해 10일 단위로 할인상품을 끊어서 앞서 만든 wantBox와 비교해주면된다.
전체 코드
function solution(want, number, discount) {
const cut = 10
let result = 0
// 자주 사용하기에 want 배열과 number배열을 하나의 객체로 만들어 준다.
// wnat의 길이가 10이하이기 때문에 가독성을 위해 for문보다 reduce를 사용했다.
const wantBox = want.reduce((acc,cur,index) => {
acc[cur] = number[index]
return acc
},{})
for (let j = 0; j<=discount.length - cut; j++) {
// 할인 상품 10일 단위로 끊기
const seriesOfDiscountedGoods = discount.slice(j,j+cut)
let count = 0
// 10일 동안의 할인 상품과 수량이 들어있는 객체 만들기
const discountBox = seriesOfDiscountedGoods.reduce((acc,cur,index) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc
},{})
// 원하는 제품과 수량이 10일 동안의 할인 상품,수량과 일치하는지 확인
for (const goods in wantBox) {
// 원하는 상품이 없거나 수량이 일치하지 않으면 early return
if(!discountBox[goods]) break
if(wantBox[goods] !== discountBox[goods]) break
count += 1
// 원하는 제품과 수량이 10일간 마트 할인과 일치하다면 result += 1
if(count === want.length){
result += 1
break
}
}
}
return result
}
다른 사람 풀이
function solution(want, number, discount) {
let count = 0;
for (let i = 0; i < discount.length - 9; i++) {
const slice = discount.slice(i, i+10);
let flag = true;
for (let j = 0; j < want.length; j++) {
if (slice.filter(item => item === want[j]).length !== number[j]) {
flag = false;
break;
}
}
if (flag) count += 1;
}
return count;
}
이 풀이는 굳이 객체를 만들지 않고 바로 계산했다.
내 코드보다 훨씬 처리속도도 빠르다.
1. 10일 단위로 할인 품목을 slice한다.
2. slice.filter(~~).length 는 want와 일치하는 품목의 수량이 몇개인지 알 수 있는 코드이다.
3. 그래서 수량을 알았을때 number[j]를 통해 내가 원하는 수량과 일치하지 않으면 바로 for문을 중단시키고 다음 날을 기준으로 10일을 끊는다.
4. 이런식으로 계속 반복한다.
여기서 눈에 띄는건 flag이다. 매번 if를 사용해서 체크할 필요없이 flag가 true인지 false인지만 확인하고 count +1 을해주면 된다.
이것을 내 코드에 적용시키면 아래와 같다.
flag가 false라는 것은 for문을 무사히 통과하지 못했다는 뜻이고 즉 조건에 맞지 않은 discountBox라는 뜻이다.
for (let j = 0; j<=discount.length - cut; j++) {
// 할인 상품 10일 단위로 끊기
const seriesOfDiscountedGoods = discount.slice(j,j+cut)
let count = 0
// 10일 동안의 할인 상품과 수량이 들어있는 객체 만들기
const discountBox = seriesOfDiscountedGoods.reduce((acc,cur,index) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc
},{})
// 원하는 제품과 수량이 10일 동안의 할인 상품,수량과 일치하는지 확인
let flag = true;
for (const goods in wantBox) {
// 원하는 상품이 없거나 수량이 일치하지 않으면 early return
if(!discountBox[goods] || wantBox[goods] !== discountBox[goods]){
flag = false;
break;
}
}
// 원하는 제품과 수량이 10일간 마트 할인과 일치하다면 result += 1
if(flag) result += 1;
}
return result
'알고리즘 > 프로그래머스 - JS' 카테고리의 다른 글
[프로그래머스] level.2 다리를 지나는 트럭 (1) | 2023.05.22 |
---|---|
[프로그래머스 - JS] level.2 프로세스 👍 (0) | 2023.05.20 |
[프로그래머스] level.2 기능개발 (0) | 2023.05.19 |
[프로그래머스] level.2 조이스틱 ★ (0) | 2023.05.18 |
[프로그래머스 - JS] level.1 같은 숫자는 싫어 (0) | 2023.05.17 |