From 91903a9a8ef8f80644a0999e07600f278f3d5cb3 Mon Sep 17 00:00:00 2001 From: Arnaud Fauconnet Date: Thu, 3 Aug 2023 17:45:59 +0200 Subject: [PATCH] Completed day 5 of 2022 in go --- 2022/go/05/answer.go | 152 +++++++++++ 2022/go/05/answer_test.go | 50 ++++ 2022/go/05/go.mod | 3 + 2022/go/05/input | 512 ++++++++++++++++++++++++++++++++++++++ 2022/go/05/sample1 | 9 + 5 files changed, 726 insertions(+) create mode 100644 2022/go/05/answer.go create mode 100644 2022/go/05/answer_test.go create mode 100644 2022/go/05/go.mod create mode 100644 2022/go/05/input create mode 100644 2022/go/05/sample1 diff --git a/2022/go/05/answer.go b/2022/go/05/answer.go new file mode 100644 index 0000000..5e8e6cc --- /dev/null +++ b/2022/go/05/answer.go @@ -0,0 +1,152 @@ +package main + +import ( + "bufio" + "errors" + "fmt" + "log" + "os" + "strconv" + "strings" +) + +type Stack []byte + +func (s *Stack) String() string { + var res strings.Builder + + for _, crate := range *s { + res.WriteByte(crate) + res.WriteString(" ") + } + return res.String() +} + +func (s *Stack) isEmpty() bool { + return len(*s) == 0 +} + +func (s *Stack) push(t ...byte) { + *s = append(*s, t...) +} + +func (s *Stack) pop(n int) ([]byte, error) { + if s.isEmpty() { + return nil, errors.New("Couldn't pop from empty stack") + } + index := len(*s) - n + ret := (*s)[index:] + *s = (*s)[:index] + return ret, nil +} + +type Move struct { + n, from, to int +} + +type Input struct { + stacks []Stack + moves []Move +} + +func input(filename string) *Input { + file, err := os.Open(filename) + check(err, "Couldn't open %q", filename) + defer file.Close() + + input := &Input{} + + scanner := bufio.NewScanner(file) + + scanner.Split(bufio.ScanLines) + + var n_stacks int = 0 + + // Parse the stacks + for scanner.Scan() { + line := scanner.Text() + + if line[1] == '1' { + break + } + + if len(input.stacks) == 0 { + n_stacks = (len(line) + 1) / 4 + input.stacks = make([]Stack, n_stacks) + } + + for i := 0; i < n_stacks; i++ { + crate := line[4*i+1] + if crate != ' ' { + input.stacks[i].push(crate) + } + } + } + + // Reverse the stacks since they were added top-down and not bottom-up + for _, stack := range input.stacks { + for i, j := 0, len(stack)-1; i < j; i, j = i+1, j-1 { + stack[i], stack[j] = stack[j], stack[i] + } + } + + scanner.Scan() // get rid of the empty line after the labeling of the stacks + + // Parse the moves + for scanner.Scan() { + line := scanner.Text() + tokens := strings.Split(line, " ") + + n, err := strconv.Atoi(tokens[1]) + check(err, "Couldn't convert %q to int", tokens[1]) + from, err := strconv.Atoi(tokens[3]) + check(err, "Couldn't convert %q to int", tokens[3]) + to, err := strconv.Atoi(tokens[5]) + check(err, "Couldn't convert %q to int", tokens[5]) + + input.moves = append(input.moves, Move{ + n: n, + from: from, + to: to, + }) + } + + return input +} + +func result(inp *Input, part int8) string { + var res strings.Builder + + for _, move := range inp.moves { + moving, err := inp.stacks[move.from-1].pop(int(move.n)) + check(err, "ntm") + if part == 1 { + for i, j := 0, len(moving)-1; i < j; i, j = i+1, j-1 { + moving[i], moving[j] = moving[j], moving[i] + } + } + + inp.stacks[move.to-1].push(moving...) + } + + for _, stack := range inp.stacks { + log.Print(stack.String()) + res.WriteByte(stack[len(stack)-1]) + } + + return res.String() +} + +func check(e error, msg string, vals ...any) { + if e != nil { + log.Printf("ERROR: "+msg, vals) + panic(e) + } +} + +func main() { + result := result(input("sample1"), 1) + + log.Println(result) + fmt.Println(result) +} diff --git a/2022/go/05/answer_test.go b/2022/go/05/answer_test.go new file mode 100644 index 0000000..1cc850f --- /dev/null +++ b/2022/go/05/answer_test.go @@ -0,0 +1,50 @@ +package main + +import ( + "reflect" + "testing" +) + +func TestInputSample1(t *testing.T) { + filename := "sample1" + expected := &Input{ + stacks: []Stack{ + {'Z', 'N'}, + {'M', 'C', 'D'}, + {'P'}, + }, + moves: []Move{ + {1, 2, 1}, + {3, 1, 3}, + {2, 2, 1}, + {1, 1, 2}, + }, + } + var got *Input = input(filename) + + if !reflect.DeepEqual(expected, got) { + t.Errorf("input(%q) = %v, want %v", filename, got, expected) + } +} + +func TestResult(t *testing.T) { + tests := []struct { + part int8 + filename string + expected string + }{ + {1, "sample1", "CMZ"}, + {1, "input", "TDCHVHJTG"}, + + {2, "sample1", "MCD"}, + {2, "input", "NGCMPJLHV"}, + } + + for _, test := range tests { + var got string = result(input(test.filename), test.part) + + if got != test.expected { + t.Errorf("result = %q, want %q", got, test.expected) + } + } +} diff --git a/2022/go/05/go.mod b/2022/go/05/go.mod new file mode 100644 index 0000000..7938845 --- /dev/null +++ b/2022/go/05/go.mod @@ -0,0 +1,3 @@ +module aoc/5 + +go 1.20 diff --git a/2022/go/05/input b/2022/go/05/input new file mode 100644 index 0000000..33b0fd6 --- /dev/null +++ b/2022/go/05/input @@ -0,0 +1,512 @@ +[F] [L] [M] +[T] [H] [V] [G] [V] +[N] [T] [D] [R] [N] [D] +[Z] [B] [C] [P] [B] [R] [Z] +[M] [J] [N] [M] [F] [M] [V] [H] +[G] [J] [L] [J] [S] [C] [G] [M] [F] +[H] [W] [V] [P] [W] [H] [H] [N] [N] +[J] [V] [G] [B] [F] [G] [D] [H] [G] + 1 2 3 4 5 6 7 8 9 + +move 6 from 4 to 3 +move 5 from 8 to 9 +move 1 from 4 to 5 +move 1 from 4 to 5 +move 2 from 2 to 7 +move 2 from 1 to 6 +move 9 from 6 to 1 +move 12 from 3 to 5 +move 1 from 8 to 4 +move 3 from 1 to 5 +move 1 from 6 to 7 +move 10 from 5 to 2 +move 14 from 5 to 1 +move 8 from 7 to 9 +move 11 from 2 to 9 +move 1 from 3 to 9 +move 11 from 1 to 5 +move 2 from 1 to 9 +move 1 from 4 to 8 +move 6 from 1 to 5 +move 1 from 8 to 3 +move 16 from 5 to 1 +move 4 from 1 to 3 +move 1 from 5 to 6 +move 4 from 3 to 4 +move 1 from 6 to 7 +move 21 from 9 to 6 +move 2 from 1 to 9 +move 2 from 4 to 9 +move 5 from 9 to 4 +move 9 from 1 to 6 +move 6 from 4 to 6 +move 1 from 6 to 2 +move 1 from 7 to 6 +move 1 from 3 to 2 +move 8 from 6 to 9 +move 3 from 1 to 8 +move 1 from 2 to 1 +move 13 from 6 to 3 +move 1 from 1 to 9 +move 2 from 1 to 6 +move 3 from 8 to 4 +move 4 from 4 to 9 +move 3 from 1 to 3 +move 22 from 9 to 8 +move 1 from 2 to 9 +move 6 from 8 to 9 +move 15 from 6 to 5 +move 5 from 8 to 9 +move 11 from 9 to 8 +move 13 from 5 to 1 +move 1 from 6 to 5 +move 1 from 9 to 3 +move 21 from 8 to 3 +move 3 from 5 to 3 +move 11 from 1 to 2 +move 25 from 3 to 1 +move 5 from 1 to 7 +move 20 from 1 to 7 +move 1 from 6 to 7 +move 16 from 3 to 9 +move 8 from 9 to 6 +move 1 from 1 to 5 +move 5 from 9 to 4 +move 2 from 2 to 1 +move 2 from 9 to 4 +move 1 from 9 to 4 +move 1 from 8 to 4 +move 1 from 5 to 2 +move 3 from 4 to 6 +move 1 from 4 to 7 +move 9 from 7 to 6 +move 5 from 4 to 6 +move 7 from 7 to 2 +move 1 from 1 to 6 +move 11 from 2 to 5 +move 10 from 5 to 1 +move 1 from 6 to 8 +move 1 from 5 to 7 +move 24 from 6 to 1 +move 12 from 1 to 4 +move 12 from 4 to 8 +move 2 from 2 to 7 +move 3 from 7 to 2 +move 5 from 2 to 8 +move 9 from 8 to 9 +move 9 from 8 to 5 +move 1 from 9 to 1 +move 14 from 1 to 8 +move 11 from 7 to 9 +move 4 from 1 to 3 +move 7 from 1 to 2 +move 3 from 3 to 7 +move 12 from 9 to 7 +move 8 from 7 to 2 +move 4 from 9 to 2 +move 1 from 3 to 6 +move 5 from 5 to 9 +move 14 from 2 to 1 +move 8 from 9 to 4 +move 6 from 4 to 5 +move 5 from 5 to 7 +move 1 from 8 to 2 +move 2 from 4 to 6 +move 4 from 7 to 3 +move 10 from 8 to 4 +move 2 from 3 to 6 +move 7 from 7 to 6 +move 10 from 4 to 8 +move 5 from 1 to 6 +move 8 from 2 to 1 +move 7 from 6 to 8 +move 9 from 6 to 5 +move 16 from 1 to 6 +move 2 from 3 to 9 +move 1 from 7 to 4 +move 2 from 9 to 1 +move 14 from 6 to 7 +move 1 from 6 to 3 +move 2 from 6 to 3 +move 9 from 5 to 7 +move 3 from 1 to 6 +move 3 from 3 to 7 +move 5 from 5 to 9 +move 3 from 6 to 2 +move 1 from 6 to 2 +move 12 from 8 to 2 +move 5 from 2 to 1 +move 2 from 1 to 3 +move 25 from 7 to 1 +move 1 from 4 to 6 +move 2 from 3 to 9 +move 26 from 1 to 9 +move 2 from 1 to 8 +move 1 from 6 to 8 +move 1 from 7 to 1 +move 7 from 8 to 1 +move 7 from 1 to 5 +move 1 from 1 to 2 +move 2 from 8 to 6 +move 32 from 9 to 8 +move 1 from 6 to 5 +move 5 from 2 to 9 +move 1 from 9 to 7 +move 24 from 8 to 3 +move 1 from 6 to 9 +move 3 from 2 to 5 +move 1 from 7 to 9 +move 4 from 9 to 3 +move 8 from 8 to 7 +move 18 from 3 to 7 +move 20 from 7 to 8 +move 6 from 8 to 9 +move 6 from 5 to 1 +move 8 from 9 to 4 +move 3 from 5 to 4 +move 8 from 8 to 4 +move 2 from 5 to 2 +move 3 from 1 to 5 +move 4 from 3 to 7 +move 6 from 2 to 9 +move 3 from 3 to 6 +move 6 from 4 to 5 +move 2 from 6 to 3 +move 1 from 3 to 1 +move 4 from 3 to 8 +move 8 from 4 to 3 +move 4 from 3 to 7 +move 4 from 4 to 5 +move 4 from 9 to 5 +move 3 from 3 to 4 +move 3 from 4 to 9 +move 1 from 1 to 4 +move 2 from 1 to 5 +move 7 from 7 to 8 +move 4 from 7 to 4 +move 1 from 6 to 7 +move 1 from 1 to 5 +move 1 from 3 to 8 +move 11 from 5 to 9 +move 17 from 9 to 8 +move 13 from 8 to 4 +move 1 from 4 to 8 +move 4 from 7 to 1 +move 4 from 8 to 3 +move 6 from 5 to 4 +move 3 from 3 to 6 +move 2 from 1 to 9 +move 1 from 9 to 5 +move 1 from 3 to 5 +move 5 from 5 to 9 +move 2 from 1 to 8 +move 21 from 8 to 6 +move 2 from 8 to 4 +move 4 from 9 to 6 +move 1 from 9 to 7 +move 19 from 4 to 1 +move 28 from 6 to 5 +move 7 from 4 to 2 +move 28 from 5 to 3 +move 1 from 9 to 4 +move 1 from 4 to 2 +move 1 from 7 to 8 +move 1 from 8 to 9 +move 13 from 1 to 3 +move 8 from 2 to 8 +move 3 from 1 to 2 +move 5 from 8 to 5 +move 1 from 2 to 7 +move 1 from 9 to 7 +move 1 from 2 to 3 +move 2 from 7 to 9 +move 1 from 2 to 6 +move 1 from 9 to 1 +move 9 from 3 to 9 +move 3 from 9 to 1 +move 1 from 6 to 8 +move 21 from 3 to 7 +move 7 from 9 to 4 +move 2 from 4 to 2 +move 1 from 8 to 6 +move 7 from 1 to 4 +move 7 from 7 to 8 +move 4 from 5 to 9 +move 10 from 7 to 1 +move 7 from 3 to 9 +move 1 from 7 to 9 +move 1 from 5 to 3 +move 3 from 3 to 5 +move 10 from 4 to 2 +move 1 from 3 to 7 +move 2 from 4 to 9 +move 3 from 9 to 1 +move 3 from 7 to 1 +move 1 from 6 to 4 +move 1 from 1 to 2 +move 1 from 3 to 4 +move 2 from 4 to 3 +move 1 from 7 to 4 +move 4 from 8 to 9 +move 1 from 4 to 9 +move 3 from 1 to 9 +move 12 from 1 to 7 +move 2 from 9 to 5 +move 12 from 9 to 7 +move 5 from 5 to 1 +move 1 from 8 to 5 +move 4 from 1 to 4 +move 1 from 9 to 6 +move 1 from 3 to 4 +move 3 from 8 to 3 +move 1 from 1 to 7 +move 8 from 2 to 5 +move 2 from 8 to 1 +move 10 from 7 to 1 +move 4 from 9 to 5 +move 2 from 5 to 8 +move 11 from 5 to 4 +move 6 from 7 to 2 +move 2 from 2 to 1 +move 1 from 7 to 5 +move 1 from 5 to 1 +move 2 from 4 to 8 +move 1 from 6 to 9 +move 8 from 4 to 3 +move 8 from 1 to 7 +move 7 from 1 to 2 +move 4 from 3 to 9 +move 1 from 9 to 6 +move 7 from 2 to 1 +move 5 from 2 to 3 +move 2 from 7 to 8 +move 5 from 8 to 4 +move 2 from 9 to 3 +move 1 from 8 to 1 +move 6 from 3 to 5 +move 10 from 3 to 1 +move 3 from 5 to 3 +move 3 from 2 to 1 +move 1 from 5 to 4 +move 6 from 4 to 5 +move 1 from 6 to 2 +move 3 from 4 to 7 +move 1 from 9 to 4 +move 2 from 3 to 1 +move 1 from 9 to 8 +move 1 from 3 to 7 +move 4 from 4 to 8 +move 2 from 7 to 4 +move 8 from 5 to 9 +move 2 from 8 to 6 +move 2 from 4 to 3 +move 2 from 3 to 4 +move 4 from 9 to 7 +move 1 from 8 to 7 +move 2 from 6 to 9 +move 2 from 8 to 9 +move 1 from 2 to 9 +move 1 from 7 to 8 +move 1 from 2 to 7 +move 19 from 7 to 6 +move 1 from 8 to 1 +move 2 from 4 to 8 +move 5 from 6 to 1 +move 2 from 7 to 2 +move 2 from 2 to 8 +move 2 from 1 to 8 +move 4 from 8 to 2 +move 3 from 2 to 8 +move 6 from 9 to 5 +move 8 from 6 to 3 +move 26 from 1 to 6 +move 1 from 5 to 3 +move 1 from 1 to 5 +move 8 from 3 to 1 +move 1 from 3 to 7 +move 3 from 9 to 2 +move 4 from 2 to 6 +move 26 from 6 to 1 +move 1 from 7 to 5 +move 3 from 8 to 4 +move 2 from 8 to 2 +move 7 from 1 to 2 +move 1 from 5 to 9 +move 2 from 4 to 6 +move 9 from 6 to 2 +move 18 from 1 to 7 +move 6 from 7 to 1 +move 6 from 5 to 6 +move 1 from 1 to 2 +move 19 from 2 to 7 +move 1 from 4 to 2 +move 9 from 7 to 1 +move 3 from 6 to 7 +move 1 from 9 to 4 +move 1 from 2 to 3 +move 8 from 7 to 8 +move 4 from 6 to 5 +move 2 from 6 to 3 +move 1 from 4 to 2 +move 4 from 5 to 1 +move 8 from 8 to 7 +move 17 from 7 to 8 +move 3 from 3 to 1 +move 1 from 2 to 8 +move 8 from 8 to 4 +move 8 from 8 to 7 +move 1 from 8 to 2 +move 7 from 7 to 6 +move 1 from 2 to 7 +move 5 from 7 to 8 +move 7 from 1 to 6 +move 10 from 6 to 1 +move 4 from 7 to 9 +move 3 from 9 to 7 +move 1 from 7 to 2 +move 6 from 4 to 2 +move 7 from 1 to 5 +move 4 from 2 to 5 +move 16 from 1 to 9 +move 3 from 2 to 7 +move 2 from 4 to 9 +move 4 from 1 to 6 +move 5 from 7 to 4 +move 4 from 6 to 3 +move 1 from 7 to 4 +move 1 from 6 to 9 +move 1 from 8 to 5 +move 4 from 3 to 2 +move 2 from 5 to 3 +move 3 from 6 to 2 +move 3 from 2 to 1 +move 9 from 5 to 8 +move 1 from 3 to 1 +move 10 from 8 to 1 +move 1 from 8 to 5 +move 16 from 9 to 2 +move 1 from 3 to 2 +move 12 from 1 to 9 +move 1 from 9 to 2 +move 3 from 1 to 6 +move 2 from 1 to 9 +move 3 from 6 to 8 +move 20 from 2 to 7 +move 16 from 9 to 7 +move 1 from 7 to 5 +move 2 from 5 to 9 +move 2 from 2 to 3 +move 2 from 8 to 5 +move 3 from 9 to 7 +move 2 from 5 to 2 +move 1 from 4 to 6 +move 2 from 1 to 4 +move 23 from 7 to 5 +move 4 from 8 to 5 +move 7 from 7 to 1 +move 16 from 5 to 7 +move 1 from 6 to 5 +move 1 from 2 to 4 +move 2 from 3 to 9 +move 1 from 2 to 3 +move 13 from 5 to 1 +move 1 from 3 to 8 +move 1 from 9 to 4 +move 19 from 1 to 9 +move 2 from 1 to 9 +move 22 from 9 to 8 +move 14 from 8 to 5 +move 12 from 5 to 3 +move 21 from 7 to 9 +move 14 from 9 to 7 +move 1 from 8 to 6 +move 9 from 3 to 7 +move 1 from 3 to 2 +move 4 from 4 to 1 +move 1 from 2 to 4 +move 1 from 3 to 9 +move 6 from 8 to 9 +move 4 from 1 to 7 +move 2 from 5 to 9 +move 6 from 4 to 5 +move 4 from 7 to 4 +move 1 from 5 to 3 +move 5 from 9 to 7 +move 2 from 3 to 1 +move 6 from 9 to 6 +move 1 from 1 to 6 +move 2 from 4 to 2 +move 8 from 7 to 5 +move 20 from 7 to 5 +move 2 from 5 to 6 +move 4 from 9 to 5 +move 1 from 1 to 3 +move 1 from 3 to 4 +move 1 from 2 to 7 +move 1 from 4 to 9 +move 9 from 6 to 3 +move 2 from 4 to 3 +move 28 from 5 to 3 +move 1 from 8 to 3 +move 1 from 8 to 1 +move 1 from 2 to 8 +move 1 from 6 to 2 +move 1 from 8 to 1 +move 6 from 5 to 7 +move 1 from 5 to 1 +move 1 from 9 to 2 +move 1 from 1 to 3 +move 1 from 9 to 7 +move 2 from 1 to 2 +move 11 from 3 to 8 +move 3 from 8 to 6 +move 3 from 6 to 9 +move 25 from 3 to 7 +move 4 from 3 to 8 +move 4 from 2 to 3 +move 9 from 8 to 9 +move 2 from 3 to 7 +move 3 from 8 to 2 +move 11 from 9 to 7 +move 1 from 9 to 1 +move 4 from 7 to 3 +move 1 from 1 to 5 +move 23 from 7 to 2 +move 12 from 2 to 3 +move 2 from 3 to 9 +move 12 from 2 to 1 +move 2 from 3 to 9 +move 1 from 5 to 4 +move 1 from 2 to 5 +move 1 from 9 to 4 +move 1 from 5 to 9 +move 2 from 4 to 2 +move 3 from 1 to 4 +move 1 from 2 to 1 +move 10 from 3 to 2 +move 7 from 7 to 3 +move 11 from 7 to 9 +move 5 from 3 to 1 +move 1 from 4 to 5 +move 11 from 2 to 3 +move 9 from 9 to 3 +move 3 from 9 to 4 +move 2 from 4 to 8 +move 1 from 5 to 6 +move 13 from 1 to 5 +move 3 from 3 to 8 +move 3 from 7 to 2 +move 1 from 7 to 4 +move 3 from 8 to 3 +move 8 from 3 to 8 +move 4 from 4 to 5 +move 2 from 8 to 2 +move 8 from 8 to 3 +move 1 from 6 to 3 +move 2 from 2 to 8 +move 6 from 5 to 2 +move 3 from 2 to 8 +move 1 from 1 to 7 +move 2 from 9 to 3 +move 3 from 5 to 4 +move 2 from 8 to 6 diff --git a/2022/go/05/sample1 b/2022/go/05/sample1 new file mode 100644 index 0000000..84933bb --- /dev/null +++ b/2022/go/05/sample1 @@ -0,0 +1,9 @@ + [D] +[N] [C] +[Z] [M] [P] + 1 2 3 + +move 1 from 2 to 1 +move 3 from 1 to 3 +move 2 from 2 to 1 +move 1 from 1 to 2