이력서 기초 다지기를 진행했다. 나는 velog에 웬만한 정보들은 다 적어두었기에, velog를 통해 자료를 모았다. 쓰면서 확실히 트러블 슈팅을 많이 써놔야 쓸 게 있구나 싶었다. 그냥 기능 구현한 정보만으로는 그다지 쓸 게 없다... 솔직히 이번 과제가 좀 애매하다고 생각은 들었지만, 그래도 일단은 내 생각대로 어떻게든 해봤고, 내가 작성해둔 velog가 어디 도망가는 것도 아니기 때문에 일단 나중에 더 추가를 하더라도 일단 쭉쭉 진도를 빼보는게 좋을 것 같다는 생각이 든다.
한 문제에 두시간을 태운 문제...
햄버거 가게에서 일을 하는 상수는 햄버거를 포장하는 일을 합니다. 함께 일을 하는 다른 직원들이 햄버거에 들어갈 재료를 조리해 주면 조리된 순서대로 상수의 앞에 아래서부터 위로 쌓이게 되고, 상수는 순서에 맞게 쌓여서 완성된 햄버거를 따로 옮겨 포장을 하게 됩니다. 상수가 일하는 가게는 정해진 순서(아래서부터, 빵 – 야채 – 고기 - 빵)로 쌓인 햄버거만 포장을 합니다. 상수는 손이 굉장히 빠르기 때문에 상수가 포장하는 동안 속 재료가 추가적으로 들어오는 일은 없으며, 재료의 높이는 무시하여 재료가 높이 쌓여서 일이 힘들어지는 경우는 없습니다.
예를 들어, 상수의 앞에 쌓이는 재료의 순서가 [야채, 빵, 빵, 야채, 고기, 빵, 야채, 고기, 빵]일 때, 상수는 여섯 번째 재료가 쌓였을 때, 세 번째 재료부터 여섯 번째 재료를 이용하여 햄버거를 포장하고, 아홉 번째 재료가 쌓였을 때, 두 번째 재료와 일곱 번째 재료부터 아홉 번째 재료를 이용하여 햄버거를 포장합니다. 즉, 2개의 햄버거를 포장하게 됩니다.
상수에게 전해지는 재료의 정보를 나타내는 정수 배열 ingredient가 주어졌을 때, 상수가 포장하는 햄버거의 개수를 return 하도록 solution 함수를 완성하시오.
function solution(ingredient) {
let str = ingredient.join("");
let result = 0;
while (str.indexOf("1231") !== -1) {
str = str.split("1231").join("");
result++;
}
return result;
}
첫 제출. 이 방식은 애초부터 오류가 있었던 게, 순서대로 1231을 한번씩 삭제해야하는데 한 번에 1231을 전부 split하기 때문에 당연히 틀린 답일 수밖에 없었다. 때문에 다시 생각하여 제출을 해보았다.
function solution(ingredient) {
let result = 0;
while (ingredient.join("").indexOf("1231") !== -1) {
ingredient.splice(ingredient.join("").indexOf("1231"), 4);
result++;
}
return result;
}
다음에 사용한 방법은, ingredient를 문자열로 변환하고 그 안에 "1231"이 존재할 경우 해당 index로부터 4개를 splice해주는 방식을 사용했다. 이 방식에 다른 오류는 없었지만, 시간 초과로 인해 실패하는 테스트 케이스가 많았다. 찾아보니 ingredient의 길이가 최대 1,000,000까지기에, 매번 문자열로 바꿔주는 게 시간이 들기에 시간 초과가 나오는 것이었다.
때문에 나는 다른 방법을 생각해야했다.
function solution(ingredient) {
let result = 0;
const arr = "1231";
let find = true;
while (find) {
find = false;
for (let i = 0; i < ingredient.length - 3; i++) {
if (ingredient.slice(i, i + 4).join("") === arr) {
ingredient.splice(i, 4);
find = true;
result++;
}
}
}
return result;
}
이 방식에서 어떤 부분이 틀렸는지는 아직 잘 모르겠지만, 무지성으로 해본 이 코드에서도 실패를 겪었다.
떄문에 뭔가 다른 방식이 필요하다고 느꼈고, stack 방식을 사용해보라는 말을 듣고 stack 방식을 적용시켜보았다.
function solution(ingredient) {
let result = 0;
const arr = "1231";
const stack = [];
for (let i = 0; i < ingredient.length; i++) {
stack.push(ingredient[i]);
if (stack.length >= 4) {
const burger = stack.slice(-4).join("");
if (burger === arr) {
stack.splice(-4);
result++;
}
}
}
return result;
}
반복문을 통해 ingredient 내 요소들을 하나씩 stack에 넣어준다.
만약 stack의 길이가 4 이상일 경우 (그 미만일 경우 1231이 들어있을 수 없기에) stack의 가장 끝 4개의 숫자를 문자열로 만들고, 1231일 경우 stack에서 해당 부분을 splice해주고, result에 1을 추가한다.
반복문이 끝나면 result를 반환한다.
항상 이런 문제를 풀고나면, 고민했던 시간들이 허무하게 느껴질 정도이다. 하지만 반대로 생각하면 이렇게 간단하게 해결할 수 있음에도 내가 생각을 해내지 못했다는 걸 증명하는 것이기에, 앞으로도 오래 걸리더라도 꾸준히 알고리즘을 풀어야할 이유가 되는 것 같다.