Advent-of-Code/year25/day1.go
2025-12-06 11:32:42 +02:00

152 lines
2.8 KiB
Go

package year25
import (
"bufio"
"fmt"
"io"
"iter"
"strconv"
"git.bizdoc.ro/gabi-public/Advent-of-Code.git/aocutils"
)
func Day1Part1(ctx aocutils.Context) (any, error) {
dial := 50
solution := 0
for pair := range day1GetPairs(ctx.Body) {
dial += pair.MustValue()
dial %= 100
if dial < 0 {
dial = 100 + dial
}
if dial == 0 {
solution += 1
}
ctx.Printf("The dial is rotated %s(%d) to point at 0 `once` \n", pair, pair.MustValue())
}
return solution, nil
}
func Day1Part2Slow(ctx aocutils.Context) (any, error) {
dial := 50
solution := 0
for pair := range day1GetPairs(ctx.Body) {
nextDial, count := day1AdvanceSimulation(dial, pair.MustValue())
dial = nextDial
solution += count
if count > 0 {
ctx.Printf("The dial is rotated %s(%d) to point at %d, during this points to 0 (%d)\n", pair, pair.MustValue(), dial, count)
} else {
ctx.Printf("The dial is rotated %s(%d) to point at %d\n", pair, pair.MustValue(), dial)
}
}
return solution, nil
}
func Day1Part2Fast(ctx aocutils.Context) (any, error) {
dial := 50
solution := 0
for pair := range day1GetPairs(ctx.Body) {
value := pair.MustValue()
nextDial, count := day1Advance(dial, value)
dial = nextDial
solution += count
if count > 0 {
ctx.Printf("The dial is rotated %s(%d) to point at %d, during this points to 0 (%d)\n", pair, pair.MustValue(), dial, count)
} else {
ctx.Printf("The dial is rotated %s(%d) to point at %d\n", pair, pair.MustValue(), dial)
}
}
return solution, nil
}
func day1GetPairs(r io.Reader) iter.Seq[Day1Pair] {
return func(yield func(Day1Pair) bool) {
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
pair := Day1Pair(scanner.Text())
if !yield(pair) {
return
}
}
if err := scanner.Err(); err != nil {
panic(err)
}
}
}
type Day1Pair string
func (p Day1Pair) Value() (int, error) {
valueStr := string(p[1:])
v, err := strconv.Atoi(valueStr)
if err != nil {
return 0, fmt.Errorf("failed to convert action value to int")
}
switch p[0] {
case 'L':
return -v, nil
case 'R':
return v, nil
default:
return 0, fmt.Errorf("unknown action value %q", p[0])
}
}
func (p Day1Pair) MustValue() int {
v, err := p.Value()
if err != nil {
panic(err)
}
return v
}
func day1AdvanceSimulation(dial int, value int) (int, int) {
solution := 0
for value < 0 {
value += 1
dial -= 1
if dial == 0 {
solution += 1
}
if dial == -1 {
dial = 99
}
}
for value > 0 {
value -= 1
dial += 1
if dial == 100 {
dial = 0
solution += 1
}
}
return dial, solution
}
func day1Advance(dial, step int) (next int, count int) {
next = dial + step
count += next / 100
if count < 0 {
count = -count
}
next = next % 100
if dial != 0 && step < 0 && next <= 0 {
count += 1
}
if next < 0 {
next += 100
}
return
}