[프로그래머스] 햄버거 만들기

YoungHyun Kim·2023년 12월 1일
2

매일매일 알고리즘

목록 보기
17/30

문제

햄버거 가게에서 일을 하는 상수는 햄버거를 포장하는 일을 합니다. 함께 일을 하는 다른 직원들이 햄버거에 들어갈 재료를 조리해 주면 조리된 순서대로 상수의 앞에 아래서부터 위로 쌓이게 되고, 상수는 순서에 맞게 쌓여서 완성된 햄버거를 따로 옮겨 포장을 하게 됩니다. 상수가 일하는 가게는 정해진 순서(아래서부터, 빵 – 야채 – 고기 - 빵)로 쌓인 햄버거만 포장을 합니다. 상수는 손이 굉장히 빠르기 때문에 상수가 포장하는 동안 속 재료가 추가적으로 들어오는 일은 없으며, 재료의 높이는 무시하여 재료가 높이 쌓여서 일이 힘들어지는 경우는 없습니다.

예를 들어, 상수의 앞에 쌓이는 재료의 순서가 [야채, 빵, 빵, 야채, 고기, 빵, 야채, 고기, 빵]일 때, 상수는 여섯 번째 재료가 쌓였을 때, 세 번째 재료부터 여섯 번째 재료를 이용하여 햄버거를 포장하고, 아홉 번째 재료가 쌓였을 때, 두 번째 재료와 일곱 번째 재료부터 아홉 번째 재료를 이용하여 햄버거를 포장합니다. 즉, 2개의 햄버거를 포장하게 됩니다.

상수에게 전해지는 재료의 정보를 나타내는 정수 배열 ingredient가 주어졌을 때, 상수가 포장하는 햄버거의 개수를 return 하도록 solution 함수를 완성하시오.

제한사항

  • 1 ≤ ingredient의 길이 ≤ 1,000,000
  • ingredient의 원소는 1, 2, 3 중 하나의 값이며, 순서대로 빵, 야채, 고기를 의미합니다.

풀이

  1. ingredient 배열의 원소를 하나 씩 스택에 넣는다.
  2. 그와 동시에 스택의 뒤에서부터 검색한 스택의 값이 [빵 -> 야채 -> 고기 -> 빵]([1, 2, 3, 1]) 이라면 해당 값들을 삭제하고, burger 갯수를 하나 추가한다.
  3. ingredient의 모든 원소값에 대해 위의 동작을 실행하면 끝.
import Foundation

func solution(_ ingredient:[Int]) -> Int {
    var sangSu: [Int] = [], burger = 0, recipe = [1,2,3,1]
    
    for ing in ingredient {
        sangSu.append(ing)
        if Array(sangSu.suffix(4)) == recipe {
            sangSu.removeLast(4)
            burger += 1
        }
    }
    
    return burger
}

회고


import Foundation

func solution(_ ingredient:[Int]) -> Int {
    var strIng = ingredient.map(String.init).joined()
    
    while strIng.contains("1231") {
        var before = strIng.count
        strIng = strIng.replacingOccurrences(of: "1231", with: "")
        var after = strIng.count

        print(before, after)
        count += (before - after) / 4
    }
    return count
}
  • 처음에는 이런 식으로 ingredient를 String 형태로 변환한 다음에, replacingOccurences 메소드를 사용해서 햄버거의 갯수를 구하려고 했다.
    • 하지만 replacingOccurences 메소드는 바꾸고자 하는 문자열들이 여러 개 탐색되면 탐색된 모든 값들을 대치시켜 버리기 때문에, 정확한 햄버거의 갯수를 구할 수 없었다.
import Foundation

func solution(_ ingredient:[Int]) -> Int {
    var arrIng: [Int] = ingredient
    var count = 0
    
        while arrIng.contains([1,2,3,1]) {
        for i in 0..<arrIng.count {
            if arrIng[i] == 1 && arrIng[i+1] == 2 && arrIng[i+2] == 3 && arrIng[i+3] == 1 {
                arrIng.removeSubrange(i...i+3)
                count += 1
                break
            }
        }
    }
    
    return count
}
  • 두 번째 시도에서는 ingredient 배열에 [빵 - 야채 - 고기 - 빵]의 배열을 계속해서 찾아낸 다음, 해당 값들의 인덱스를 사용해서 removeSubrange 메소드를 통해 제작가능한 햄버거의 갯수를 찾아냈다. (Xcode에서는 훌륭하게 자신의 임무를 완수한 내 코드...)
    • 하지만, 이 방식의 문제점은 바로 프로그래머스의 swift 컴파일러 버전이 5.2라는 것.. 이었다.
    • 내가 사용한 contains 메소드는 Collection 타입의 자료를 매개로 실행되는 것이고, 이 메소드는 적어도 컴파일러 버전 5.4 이상에서 구동이 되는 메소드였기에 런타임 에러를 와장창 뽑아내며 구동에 실패했다.
  • 위와 같은 문제들을 겪고 인터넷 선배님들에게 힌트를 얻어서 스택 자료형을 구현하는 것으로 문제를 풀었다.
profile
iOS 개발자가 되고 싶어요

0개의 댓글