1일 차: 리스프가 아닙니다(1부).

오늘 우리는 Advent of Code 2015의 첫 번째 문제인 "Not Quite Lisp"를 해결하는 방법을 살펴볼 것입니다. 테스트 주도 개발을 사용하여 이를 수행할 것입니다.

Advent of Code에 대해 들어본 적이 없는 분들을 위해 여기에서 자세한 내용을 읽을 수 있습니다: About Advent of code

즉, 12월 1일부터 12월 25일까지 매일 재미있는 휴일 테마 퍼즐을 게시하는 연례 행사입니다. 매년 수천 명의 사람들이 Advent of Code에 참여합니다.

먼저 문제를 먼저 살펴 보겠습니다.

--- Day 1: Not Quite Lisp ---

Santa was hoping for a white Christmas, but his weather
machine's "snow" function is powered by stars, and he's
fresh out!

To save Christmas, he needs you to collect fifty stars
by December 25th.

Collect stars by helping Santa solve puzzles. Two puzzles
will be made available on each day in the Advent calendar;
the second puzzle is unlocked when you complete the first.
Each puzzle grants one star. Good luck!

Here's an easy puzzle to warm you up.

Santa is trying to deliver presents in a large apartment
building, but he can't find the right floor - the directions
he got are a little confusing. He starts on the ground floor
(floor 0) and then follows the instructions one character
at a time.

An opening parenthesis, (, means he should go up one floor,
and a closing parenthesis, ), means he should go down
one floor.

The apartment building is very tall, and the basement is
very deep; he will never find the top or bottom floors.

