1
0
Fork 0

♻️ Refactored whole repo contents into testable puzzle modules

This commit is contained in:
Maxim Lebedev 2023-12-02 04:01:29 +06:00
parent 6910155f91
commit 58a0fbf077
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
8 changed files with 231 additions and 78 deletions

77
day1_test.go Normal file
View File

@ -0,0 +1,77 @@
package adventofcode_test
import (
"bytes"
"fmt"
"log"
"os"
"path/filepath"
"source.toby3d.me/toby3d/adventofcode/internal/day1/part1"
"source.toby3d.me/toby3d/adventofcode/internal/day1/part2"
)
/*
Something is wrong with global snow production, and you've been selected to take
a look. The Elves have even given you a map; on it, they've used stars to mark
the top fifty locations that are likely to be having problems.
You've been doing this long enough to know that to restore snow operations, you
need to check all fifty stars by December 25th.
Collect stars by solving 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!
You try to ask why they can't just use a weather machine ("not powerful enough")
and where they're even sending you ("the sky") and why your map looks mostly
blank ("you sure ask a lot of questions") and hang on did you just say the sky
("of course, where do you think snow comes from") when you realize that the
Elves are already loading you into a trebuchet ("please hold still, we need to
strap you in").
As they're making the final adjustments, they discover that their calibration
document (your puzzle input) has been amended by a very young Elf who was
apparently just excited to show off her art skills. Consequently, the Elves are
having trouble reading the values on the document.
Consider your entire calibration document. What is the sum of all of the
calibration values?
*/
func ExampleDay1() {
input, err := os.ReadFile(filepath.Join("internal", "day1", "testdata", "input"))
if err != nil {
log.Fatalln("cannot open input file:", err)
}
result, err := part1.Calibrate(bytes.NewReader(input))
if err != nil {
log.Fatalln("cannot sum all calibration values:", err)
}
fmt.Println(result)
// Output: 54601
}
/*
Your calculation isn't quite right.
Equipped with this new information, you now need to find the real first and last
digit on each line.
What is the sum of all of the calibration values?
*/
func ExampleDay1_PartTwo() {
input, err := os.ReadFile(filepath.Join("internal", "day1", "testdata", "input"))
if err != nil {
log.Fatalln("cannot open input file:", err)
}
result, err := part2.Calibrate(bytes.NewReader(input))
if err != nil {
log.Fatalln("cannot sum all calibration values:", err)
}
fmt.Println(result)
// Output: 54078
}

3
doc.go Normal file
View File

@ -0,0 +1,3 @@
// Package provides attempts and solutions for Advent Of Code 2023 puzzles:
// https://adventofcode.com/2023
package adventofcode

View File

@ -0,0 +1,54 @@
package part1
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
func Calibrate(r io.Reader) (uint, error) {
scanner := bufio.NewScanner(r)
var sum uint
for scanner.Scan() {
line := scanner.Text()
calVal, err := makeCalibrationValue(strings.NewReader(line))
if err != nil {
return 0, fmt.Errorf("cannot make calibration value from '%s': %w", line, err)
}
sum += uint(calVal)
}
return sum, nil
}
func makeCalibrationValue(r io.Reader) (uint8, error) {
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanRunes)
parts := make([]rune, 0)
for scanner.Scan() {
text := scanner.Bytes()
switch text[0] {
default:
continue
case '1', '2', '3', '4', '5', '6', '7', '8', '9':
parts = append(parts, rune(text[0]))
}
}
digit := fmt.Sprintf("%c%c", parts[0], parts[len(parts)-1])
result, err := strconv.ParseUint(digit, 10, 8)
if err != nil {
return 0, fmt.Errorf("cannot parse '%s' as calibration value number: %w", digit, err)
}
return uint8(result), nil
}

View File

