152 lines
2.8 KiB
Go
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
|
|
}
|