For example:

    (()) and ()() both result in floor 0.
    ((( and (()(()( both result in floor 3.
    ))((((( also results in floor 3.
    ()) and ))( both result in floor -1.
    ))) and )())()) both result in floor -3.

To what floor do the instructions take Santa?


모든 문제에는 수반되는 퍼즐 입력이 있습니다. 이 문제에 대한 입력은 다음과 같습니다.

()()(()()()(()()((()((()))((()((((()()((((()))()((((())(((((((()(((((((((()(((())(()()(()((()()(()(())(()((((()((()()()((((())((((((()(()(((()())(()((((()))())(())(()(()()))))))))((((((((((((()())()())())(())))(((()()()((((()(((()(()(()()(()(()()(()(((((((())(())(())())))((()())()((((()()((()))(((()()()())))(())))((((())(((()())(())(()))(()((((()())))())((()(())(((()((((()((()(())())))((()))()()(()(()))))((((((((()())((((()()((((()(()())(((((()(()())()))())(((()))()(()(()(()((((()(())(()))(((((()()(()()()(()(((())())(((()()(()()))(((()()(((())())(()(())())()()(())()()()((()(((()(())((()()((())()))((()()))((()()())((((()(()()(()(((()))()(()))))((()(((()()()))(()(((())()(()((()())(()(()()(()())(())()(((()(()())()((((()((()))))())()))((()()()()(())()())()()()((((()))))(()(((()()(((((((())()))()((((()((())()(()())(())()))(()(()())(((((((())))(((()))())))))()))())((())(()()((())()())()))))()((()()())(())((())((((()())())()()()(((()))())))()()))())(()()()(()((((((()()))())()))()(((()(((())((((()()()(()))())()()))))())()))())((())()())(((((())())((())())))(((())(((())(((((()(((((())(()(()())())(()(())(()))(()((((()))())()))))())))((()(()))))())))(((((())()))())()))))()))))(((()))()))))((()))((()((()(()(())()())))(()()()(())()))()((((())))))))(())(()((()()))(()))(()))(()((()))))))()()((((()()))()())()))))))()()()))(()((())(()))((()()()())()(((()((((())())))()((((()(()))))))())))()()())()))(()))))(()())()))))))((())))))))())()))()((())())))(()((()))()))(())))))(()))()())()()))((()(()))()()()()))))())()()))())(())()()))()))((()))))()()(()())))))()()()))((((()))()))))(()(())))(()())))((())())(()))()))))()())))()())()())))))))))()()))))())))((())((()))))())))(((()())))))))(()))()()))(()))()))))()())))))())((((()())))))))())))()()))))))))()))()))))()))))))(())))))))))())))))))))))))))())())((())))))))))()))((())))()))))))))())()(()))))))())))))()()()())()(()()()(()())(()))()()()(()())))())())))()))))())))))))()()()()())(())())()())()))))(()()()()()))))()))())())))((()())()())))()))()))))(()())))()))))))))(((()))()()))))))))))))))))))))(()))(()((()))())))())(()))(()(()(())))))()(()))()))()()))))))))))))()((()())(())())()(())))))())()())((()()))))(()()))))())()(())()))))))))))))))))))))()))(()(()())))))))()()((()))()))))))((())))()))))))))((()))())()()))())()()))((()))())))))))))))(()())()))(())((()(()()))(()())(())))()())(()(())()()))))()))()(()))))))(()))))))))))(()))())))))))))())))))())))(())))))()))))(())())))))))))()(()))))()())))())(()))()())))))))))))))())()()))))()))))))())))))()))))(())(()()()()((())()))())(()))((())()))())())(())(()()))))()))(())()()((())(())))(())))()))())))))))))()(((((())())))(())()))))(())))((()))()(((((((()))))()()))(())))))()(()))))(()()))()))())))))))(()())()))))))))())))(()))())()))(())()((())())()())())(()(()))))()))))))((()())(())()()(()())))()()))(())(())(()))())))()))(()))()()))((((()))))()))((()()()))))()))()))())))(()))()))))(())))()))())()(()))()())))())))))))())))())))()()))))))(()))())())))()))()()())())))))))))))))())))()))(()()))))())))())()(())))())))))))))))))))))()()())())))))()()()((()(()))()()(())()())()))()))))()()()))))))((()))))))))()(()(()((((((()()((()())))))))))))()))())))))((())())(()))())))())))))())()()())(())))())))()())())(())))))))()()(())))()))())))())())())()))))))))()))(()()()())())())))(())())))))))()()())()))))())))())()(())())))))))()())()))(()()(())())))()(()((()()((()()(((((())(()())()))(())()))(())))(())))))))()))()))((()))()))()))))))))()))))))))((()()())(()))(((()))(())))()))((())(((())))()())))())))))((())))))(())())((((((())())()(()))()(()((()())))((())()(()(()))))(())(()()())(())))())((()(((())())))(((()())())))())()(())())((((()()))))())((()))()()()()(())(((((((()()()((()))())(()())))(())())((((()()(()))))()((())))((())()))()(((()))())))()))((()(()))(())(()((((())((((()()(()()))(((())(()))))((((()(()))(())))))((()))(()))((()(((()(()))(()(()((()(())(()(()(()(()()((()))())(((())(()(()))))(()))()()))(())))(())()(((())(()))()((((()()))))())(()))))((())()((((()(((()))())())(((()))()())((())(())())(())()(())()(()()((((((()()))))()()(((()()))))()())()(((()(()))(()(()())(()(()))))(((((()(((())())))))(((((()((()()((())())((((((()(())(()()((()()()()()()()(()()))()(((()))()))(((((((())(((()((()())()((((())(((()(())))()((()(()()()((())((()())()))()))())))())((((((()))(()(()()()))(()((()(()(()))()((()(((()()()((())(((((())()(()))())())((()(())))(()(()())(())((())())())(((()()()(())))))())(()))))))()))))))())((()()()))((()((((((()))(((()((((()()()(((()))())()(()()(((()((()()()()())()()))()()()(()(())((()))))(()))())))))))()(()()(((((())()(()(((((()((()(()()())(()((((((((()((((((())()((((()()()((()((()((((((()))((())))))))())()))((()(()))()(()()(()((())((()()((((((((((((()())(()()()))((((()((((((())(()))())(()()((()()))()(((((((()((()()((((((()(((())))((())))((((((((()()(((((((())(((((()())(((())((())()((((()(((((((()(()(((()((((((()(((()(((((((((((()()((()()(()))((()()(((()(((())))((((())()(()(((())()(()(((())(((((((((((()))())))((((((())((()()((((()())())((((()()))((())(((((()(()()(()()()((())(()((()()((((()(((((()((()(()((((()())((((((()(((((()()(()(()((((())))(())(())(())((((()(()()((((()((((()()((()((((((())))(((((()))))()))(()((((((((()(((())())(((())))(()(()((())(((()((()()(((((()((()()(((())()(()))(((((((())(()(((((()))((()((()((()))(())())((((()((((())()(()))(((()(((((((((((((((())(((((((((()))(((()(()()()()((((((()((())()((((((((()(())(((((((((((()(()((())()((()()(()(()()((((()()((())(()((()()(()()((((()(((((((())))((((())(())()(((()()((()()((((()((()(((()((())(((()()()((((()((((()()(()(()((((((((())(()(((((())(()())(((((((()())()(()((((()((())(()()())((((()()(((()((((())(())(()()(((((((((()()))()(((())(()(()((((((())(()()())(()))()()(((()(((()((())(()(((((((()(()(()((()(((((()(()((()(()((((((()((((()()((((()(((()((())(()(()((()()((((()()(())()(())(((())(()((((((((()())(((((((((()(())()((((())))()))()()(((((()()((((((())(()()(((()(()(((((((()(()(((((((())(())((((()((()(())))((((()()())(()))((()())((((()(((((()(()(())(()(()()())(((((()(((((()((((()()((((((((()()))(()((((((())((((())()(()(((()()()(((()(()(())(())(((((()(())())((((())(())(()(((()(((((())((((())())((()(((((((()(((())(()(()))(((((((((()((()((()()(()((((())(((()((())((((())(()(((()(((()(()((((()(((())(()(((()(()()(()(()((()()(()())(())())((()(()(((()(((()(((()()(((((((((()(((((((((()()(((()(((()())((((()(()(((()()()((())((((((((((())(()(((()((((()())((((()((()))(((()()()(((((()(((((((())((()())(()((((())((((((((())(()((()((((((((((()()((()((()()))(((()())()())()(((()())()()(()(()(((((((())()))(())()))())()()((())()((()((((()((()((())(((((()((((((()(())))(()))())(((()))((()()(()(((()))((((())()(((()))))()(()(())()(((((())(()(()(())(())()((()()()((((()(())((()())(()(()))(()(()(()()(())()()(()((())()((()))))()))((()(()()()()((()())(()))())()(()(((((((((())())((()((()((((((())()((((())(((())((()(()()()((())(()((())(((()((((()()((()(()(((((())()))()((((((()))((())(((()()))(((())(())()))(((((((())(())())()(())(((((()))()((()))()(()()((()()()()()())(((((((


내 첫인상은 이 챌린지가 매우 간단하다는 것입니다. 0에서 시작하고 문자열의 각 문자에 따라 1씩 증가 또는 감소해야 합니다.

시작하겠습니다.

우리는 두 가지 기능을 작성할 것입니다. 1만큼 증가하는 것과 1만큼 감소하는 것.

그러나 그 전에 위의 각 기능에 대해 하나씩 두 개의 테스트를 작성할 것입니다.

func TestIncrementByOne(t *testing.T) {
    assert.Equal(t, 1, IncrementByOne(0))
    assert.Equal(t, 200, IncrementByOne(199))
    assert.Equal(t, 0, IncrementByOne(-1))
}

func TestDecrementByOne(t *testing.T) {
    assert.Equal(t, 0, DecrementByOne(1))
    assert.Equal(t, 199, DecrementByOne(200))
    assert.Equal(t, -1, DecrementByOne(0))
}


이러한 테스트를 실행하려고 하면 테스트가 실패하는 것을 볼 수 있습니다.

# github.com/damiensedgwick/aoc2015/day_1 [github.com/damiensedgwick/aoc2015/day_1.test]
./main_test.go:9:21: undefined: IncrementByOne
./main_test.go:10:23: undefined: IncrementByOne
./main_test.go:11:21: undefined: IncrementByOne
./main_test.go:15:21: undefined: DecrementByOne
./main_test.go:16:23: undefined: DecrementByOne
./main_test.go:17:22: undefined: DecrementByOne
FAIL    github.com/damiensedgwick/aoc2015/day_1 [build failed]


테스트를 통과시키는 코드가 존재하지 않기 때문입니다.

따라서 다음 단계는 앞에서 언급한 두 함수를 만드는 것입니다.

func IncrementByOne(n int) int {
    return n + 1
}

func DecrementByOne(n int) int {
    return n -1
}


매우 간단합니다. 테스트를 다시 실행해 보겠습니다.

PASS
ok      github.com/damiensedgwick/aoc2015/day_1 0.177s


완벽한!

다음으로, 문자열을 가져와서 반복할 수 있도록 문자열 조각으로 바꾸는 함수로 실제로 할 수 있다고 생각합니다.

항상 그렇듯이 테스트를 먼저 작성합니다.

func TestCreateStringSlice(t *testing.T) {
    assert.Equal(t, []string{
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
    }, CreateStringSlice("abcdef"))
}


이제 테스트를 실행하면 오류가 발생하므로 새 테스트를 통과하는 함수를 작성해야 합니다.

func CreateStringSlice(str string) []string {
    return strings.Split(str, "")
}


좋아, 또 다른 합격 시험!
main.go 의 상단에서 텍스트 파일의 입력을 로드하는 빠른 함수를 만들었습니다. 문자열을 파일에 바로 붙여넣을 수도 있었지만 가능한 한 깔끔하게 유지하고 싶었습니다.

그 기능은 아래와 같습니다.

func LoadInput(path string) string {
    input, err := os.ReadFile(path)
    if err != nil {
        log.Fatal(err)
    }

    return string(input)
}


이제 문제를 시도하는 데 필요한 모든 조각이 있으므로 조각을 함께 추가하고 문자열 조각을 반복하여 올바른 결과를 생성할 수 있는지 확인합니다.

우리의 주요 기능에서 우리는 쓸 수 있습니다.

func main() {
    var result = 0

    input := LoadInput("./input.txt")
    slice := strings.Split(input, "")

    for _, v := range slice {
        switch v {
        case "(":
            result = IncrementByOne(result)
        case ")":
            result = DecrementByOne(result)
        }
    }

    fmt.Println(result)
}


이제 go run main.go를 실행하면 결과가 280가 됩니다. 이 문제에 대해 Advent of Code에 280을 입력하면 올바른 결과를 얻을 수 있습니다.

That's the right answer! You are one gold star closer to powering the weather machine. [Continue to Part Two]


다른 Advent of Code 문제와 함께 앞으로 파트 2를 완료할 예정입니다.

좋은 웹페이지 즐겨찾기