@ -0,0 +1,44 @@
package part1_test
import (
"fmt"
"log"
"strings"
"source.toby3d.me/toby3d/adventofcode/internal/day1/part1"
)
func Example() {
var sum uint = 0
// The newly-improved calibration document consists of lines of text;
// each line originally contained a specific calibration value that the
// Elves now need to recover. On each line, the calibration value can be
// found by combining the first digit and the last digit (in that order)
// to form a single two-digit number.
for _, exampleLine := range []string{
"1abc2",
"pqr3stu8vwx",
"a1b2c3d4e5f",
"treb7uchet",
} {
calibrationValue, err := part1.Calibrate(strings.NewReader(exampleLine))
if err != nil {
log.Fatalln(err)
}
sum += calibrationValue
fmt.Println(calibrationValue)
}
// Adding these together produces 142.
fmt.Println(sum)
// Output:
// 12
// 38
// 15
// 77
// 142
}

View File

@ -1,4 +1,4 @@
package main
package part2
import (
"bufio"
@ -8,23 +8,23 @@ import (
"strings"
)
func Trebuchet(r io.Reader) (uint, error) {
func Calibrate(r io.Reader) (uint, error) {
scanner := bufio.NewScanner(r)
var total uint
var sum uint
for scanner.Scan() {
line := scanner.Text()
calibrationValue, err := makeCalibrationValue(strings.NewReader(line))
calVal, err := makeCalibrationValue(strings.NewReader(line))
if err != nil {
return 0, fmt.Errorf("cannot make calibration value from '%s': %w", line, err)
}
total += uint(calibrationValue)
sum += uint(calVal)
}
return total, nil
return sum, nil
}
func makeCalibrationValue(r io.Reader) (uint8, error) {

View File

@ -0,0 +1,47 @@
package part2_test
import (
"fmt"
"log"
"strings"
"source.toby3d.me/toby3d/adventofcode/internal/day1/part2"
)
func Example() {
var sum uint = 0
// It looks like some of the digits are actually spelled out with
// letters: one, two, three, four, five, six, seven, eight, and nine
// also count as valid "digits".
for _, exampleLine := range []string{
"two1nine",
"eightwothree",
"abcone2threexyz",
"xtwone3four",
"4nineeightseven2",
"zoneight234",
"7pqrstsixteen",
} {
calibrationValue, err := part2.Calibrate(strings.NewReader(exampleLine))
if err != nil {
log.Fatalln(err)
}
sum += calibrationValue
fmt.Println(calibrationValue)
}
fmt.Println(sum)
// Output:
// 29
// 83
// 13
// 24
// 42
// 14
// 76
// 281
}

22
main.go
View File

@ -1,22 +0,0 @@
package main
import (
"bytes"
"log"
"os"
"path/filepath"
)
func main() {
input, err := os.ReadFile(filepath.Join("testdata", "input1.txt"))
if err != nil {
log.Fatalln("cannot open input file:", err)
}
result, err := Trebuchet(bytes.NewReader(input))
if err != nil {
log.Fatalln("cannot sum all calibration values:", err)
}
log.Println(result)
}

View File

@ -1,50 +0,0 @@
package main
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestTrebuchet(t *testing.T) {
t.Parallel()
for name, tc := range map[string]struct {
input string
expect uint
}{
"mixed": {input: "two1nine", expect: 29},
"edges": {input: "eightwothree", expect: 83},
"inner": {input: "abcone2threexyz", expect: 13},
"suffix": {input: "xtwone3four", expect: 24},
"numbers": {input: "4nineeightseven2", expect: 42},
"race": {input: "zoneight234", expect: 14},
"more": {input: "7pqrstsixteen", expect: 76},
"everything": {
input: "two1nine\n" +
"eightwothree\n" +
"abcone2threexyz\n" +
"xtwone3four\n" +
"4nineeightseven2\n" +
"zoneight234\n" +
"7pqrstsixteen",
expect: 281,
},
} {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
t.Parallel()
actual, err := Trebuchet(strings.NewReader(tc.input))
if err != nil {
t.Fatal(err)
}
if tc.expect != actual {
t.Errorf("want %d, got %d", tc.expect, actual)
}
})
}
}