Compare commits

...

8 Commits

Author SHA1 Message Date
bcd7daea9e day02 2025-12-04 11:56:36 +00:00
9c2e2c68dd day04 2025-12-04 11:53:17 +00:00
Gareth
90083f28e5 Day02 2025-12-02 06:54:15 +00:00
Gareth
7f6c31c003 Day03 2025-12-03 20:03:14 +00:00
Gareth
015607cde3 Day01 2025-12-01 18:11:11 +00:00
358249e78a day1 2025-12-01 14:04:11 +00:00
d730d3c444 after pull 2025-02-14 15:16:07 +00:00
759b9c9544 work 2025-02-14 15:14:46 +00:00
68 changed files with 23180 additions and 14 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
2024
2023/*

View File

@@ -52,14 +52,54 @@ func Part1(input string) int {
return dist
}
func Part2(input string) int {
const saves int = 100
count := 0
maze := Maze{}.Parse(input)
fmt.Println(maze)
// fmt.Println(maze)
data := inputGraph(*maze)
graph := dijkstra.CreateGraph(data)
_, count := dijkstra.GetShortestPath(data.From, data.To, graph)
path, dist := dijkstra.GetShortestPath(data.From, data.To, graph)
cost := make(map[Vec]int)
cheats := []Cheat{}
for i, p := range path {
cost[Vec{p.X, p.Y}] = i
}
cheat_data := cheatGraph(*maze)
for _, s := range path[:len(path)-saves] {
fmt.Println("Checking start:", s)
for _, e := range path[saves:] {
fmt.Println("\tChecking end", e)
cheat_data_1 := cheatGraphAdd(maze, cheat_data, s)
cheat_data_2 := cheatGraphAdd(maze, cheat_data_1, e)
cheat_graph := dijkstra.CreateGraph(cheat_data_2)
_, cheat_dist := dijkstra.GetShortestPath(dijkstra.Point{X: s.X, Y: s.Y}, dijkstra.Point{X: e.X, Y: e.Y}, cheat_graph)
fmt.Println("\t\tcheat distance:", cheat_dist)
if cheat_dist <= 20 {
cheat := Cheat{start: Vec{s.X, s.Y}, end: Vec{e.X, e.Y}, cost: cost[Vec{s.X, s.Y}] + cheat_dist + dist - cost[Vec{e.X, e.Y}]}
fmt.Println("\t\tSaving cheat:", cheat)
cheats = append(cheats, cheat)
}
}
}
for _, cheat := range cheats {
save := dist - cheat.cost
// fmt.Println("[", i, "]", "save", save)
if save >= saves {
count++
}
}
return count
}
func abs(in int) int {
if in < 0 {
return in * -1
}
return in
}
func inputGraph(maze Maze) dijkstra.InputGraph {
data := dijkstra.InputGraph{}
data.From = dijkstra.Point{X: maze.start.x, Y: maze.start.y}
@@ -89,6 +129,58 @@ func inputGraph(maze Maze) dijkstra.InputGraph {
return data
}
func cheatGraph(maze Maze) dijkstra.InputGraph {
data := dijkstra.InputGraph{}
for y := 0; y < maze.height; y++ {
for x := 0; x < maze.width; x++ {
if maze.grid.Get(x, y) == CORRIDOR {
continue
}
for _, dir := range DIRECTIONS {
nx, ny := x+dir.x, y+dir.y
if nx < 0 || ny < 0 || nx >= maze.width || ny >= maze.height {
continue
}
if maze.grid.Get(nx, ny) == CORRIDOR {
continue
}
data.Graph = append(data.Graph, dijkstra.InputData{
Source: dijkstra.Point{X: x, Y: y},
Destination: dijkstra.Point{X: nx, Y: ny},
Weight: 1,
})
}
}
}
return data
}
func cheatGraphAdd(maze *Maze, in dijkstra.InputGraph, s dijkstra.Point) dijkstra.InputGraph {
x := s.X
y := s.Y
out := dijkstra.InputGraph{}
out.From = in.From
out.To = in.To
out.Graph = append([]dijkstra.InputData{}, in.Graph...)
for _, dir := range DIRECTIONS {
nx, ny := x+dir.x, y+dir.y
if nx < 0 || ny < 0 || nx >= maze.width || ny >= maze.height {
continue
}
if maze.grid.Get(nx, ny) == CORRIDOR {
continue
}
out.Graph = append(out.Graph, dijkstra.InputData{
Source: dijkstra.Point{X: x, Y: y},
Destination: dijkstra.Point{X: nx, Y: ny},
Weight: 1,
})
}
return out
}
func (m Maze) Parse(input string) *Maze {
m.grid = inputs.ToGrid2D(input, "\n", "", '?', func(c string) Cell { return Cell(c[0]) })
m.height, m.width = m.grid.SizeY(), m.grid.SizeX()

View File

@@ -26,6 +26,20 @@ func TestPart1(t *testing.T) {
}
func TestPart2(t *testing.T) {
r := Part2("")
r := Part2(`###############
#...#...#.....#
#.#.#.#.#.###.#
#S#...#.#.#...#
#######.#.#.###
#######.#.#...#
#######.#.###.#
###..E#...#...#
###.#######.###
#...###...#...#
#.#####.#.###.#
#.#...#.#.#...#
#.#.#.#.#.#.###
#...#...#...###
###############`)
require.Equal(t, 0, r)
}

181
2024/go/day21/day21.go Normal file
View File

@@ -0,0 +1,181 @@
package day21
import (
"adventofcode2024/utils"
"adventofcode2024/utils/dijkstra"
"adventofcode2024/utils/memo"
"fmt"
"math"
"strings"
)
type Pair struct {
s dijkstra.Point
d dijkstra.Point
}
type Path struct {
path []dijkstra.Point
path_str string
cost int
}
type State struct {
code string
depth int
isNumericPad bool
}
var numericPad = map[dijkstra.Point]string{
{X: 0, Y: 0}: "7", {X: 1, Y: 0}: "8", {X: 2, Y: 0}: "9",
{X: 0, Y: 1}: "4", {X: 1, Y: 1}: "5", {X: 2, Y: 1}: "6",
{X: 0, Y: 2}: "1", {X: 1, Y: 2}: "2", {X: 2, Y: 2}: "3",
{X: 1, Y: 3}: "0", {X: 2, Y: 3}: "A",
}
var directionPad = map[dijkstra.Point]string{
{X: 1, Y: 0}: "^", {X: 2, Y: 0}: "A",
{X: 0, Y: 1}: "<", {X: 1, Y: 1}: "v", {X: 2, Y: 1}: ">",
}
var directions = []dijkstra.Point{{X: 0, Y: 1}, {X: 0, Y: -1}, {X: 1, Y: 0}, {X: -1, Y: 0}}
var lookup_np = get_paths(numericPad)
var lookup_dp = get_paths(directionPad)
var m *memo.Memo
func init() {
m = memo.New(get_shortest_path)
}
func Part1(input string) int {
codes := strings.Split(input, "\n")
cost := 0
for _, code := range codes {
initialState := State{
code: code,
depth: 2,
isNumericPad: true,
}
result := m.Get(initialState).(int)
cost += result * utils.MustAtoi(code[:len(code)-1])
}
return cost
}
func Part2(input string) int {
codes := strings.Split(input, "\n")
cost := 0
for _, code := range codes {
initialState := State{
code: code,
depth: 25,
isNumericPad: true,
}
result := m.Get(initialState).(int)
cost += result * utils.MustAtoi(code[:len(code)-1])
}
return cost
}
func get_paths(in map[dijkstra.Point]string) map[Pair][]Path {
lookup := make(map[Pair][]Path)
data := dijkstra.InputGraph{}
for p := range in {
for _, dir := range directions {
np := dijkstra.Point{X: p.X + dir.X, Y: p.Y + dir.Y}
if in[np] != "" {
data.Graph = append(data.Graph, dijkstra.InputData{
Source: p,
Destination: np,
Weight: 1,
})
}
}
}
graph := dijkstra.CreateGraph(data)
for s := range in {
for d := range in {
paths, cost := dijkstra.GetAllShortestPaths(s, d, graph)
for _, path := range paths {
path_str := ""
for x := 1; x < len(path); x++ {
f := path[x-1]
t := path[x]
switch {
case f.X == t.X && f.Y < t.Y:
// Moving verticallY down
path_str += "v"
case f.X == t.X && f.Y > t.Y:
// Moving verticallY up
path_str += "^"
case f.Y == t.Y && f.X < t.X:
// Moving horizontallY right
path_str += ">"
case f.Y == t.Y && f.X > t.X:
// Moving horizontally left
path_str += "<"
default:
// No matching case or invalid input
fmt.Println("Invalid direction")
}
}
lookup[Pair{s, d}] = append(lookup[Pair{s, d}], Path{path, path_str, cost})
}
}
}
return lookup
}
func find_point(in string, lookup map[dijkstra.Point]string) dijkstra.Point {
for k, v := range lookup {
if v == in {
return k
}
}
return dijkstra.Point{}
}
func get_shortest_path(key interface{}) interface{} {
state := key.(State)
if state.depth < 0 {
return len(state.code)
}
// (Optional) If you need to modify the state, work on a copy.
newState := state
newState.code = "A" + state.code
cost := 0
for x := 0; x<len(newState.code)-1; x++ {
pps := shortest_paths(string(newState.code[x]), string(newState.code[x+1]), newState.isNumericPad)
min := math.MaxInt // Start with a very high number not just 65535
for _, pp := range pps {
nextState := State{
code: pp.path_str + "A",
depth: newState.depth - 1,
isNumericPad: false,
}
mm := m.Get(nextState).(int)
if mm < min {
min = mm
}
}
cost += min
}
return cost
}
func shortest_paths(s, d string, isNumericPad bool) []Path {
if isNumericPad {
return lookup_np[Pair{s: find_point(s, numericPad), d: find_point(d, numericPad)}]
} else {
return lookup_dp[Pair{s: find_point(s, directionPad), d: find_point(d, directionPad)}]
}
}

View File

@@ -0,0 +1,25 @@
package day21
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1(`029A
980A
179A
456A
379A`)
require.Equal(t, 126384, r)
}
func TestPart2(t *testing.T) {
r := Part2(`029A
980A
179A
456A
379A`)
require.Equal(t, 126384, r)
}

5
2024/go/day21/input.txt Normal file
View File

@@ -0,0 +1,5 @@
480A
965A
140A
341A
285A

9
2024/go/day21/tt Normal file
View File

@@ -0,0 +1,9 @@
v<A <A A >>^A v<<A>A<A>>^AvAA<^A>AvA<^A>vA^A
<vA <A A >>^A vA A <^A >A <v<A>>^AvA^A<vA>^A<v<A>^A>AAvA^A<v<A>A>^AAAvA<^A>A
v < < A > > ^ A <A>AvA<^AA>A<vAAA>^A
< A ^A>^^AvvvA
0 29A

Binary file not shown.

91
2024/go/day22/day22.go Normal file
View File

@@ -0,0 +1,91 @@
package day22
import (
"adventofcode2024/utils"
rb "adventofcode2024/utils/ringbuffer"
"strconv"
"strings"
)
func Part1(input string) int {
var secret uint
total := 0
secrets := strings.Split(input, "\n")
for _, secret_str := range secrets {
secret = uint(utils.MustAtoi(secret_str))
for i := 0; i < 2000; i++ {
secret ^= secret * 64
secret %= 16777216
secret ^= secret / 32
secret %= 16777216
secret ^= secret * 2048
secret %= 16777216
}
total += int(secret)
}
return total
}
func Part2(input string) int {
var secret uint
var banannas0, banannas1, banannas2, banannas3, banannas4 int
seq_map := make(map[string]int)
total := 0
ringBuffer := rb.NewRingBuffer[uint](5)
secrets := strings.Split(input, "\n")
for _, secret_str := range secrets {
found_map := make(map[string]bool)
secret = uint(utils.MustAtoi(secret_str))
for i := 0; i < 2000; i++ {
secret = get_next_secret(secret)
ringBuffer.Add(secret)
if ringBuffer.Len() < 5 { continue }
ring := ringBuffer.Get()
banannas0 = get_bannnas(ring[0])
banannas1 = get_bannnas(ring[1])
banannas2 = get_bannnas(ring[2])
banannas3 = get_bannnas(ring[3])
banannas4 = get_bannnas(ring[4])
map_str := diff_bannanas(banannas1, banannas0) +
diff_bannanas(banannas2, banannas1) +
diff_bannanas(banannas3, banannas2) +
diff_bannanas(banannas4, banannas3)
if _, ok := found_map[map_str]; !ok {
seq_map[map_str] += banannas4
found_map[map_str] = true
}
}
}
for _, v := range seq_map {
if v > total {
total = v
}
}
return total
}
func get_next_secret(in uint) uint {
in ^= in * 64
in %= 16777216
in ^= in / 32
in %= 16777216
in ^= in * 2048
in %= 16777216
return in
}
func get_bannnas(secret uint) int {
return int(secret) % 10
}
func diff_bannanas(a, b int) string {
ret := ""
diff := a - b
if diff >= 0 {
ret = "+" + strconv.Itoa(diff)
} else {
ret = strconv.Itoa(diff)
}
return ret
}

View File

@@ -0,0 +1,20 @@
package day22
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1("1")
require.Equal(t, 8685429, r)
}
func TestPart2(t *testing.T) {
r := Part2(`1
2
3
2024`)
require.Equal(t, 23, r)
}

2154
2024/go/day22/input.txt Normal file

File diff suppressed because it is too large Load Diff

242
2024/go/day23/day23.go Normal file
View File

@@ -0,0 +1,242 @@
package day23
import (
"fmt"
"regexp"
"sort"
"strings"
)
type Lan struct {
nodes []*Node
}
type Node struct {
key string
adjacent []*Node
loops [][]*Node
}
func Part1(input string) int {
total := 0
lan := &Lan{}
pattern := `^([a-z]{2})-([a-z]{2})$`
re := regexp.MustCompile(pattern)
lines := strings.Split(input, "\n")
for _, line := range lines {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
lan.AddNode(match[1])
lan.AddNode(match[2])
lan.AddConnection(match[1], match[2])
lan.AddConnection(match[2], match[1])
}
}
for _, node := range lan.nodes {
if node.key[0] == 't' {
connections := node.adjacent
for _, connection := range connections {
c := lan.getNode(connection.key)
for _, n1 := range c.adjacent {
for _, n2 := range connections {
if n1.key == n2.key {
already_found := false
for _, loop := range node.loops {
if contains(loop, c.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range c.loops {
if contains(loop, node.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range n2.loops {
if contains(loop, c.key) && contains(loop, node.key) {
already_found = true
break
}
}
if !already_found {
already_found = true
total++
loop := make([]*Node, 0)
loop = append(loop, node)
loop = append(loop, c)
loop = append(loop, n2)
node.loops = append(node.loops, loop)
fmt.Printf("%v,%v,%v\n", node.key, c.key, n2.key)
}
}
}
}
}
}
}
lan.Print()
t := 0
for _, node := range lan.nodes {
if node.key[0] == 't' {
t += len(node.loops)
fmt.Printf("Node: %v\n", node.key)
for _, loop := range node.loops {
for _, n := range loop {
fmt.Printf(" %v ", n.key)
}
fmt.Println()
}
}
}
fmt.Printf("Total: %d\n", t)
return total
}
func Part2(input string) int {
total := 0
lan := &Lan{}
pattern := `^([a-z]{2})-([a-z]{2})$`
re := regexp.MustCompile(pattern)
lines := strings.Split(input, "\n")
for _, line := range lines {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
lan.AddNode(match[1])
lan.AddNode(match[2])
lan.AddConnection(match[1], match[2])
lan.AddConnection(match[2], match[1])
}
}
for _, node := range lan.nodes {
connections := node.adjacent
for _, connection := range connections {
c := lan.getNode(connection.key)
for _, n1 := range c.adjacent {
for _, n2 := range connections {
if n1.key == n2.key {
already_found := false
for _, loop := range node.loops {
if contains(loop, c.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range c.loops {
if contains(loop, node.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range n2.loops {
if contains(loop, c.key) && contains(loop, node.key) {
already_found = true
break
}
}
if !already_found {
already_found = true
total++
loop := make([]*Node, 0)
loop = append(loop, node)
loop = append(loop, c)
loop = append(loop, n2)
node.loops = append(node.loops, loop)
fmt.Printf("%v,%v,%v\n", node.key, c.key, n2.key)
}
}
}
}
}
}
lan.Print()
maxLoop := 0
var maxNode *Node
for _, node := range lan.nodes {
if len(node.loops) > maxLoop {
maxLoop = len(node.loops)
maxNode = node
}
}
fmt.Printf("Max: %d\n", len(maxNode.loops))
nodeList := make([]*Node, 0)
keyList := make([]string, 0)
for _, loop := range maxNode.loops {
for _, l := range loop {
if !contains(nodeList, l.key) {
nodeList = append(nodeList, l)
keyList = append(keyList, l.key)
}
}
}
sort.Strings(keyList)
fmt.Println(strings.Join(keyList, ","))
return len(nodeList)
}
func (g *Lan) AddNode(key string) {
if !contains(g.nodes, key) {
g.nodes = append(g.nodes, &Node{key: key})
}
}
func (g *Lan) AddConnection(from, to string) {
fromNode := g.getNode(from)
toNode := g.getNode(to)
if fromNode == nil || toNode == nil {
err := fmt.Errorf("Error: Invalid edge (%v --> %v)", from, to)
fmt.Println(err.Error())
} else if contains(fromNode.adjacent, to) {
err := fmt.Errorf("Error: Existing edge (%v --> %v)", from, to)
fmt.Println(err.Error())
} else {
fromNode.adjacent = append(fromNode.adjacent, toNode)
}
}
func (g *Lan) getNode(key string) *Node {
for i, v := range g.nodes {
if v.key == key {
return g.nodes[i]
}
}
return nil
}
func (g *Lan) Print() {
for _, v := range g.nodes {
fmt.Printf("\nNode %v : ", v.key)
for _, v := range v.adjacent {
fmt.Printf(" %v ", v.key)
}
fmt.Println()
for _, loop := range v.loops {
for _, v := range loop {
if v != nil {
fmt.Printf(" %v ", v.key)
}
}
fmt.Println()
}
}
}
func contains(list []*Node, key string) bool {
for _, v := range list {
if key == v.key {
return true
}
}
return false
}

View File

@@ -0,0 +1,79 @@
package day23
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1(`kh-tc
qp-kh
de-cg
ka-co
yn-aq
qp-ub
cg-tb
vc-aq
tb-ka
wh-tc
yn-cg
kh-ub
ta-co
de-co
tc-td
tb-wq
wh-td
ta-ka
td-qp
aq-cg
wq-ub
ub-vc
de-ta
wq-aq
wq-vc
wh-yn
ka-de
kh-ta
co-tc
wh-qp
tb-vc
td-yn`)
require.Equal(t, 7, r)
}
func TestPart2(t *testing.T) {
r := Part2(`kh-tc
qp-kh
de-cg
ka-co
yn-aq
qp-ub
cg-tb
vc-aq
tb-ka
wh-tc
yn-cg
kh-ub
ta-co
de-co
tc-td
tb-wq
wh-td
ta-ka
td-qp
aq-cg
wq-ub
ub-vc
de-ta
wq-aq
wq-vc
wh-yn
ka-de
kh-ta
co-tc
wh-qp
tb-vc
td-yn`)
require.Equal(t, "co,de,ka,ta", r)
}

3380
2024/go/day23/input.txt Normal file

File diff suppressed because it is too large Load Diff

297
2024/go/day24/day24.go Normal file
View File

@@ -0,0 +1,297 @@
package day24
import (
"adventofcode2024/utils"
"fmt"
"regexp"
"sort"
"strings"
)
type Network struct {
gates []*Gate
wires []*Wire
}
type State int
const (
NA State = iota - 1
ZERO
ONE
)
type Wire struct {
name string
state State
}
type Operation int
const (
AND Operation = iota
OR
XOR
)
type Gate struct {
in [2]*Wire
out *Wire
op Operation
}
func Part1(input string) int {
network := &Network{}
network.wires = make([]*Wire, 0)
data := strings.Split(input, "\n\n")
network.AddWires(data[0])
network.AddGates(data[1])
for {
if network.OutputKnown() {
break
}
for _, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
if gate.out.state == NA && gate.in[0].state != NA && gate.in[1].state != NA {
switch gate.op {
case AND:
gate.out.state = And(gate.in[0].state, gate.in[1].state)
case OR:
gate.out.state = Or(gate.in[0].state, gate.in[1].state)
case XOR:
gate.out.state = Xor(gate.in[0].state, gate.in[1].state)
}
}
}
}
return int(network.Output())
}
func Part2(input string) int64 {
data := strings.Split(input, "\n\n")
inputs := strings.Split(data[0], "\n")
num_inputs := len(inputs) / 2
fmt.Println(num_inputs)
var x_value int64
var y_value int64
var z_value int64
y_value = 0
for i := 0; i < num_inputs; i++ {
// y_value = 1 << i
x_value = 1 << i
network := &Network{}
network.wires = make([]*Wire, 0)
network.AddWires2("x", num_inputs, x_value)
network.AddWires2("y", num_inputs, y_value)
network.AddGates(data[1])
// for i, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
// }
network.SwapOutputs("z07", "rts")
network.SwapOutputs("z12", "jpj")
network.SwapOutputs("z26", "kgj")
network.SwapOutputs("vvw", "chv")
// for i, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
// }
for {
if network.OutputKnown() {
break
}
for _, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
if gate.out.state == NA && gate.in[0].state != NA && gate.in[1].state != NA {
switch gate.op {
case AND:
gate.out.state = And(gate.in[0].state, gate.in[1].state)
case OR:
gate.out.state = Or(gate.in[0].state, gate.in[1].state)
case XOR:
gate.out.state = Xor(gate.in[0].state, gate.in[1].state)
}
}
}
}
z_value = network.Output()
if x_value + y_value != z_value {
fmt.Printf("(%d):\t x:%4d\t: y:%4d z:%4d\n", i, x_value, y_value, z_value)
}
}
ans := []string{"z07", "rts", "z12", "jpj", "z26", "kgj", "vvw", "chv"}
sort.Strings(ans)
fmt.Println(strings.Join(ans, ","))
return z_value
}
func (n *Network) AddWires(data string) {
for _, line := range strings.Split(data, "\n") {
v := strings.Split(line, ": ")
n.AddWire(&Wire{name: v[0], state: to_state(v[1])})
}
}
func (n *Network) AddWire(wire *Wire) {
n.wires = append(n.wires, wire)
}
func (n *Network) AddWires2(w string, count int, value int64) {
for x := 0; x < count; x++ {
name := fmt.Sprintf("%s%02d", w, x)
v := fmt.Sprintf("%d", (value>>x)&1)
n.AddWire(&Wire{name: name, state: to_state(v)})
}
}
func (n *Network) AddGates(data string) {
// ntg XOR fgs -> mjb
pattern := `^([a-z0-9]{3}) (AND|OR|XOR) ([a-z0-9]{3}) -> ([a-z[0-9]{3})$`
re := regexp.MustCompile(pattern)
for _, line := range strings.Split(data, "\n") {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
n.AddGate(match[1], match[2], match[3], match[4], &n.wires)
}
}
}
func (n *Network) SwapOutputs(a, b string) {
_, wire1 := to_wire(a, n.wires)
_, wire2 := to_wire(b, n.wires)
for _, gate := range n.gates {
if gate.out.name == a {
gate.out = wire2
} else if gate.out.name == b {
gate.out = wire1
}
}
}
func (n *Network) AddGate(in0, op, in1, out string, wires *[]*Wire) {
var in [2]*Wire
var outw *Wire
*wires, in[0] = to_wire(in0, *wires)
*wires, in[1] = to_wire(in1, *wires)
*wires, outw = to_wire(out, *wires)
n.gates = append(n.gates, &Gate{in: in,
op: to_operation(op),
out: outw})
}
func (n *Network) OutputKnown() bool {
for _, gate := range n.gates {
if gate.out.name[0] != 'z' {
continue
}
if gate.out.state == NA {
return false
}
}
return true
}
func (n *Network) Output() int64 {
var ret int64
ret = 0
for _, gate := range n.gates {
if gate.out.name[0] != 'z' {
continue
}
addr := utils.MustAtoi(gate.out.name[1:])
if gate.out.state == ONE {
ret += 1 << addr
}
}
return ret
}
func (n Gate) String() string {
return n.in[0].name + "(" + n.in[0].state.String() + ")\t" + n.op.String() + " " + n.in[1].name + "(" + n.in[1].state.String() + ")\t ->\t" + n.out.name + " (" + n.out.state.String() + ")"
}
func to_state(in string) State {
switch in {
case "1":
return ONE
case "0":
return ZERO
}
return NA
}
func to_operation(in string) Operation {
var val Operation
switch in {
case "AND":
val = AND
case "OR":
val = OR
case "XOR":
val = XOR
}
return val
}
func to_wire(in string, wires []*Wire) ([]*Wire, *Wire) {
for _, v := range wires {
if in == v.name {
return wires, v
}
}
wire := Wire{name: in, state: NA}
wires = append(wires, &wire)
return wires, &wire
}
func And(a, b State) State {
if a == ONE && b == ONE {
return ONE
}
return ZERO
}
func Or(a, b State) State {
if a == ONE || b == ONE {
return ONE
}
return ZERO
}
func Xor(a, b State) State {
if (a == ONE && b == ZERO) || (a == ZERO && b == ONE) {
return ONE
}
return ZERO
}
func (state State) String() string {
switch state {
case NA:
return "NA"
case ZERO:
return "0"
case ONE:
return "1"
default:
return "Invalid"
}
}
func (op Operation) String() string {
switch op {
case OR:
return "OR"
case AND:
return "AND"
case XOR:
return "XOR"
default:
return "Invalid"
}
}

View File

@@ -0,0 +1,17 @@
package day24
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1("")
require.Equal(t, 0, r)
}
func TestPart2(t *testing.T) {
r := Part2("")
require.Equal(t, 0, r)
}

313
2024/go/day24/input.txt Normal file
View File

@@ -0,0 +1,313 @@
x00: 1
x01: 0
x02: 1
x03: 1
x04: 0
x05: 0
x06: 1
x07: 1
x08: 0
x09: 1
x10: 1
x11: 1
x12: 1
x13: 0
x14: 1
x15: 1
x16: 1
x17: 1
x18: 1
x19: 1
x20: 0
x21: 1
x22: 0
x23: 1
x24: 0
x25: 1
x26: 1
x27: 1
x28: 1
x29: 0
x30: 0
x31: 1
x32: 0
x33: 1
x34: 1
x35: 0
x36: 0
x37: 1
x38: 0
x39: 1
x40: 1
x41: 1
x42: 1
x43: 0
x44: 1
y00: 1
y01: 0
y02: 0
y03: 1
y04: 1
y05: 0
y06: 0
y07: 0
y08: 0
y09: 0
y10: 0
y11: 1
y12: 0
y13: 1
y14: 0
y15: 1
y16: 1
y17: 1
y18: 1
y19: 0
y20: 0
y21: 1
y22: 1
y23: 1
y24: 1
y25: 0
y26: 0
y27: 1
y28: 1
y29: 1
y30: 1
y31: 0
y32: 0
y33: 0
y34: 1
y35: 1
y36: 1
y37: 0
y38: 1
y39: 1
y40: 1
y41: 1
y42: 0
y43: 1
y44: 1
x03 AND y03 -> htr
gwb AND kvf -> pkd
x04 AND y04 -> jjm
qcm XOR twv -> z21
rrq XOR bmp -> z44
x43 AND y43 -> pnn
x06 XOR y06 -> qmt
x26 AND y26 -> z26
y00 AND x00 -> whb
jfq XOR fbb -> z36
y33 AND x33 -> mmb
x38 AND y38 -> vqt
bbh OR qtd -> jfq
cbs AND ttb -> qtd
wqs OR cmf -> tpf
x10 AND y10 -> bfm
djp OR pfb -> qvr
x20 XOR y20 -> vhb
kkd XOR cjg -> z32
qpp XOR stg -> z41
kkd AND cjg -> mdv
tpp OR pfj -> twv
www AND qdf -> vjf
y15 XOR x15 -> hmr
mtg XOR sqm -> z09
x33 XOR y33 -> chc
x41 AND y41 -> pkj
x31 AND y31 -> cvn
x09 AND y09 -> nvw
mtg AND sqm -> chg
pkr AND kcv -> thc
x07 XOR y07 -> cds
x15 AND y15 -> fpr
mwv AND jsg -> wdw
mwv XOR jsg -> z38
y16 XOR x16 -> svs
y14 XOR x14 -> fnq
wth OR vjf -> btv
bvp AND gdb -> stc
cjb XOR rjc -> z04
x13 AND y13 -> pfb
x30 AND y30 -> qgf
htq AND rtk -> dsm
x18 XOR y18 -> kvf
y12 AND x12 -> mqn
bcj XOR bkh -> z03
x07 AND y07 -> sdj
bdf OR wbw -> qkf
y30 XOR x30 -> kbn
tpf AND vhb -> tpp
hqd OR fpr -> hgh
vfm XOR hbw -> z23
x01 AND y01 -> bdf
nvw OR chg -> vgp
x21 XOR y21 -> qcm
bwg AND mfn -> djp
dnf OR pkj -> ksp
y44 AND x44 -> gqr
y11 AND x11 -> smr
smr OR dsm -> ksn
jkm OR pkd -> rjf
thc OR sqt -> rbd
qvr XOR fnq -> z14
cjb AND rjc -> fsb
svg XOR fmt -> z31
x06 AND y06 -> ssv
dtj OR vvq -> jvp
chv XOR fqf -> z34
cvr AND hck -> pjd
dqp AND nbm -> hvv
x29 AND y29 -> vvq
y13 XOR x13 -> mfn
ksn AND nft -> z12
jjd XOR whb -> z01
chc AND rnq -> vjh
y36 AND x36 -> kfn
cwh OR vvw -> ttb
qkf AND wsv -> pqc
rdj OR kfv -> gdb
x08 AND y08 -> jrr
x02 AND y02 -> vdf
x12 XOR y12 -> nft
ptf OR jrr -> sqm
tdv OR wjp -> cjw
qvr AND fnq -> mch
x28 XOR y28 -> cfj
gtn XOR qmt -> z06
mqn OR jpj -> bwg
x36 XOR y36 -> fbb
qht OR bfm -> htq
y42 AND x42 -> mkg
ksn XOR nft -> jpj
x20 AND y20 -> pfj
cmt AND nbq -> gmc
rbd XOR knm -> z25
pvj XOR ksp -> z42
kgj OR stc -> www
tpf XOR vhb -> z20
pjd OR dsg -> mwv
cbs XOR ttb -> z35
bfk OR jvm -> gwb
ffj XOR rpg -> z17
vjr OR kwg -> pkr
pvj AND ksp -> dkc
y37 XOR x37 -> cvr
btv XOR cfj -> z28
gtq OR qgf -> fmt
nbq XOR cmt -> z39
wgq AND dqj -> tws
x24 AND y24 -> sqt
whj OR pnn -> bmp
x02 XOR y02 -> wsv
stg AND qpp -> dnf
kbn XOR jvp -> z30
y39 AND x39 -> gwq
cds AND rkv -> nph
kvf XOR gwb -> z18
mkg OR dkc -> sch
bqh XOR rjf -> z19
hck XOR cvr -> z37
jmk OR ssv -> rkv
x21 AND y21 -> cgd
pqc OR vdf -> bkh
rff OR mts -> rpg
bkh AND bcj -> rhq
bnv OR bst -> stg
bwg XOR mfn -> z13
sgt AND scc -> bnv
btv AND cfj -> tdv
svs AND hgh -> rff
hbw AND vfm -> kwg
x40 XOR y40 -> scc
y17 AND x17 -> jvm
y34 AND x34 -> chv
y35 AND x35 -> bbh
mdv OR rft -> rnq
fqf AND chv -> cwh
y28 AND x28 -> wjp
sch AND srj -> whj
htr OR rhq -> rjc
x05 XOR y05 -> dqp
cvn OR qnk -> cjg
y14 AND x14 -> tfr
y11 XOR x11 -> rtk
jfq AND fbb -> trr
ppb AND hmr -> hqd
gtb OR hvv -> gtn
y44 XOR x44 -> rrq
rtk XOR htq -> z11
x01 XOR y01 -> jjd
hmv XOR rts -> z08
y10 XOR x10 -> vpc
jvp AND kbn -> gtq
cjw AND ntj -> dtj
x22 AND y22 -> prp
ppb XOR hmr -> z15
y18 AND x18 -> jkm
x39 XOR y39 -> nbq
jjd AND whb -> wbw
x34 XOR y34 -> vvw
x19 AND y19 -> wqs
gwq OR gmc -> sgt
rbd AND knm -> rdj
srj XOR sch -> z43
y05 AND x05 -> gtb
x08 XOR y08 -> hmv
y25 AND x25 -> kfv
cgd OR jth -> dqj
vpc XOR vgp -> z10
tws OR prp -> hbw
jjm OR fsb -> nbm
wdw OR vqt -> cmt
rrq AND bmp -> cbv
rts AND hmv -> ptf
svs XOR hgh -> z16
y41 XOR x41 -> qpp
ntj XOR cjw -> z29
ffj AND rpg -> bfk
gqr OR cbv -> z45
x25 XOR y25 -> knm
chc XOR rnq -> z33
y43 XOR x43 -> srj
vgp AND vpc -> qht
x00 XOR y00 -> z00
cds XOR rkv -> rts
x24 XOR y24 -> kcv
x32 AND y32 -> rft
nbm XOR dqp -> z05
x35 XOR y35 -> cbs
mch OR tfr -> ppb
x16 AND y16 -> mts
www XOR qdf -> z27
x23 AND y23 -> vjr
x26 XOR y26 -> bvp
gtn AND qmt -> jmk
x29 XOR y29 -> ntj
y19 XOR x19 -> bqh
rjf AND bqh -> cmf
y38 XOR x38 -> jsg
x32 XOR y32 -> kkd
y03 XOR x03 -> bcj
y31 XOR x31 -> svg
y22 XOR x22 -> wgq
qkf XOR wsv -> z02
bvp XOR gdb -> kgj
x04 XOR y04 -> cjb
x17 XOR y17 -> ffj
y37 AND x37 -> dsg
y27 AND x27 -> wth
y23 XOR x23 -> vfm
sgt XOR scc -> z40
mmb OR vjh -> fqf
qcm AND twv -> jth
y09 XOR x09 -> mtg
sdj OR nph -> z07
wgq XOR dqj -> z22
trr OR kfn -> hck
y27 XOR x27 -> qdf
kcv XOR pkr -> z24
x42 XOR y42 -> pvj
x40 AND y40 -> bst
svg AND fmt -> qnk

76
2024/go/day25/day25.go Normal file
View File

@@ -0,0 +1,76 @@
package day25
import (
"fmt"
"strings"
"math"
)
type Lock struct {
diagram string
combination int
}
type Key struct {
diagram string
combination int
}
type Pair struct {
l Lock
k Key
}
func Part1(input string) int {
data := strings.Split(input, "\n\n")
locks := make([]Lock, 0)
keys := make([]Key, 0)
pairs := make([]Pair, 0)
for _, in := range data {
if in[0] == '#' {
locks = append(locks, Lock{diagram: in, combination: combination(in, '.') })
} else {
keys = append(keys, Key{diagram: in, combination: combination(in, '#')})
}
}
for _, l := range locks {
for _, k := range keys {
if key_fits(l.combination, k.combination) {
pairs = append(pairs, Pair{l: l, k: k})
}
}
}
fmt.Printf("locks: %d, keys: %d\n", len(locks), len(keys))
fmt.Printf("pair0 lock\n%s\n%d\n", pairs[0].l.diagram , pairs[0].l.combination)
fmt.Printf("pair0 key\n%s\n%d\n",pairs[0].k.diagram, pairs[0].k.combination)
return len(pairs)
}
func Part2(input string) int {
return 0
}
func combination(d string, k rune) int {
comb := 0
rows := strings.Split(d, "\n")
columns := len(rows[0])
for _, r := range rows {
for i, c := range r {
if c == k {
comb += 1 * int(math.Pow10(columns - i - 1))
}
}
}
return comb
}
func key_fits(l int, k int) bool {
for i:=1;i<6;i++ {
ll := l % int(math.Pow10(i))
kk := k % int(math.Pow10(i))
if ll < kk { return false }
}
return true
}

View File

@@ -0,0 +1,24 @@
package day25
import (
"log"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
data, err := os.ReadFile("input.txt")
if err != nil {
log.Fatalf("failed to read file: %s", err)
}
r := Part1(string(data))
require.Equal(t, 0, r)
}
func TestPart2(t *testing.T) {
r := Part2("")
require.Equal(t, 0, r)
}

3999
2024/go/day25/input.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,14 @@
module adventofcode2024
go 1.19
go 1.23.2
toolchain go1.23.5
require (
github.com/deckarep/golang-set/v2 v2.7.0
github.com/luxedo/esb_fireplace-go v0.3.0
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
)
require github.com/spf13/pflag v1.0.5 // indirect
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect

View File

@@ -2,12 +2,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set/v2 v2.7.0 h1:gIloKvD7yH2oip4VLhsv3JyLLFnC0Y2mlusgcvJYW5k=
github.com/deckarep/golang-set/v2 v2.7.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/luxedo/esb_fireplace-go v0.3.0 h1:zhpWG9AJfWEzqiaYsPjlBAwIMa1IF1gWoQoM4zvdLxI=
github.com/luxedo/esb_fireplace-go v0.3.0/go.mod h1:L8zIvYDHIKTHc3g3VACvjS0qBHvKmt31KRjWLP5ftkU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=

View File

@@ -26,6 +26,11 @@ import (
"adventofcode2024/day17"
"adventofcode2024/day18"
"adventofcode2024/day19"
"adventofcode2024/day21"
"adventofcode2024/day22"
"adventofcode2024/day23"
"adventofcode2024/day24"
"adventofcode2024/day25"
"adventofcode2024/utils"
)
@@ -90,6 +95,21 @@ func main() {
case 19:
fmt.Printf("part 1: %d\n", day19.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day19.Part2(utils.Readfile(d)))
case 21:
fmt.Printf("part 1: %d\n", day21.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day21.Part2(utils.Readfile(d)))
case 22:
fmt.Printf("part 1: %d\n", day22.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day22.Part2(utils.Readfile(d)))
case 23:
fmt.Printf("part 1: %d\n", day23.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day23.Part2(utils.Readfile(d)))
case 24:
fmt.Printf("part 1: %d\n", day24.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day24.Part2(utils.Readfile(d)))
case 25:
fmt.Printf("part 1: %d\n", day25.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day25.Part2(utils.Readfile(d)))
default:
panic(fmt.Errorf("no such day: %d", d))
}
@@ -99,7 +119,7 @@ func main() {
// Reads day from os.Args.
func day() int {
latest := 19
latest := 24
if len(os.Args) == 1 {
return latest
}

View File

@@ -1,7 +1,6 @@
package dijkstra
import (
"fmt"
"math"
"sync"
)
@@ -92,7 +91,7 @@ func getShortestPath(startNode *Node, endNode *Node, g *ItemGraph) ([]Point, int
pathval = prev[pathval]
}
finalArr = append(finalArr, pathval)
fmt.Println(finalArr)
// fmt.Println(finalArr)
for i, j := 0, len(finalArr)-1; i < j; i, j = i+1, j-1 {
finalArr[i], finalArr[j] = finalArr[j], finalArr[i]
}

View File

@@ -0,0 +1,47 @@
package memo
import "sync"
type Func func(key interface{}) interface{}
type result struct {
value interface{}
}
type Memo struct {
f Func
cache map[interface{}]result
mu sync.RWMutex // Allows concurrent reads.
}
func New(f Func) *Memo {
return &Memo{
f: f,
cache: make(map[interface{}]result),
}
}
func (memo *Memo) Get(key interface{}) interface{} {
// First, try to read the cache using a read lock.
memo.mu.RLock()
res, ok := memo.cache[key]
memo.mu.RUnlock()
if ok {
return res.value
}
// Compute the result without holding the lock.
computed := memo.f(key)
// Now acquire a write lock to update the cache.
memo.mu.Lock()
// Double-check: another goroutine may have stored the result in the meantime.
res, ok = memo.cache[key]
if !ok {
res.value = computed
memo.cache[key] = res
}
memo.mu.Unlock()
return res.value
}

View File

@@ -0,0 +1,56 @@
package ringbuffer
import (
"sync"
)
type RingBuffer[T any] struct {
buffer []T
size int
mu sync.Mutex
write int
count int
}
// NewRingBuffer creates a new ring buffer with a fixed size.
func NewRingBuffer[T any](size int) *RingBuffer[T] {
return &RingBuffer[T]{
buffer: make([]T, size),
size: size,
}
}
// Add inserts a new element into the buffer, overwriting the oldest if full.
func (rb *RingBuffer[T]) Add(value T) {
rb.mu.Lock()
defer rb.mu.Unlock()
rb.buffer[rb.write] = value
rb.write = (rb.write + 1) % rb.size
if rb.count < rb.size {
rb.count++
}
}
// Get returns the contents of the buffer in FIFO order.
func (rb *RingBuffer[T]) Get() []T {
rb.mu.Lock()
defer rb.mu.Unlock()
result := make([]T, 0, rb.count)
for i := 0; i < rb.count; i++ {
index := (rb.write + rb.size - rb.count + i) % rb.size
result = append(result, rb.buffer[index])
}
return result
}
// Len returns the current number of elements in the buffer.
func (rb *RingBuffer[T]) Len() int {
rb.mu.Lock()
defer rb.mu.Unlock()
return rb.count
}

View File

@@ -0,0 +1,64 @@
package day01
import (
"strconv"
"strings"
)
func Part1(input string) int {
lines := strings.Split(input, "\n")
position := 50
output := 0
for _, line := range lines {
direction := line[0]
amount, _ := strconv.Atoi(line[1:])
if direction == 'R' {
position += amount
for position > 99 {
position -= 100
}
} else if direction == 'L' {
position -= amount
for position < 0 {
position += 100
}
}
if position == 0 {
output++
}
}
return output
}
func Part2(input string) int {
lines := strings.Split(input, "\n")
position := 50
output := 0
for _, line := range lines {
direction := line[0]
amount, _ := strconv.Atoi(line[1:])
step := 1
if direction == 'L' {
step = -1
}
for i := 0; i < amount; i++ {
position = (position + step) % 100
if position < 0 {
position += 100
}
if position == 0 {
output++
}
}
}
return output
}

View File

@@ -0,0 +1,35 @@
package day01
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPart1(t *testing.T) {
r := Part1(`L68
L30
R48
L5
R60
L55
L1
L99
R14
L82`)
assert.Equal(t, 3, r)
}
func TestPart2(t *testing.T) {
r := Part2(`L68
L30
R48
L5
R60
L55
L1
L99
R14
L82`)
assert.Equal(t, 6, r)
}

4059
2025/gareth/day01/input.txt Normal file

File diff suppressed because it is too large Load Diff

49
2025/gareth/day01/poc.py Normal file
View File

@@ -0,0 +1,49 @@
def part1(input_file):
file = open(input_file, "r")
line = file.readline()
position = 50
output = 0
while line:
direction = line[0]
amount = int(line[1:])
if direction == "R":
position += amount
while position > 99:
position -= 100
elif direction == "L":
position -= amount
while position < 0:
position += 100
if position == 0:
output += 1
line = file.readline()
file.close()
print("Part 1:", output)
def part2(input_file):
position = 50
output = 0
with open(input_file) as file:
for line in file:
line = line.strip()
direction = line[0]
amount = int(line[1:])
step = 1 if direction == "R" else -1
for _ in range(amount):
position = (position + step) % 100
if position == 0:
output += 1
print("Part 2:", output)
part1("input.txt")
part2("input.txt")

119
2025/gareth/day02/day02.go Normal file
View File

@@ -0,0 +1,119 @@
package day02
import (
"math"
"strconv"
"strings"
)
// Very messy and not my finest work but not too bad for 6am
func parseInput(input string) [][2]int {
var ranges [][2]int
lines := strings.Split(strings.TrimSpace(input), ",")
for _, part := range lines {
if part == "" {
continue
}
ab := strings.Split(part, "-")
if len(ab) != 2 {
continue
}
a, _ := strconv.Atoi(ab[0])
b, _ := strconv.Atoi(ab[1])
ranges = append(ranges, [2]int{a, b})
}
return ranges
}
func divisors(n int) []int {
out := make([]int, 0)
for i := 1; i <= n; i++ {
if n%i == 0 {
out = append(out, i)
}
}
return out
}
func Part1(input string) int {
ranges := parseInput(input)
invalidSum := 0
for _, r := range ranges {
low, high := r[0], r[1]
minLen := len(strconv.Itoa(low))
maxLen := len(strconv.Itoa(high))
for digits := minLen; digits <= maxLen; digits++ {
if digits%2 != 0 {
continue
}
half := digits / 2
start := int(math.Pow(10, float64(half-1)))
end := int(math.Pow(10, float64(half)))
for first := start; first < end; first++ {
s := strconv.Itoa(first)
selected, _ := strconv.Atoi(s + s)
if selected < low {
continue
}
if selected > high {
break
}
invalidSum += selected
}
}
}
return invalidSum
}
func Part2(input string) int {
ranges := parseInput(input)
total := 0
for _, r := range ranges {
low, high := r[0], r[1]
seen := make(map[int]bool)
minLen := len(strconv.Itoa(low))
maxLen := len(strconv.Itoa(high))
for d := minLen; d <= maxLen; d++ {
for _, L := range divisors(d) {
k := d / L
if k < 2 {
continue
}
start := int(math.Pow(10, float64(L-1)))
end := int(math.Pow(10, float64(L)))
for base := start; base < end; base++ {
s := strings.Repeat(strconv.Itoa(base), k)
selected, _ := strconv.Atoi(s)
if selected < low {
continue
}
if selected > high {
break
}
if !seen[selected] {
seen[selected] = true
total += selected
}
}
}
}
}
return total
}

View File

@@ -0,0 +1,17 @@
package day02
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPart1(t *testing.T) {
r := Part1(`11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124`)
assert.Equal(t, 1227775554, r)
}
func TestPart2(t *testing.T) {
r := Part2(`11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124`)
assert.Equal(t, 4174379265, r)
}

View File

@@ -0,0 +1 @@
78847-119454,636-933,7143759788-7143793713,9960235-10043487,44480-68595,23468-43311,89-123,785189-1014654,3829443354-3829647366,647009-692765,2-20,30-42,120909-197026,5477469-5677783,9191900808-9191943802,1045643-1169377,46347154-46441299,2349460-2379599,719196-779497,483556-641804,265244-450847,210541-230207,195-275,75702340-75883143,58-84,2152-3237,3367-5895,1552-2029,9575-13844,6048-8966,419388311-419470147,936-1409,9292901468-9292987321

View File

@@ -0,0 +1,200 @@
3238233422322723245312524333415334121333413432322532233243267325442232433333224143383436222223233233
3655644666946277273684457436668666955664663983765757454464876854654654857865665766676664954456576457
2222222214221321222242232252322221422222222212122123221322623222234222422221122212282121422123326322
2124214643322332212222134232222223323244234222412424222132142344221221232224211124244142332242234423
3436232236223426333625431396643366362565194162563644533454346253234235616323362232354352264323633232
5222522242424132416252524213114222342315134433221233322222231246224242332433133211133213224152222532
5426122223223222711223433222337222332222222833232224339146332213332173223213812332213383222132234312
6754666344575335444575875747453663683596555517664555664546484534645635645553474345756556566654566656
5433475435554344344375445374544445355635555544744477536637334335232664335527685544454753243246465444
2533323723332334421324325274334254525431339343344558454433386313383333342332322853233331232763541433
3434243341345332224133423322532152471432322626222426413335421225224211233163443935254725234333133342
3541448771235152323243338633424215242426556266442614844233795554292323321243648444233424278324436324
4232241923231442232233522224233222222232431222432321223233222123223234123233322133322222222322224341
2322413333333323433423333323333431233331323233463333343333223323333323333323323333333332354333332133
2212425414842355412223552127242426224852234212232212232222255523322321224232222232323222235222434633
2222323222221122221215238122312222122214221322215512242233212223122222232412233122321222222271322222
5215532261853227652345746126415532422366821723536247423754252265364642376432522655527226425574722471
3222222422252332112231224221356222221223222134222221232223313326222222131432222522333222223122622222
6676222427665466767653734672313657732795538736586768869694693597677586674659542276554762257672793343
3653535256345253634345457434518545543444445544575534454455644555557475445545334555545353535563446555
2233222222323144222222444222122411422321222212315431213323242223222222242233222224322232221212242531
3424593117244244313425222742513498752244424152632323419112114524386212455225243275425565524227362317
5531424542533424455635625443656442662633435324445245422523346364263544533554433452426246313433372514
2522967564465922868445536669545363547885536537774684644666145884654894493744892656428549864924265585
8736457373466777928237878853455465677654727936757338659679873668786246374673877537787726887267376752
2962633343332244174633334533659659344458746512754522225623134372535234242564234635563533366423245423
5534345333543743355425442536744453254445333225545543535344457451545632594543356384535385568433456583
1222242782342223422232152131532242432823342274223223333234321212231233434122949312531515162212332222
3434444332724222433423222345344859344234434244424222439432433414116164422214232344446376442441344422
1222131622223342163222227222122143223242122222121212232322222226112222222221222222222252212222224251
4262513533352222332233331225332231334153323333343383333133232834422433332433333343231743131343623232
2555454275557549374368453564565154525643271535272434413352635365473535263236544335364434615263242555
2132223355322342221432325223133355343253533434522435535322233332423232323244152221532243233455233213
4333343123322333234342333333323333322322324231321332212223322333332323234332221332323311243233133313
2332233333222334222442235222225322232322253234322231453222232241223133221323632233412254332224124244
3441632222323232421248242763264244122234632343422122214222322222244421122442226222412431417242323342
2343221313234232624432424245315522424236224523135333322124222312233232412231324422232221244343433431
3343222224333332146373333536133223346235344317253322382322262522232642222242324443332123216233333336
2322312242313222417322222222222216232212214122221242233233243122243212322223222232222221852212222312
2223223341233323322432232212233323331231233213322232233322231334742823233312233134243223333133122813
3228334576353333562327554733771334232485374333433542631274235374544691334331347733234373357337725333
3454244353353733542724475534227534446346833483535544236532367313365345453652244346263533435345913544
2246211242428262951721221182321231224644212222142422283351232222221262176382312228292322229224212222
6431432336442565163354443334452545623333245524212534544624222324342356231541294462352313344454212354
2252117225531222122221132222211222212222142223318712222127262222211222122422322212222242922222231312
1123144213142231424531224423714253222543235421344223222121252523232422211142423222321624314221344422
5232224422123225232122225112224241222222223215252312222321153231322223323222245523253328123222222551
3621232222112263122322246123222323222222512232221321432423223272222142328132212121222121722217621221
2214222412122212232321333262225222332232232227222242222222335335222223332222262222223532514222121223
2444741342314432395654242442245546624556344421445142212345263223224343343424334485233344552235344253
3333463433354333837333621424322336535344233323423838531653453683332523962234334133224526144314536364
5233451445357625537562657759256372535254626263575665372569645126455436743347439353353254435432874561
3663386342525234673448454446432334344423338533332433256344673633766354323333234733666733443363156993
4646264122632272152731226385422122232389226213253536722212342532472422734255623435243713254142122416
3324315533434373442757634653443532352441324226346363223259263334634127442224334414533372361535353625
3123247753461326484274222842132361327344636382448381324233242757236332232212231414124233233873435132
3233343222325533333253333344532433545334343153543345332342242432335532543365242334353225242142246234
2233122341331332425544342454212321223425213335322342532322111224221332254222245232433433337242232311
3634366254544744542544545363644446633443454444433454343444445442535455234542947463224644445635444433
3633332723672391314313438632262276312226266642352226633983253547635125722222233222322926322577322232
3349532424243225533432226342412622222355454427424444422423223514522514554332136332333124532332242453
3322652426343223283633633453326532426128221533638567312453331214352342234233823343233331348433483233
3263222324513843332311751222421122234213332433332233432222452233322223233232231222314232122413333346
3324424543235445343532636425243343353347322733541434155245334643241125223435453448654645267683332472
4234523123332252462334421551311512252533524623636312441222334223323142422752276162215723345522233424
3453355424333343224433334444322836743342424333464334424342244444532744223434353439324346343134345443
5232225334455644395443426443453336424533442322134345525242534235325326232332254333459253214434432564
4323344383331322442312221213433424324423315127366323232352236343344337114672432324332542133443313334
1764276943738333483449376253345367364323233372359752443954437338534536336432543736348373352783333548
2332239223223854323335331223333383313233221523333228336232341351833392228333813353333132432338233323
4583591334525833233466252342338345436334284343934424328652553552334233137558828333333482323533333745
4233444624654525435643568366547136244562544465423332263526257467634235533338336334454535625566363266
7152548554343414554436353216685221244535423895629554685556276432315645347364425558275323214283253454
2421264125122232322422263243242143322542832641422542623222222234312242112672321232211432331256525423
3452151314152322833231342345322332321332325731334515333322253125224452542121222641233122412326723521
3223333523324343142123232222312322343214453442342321232244232232313424324242452234313221443212322314
5455335555555244444343434356464535433565522544555544533435444535455454563751494555455525542312553642
2532323522123514123223222362334223243315331623312522222332232566327213321322236133323352321232252211
2223328233439225525461513372563325152332242222423331327722331422417422244522425251452226185433552133
2222361253434322222324326322322573223432333333736363133233122352132233332333641323133312322223133132
1226344252613414224222243423523423232134321332276321322234142322432427224252624232424332525226523222
2252321212212225132232214262243322222521132222232122111222321221221222232242522121229221222412222222
3112422332212244222132422321223121113323132223285222231111222324432262344212322223243222211223223232
3223833132233332453422423333764133253133323332252225266362252326131253337333351413333314522222314332
5223423222232512422633522223243143252433355433435243152432332224244352243415222332312334453521223332
2333122244233465315224221212321234353232323336532422482322333112522422323624153222632331534322232224
3231222242442232122232443314242222442223251242432222424122251512222442323524422422432242342313223344
5644414434454344454443543383452425354534344244343858446444355554238543437342544643643345631355464355
1232222332222332243322212212424322232323321323212223322232332131331332313225133332222342532512334323
1125422227334692563222364233231324222323356241222463222274411354445223323221223523423337388626432965
6225122321122223211424222214222712222242242222422243222222132211223222223421223334611222222122222222
3645564444551544255548255454537635664556558585153955773356653554496365547554555454555423535344655555
1343221246323622245222234442432224253426267241221242242442444262472422221321232744752242322632314632
3232555333332354435335362634135123343356244234263316444276362432623333533533641533565535443255432634
3335333333133123333233353233233353333323334252334332323443323335333332333333433332331334233224542352
4676333533566746975628576749784694456766435483543573628547353567434736535766335667475674437754646756
2242712275422321222222123312422224243221212214222221434231315221232112222222121224712222242123322211
5232222113532224143221226251323324512122432423115322423221213222421232352654122252222432221522211221
2324326227332323323532862322424313121233432131332213321223233253423222283334252232219222461333123233
4638233763365656447356534356533563586353256748731467735514376457957325763695463546863356585443543874
4341223424434414544235445342328633543233443454413422444432343354433212242334262372215412124162174444
2326422519242433234222212432229723223323222322272642222323224241222452132242233142323222326431213229
2223326632213632543326153452322572226456223517446532123552312254533353514633325153244532252125332415
2548666542777567464423266492454544354454661745445344433867825595845487556474674534981345944556448496
3655836499753458447557343546944375655847554565459678854745985557565559545786564587863495674374558454
3272131532423362122223222322224622212282353323224321341281632222222528127232143262222222222262122122
2323222636483639363543233522326412713366693834623222221262373242138544415536224232523552252434745421
4576436326433332514343177135333415334462323434333633364617529635433436471434343574323543333534243333
7673924444565367226382625746534735668736376676725229766887388769486869648253727666686455732798673765
3242233522822433682823442441234512251142431642222244224352242172253256326332562448225246152424652223
2212212132222222228121133322232212222122222222422222212221222232221222221222222222311232212221222232
6466366554766673666845986646655556565666566546466763676654556666655756658655845534676566554257656666
2524152234153624656232213316273225622342332147241252323725113232215222426521213342223232333354222368
2223221222112512241122625222211322222213223222222222222312212222222121222142222211221222324322352222
1142652163542323322533543552241232222544345356425364346176325632225132253835472375562224422524325536
5392386646332728446732822143641788824676122643322647637183734251272163248735585358825328124247257556
2222323133232232223222212232113633222222221633222212334222224332422243113332212522132322222122312231
8683886678883624393276865368669575448493288727667228697234668168889838956386424374723775752657959836
3533425634665614423437735633756435366347744722543444677523242286463445344134345754464253774437421336
4463354424463534587843748445543473465646734545484353344345448664673433546735755553462345543244443443
3333494444324354464344753344444434442642424441645245754424433343613243676696454445443236434745474443
3334332433325432333124543334533333323553326334334483343323625345363333533333333333343453253342355266
1432236233423212223212242223121222252252212312221212762122212232322212323242235322211432422222224322
3333256463413233344333333312633332333325453422324333392463463322433225353231334433353243323444333333
7736237745293832739263726338732559784369673833547354558664757444786583187833223136867423585569516866
1131142332334142214421311222143312133214121223313231113442421334232144444222434113313432133424156789
3232124235342282623122252222373334433336322328113723262283353333823268352326382427242736332935222631
4468556567768676565885994797565466448385756746485674257645947658644358697757959999496265554795754628
2575245654587756544544555344325445444253846472736554654944456444532452574557457754455533455716351349
1449228731625783546145322282376767945223354784761591623444944679322296782334427733195467724784774276
2423643333337342333443333443333223333223346534343343634333534463723344313232423443333333243444143325
3335433461436335223245436411433353533346463835374345434473722236532435335542455353323333377788217332
2333423523644253232534232641334254632223332955423322342335543262329423753433432543282382132331333323
3244233433334443424441433434444534331244434432333323433414343334243433333434423224334334332434333433
6362712672268282283761924427141563687696283521585244925674622472623724287874234626273255264425238433
5328341233214483581323225524443336235432243422416445223334234212623234324243622412332523332443531452
3637386345347745474463377423675454654368458535577555336134534368354335444343774333474342353954334455
4434644244265424543324753622464334553552134445344662544355363441242264543543344425444645544434464446
3223212233353232233322333339364223224354221333223233543242213332331222243424322213322133134332333331
3153332553335544459766263375645636357666454552552332634752646655261553677536455646676626535362454335
5473534221354325227446257652544438222494273862536522244571444476228542225343361292447541154453339474
2221224222412325222534221221431233522264323422233352422222231322244442232223232225423242263232552343
5332427364273242312934243526733672664424442218537634449366534313935634536814632433225563842264427242
6235266277265342456137175322124157375434143165657145451146775315575231444663125462654744375531134289
3421222675734234317233291215315253432642242377222257341342223228582427172712135272254627136261223634
5433432112325134322333333233212322113333132322243423344352242233413143221311322442322313241245332221
3423734435853334374537836333333333317433352683453443353785482319323532251323373393833533838862838333
5657323833536351353333363782336373322831333642333243533331333328332333353233285222557336315323313364
2442519326432623532344727393285833347123418565397636331334347245722384632864525658762677744314646333
4125132521333231232235325331322342325622223234122792354213323311343523232323513253493324352496461423
3362421473222221213315222122344245222332224252326272222233232223321122235226142321223231326313224262
3732354133363432432423713233832433328234144313334323734464244363423672452673398233733263233338332332
3767773886665564214526315412774737756177467576263358827536626878161412332417831532815537625153423729
5521353234533542595546884224253243311325323554357328942323262343928222538322263522364222442233333513
2122322414223533222473242424222413224345321522325224322233424513224423322265123243112323352122333232
7483463487356554736635846165545667958374844736734327464437954584362574727377684673345568765357378597
2223232322112222262322322222223231422232232138221132212222221222213211221422223221321122111312126322
3366233325237424446412434433264222422124255734432634244335324412245234313132252455237262464232345253
4632413335342647253154534151123228132631386328422413224472722724124342692236632614222343373223423233
3342342323422353444442211123321342434233724244422661444243432722422232322335141331341534432231731331
7432225572522677423322272674452522724824325224215725322516323534252222823224553583222223552526274681
6564655556755655663744565365543666448665653225365335532354433635744424842635386541465356658353534585
1131244223511213433154353112523334432223215444342241233422145422553442224323331354313244212522426789
1111213122221322123222222222522212147228223621223212221222292312212231212121222222212231211222522222
2231621272211225174214132224132343252231425544532282456435473144273127234233623632443512324484121493
2121243212342132322231232321322151244424133442362222324422232121424122332112222233313421412322213232
2165314643441353632241614323463656325426665666531632561352152353513121235251663454652635354134356789
2475231214243222622422128232222142342334542525221442122264428122222445212442812222331313922242222331
3223323354333323234372444242373463821436122221823232432533533332344446513142323333541222341244217455
7455526631444542356445533352351453423842653536563363453344445222432533133425443346642463393231542655
8653953554777855947635356623955473553347535456542373216442635855766435335778333435863355534534696334
2123313323533233522234325253134223134342463263454131142213134333334342242414333242344253333223253576
4433351364335323163334323233734633344234343533524223331454334134343345333444333552324335333343135322
2676247333884956267277436553754385673228458733632722367132455754724742672592656787535922265428847452
5323342343344336454433333263423311328341322515255533364322646234565644344713216323855642632233565373
1133221326942423244343323212222522121122242234221225552555243122222312226242322423242232122444161112
5745757585647764645595455547777555574756775757484475665467555762654756556574765346685567548956663759
4571321513255225214645223224114322318122222133446333321233692233524333646292412121393432285264282222
3315332122322222252323332342321332263332143133412214123234344222242232422421243212314333132222424435
3712452322745236234223432424523225472154354252623312322322292124423152214233272422452233312342222123
2122122322222323222222212212222222332221213623222211262522221222212222212222121122224222222222111221
3878463445456594343447696625474456434384664578488543373834987437558867455385835783452453584558746285
8227231432234323326226222222223372233534224124232221133433311232252143422323253144252323242443131223
3132233422232215222221112223612232536153612126257222232312223242621262223332122326225212331248125352
8899389687567746688684992465866799836886577885757998968855448995658978853857785665776749875746666754
6475176885462947335537363373673946483735476343335337376275334622583395356234523457624566667937332358
5224457327442414324723564554424233627423444241443524344435827527429432834214343559324444555454761422
4345325324355364334338464343241431247363234433363424532466863333432433643343475452322533364254343431
5625893313532515654777281766549484453214439528733524862827285532721155253735432342894254445442515426
2122223322323322233323333223313252222332324223123133413222233233323314213333222523332334223636232232
3566454444795375834465668434645852632845467948764654464536444457635457666446253333457744448568467955
3332274361452133542353243425423322231353344222151231312224534225344533323512113225552346234224515122
3354332242433513337253337122133125323366332332223232244315522724231444323232633334123733113142742332
1623223222222531261632222222222122122132143453212312262623222212222522112122223723222232225514326145
5436354633654663574759344344656465454835454465474656557565544645346443956474444444954284444443734465
5429583223625147865243782836886657435836657243263351643255252433652481223336266125523653422527977354
3333221212323232323322224222224222232323233222233232212223322232232123122323222323323123233242273222
2312322223223323122223323243322233333123322224331223133421423222331223343245423333234322422321233322
5526855555441556453553354355557545724544436564664664877456643366453637585245747634666665454447345764
2231312322221222122222221343522122112222225222123221221221221232222222242231112122222221221121222311

View File

@@ -0,0 +1,200 @@
886223233233
999956576457
842223326322
644444444444
996666666663
664452222532
988332234312
987766666666
875446465444
988887654433
975433333342
998834436324
954444334341
654333332133
885555544633
855471322222
887777777471
665333622222
999999793343
877763446555
544443342531
999877362317
666666672514
999999996585
999988888887
999877766666
988843456583
996222332222
997644444442
765222224251
887443623232
987776666655
555555555555
444444433333
654334124244
877242323342
665544444444
866633333336
852212222312
844333333813
977777725333
887666913544
999224212222
965454212354
922222231312
764422344422
823222222551
872227621221
765542222223
985555344253
966444536364
999555874561
888777766993
977775442416
977655353625
888888745132
655544246234
557242232311
976665444433
999677322232
976533342453
888884483233
875544333346
867683332472
777552233424
964334345443
995444432564
877754443334
999988833548
998858233323
998888853745
886666363266
998883253454
874356525423
876446723521
555444332314
955555555642
765332252211
985433552133
776664333333
776556523222
922412222222
864443323232
877552314332
655555555553
866543232224
555544444444
888876666455
553512334323
988626432965
762222222222
997555655555
777763314632
766666555634
555554542352
999887777777
777423322211
665552221221
961333123233
998854543874
875462174444
997766433229
776655555415
999956448496
999999978454
888766222122
998865745421
977554243333
999998673765
888865652223
843332222232
988877656666
777655422368
654432352222
877654325536
988888888888
665332312231
999999959836
877747421336
888887776554
996745474443
866555455266
765442224322
966555444433
999989516866
444444456789
888935222631
999999999999
977777651349
999999987776
774444444445
877788217332
998833333333
544444444444
999887768433
888666655452
888954334455
766666666446
965544444433
977777776666
997555339474
663232552343
999886447242
777777777789
988777776664
555445332221
998888838333
888887653364
999888777766
995496461423
776633224262
987638332332
888888887729
999886644513
765522333232
998887778597
843332126322
777664345253
973223423233
775544731331
888556274681
888853534585
555555556789
933322522222
877784121493
644444433232
666666666789
922242222331
886554447455
903231542655
999888696334
665533353576
765555555532
999658847452
886633565373
964444461112
988956663759
999864282222
644444444445
975342222123
665422222222
999888888888
877555544433
766658125352
999999999999
999937332358
995555761422
887654343431
999955515426
554636232232
998868467955
766424515122
777742742332
735514326145
999844734465
988888977354
443342273222
544432233322
888777345764
554322222311

View File

@@ -0,0 +1,69 @@
package day03
import (
"strconv"
"strings"
)
func Part1(input string) int {
lines := strings.Split(input, "\n")
output := 0
for _, bank := range lines {
best := 0
length := len(bank)
for i := 0; i < length; i++ {
tens, _ := strconv.Atoi(string(bank[i]))
for j := i + 1; j < length; j++ {
ones, _ := strconv.Atoi(string(bank[j]))
value := tens*10 + ones
if value > best {
best = value
}
}
}
output += best
}
return output
}
func Part2(input string) int {
lines := strings.Split(strings.TrimSpace(input), "\n")
total := 0
k := 12
for _, bank := range lines {
bank = strings.TrimSpace(bank)
n := len(bank)
start := 0
chosen := make([]byte, 0, k)
for picked := 0; picked < k; picked++ {
// leave enough digits to complete the subsequence
last := n - (k - picked)
bestChar := bank[start]
bestIdx := start
for i := start + 1; i <= last; i++ {
if bank[i] > bestChar {
bestChar = bank[i]
bestIdx = i
if bestChar == '9' {
break
}
}
}
chosen = append(chosen, bestChar)
start = bestIdx + 1
}
val, _ := strconv.Atoi(string(chosen))
total += val
}
return total
}

View File

@@ -0,0 +1,23 @@
package day03
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPart1(t *testing.T) {
r := Part1(`987654321111111
811111111111119
234234234234278
818181911112111`)
assert.Equal(t, 357, r)
}
func TestPart2(t *testing.T) {
r := Part2(`987654321111111
811111111111119
234234234234278
818181911112111`)
assert.Equal(t, 3121910778619, r)
}

View File

@@ -0,0 +1,200 @@
886223233233
999956576457
842223326322
644444444444
996666666663
664452222532
988332234312
987766666666
875446465444
988887654433
975433333342
998834436324
954444334341
654333332133
885555544633
855471322222
887777777471
665333622222
999999793343
877763446555
544443342531
999877362317
666666672514
999999996585
999988888887
999877766666
988843456583
996222332222
997644444442
765222224251
887443623232
987776666655
555555555555
444444433333
654334124244
877242323342
665544444444
866633333336
852212222312
844333333813
977777725333
887666913544
999224212222
965454212354
922222231312
764422344422
823222222551
872227621221
765542222223
985555344253
966444536364
999555874561
888777766993
977775442416
977655353625
888888745132
655544246234
557242232311
976665444433
999677322232
976533342453
888884483233
875544333346
867683332472
777552233424
964334345443
995444432564
877754443334
999988833548
998858233323
998888853745
886666363266
998883253454
874356525423
876446723521
555444332314
955555555642
765332252211
985433552133
776664333333
776556523222
922412222222
864443323232
877552314332
655555555553
866543232224
555544444444
888876666455
553512334323
988626432965
762222222222
997555655555
777763314632
766666555634
555554542352
999887777777
777423322211
665552221221
961333123233
998854543874
875462174444
997766433229
776655555415
999956448496
999999978454
888766222122
998865745421
977554243333
999998673765
888865652223
843332222232
988877656666
777655422368
654432352222
877654325536
988888888888
665332312231
999999959836
877747421336
888887776554
996745474443
866555455266
765442224322
966555444433
999989516866
444444456789
888935222631
999999999999
977777651349
999999987776
774444444445
877788217332
998833333333
544444444444
999887768433
888666655452
888954334455
766666666446
965544444433
977777776666
997555339474
663232552343
999886447242
777777777789
988777776664
555445332221
998888838333
888887653364
999888777766
995496461423
776633224262
987638332332
888888887729
999886644513
765522333232
998887778597
843332126322
777664345253
973223423233
775544731331
888556274681
888853534585
555555556789
933322522222
877784121493
644444433232
666666666789
922242222331
886554447455
893231542655
999888696334
665533353576
765555555532
999658847452
886633565373
964444461112
988956663759
999864282222
644444444445
975342222123
665422222222
999888888888
877555544433
766658125352
999999999999
999937332358
995555761422
887654343431
999955515426
554636232232
998868467955
766424515122
777742742332
735514326145
999844734465
988888977354
443342273222
544432233322
888777345764
554322222311

200
2025/gareth/day03/input.txt Normal file
View File

@@ -0,0 +1,200 @@
3133322312313332336153233333232281412234221222433272332313372222212233114622232233232321251122522243
3122243233322223222333513239233621333333523352333332361333233332142327423622333222313333242321112633
4453322423234323362634238645943333332463321659433346534324232461344544333233244323632243313334262243
6448895538826857235274976247543575444367645757464434697575874665478695238342662743886877975373645693
1134322241232322332224331133221412522322512233243421322616252222333223234632221323236212122235222232
4479242568986515346653123325247575265256582134963244533552224424124932962555334232534326255446632228
4426412316324254531114425464123214136311441166652543321621464654422165654455166414253156226642564789
5534943265545533146737249872452756665433166617813432253534268559555562632512417473647255444385366543
2221332232313335223223326323322224151322223433133252223132133333322233214222322312232523263323423153
1155555265656565945445445515455565444244558495552543595233253554355543555166554543534544555656645543
5375486865865543646375445844234147342565375934762358696736345227447645746233234765477442546863537543
6377523531453435443574315246554564646533255523533634533446327354552235123544256343543443365343544511
2422254262221214222343113222324222333329322249243446644483212142441542442142772223232574324424181222
3224333232343284522635562216535334233333536453225622315363634232432466373433543323243533423284256324
4432415264423343424524442424742353234444345363444422353244434443343332333546444335242244627424244243
7767456236539425625242747855734379453334633444259221833233727325141263383682327576726881586533226355
3343333333246334333333263333323433324132433343332433532132343325334212233133634336333234323332432315
2545646456545665546554557642556656266463445455556567566554626345676354456627654646455474646644665564
2433322122222373442324254224352332243332344233312212352211234232225222332233223224342225222274113431
1223422644542352452322244433123652524124232425213252533524232534322314254452515244242714442534236535
7436355442424144524648655572983555456553857475342849745533523555546973473555554944447583517666354456
3354332343233333452257333931333223233335144343942363333543125533424231253335233434333343625642342632
3647245432355223452345235453444454556385447243713344435475324247366313427577347544434475354531354524
4314134344421241423142421243322114312343414231231414312224131424313323421144233232133431142343256789
2222111212322211222112132213222212222222132221132222222123322131122222212222231122232232221311222324
2424173245432343439465475433352422232321126342412321321435225432122533311335433362254314243332232463
5432844335323357331133233332533333327333313334233352412333333233365332145242434323532233181231535233
1122222324224222222621224242213424221425222222232225523221252242222422222223273621423422222722122323
3743645335445453868636766323672563545876934124483636326664252554379555153588677644765253523733987369
5357445367737667464565657347567552566686446856726214455772537522723666354383457331466626922574666357
3333934435333143333423333233233333334223233373434323311312334242133323367353434543333332624432323323
4685698384447433555446379545435874726526559232776446567445196374345785664753345546553862439481975585
2212223222212332231232222132163221132622232212133122221222122222612322122222222223212222226312322421
5645463571423453464433469435453344796455674543332563556133146515444546844326644423846514542342333534
5233343336233633224232332226113236322312215233353333333233323225343322343233343332224333623344323535
2342227243452224224445323223453342338712363445723133323442333424337633477313342332344444423433231443
2322646222222622122328223598236932644822522322621822682225749223422722223295431517222264613228152266
3445337447457232452444444394435382372764533466433734666743653344444157847767544663564445646846443757
2345347254535445132343932232422424544332455215333234424312533544211549233443734343253222443234332442
3634423344236444353464244134443345441224432333244241544141436324533444442354254344342534242424432523
7231332334535312223652264335534314334339453253542133461336312553283783443222363334331323822343232336
4221531424224412332642233238323432423633612512612225323826323434223312553323464335223261346234222215
4852321327577233324223658814222972473235384575471636527421366343326547673464274328261632225124477363
4342434343136343441515223132333547653332527353453324142334635833314333521334343335833223275643443343
6232446431323244223342517443462442213564321235238323512333422223942532333314333533336445328333133313
4211222542621142332222526522264413212222222226235234262421412272422322222253315344224223111225352522
2331223232322433333332333355634234333331363332222242333322235232433333122323333333331275323333341322
2322522335333232118153272322334212233352323326222152533234523222322333853271235332224362522212223347
2321343321133234211232413223232232221222234222212222133232353333333233323332232341322322312222314232
4344543344434612415344744444334354334344433433443443334333434362442126412324434934444323343322533233
5643658557246447555486543355346775386523277657558583745333466455764754463595556546563568576565747415
4552242557446235454434454445323325544455552562564444654723532555754514513453455555524444555443355454
1322322227621133332121229623644292425743422847369633622414544923322264223222229451322343322282245422
3244443141414423334433521233353243444553236742616135424651457174227443324483447653434435493443352814
2332223456283243422565442411734626213212333322325345523122422222371255521233354282314243212222346811
2363353334438332753485332283432143844634134442235314333384332534411233538127123239559335324525173367
2233233235323213323132223232332232621212413332243333221332262343222325233233332322232321322733333533
2231262835222374325232237412434734246872142222265422343242152342423432436121422253232122126267228124
1617167414613376433741444343412452466424234322622744322463534122616275543323335313246433145323634344
5441422332252342442332233334339332433235422344223323424333371413343368215245423533624433223433224424
5534454447443434664553364454363373732666955334475424343455425356554543445373545445245366445534436457
2222222322332223313223222233343232342213323122225322132323323122322322212224312123334213224233112122
9444357435334337357253725853774787427781646153537837242484337664753556284673879345232837794643776362
3342224442222181242514542211552421273421221222222242542122262112533512423221252264622254256333422222
2453731182222236429123338923242731234422523223344333428262421262434223333123925274944122752262893652
7949675436668479445173944387468424444569538485763648466358543449982534369694559465844889937793478483
7525897989956253492876668653639333498484589824962736766226854174794787349995765998753465867748726349
3635215333523534323341652262264217242224324647362243332241232324325432233341454332324444452335255342
3235351532451225333552323425133565323333523333532342333333323353443234333235331332335133323353332334
2252462228323222133422254213212224722222422214221522225342225662285222152222325521552412223246252222
3343236352334472233435233253522333432334333322233323443343332143326443333333433334715332332334633313
3786957948699888786853995899657847776498789968998426859865395758275768954934688959957289759966967954
2733323322522332132223212333226332122722333142323321424266531312723323242333221432322122723233322322
2214362331522324431343484534342563442521534253435544744566456425653335355451545532333553345425858454
5439639959656979786597966563879777365396989655738678365562377327838388788969939837638653376636484953
2334734343343342344324343324334229342447239523333332334434372343343313134312134226222424132452333432
6724425365545232331435216575552744494554556545652355844652163542535345535243555443365513835532355415
3333332333333323354333233113313323333433332343333333443322523333533333333333623332433334232333233843
4437367564574537445498644432636847544474774435442876774346358678448734343669734643458454137848456656
2221222532213222123222232232212352211512223322322242232221233211422222222222222321225223222322222223
5523456333647612353377254433323232777323374323333343377352333433535387932733632343544313464633245324
2131222221222221222322221222221222221222242221222522121241211921122123222222223223822123222112251212
4431321233433243246213271132122221422323216234242222414223122222223163143332412253432423342223322323
3212262231352432332221321123222222323233252235424232392223223323234242532295245423442324143632522321
3274664282142364423211712233331324112364463223322125334345432332343352626324334284342452333372433324
9444554543554344534533543433444545554335335444442415365444444344134434228234563544423345343434435434
2322122323223132333222232332212533335221323432122323311262258223221432233223232343122323233333323233
4256445456356234755252516444543554233114323445333343454544444343532522224354232633355344321153422553
4656646715951462515563625654623643675644244445461467442462724776725663573121654549477361684255565445
2412221621223579553212322122235622225222125314222342212222222242222452141244422122522434921432212622
6566634554426546464435632522556466513452241424466565634522462654256455954636655157657446265256464314
2232611127632222111253221222226223223332222232222422271221133212321274222222312222223222251222212211
3353333333423336434373333353533425543333343333355343322543345355353333435353452335526343433355233333
2232223125232228222252533215233242422222222626123421221122112232343251742223233147222325232312231212
2323123223312262212146322212233522241222172232221321131322442222262321332123322912121222283242226242
4323622424322343523242324243522243246322262433212124323725541125142234322112351254231262312423244331
3361432233356332382222223333331233253363333343343365436131232232332312632331311332143322233863223338
3544383332295358255736425434222332233532256313234333363422833333337552233523332136233532234333325395
3323336324432223322333122223332332423133333223333333334543333333324333332253313332214333332223336311
5323563292737384237353387233322636363232453633553126738638735823373373435622713635232355136633323636
2114612138321225442242222224261222316622144442133312753354321214223121122536313226212222326142321362
6247453657645373434535444546656443327532476675344456355444643425446457447542633364545666645364735444
5422232383222221223233438833242733524342531233346374541123222534933328234212332332431321334443342242
1222221423223257321853321231223214422626112124124434322222621222252124221232622222513333323332412222
4279267668473452164259647337628548416726542527684472572412482564723752584633674525865775664775735584
5532212374612312333223242722231352223634282227622272521247225713222322222732316254422161228354446632
8867713564683676748783437544467384488468446476686464457578677965554479566376776534547672436488548648
4432412431321244322223521212342532232123325143323443733324332332243267132321221332223741233353422422
2322643323222232112212242735126521125222224241222522321161524333233313211222124153262226281422133221
7322221223222412714481222222222322224322258972232263272221262522232312242333722254313622233313232523
1424333334432242333333217332133722323433333232423345221345322223237253433333331432723266113334723123
1554363178113723478281266824262175158814163872852231451314645635246255668373368144125743153665532639
3334422364546744444571324532515243445314327453562167372456431242412524845442335226535535622772332552
2222223134232233234332332221433322872433224442342223423143333332434211223111222233232342713313323234
1222423212523452211222332121322232237262212222142252321222232521222212224511215122222222222322292222
6631222242632295822463483545724493546522256233322262222162622213226222318247222223673345232221374727
9979445565769447954725462535745746643554655956665664577574938675685834745555555843163646964452585854
1332233234222322212223122322333223242211232311232122231232532123313123342213124332212232222313123422
2122334242282422223229264223226722221432333379232322232115523232914966353333222313312228322232212924
8343226936424543433358424471743573555183245538845343644843333644476253356665232431732843754715276894
2423351416282141513226654215256452255321353212251421668125645232252535223245622625455325622543563323
2274222214222142221222225322232432231112221122221222232222222222642222222222222221121122212222222235
3422682214212444242412325341132151543223242222282126232216244427422332444242221215644222232122248244
5541555542521324121252535576224242537173484424612452232243421422531472346351322523551252252552233524
2231222325222222225132231123323242332231323312223224212252222113222352343422224342343214242242343222
2233212323232731132273372323333232531733212122422332112222152425432223333214222343346424232122223227
2346232422343424233244432617445135414564434834543737212455135533233433343225513434424221234423247424
1332232244222224222223228322332433323223321322224332321333212131122223213322332222222312342324234243
4242322312462124223242542232231252113152522223252233432222113252223125121321441321222333522221212252
1513432234151521123135555522234223143424445531424215355121251233522152155523543145553341213351316789
7366935544647586715762426265348565354476656763647423463446645164663574133177633738317724578374467853
2343324233233334322334244353253333242243444255312511613453423124334114221422444433334334244222442342
1422222222221221355224124621132331331321254223122332424122222334332222125622224222222234142215412211
3134321323343443255344344434453324443224354363343453334233333431462242242324335223534514355243435423
5222413432231237673211737244322222322232322333646125231325327543712232436222153223332222624331254671
4233343233221232323123221533436325132233334241332331332323332332722573235423212335122332222353334452
3342213523152244352423222422232216227222232224425152224254255344122222252521212221324721421312142113
5443532343322363325774162333323333443454235238635225234438152223433237532483232687334576237363223632
3525534323644464333434346333422313257324256662344813443535135522333325639142443433233412333334373232
3342353132322323643442342423333332442345213324232222311225243324342322322434434234312342223435327343
2215597625242266434372426244333213443522253842323164522435692342284562521223343552315229322242221227
1212122272221221121222222222221221221122322223222422222222222223222222121222112221232222222212121212
2232132433233232211321454322214533324412345133122142221132442333225444243225232122232334344255333248
4464243242222335423344333434433433242252554245241234345253321234433352433444252234434144322443342543
3234365123622223221245143121253333444522222425214322432242622324237212333324223225322622422212425244
2242532233123792312413232932121722127222132121234222425322245132122132463125241322212263322136264211
3231222332243335321223233443422232322442444223323231323324122323424323222232243322232333223423133432
2333323223221232331222232322231223433224211222322622232322212215314223223233233231432213223533322232
5685532356255584756433641634235331742524254473246125141476432485435332353546445547446314385122855534
3456344445212414323432544232434235223444344122345553442335433334642541253529243334245454422416453334
2242223333222224331222222224222213223442132215222224212242141434231422422321232324221242421122222221
4333383632323322333324334224213333343342331143313433373234444315333444234333426312232333333333333231
4422573134244263324522241316311233233345482124424135232342731328433124413172222363523414325222222235
8223222222223265116222241163153222221837124433322226411224124342242222211124224622232631311722222232
3534844444358244575564454474856336445454755444455343444474444444645445546533545644434545455796435534
5246624225353223243323273165442621323333333123334332382322253232425421234472524433335434243882427322
2622323243433253232235529421362332133154323347434333144623235223443386532663222714312453312332922243
6254635483964638693943763425358947433957247545953555563652853678776754953655625943564529736585973954
2322334323282133213433432312122334552333234331332323332133333453321231223443332322223322223232344233
7224322222942233222211513133321222415212123242343222221222321222232225222232232132121222322123221621
1225222222212232223123211521223222222125221222122321241121212122222212421225222222222212222214222214
3455555535554564555445635435535543554544554556355345355442544554654555355555555665355553254553555555
2222324212222222422524544232122575261333322725132222622222154521224131343233225251222424223223222725
3521324722222232242122232363222243232752125434212232222532322423433333343324223632223322554222322233
2121122222422243544422122274222333224613232245284121222154223452222423212923223212423721247422214443
3232123212232232332132133233235323221132333232142232322424423223223233322333533212335522213243333225
5177873528233661875332469534892728351386833272255574426731755914333233645873733629823353556313583595
6213333321253232322333523323332633233333333333342333321322331333333233233632223322333331323333322432
3373387333349854145353324345434853343433443383443464444348654344472386435784658634343747633383336233
3429393345344644363565375244243244543445333234583345434344333135232345425321562493523433442464453125
7434393434642448179344313244242244443334153444233223447721424341442646322442443243734342434424343132
1244334475341363372534443352243439515444744262343553842424433344935322537333743445483242533535575352
4373352144322333242451324432374254562431453553422453364243247143313112135443554413724423442244344343
4645563438835975552364244145474938135353452575749545556369475163573344256676416536453365734433955534
6232751632512233322312224324344212527243552223398222882323622722722224334225222624223622322122922221
4223353243524233432349343652523535235233224334132313433232525423554347244383334134332353332324634362
6532462659251523335544424644765725565347323437746464722418144255561673163326362423584544542752864364
5265355258244364654458553255366345454346535266544325444635233353471156843374465356142345463754544854
5333353133323333323343132235333233323143153333233433333222333223137423342522433322333332234335332535
3343433335343224443543432424333332343444333343333543244233435343243443233333344334124313343434343433
2132223322352221414222224422373422222222121184282212212222282122132224922234212512232471123423323362
1413222223123221226221725321142212231265522332127222422225222221322612223221235236219264422624221262
5215532874414323333352366199522245239342514438736631253368515152244356456573554592786424522845643456
4417433536414623449345363555313956437344537433233143853437256255344445324355363438433364353338273432
9786442645664536665425664482742494456631544436686579472166986232969232465525665274256524554446252662
7958556354745775266427683599272776745837655766567766478547674576675966775675453266655377755445127877
5464552767524334662646466373452456426544534386534264666332434446647473347556664167687664465556657669
3422237124533342313322332343432422323331233233222242113143423543443433332132333322332413314433235233
4587342221574643382424242413447556444383723349732441445448443257237364434145323768154243948226831343
2221133422982213342263223186422352211522242546232221229332462243222322233532222523222453423562225325
2232322525454232321533421132124421322231444522244114254333232332242422123322343441233333323224343323
3492347628432423334213264323334346561327733347235153431435542344443348225132245133133333227467376436
8675854562453553452445363245546664724456664357445334546665574645544825336454434173841475542574626397
4641325112314637326112652435765437554615742634552761743652475771227735261274664454467743363221532389
5441442463462432334372323724264223324451341845243644423243344443444443311445145221455434154476234134
4736271123322227262237354426264364322116234962553425433242763332336233344642676342164432232444346326
2332523223522224222223222325231233422142332232232243123152223122232122242222225223423133253314233332
3423367354345622372133357333724233735422453433236215132354452443633773454444335633445994526245447446
2272212144222112122221622522282525121222522511222341112226225222222132143225252222221212241122422222
5473262656595786245443644533532333343956663244245223445432655542666423485355334437736432226543565526

58
2025/gareth/day03/poc.py Normal file
View File

@@ -0,0 +1,58 @@
def part1(input_str):
lines = input_str.strip().split("\n")
output = 0
for bank in lines:
best = 0
length = len(bank)
for i in range(length):
tens = int(bank[i])
for j in range(i + 1, length):
ones = int(bank[j])
value = tens * 10 + ones
if value > best:
best = value
output += best
return output
def part2(input_str, k = 12):
lines = input_str.strip().split("\n")
total = 0
for bank in lines:
bank = bank.strip()
n = len(bank)
start = 0
chosen = []
for picked in range(k):
last = n - (k - picked)
best_char = bank[start]
best_idx = start
for i in range(start + 1, last + 1):
if bank[i] > best_char:
best_char = bank[i]
best_idx = i
if best_char == '9':
break
chosen.append(best_char)
start = best_idx + 1
total += int("".join(chosen))
return total
with open("input.txt") as f:
data = f.read()
print("Part1:", part1(data))
print("Part2:", part2(data, 12))

11
2025/gareth/go.mod Normal file
View File

@@ -0,0 +1,11 @@
module aoc/2025
go 1.23.2
require github.com/stretchr/testify v1.11.1
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

9
2025/gareth/go.sum Normal file
View File

@@ -0,0 +1,9 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

17
2025/gareth/main.go Normal file
View File

@@ -0,0 +1,17 @@
package main
import (
"aoc/2025/day02"
"fmt"
"os"
"time"
)
func main() {
start := time.Now()
data, _ := os.ReadFile("day02/input.txt")
fmt.Printf("part 1: %d\n", day02.Part1(string(data)))
fmt.Printf("part 2: %d\n", day02.Part2(string(data)))
elapsed := time.Since(start)
fmt.Printf("Execution time: %s\n", elapsed)
}

16
2025/go/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"args": ["1"]
}
]
}

128
2025/go/day01/day01.go Normal file
View File

@@ -0,0 +1,128 @@
package day01
import (
"adventofcode2025/utils"
"fmt"
"strings"
)
type Dir int
const (
Left Dir = iota
Right
Safe
Unsafe
)
type Instruction struct {
Turn Dir
Steps int
}
func Part1(input string) int {
lines := strings.Split(input, "\n")
position := 50
code := 0
Instructions := make([]Instruction, 0)
for _, line := range lines {
var steps int
var dir Dir
switch line[0] {
case 'L':
steps = utils.MustAtoi(line[1:])
dir = Left
case 'R':
steps = utils.MustAtoi(line[1:])
dir = Right
default:
fmt.Println("Invalid direction")
continue
}
if steps > 100 {
steps = steps % 100
}
Instructions = append(Instructions, Instruction{Turn: dir, Steps: steps})
}
fmt.Print(Instructions)
for _, instr := range Instructions {
if instr.Turn == Left {
if position-instr.Steps < 0 {
position = 100 + (position - instr.Steps)
} else {
position -= instr.Steps
}
} else if instr.Turn == Right {
if position+instr.Steps >= 100 {
position = (position + instr.Steps) - 100
} else {
position += instr.Steps
}
}
fmt.Println("\n", instr.Turn, instr.Steps, "->", position)
if position == 0 {
code++
}
}
return code
}
func Part2(input string) int {
lines := strings.Split(input, "\n")
position := 50
code := 0
Instructions := make([]Instruction, 0)
for _, line := range lines {
var steps int
var dir Dir
switch line[0] {
case 'L':
steps = utils.MustAtoi(line[1:])
dir = Left
case 'R':
steps = utils.MustAtoi(line[1:])
dir = Right
default:
fmt.Println("Invalid direction")
continue
}
Instructions = append(Instructions, Instruction{Turn: dir, Steps: steps})
}
fmt.Print(Instructions)
for _, instr := range Instructions {
if instr.Steps > 100 {
code = code + (instr.Steps / 100)
instr.Steps = instr.Steps % 100
}
if instr.Turn == Left {
if position-instr.Steps < 0 {
if position != 0 {
code++
}
position = 100 + (position - instr.Steps)
} else {
position -= instr.Steps
if position == 0 {
code++
}
}
} else if instr.Turn == Right {
if position+instr.Steps > 99 {
if position != 0 {
code++
}
position = (position + instr.Steps) - 100
} else {
position += instr.Steps
if position == 0 {
code++
}
}
}
fmt.Println("\n", instr.Turn, instr.Steps, "->", position, "code:", code)
}
return code
}

View File

@@ -0,0 +1,34 @@
package day01
import (
"testing"
"github.com/stretchr/testify/require")
func TestPart1(t *testing.T) {
r := Part1(`L68
L30
R48
L5
R60
L55
L1
L99
R14
L82`)
require.Equal(t, 3, r)
}
func TestPart2(t *testing.T) {
r := Part2(`L68
L30
R48
L5
R60
L55
L1
L99
R14
L82`)
require.Equal(t, 6, r)
}

4777
2025/go/day01/input.txt Normal file

File diff suppressed because it is too large Load Diff

59
2025/go/day02/day02.go Normal file
View File

@@ -0,0 +1,59 @@
package day02
import (
"adventofcode2025/utils"
"fmt"
"strings"
)
func Part1(input string) int {
ranges := strings.Split(input, ",")
count := 0
for _, r := range ranges {
min_s, max_s := strings.Split(r, "-")[0], strings.Split(r, "-")[1]
min := utils.MustAtoi(min_s)
max := utils.MustAtoi(max_s)
for i := min; i <= max; i++ {
s := fmt.Sprintf("%d", i)
if len(s)%2 != 0 {
continue
}
if s[:len(s)/2] != s[len(s)/2:] {
continue
}
count += utils.MustAtoi(s)
}
}
return count
}
func Part2(input string) int {
ranges := strings.Split(input, ",")
count := 0
for _, r := range ranges {
min_s, max_s := strings.Split(r, "-")[0], strings.Split(r, "-")[1]
min := utils.MustAtoi(min_s)
max := utils.MustAtoi(max_s)
for i := min; i <= max; i++ {
s := fmt.Sprintf("%d", i)
for numDigits := 1; numDigits <= len(s)/2; numDigits++ {
if len(s)%numDigits != 0 {
continue
}
found := true
for j := 1; j < len(s)/numDigits; j++ {
if s[0:numDigits] != s[j*numDigits:(j+1)*numDigits] {
found = false
continue
}
}
if found {
count += utils.MustAtoi(s)
break
}
}
}
}
return count
}

Binary file not shown.

68
2025/go/day03/day03.go Normal file
View File

@@ -0,0 +1,68 @@
package day03
import (
"adventofcode2025/utils"
"fmt"
"strings"
)
const NUM_OF_CELLS = 12
func Part1(input string) int {
var jolts []int
batteries := strings.Split(input, "\n")
for _, battery := range batteries {
maxJolt := 0
cells := strings.Split(battery, "")
for i := 0; i < len(cells)-1; i++ {
for j := i + 1; j < len(cells); j++ {
jolt := utils.MustAtoi(fmt.Sprintf("%s%s", cells[i], cells[j]))
if jolt > maxJolt {
maxJolt = jolt
}
}
}
jolts = append(jolts, maxJolt)
}
sum := 0
for _, jolt := range jolts {
sum += jolt
}
return sum
}
func Part2(input string) int {
var jolts []string
batteries := strings.Split(input, "\n")
for _, battery := range batteries {
start := 0
end := len(battery) - NUM_OF_CELLS
j := ""
for i := 0; i < NUM_OF_CELLS; i++ {
v, pos := find_first_max(battery[start : end+1])
j = j + v
start = start + pos + 1
end = len(battery) - NUM_OF_CELLS + i + 1
}
jolts = append(jolts, j)
}
sum := 0
for _, jolt := range jolts {
fmt.Println(jolt)
sum += utils.MustAtoi(jolt)
}
return sum
}
func find_first_max(s string) (string, int) {
max := byte('0')
pos := -1
for i := 0; i < len(s); i++ {
t1 := s[i]
if t1 > max {
max = s[i]
pos = i
}
}
return string(max), pos
}

View File

@@ -0,0 +1,20 @@
package day03
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1(`987654321111111
811111111111119
234234234234278
818181911112111`)
require.Equal(t, 357, r)
}
func TestPart2(t *testing.T) {
r := Part2(`7455526631444542356445533352351453423842653536563363453344445222432533133425443346642463393231542655`)
require.Equal(t, 893231542655, r)
}

200
2025/go/day03/input.txt Normal file
View File

@@ -0,0 +1,200 @@
3238233422322723245312524333415334121333413432322532233243267325442232433333224143383436222223233233
3655644666946277273684457436668666955664663983765757454464876854654654857865665766676664954456576457
2222222214221321222242232252322221422222222212122123221322623222234222422221122212282121422123326322
2124214643322332212222134232222223323244234222412424222132142344221221232224211124244142332242234423
3436232236223426333625431396643366362565194162563644533454346253234235616323362232354352264323633232
5222522242424132416252524213114222342315134433221233322222231246224242332433133211133213224152222532
5426122223223222711223433222337222332222222833232224339146332213332173223213812332213383222132234312
6754666344575335444575875747453663683596555517664555664546484534645635645553474345756556566654566656
5433475435554344344375445374544445355635555544744477536637334335232664335527685544454753243246465444
2533323723332334421324325274334254525431339343344558454433386313383333342332322853233331232763541433
3434243341345332224133423322532152471432322626222426413335421225224211233163443935254725234333133342
3541448771235152323243338633424215242426556266442614844233795554292323321243648444233424278324436324
4232241923231442232233522224233222222232431222432321223233222123223234123233322133322222222322224341
2322413333333323433423333323333431233331323233463333343333223323333323333323323333333332354333332133
2212425414842355412223552127242426224852234212232212232222255523322321224232222232323222235222434633
2222323222221122221215238122312222122214221322215512242233212223122222232412233122321222222271322222
5215532261853227652345746126415532422366821723536247423754252265364642376432522655527226425574722471
3222222422252332112231224221356222221223222134222221232223313326222222131432222522333222223122622222
6676222427665466767653734672313657732795538736586768869694693597677586674659542276554762257672793343
3653535256345253634345457434518545543444445544575534454455644555557475445545334555545353535563446555
2233222222323144222222444222122411422321222212315431213323242223222222242233222224322232221212242531
3424593117244244313425222742513498752244424152632323419112114524386212455225243275425565524227362317
5531424542533424455635625443656442662633435324445245422523346364263544533554433452426246313433372514
2522967564465922868445536669545363547885536537774684644666145884654894493744892656428549864924265585
8736457373466777928237878853455465677654727936757338659679873668786246374673877537787726887267376752
2962633343332244174633334533659659344458746512754522225623134372535234242564234635563533366423245423
5534345333543743355425442536744453254445333225545543535344457451545632594543356384535385568433456583
1222242782342223422232152131532242432823342274223223333234321212231233434122949312531515162212332222
3434444332724222433423222345344859344234434244424222439432433414116164422214232344446376442441344422
1222131622223342163222227222122143223242122222121212232322222226112222222221222222222252212222224251
4262513533352222332233331225332231334153323333343383333133232834422433332433333343231743131343623232
2555454275557549374368453564565154525643271535272434413352635365473535263236544335364434615263242555
2132223355322342221432325223133355343253533434522435535322233332423232323244152221532243233455233213
4333343123322333234342333333323333322322324231321332212223322333332323234332221332323311243233133313
2332233333222334222442235222225322232322253234322231453222232241223133221323632233412254332224124244
3441632222323232421248242763264244122234632343422122214222322222244421122442226222412431417242323342
2343221313234232624432424245315522424236224523135333322124222312233232412231324422232221244343433431
3343222224333332146373333536133223346235344317253322382322262522232642222242324443332123216233333336
2322312242313222417322222222222216232212214122221242233233243122243212322223222232222221852212222312
2223223341233323322432232212233323331231233213322232233322231334742823233312233134243223333133122813
3228334576353333562327554733771334232485374333433542631274235374544691334331347733234373357337725333
3454244353353733542724475534227534446346833483535544236532367313365345453652244346263533435345913544
2246211242428262951721221182321231224644212222142422283351232222221262176382312228292322229224212222
6431432336442565163354443334452545623333245524212534544624222324342356231541294462352313344454212354
2252117225531222122221132222211222212222142223318712222127262222211222122422322212222242922222231312
1123144213142231424531224423714253222543235421344223222121252523232422211142423222321624314221344422
5232224422123225232122225112224241222222223215252312222321153231322223323222245523253328123222222551
3621232222112263122322246123222323222222512232221321432423223272222142328132212121222121722217621221
2214222412122212232321333262225222332232232227222242222222335335222223332222262222223532514222121223
2444741342314432395654242442245546624556344421445142212345263223224343343424334485233344552235344253
3333463433354333837333621424322336535344233323423838531653453683332523962234334133224526144314536364
5233451445357625537562657759256372535254626263575665372569645126455436743347439353353254435432874561
3663386342525234673448454446432334344423338533332433256344673633766354323333234733666733443363156993
4646264122632272152731226385422122232389226213253536722212342532472422734255623435243713254142122416
3324315533434373442757634653443532352441324226346363223259263334634127442224334414533372361535353625
3123247753461326484274222842132361327344636382448381324233242757236332232212231414124233233873435132
3233343222325533333253333344532433545334343153543345332342242432335532543365242334353225242142246234
2233122341331332425544342454212321223425213335322342532322111224221332254222245232433433337242232311
3634366254544744542544545363644446633443454444433454343444445442535455234542947463224644445635444433
3633332723672391314313438632262276312226266642352226633983253547635125722222233222322926322577322232
3349532424243225533432226342412622222355454427424444422423223514522514554332136332333124532332242453
3322652426343223283633633453326532426128221533638567312453331214352342234233823343233331348433483233
3263222324513843332311751222421122234213332433332233432222452233322223233232231222314232122413333346
3324424543235445343532636425243343353347322733541434155245334643241125223435453448654645267683332472
4234523123332252462334421551311512252533524623636312441222334223323142422752276162215723345522233424
3453355424333343224433334444322836743342424333464334424342244444532744223434353439324346343134345443
5232225334455644395443426443453336424533442322134345525242534235325326232332254333459253214434432564
4323344383331322442312221213433424324423315127366323232352236343344337114672432324332542133443313334
1764276943738333483449376253345367364323233372359752443954437338534536336432543736348373352783333548
2332239223223854323335331223333383313233221523333228336232341351833392228333813353333132432338233323
4583591334525833233466252342338345436334284343934424328652553552334233137558828333333482323533333745
4233444624654525435643568366547136244562544465423332263526257467634235533338336334454535625566363266
7152548554343414554436353216685221244535423895629554685556276432315645347364425558275323214283253454
2421264125122232322422263243242143322542832641422542623222222234312242112672321232211432331256525423
3452151314152322833231342345322332321332325731334515333322253125224452542121222641233122412326723521
3223333523324343142123232222312322343214453442342321232244232232313424324242452234313221443212322314
5455335555555244444343434356464535433565522544555544533435444535455454563751494555455525542312553642
2532323522123514123223222362334223243315331623312522222332232566327213321322236133323352321232252211
2223328233439225525461513372563325152332242222423331327722331422417422244522425251452226185433552133
2222361253434322222324326322322573223432333333736363133233122352132233332333641323133312322223133132
1226344252613414224222243423523423232134321332276321322234142322432427224252624232424332525226523222
2252321212212225132232214262243322222521132222232122111222321221221222232242522121229221222412222222
3112422332212244222132422321223121113323132223285222231111222324432262344212322223243222211223223232
3223833132233332453422423333764133253133323332252225266362252326131253337333351413333314522222314332
5223423222232512422633522223243143252433355433435243152432332224244352243415222332312334453521223332
2333122244233465315224221212321234353232323336532422482322333112522422323624153222632331534322232224
3231222242442232122232443314242222442223251242432222424122251512222442323524422422432242342313223344
5644414434454344454443543383452425354534344244343858446444355554238543437342544643643345631355464355
1232222332222332243322212212424322232323321323212223322232332131331332313225133332222342532512334323
1125422227334692563222364233231324222323356241222463222274411354445223323221223523423337388626432965
6225122321122223211424222214222712222242242222422243222222132211223222223421223334611222222122222222
3645564444551544255548255454537635664556558585153955773356653554496365547554555454555423535344655555
1343221246323622245222234442432224253426267241221242242442444262472422221321232744752242322632314632
3232555333332354435335362634135123343356244234263316444276362432623333533533641533565535443255432634
3335333333133123333233353233233353333323334252334332323443323335333332333333433332331334233224542352
4676333533566746975628576749784694456766435483543573628547353567434736535766335667475674437754646756
2242712275422321222222123312422224243221212214222221434231315221232112222222121224712222242123322211
5232222113532224143221226251323324512122432423115322423221213222421232352654122252222432221522211221
2324326227332323323532862322424313121233432131332213321223233253423222283334252232219222461333123233
4638233763365656447356534356533563586353256748731467735514376457957325763695463546863356585443543874
4341223424434414544235445342328633543233443454413422444432343354433212242334262372215412124162174444
2326422519242433234222212432229723223323222322272642222323224241222452132242233142323222326431213229
2223326632213632543326153452322572226456223517446532123552312254533353514633325153244532252125332415
2548666542777567464423266492454544354454661745445344433867825595845487556474674534981345944556448496
3655836499753458447557343546944375655847554565459678854745985557565559545786564587863495674374558454
3272131532423362122223222322224622212282353323224321341281632222222528127232143262222222222262122122
2323222636483639363543233522326412713366693834623222221262373242138544415536224232523552252434745421
4576436326433332514343177135333415334462323434333633364617529635433436471434343574323543333534243333
7673924444565367226382625746534735668736376676725229766887388769486869648253727666686455732798673765
3242233522822433682823442441234512251142431642222244224352242172253256326332562448225246152424652223
2212212132222222228121133322232212222122222222422222212221222232221222221222222222311232212221222232
6466366554766673666845986646655556565666566546466763676654556666655756658655845534676566554257656666
2524152234153624656232213316273225622342332147241252323725113232215222426521213342223232333354222368
2223221222112512241122625222211322222213223222222222222312212222222121222142222211221222324322352222
1142652163542323322533543552241232222544345356425364346176325632225132253835472375562224422524325536
5392386646332728446732822143641788824676122643322647637183734251272163248735585358825328124247257556
2222323133232232223222212232113633222222221633222212334222224332422243113332212522132322222122312231
8683886678883624393276865368669575448493288727667228697234668168889838956386424374723775752657959836
3533425634665614423437735633756435366347744722543444677523242286463445344134345754464253774437421336
4463354424463534587843748445543473465646734545484353344345448664673433546735755553462345543244443443
3333494444324354464344753344444434442642424441645245754424433343613243676696454445443236434745474443
3334332433325432333124543334533333323553326334334483343323625345363333533333333333343453253342355266
1432236233423212223212242223121222252252212312221212762122212232322212323242235322211432422222224322
3333256463413233344333333312633332333325453422324333392463463322433225353231334433353243323444333333
7736237745293832739263726338732559784369673833547354558664757444786583187833223136867423585569516866
1131142332334142214421311222143312133214121223313231113442421334232144444222434113313432133424156789
3232124235342282623122252222373334433336322328113723262283353333823268352326382427242736332935222631
4468556567768676565885994797565466448385756746485674257645947658644358697757959999496265554795754628
2575245654587756544544555344325445444253846472736554654944456444532452574557457754455533455716351349
1449228731625783546145322282376767945223354784761591623444944679322296782334427733195467724784774276
2423643333337342333443333443333223333223346534343343634333534463723344313232423443333333243444143325
3335433461436335223245436411433353533346463835374345434473722236532435335542455353323333377788217332
2333423523644253232534232641334254632223332955423322342335543262329423753433432543282382132331333323
3244233433334443424441433434444534331244434432333323433414343334243433333434423224334334332434333433
6362712672268282283761924427141563687696283521585244925674622472623724287874234626273255264425238433
5328341233214483581323225524443336235432243422416445223334234212623234324243622412332523332443531452
3637386345347745474463377423675454654368458535577555336134534368354335444343774333474342353954334455
4434644244265424543324753622464334553552134445344662544355363441242264543543344425444645544434464446
3223212233353232233322333339364223224354221333223233543242213332331222243424322213322133134332333331
3153332553335544459766263375645636357666454552552332634752646655261553677536455646676626535362454335
5473534221354325227446257652544438222494273862536522244571444476228542225343361292447541154453339474
2221224222412325222534221221431233522264323422233352422222231322244442232223232225423242263232552343
5332427364273242312934243526733672664424442218537634449366534313935634536814632433225563842264427242
6235266277265342456137175322124157375434143165657145451146775315575231444663125462654744375531134289
3421222675734234317233291215315253432642242377222257341342223228582427172712135272254627136261223634
5433432112325134322333333233212322113333132322243423344352242233413143221311322442322313241245332221
3423734435853334374537836333333333317433352683453443353785482319323532251323373393833533838862838333
5657323833536351353333363782336373322831333642333243533331333328332333353233285222557336315323313364
2442519326432623532344727393285833347123418565397636331334347245722384632864525658762677744314646333
4125132521333231232235325331322342325622223234122792354213323311343523232323513253493324352496461423
3362421473222221213315222122344245222332224252326272222233232223321122235226142321223231326313224262
3732354133363432432423713233832433328234144313334323734464244363423672452673398233733263233338332332
3767773886665564214526315412774737756177467576263358827536626878161412332417831532815537625153423729
5521353234533542595546884224253243311325323554357328942323262343928222538322263522364222442233333513
2122322414223533222473242424222413224345321522325224322233424513224423322265123243112323352122333232
7483463487356554736635846165545667958374844736734327464437954584362574727377684673345568765357378597
2223232322112222262322322222223231422232232138221132212222221222213211221422223221321122111312126322
3366233325237424446412434433264222422124255734432634244335324412245234313132252455237262464232345253
4632413335342647253154534151123228132631386328422413224472722724124342692236632614222343373223423233
3342342323422353444442211123321342434233724244422661444243432722422232322335141331341534432231731331
7432225572522677423322272674452522724824325224215725322516323534252222823224553583222223552526274681
6564655556755655663744565365543666448665653225365335532354433635744424842635386541465356658353534585
1131244223511213433154353112523334432223215444342241233422145422553442224323331354313244212522426789
1111213122221322123222222222522212147228223621223212221222292312212231212121222222212231211222522222
2231621272211225174214132224132343252231425544532282456435473144273127234233623632443512324484121493
2121243212342132322231232321322151244424133442362222324422232121424122332112222233313421412322213232
2165314643441353632241614323463656325426665666531632561352152353513121235251663454652635354134356789
2475231214243222622422128232222142342334542525221442122264428122222445212442812222331313922242222331
3223323354333323234372444242373463821436122221823232432533533332344446513142323333541222341244217455
7455526631444542356445533352351453423842653536563363453344445222432533133425443346642463393231542655
8653953554777855947635356623955473553347535456542373216442635855766435335778333435863355534534696334
2123313323533233522234325253134223134342463263454131142213134333334342242414333242344253333223253576
4433351364335323163334323233734633344234343533524223331454334134343345333444333552324335333343135322
2676247333884956267277436553754385673228458733632722367132455754724742672592656787535922265428847452
5323342343344336454433333263423311328341322515255533364322646234565644344713216323855642632233565373
1133221326942423244343323212222522121122242234221225552555243122222312226242322423242232122444161112
5745757585647764645595455547777555574756775757484475665467555762654756556574765346685567548956663759
4571321513255225214645223224114322318122222133446333321233692233524333646292412121393432285264282222
3315332122322222252323332342321332263332143133412214123234344222242232422421243212314333132222424435
3712452322745236234223432424523225472154354252623312322322292124423152214233272422452233312342222123
2122122322222323222222212212222222332221213623222211262522221222212222212222121122224222222222111221
3878463445456594343447696625474456434384664578488543373834987437558867455385835783452453584558746285
8227231432234323326226222222223372233534224124232221133433311232252143422323253144252323242443131223
3132233422232215222221112223612232536153612126257222232312223242621262223332122326225212331248125352
8899389687567746688684992465866799836886577885757998968855448995658978853857785665776749875746666754
6475176885462947335537363373673946483735476343335337376275334622583395356234523457624566667937332358
5224457327442414324723564554424233627423444241443524344435827527429432834214343559324444555454761422
4345325324355364334338464343241431247363234433363424532466863333432433643343475452322533364254343431
5625893313532515654777281766549484453214439528733524862827285532721155253735432342894254445442515426
2122223322323322233323333223313252222332324223123133413222233233323314213333222523332334223636232232
3566454444795375834465668434645852632845467948764654464536444457635457666446253333457744448568467955
3332274361452133542353243425423322231353344222151231312224534225344533323512113225552346234224515122
3354332242433513337253337122133125323366332332223232244315522724231444323232633334123733113142742332
1623223222222531261632222222222122122132143453212312262623222212222522112122223723222232225514326145
5436354633654663574759344344656465454835454465474656557565544645346443956474444444954284444443734465
5429583223625147865243782836886657435836657243263351643255252433652481223336266125523653422527977354
3333221212323232323322224222224222232323233222233232212223322232232123122323222323323123233242273222
2312322223223323122223323243322233333123322224331223133421423222331223343245423333234322422321233322
5526855555441556453553354355557545724544436564664664877456643366453637585245747634666665454447345764
2231312322221222122222221343522122112222225222123221221221221232222222242231112122222221221121222311

92
2025/go/day04/day04.go Normal file
View File

@@ -0,0 +1,92 @@
package day04
import (
"adventofcode2025/utils/grid2d"
"adventofcode2025/utils/inputs"
)
func Part1(input string) int {
adj := 0
rolls := 0
grid := inputs.ToGrid2D(input, "\n", "", "", func(c string) string { return c })
directions := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {-1, 1}, {1, 1}, {-1, -1}, {1, -1}}
for j := 0; j < grid.SizeY(); j++ {
for i := 0; i < grid.SizeX(); i++ {
if !checkChar(i, j, grid, "@") {
continue
}
for _, dir := range directions {
x := i + dir[0]
y := j + dir[1]
if checkChar(x, y, grid, "@") {
adj++
}
}
if adj < 4 {
rolls++
}
adj = 0
}
}
return rolls
}
func Part2(input string) int {
grid := inputs.ToGrid2D(input, "\n", "", "", func(c string) string { return c })
rolls := countRolls(grid)
total := rolls
for rolls > 0 {
removeRolls(grid) // modifies grid
rolls = countRolls(grid) // compute only once per loop
total += rolls
}
return total
}
func checkChar(x int, y int, grid *grid2d.Grid[string], c string) bool {
if x < 0 || x >= grid.SizeX() || y < 0 || y >= grid.SizeY() {
return false
}
if grid.Get(x, y) == c {
return true
}
return false
}
func countRolls(grid *grid2d.Grid[string]) int {
adj := 0
rolls := 0
directions := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {-1, 1}, {1, 1}, {-1, -1}, {1, -1}}
for j := 0; j < grid.SizeY(); j++ {
for i := 0; i < grid.SizeX(); i++ {
if checkChar(i, j, grid, ".") {
continue
}
for _, dir := range directions {
x := i + dir[0]
y := j + dir[1]
if checkChar(x, y, grid, "@") || checkChar(x, y, grid, "x") {
adj++
}
}
if adj < 4 {
grid.Set(i, j, "x")
rolls++
}
adj = 0
}
}
return rolls
}
func removeRolls(grid *grid2d.Grid[string]) {
for j := 0; j < grid.SizeY(); j++ {
for i := 0; i < grid.SizeX(); i++ {
if checkChar(i, j, grid, "x") {
grid.Set(i, j, ".")
}
}
}
}

View File

@@ -0,0 +1,35 @@
package day04
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1(`..@@.@@@@.
@@@.@.@.@@
@@@@@.@.@@
@.@@@@..@.
@@.@@@@.@@
.@@@@@@@.@
.@.@.@.@@@
@.@@@.@@@@
.@@@@@@@@.
@.@.@@@.@.`)
require.Equal(t, 13, r)
}
func TestPart2(t *testing.T) {
r := Part2(`..@@.@@@@.
@@@.@.@.@@
@@@@@.@.@@
@.@@@@..@.
@@.@@@@.@@
.@@@@@@@.@
.@.@.@.@@@
@.@@@.@@@@
.@@@@@@@@.
@.@.@@@.@.`)
require.Equal(t, 43, r)
}

140
2025/go/day04/input.txt Normal file
View File

@@ -0,0 +1,140 @@
@@@@@@@@@.@@@@@@@@@.@.@..@@..@@.@.@@.@@.@@@@@@..@@..@.@.@@..@.@.@@@@@.@@.@@@@@@..@@@@@@@....@@@@@@@@.@.@.@@@@@@@@@@.@..@@@@@@@@@@@@@@@@.@.@@
@@@.@@@.@@@@@@..@..@@@@.@.@.@.@@@@.@.@@@@@@@..@@.@@.@.@@@@.@@@@@@.@@@@.@.@@@...@@.@@@@@@.@.@@@.@.@@@@@.@@@@@@@.@@.@@@@@@@@.@..@@@@.@@@@@@.@@
@@..@@.@@@.@@@@..@@..@..@@@@@@.@.@@..@@@@....@@@@@@.@.@@.@..@@@@@.@@@@.@@@@@..@@@.@@.@@.@@..@@@@@@@@.@@@@.@@@.@@@@@@@@@@.@@.@@@@.@@@..@@@.@@
@...@@.@...@@@@@@.@@..@@@@@@@.@...@@@@.@.@@...@@@.@@@@@@.@@@.@@@.@.@..@@@@@@@@.@.@@@@..@@@.....@.@@@@..@...@.@@@@@..@@@.@@@.@@....@.@@@...@.
..@@@@@.@.@@.@@@..@@@@@@.@@@.@@@@.@@@@.@...@@@@@...@.@@@..@..@..@.@.@.@@@@..@....@@@...@@@@@.@@.@@.@..@.@@@..@@@@@@@@..@.@.@@.@@@..@@@..@@@@
@@@.@@..@@.@@@..@@.....@@...@@@.@.@@@@@.@@@@..@.@@@@.@.@@@@@@.....@@.@@.@..@@@@@@@..@@.@@..@@@@.@@@.@..@@@.@@@@.@@@.@@@.@@@@@@..@@@@@@.@.@..
.@@@@.@.@..@.@@@@...@.@..@.@@@.@..@.@...@@@.@@..@..@...@@@..@@@@.@@@.@@@.@@@@.@.@...@@@@.@..@@@.@@..@.@.@@...@.@@.@.@@.@.@.@@@@.@@..@@@@.@@.
.@@@@@@@@@@@...@.@.@@@.@@.@.@.@.@@@@@@@.@@.@@@......@.@@.@@@.@@@@...@@@@@@@@@@@@@@@@.@@@.@@.@..@@.@@@@@..@@@@@@...@@@.@@@.@.@@@@.@@@@@@...@@
@..@.@@.@@@..@@@.@@.@@@@@@@@@@@@@@.@....@...@@.@@@..@@@@.@@@@@@@@@.@.@@..@@.@@@.@.@.@@@.@.@@@.@@@......@@@@...@@.@@@@.@.@@@.@.@@..@@@@.@.@@@
@@.@..@.@@@@@@@@.@.@@@@@.@.@.@@.@@@.@@@@@@@.@@@@@..@@@@.@@@@@@..@@@@@@..@.@.@@@.@@@@.@.@@.@@@.@@@@.@.@@...@@@@@@@.@@..@@@@.@@@.@@@.@@@@@..@@
@..@.@.@..@.@@.@@@.@..@@@@.@.....@..@@@@@..@@@..@@.@@@@@@.@@@....@@..@@@@@@@@@..@@@.@@..@@@.@.@@@@@.@@.@@@..@...@@.@@@..@.@.@.@@...@@.@@@.@.
.@@@.@@.@@@..@..@@.@.@@@@@@.@.@.@@@@.@@@@@@@@..@.@@@@@@@@.@@@@@@@@@@.@@.@@@...@@.@@@@@@@.@@@.@..@@.@....@@.@@...@@.@@..@.@..@@@@..@.@@@.@..@
.@.@@@.@@.@..@.@.@.@@.@.@@...@.@@.@..@.@..@.@@.@@.@@@@@.@@.@.@.@@@@@@@@@@@.@@@@@.@.@@.@@@.@.@@@@.@@@@.@..@.@@@@@.@@@@@.@.@@@.@@@.@@@@.@@.@@.
.@@..@.@@@@.@@@@@.@@@..@@@..@...@@@@@@.@.@.@.@@@@@@@.@@..@@@.....@@.@.@@@..@@@@..@@@..@.@@.@@@@@@.@@@...@...@@@@.@@@@@@@@@..@@@.@.@@.@@@@@..
.@..@@.@..@@@@@@@@@@@@.@@@@.@..@.@@@......@@@@@@.@.@..@@.@.@@.@.@...@.@.@@@@@@.@@@.@@@@@@..@.@.@...@..@@.@..@@@...@.@@@..@@...@@@@@@@@@..@..
@@.@...@@@@.@..@@.@@@.@@@.@.@.@.@.@.@.@@.@@@.@.@@@@@.@@@..@@..@..@@@@.@.@@@.@@.@.@@@@@@@@@.@.@.@.@@@@.@@@.@@@@.@@@.@..@.@@@@@@@.@@..@@@@..@@
@@.@@.@@.@@@@.@@@.@@@.@@@@...@@@@@@@@@.@@@.@@.......@@@..@@.@@@@@@@@...@@.@@@@@@@@@.@@@@@@@@.@.@@@@.@.@@@@@.@@@@@.@.@@@.@@@@@@@@@.@@.@.@@@.@
.@.@@@@@@@@@.@@@@..@.@.@.@@@@.@@@@@.@@....@.@.@.@@..@.@@@@@.@@@@@@@@.@.@@...@@@.@@@.@@@...@.@@@@@.@.@.@@@.@@@.@@@...@@.@@@....@.@@@@.@@@....
@.@@@.@@.@@@@@@@@@@.@@.@@@@@@@@@@@.@@@@@@@@@@@.@@@.@@.@..@.@@@@.@.@.@@.@..@@@@.@@@@@@@..@@@@@@@@.@.@.@@@@@.@.@@@@@..@..@.@.@@@.@@.@@@@..@@@@
.@...@@@@..@@@@...@@@@...@@@@.@...@.@@.@@@@@.@.@@@.@@@@@.@.@@@@@@....@@@@@@....@@@@.@.@@@@@@.@@@@@.@@.@..@.@@@@...@@@@@@.@..@@@@....@.@@.@@@
..@.@@@..@@@@.@@@@..@@.@@....@@@@.....@.@.@@@.@.@@@.@@@@@...@@@@@@.@@@@@..@@.@@..@@@.@..@.@....@@@.@.@.@.@@.@@@@@@@.@@@@@@@@.@.@.@@@..@..@.@
.@.@@@@@@@@@@@..@.@@@@.@@.@@@@..@...@..@@@.@.@@@@...@.@.@@..@.@@@@@@@@.@@.@.@..@@@.@.@@...@.@@@@..@.@@.....@.@@@@@.......@@@@@..@@@@@@@.@.@@
@@.@.@@@@@@@@@@@@.@@.@@@@@@.@@@.@.@.@@@@@@@.....@..@@.@@@@.@.@@@@@@.@@...@@.@@.@@@@.@.@....@...@.@.@@@@@@.....@@..@.@.@@.@@@@...@@@@@.@@@@@@
.@@@@..@@@@@@..@.@..@.@@.@...@@@@.@@@.@@.@@....@.@@@...@.@@....@.@@.@@@..@@@@.@@@@.@..@.@.@@@@.@@@@....@@.@@..@@@@@@.@@.@@.@..@@.@.@@@....@@
.@@.@@.@@@@@@@.@@@@@@.@@.@.@@@.@@..@.@@.@.@@@@@@.@@@.@@@@@@@@.@....@@@@@@..@...@.@.@@@@@@@.@.@@@@.@.@@@@.@@@....@@@@@@.@@@@@@@@@.@@@.@@@@@@.
@...@@@@@@.@@@.@..@@@.@.@@.@@.@@@@.@@@...@.@@@@@@@@@@@..@@@..@@..@@.@.@@.@@@@@@@.@@@@@.@@.@..@@.@@...@@@..@@@@....@@.@@@@@@@@@....@.@.@.@@.@
.@.@.@@@@@@@.@@.@.@@.@.@@@@.@@@..@@@@@@.@@@.@@.@@@@@.@..@@@@.@@@...@@@..@..@@..@.@@@@@@.@@@@@@.@@@@@.@@@@@..@@@.@@@@.@@.@@.@@@@@@@@@...@.@@@
@.@@@@@.@.@.@..@.@..@..@.@@@@@.@@@@@@@@@@.@@@@@@@.@.@@.@@@@@@..@@.@.@@@.@..@.@@@..@.@@@.@@@..@@@.@@@@@@.@@.@@.@.@@@@..@@@@@@@...@@@@@@...@@@
.@@@@@@.@@@.@@.@@@..@@.@@@@@@@.....@@@@.@@@@@@@@.....@.@@@.@@@@@@@..@.@@@@..@@.@....@.@.@.@@@@@@@@.@..@..@..@@@@..@@...@@@.@@@@..@@@@..@@@@.
@@.@@@@.@@@@@@.@@.@@.@@@@@@@@@@@.@@.@@..@@@@.@@@.@@.@@@@@.@.@@@@@@..@@@.@@@@@.@@.....@@@.@@.@@@@@@@@.@@@..@@..@@.@@.......@.@@@@...@@@@.@@..
@.@.....@@@...@@@.@@..@.@@@@@.@...@@.@@.@@@@@.@@..@@@@@@@@@@@.@@@.@@.@@@@..@...@@@..@@@.@.@.@.@.@@@@..@@....@.@..@.@@@.@..@....@.@@.@.@.@@@@
@@.@@@..@@@@@.@.@@.@@@@@@@@.@..@@@@..@@@@@@..@.@@.@@@@@@@@@@@@@..@@.@@@@.@@.@@.@@@.@@.@.@@@@@@@.@@.@@.@@@@@@@.@@....@@@...@@@@@@@@@..@@.@.@@
@..@..@@@.@..@@@@...@@.@.@...@.@@.@.@@.@.@.@.@@@@@.@.@@@@@@@@@@@..@@.@.@..@@.@@.@@.@.@.@@.@@.@@@.@@@..@..@@.@@.@@@@..@...@@@.@@@.@.@@@@@.@@@
@@@.@@.@.@.@@@@@.@@@....@@@@@@@.@@@@.@@..@@@@@@.@.@@.@.@.@@@.@.@@@@@.@@@...@@@.@.@@...@.@@.@@@@..@@@@.@.@..@@@@.@@.@@@@@@@@@@..@@@@.@@@.@@.@
@@.@@@..@@..@.@@@..@.@@@@@.@..@@@.@.@@.@@.@@@.@@@@@@.@@.@@.@@@@.@.@@@@@.@@@@.@@.@@@.@@..@@@@.....@@@@.@@@@@@@.@@@.@@.@@@@@..@@.@@...@@@@@@.@
@@@@.@.@@@@.@@.@@@@@..@.@@@@.@@.@.@@@@@@.@@.@@.@@.@@@.@@.@@@.@@@.@@@...@@@@..@@.@@@@@@@@@..@@@..@.@.@.@@..@@.@@@@.@@@.@.@@@..@@@.@@@@@@@@@.@
@@.@@..@@@.@@.....@...@@@.@@.@.@..@.@.@@@@@@.@.@@.@.@.@@.@.@@@@@@@@..@@@@.@@@.@.@@..@.@.@@@@@@@@@.@@@@@@.@.@..@@..@...@......@@@.@@.@@@@@@@.
@@@@..@...@@@@.@@@@@@@@.@@...@.@...@@@@.@@@@@@@@.@@@..@@.@@@@@.@@@@.@.....@@.@@.@.@..@.@@.@@@@@.@@@@@.@@@@@@@.@@@@..@@@@@@@@..@..@@.@@.@.@@@
.@@@@@@.@@.@@@@@@@.@@.@@.@.@@....@@.@.@@@@@@..@@@.@.@.....@.@@@@@@@@.@@@...@.@@.@.@@@@@.@...@@..@@.@@@@..@....@@@..@@@..@..@@@@@.@@....@@..@
@@@.....@.@@@@@@@@@.@@@@@@@@.@.@@.@@@...@@@.@@@.@@@@@@@.@@@.@..@@@@.@@@@@.@@@@.@@@@.@@.@@@@.@.@@@.@..@@@@.@@..@@.@.@.@@.@@..@@.....@@@@@@@.@
@@@...@.@@.@@@@..@@@@@.@@@@@@@...@@..@@@.@.@@@.@@..@@@@.@@@@.@@.@@..@@..@.@@@@.@@@..@@@@.@@@@.@@..@@..@.@@@.@..@@@@@@@.@.....@.@.@.@..@@@@@.
..@...@@.@@@@.@.@.@...@@..@@.@.@@.@@@.@@@@@@@@.@.@@...@.@@@@@@@@.@.@@@@@@@.@@@@..@@@@@@@@..@@@@@@.@@@...@@@@..@@.@@@..@.@@@@@@@.@@@..@@@@@@@
.@.@.@.@@@@@@@@.@@@@@..@@..@@...@.@.@@....@@...@@@....@@.@.@.@@.@@.@@.@...@@@...@..@.@.@.@.@@@.@@@.@@.@@@@@@.@...@.@@@@@@.@@.@.@@@@@@@@.@@@.
@@@..@@.@@@@@.@.@@@.@@@@..@....@..@@..@@@.@.@@@.@@...@@.@@.@.@@...@@@.@@.@@@@@.@.@.@@@.@@.@@@...@@.@....@@@.@@@.@@.@@@@.@@.@.@@@@@@.@@...@@@
@@@@.@.@@@@@@.@@.@@@@@@@@.@@@@@@@@@@.@@@@.@@@@.@@@.@.@@.@.@@..@@.@.@@.@@@..@@.@...@@.@@..@@@@.@@.@@....@@@...@@.@..@@@@@.@.@.@.@.@@.@@@.@@@@
@@@@@...@@@@.@.@@..@@@.@..@@@.@.@.@..@@@...@@.@@@..@@.@@..@.@@@..@@@..@@@@@...@@@@@.@@@...@@@@.@.@..@.@.@@.@@@...@@@@@.@@..@@..@@@.@@@@..@..
..@@@@..@@@@@@.......@@..@.@@.@@@...@@.@@@@@.@@@@.@...@@@@.@@.@@.@@@@.@@.@.@.@@@.....@@...@@@@.@@@..@@@.@.....@..@@@@...@@@@@@..@@@@@.@..@@@
@.@@@@@.@@...@.@@@@@@@@.@@@@@...@.@.@@@@..@.@@@.@@@.@@.@@.......@@.@@@@.@.@@@@@@@.@.@@..@@@@.@.@@.@@@@@..@@@.@.@...@.@@..@@@@@@.@.@@@...@@..
@@@..@......@.@@@...@@@@.@..@@@@@@.@@@..@@@@@@@@@@@@@.@@@@@@@@@.@.@..@.@@@..@.@.@.@@@@.@@@@..@@.@@..@..@@@@@@@@@@@@@@@@@@@.@@..@@.@@@@@@@@@.
.@@.@@@@@@@.@@.@@@@.@.@..@@@@@..@...@..@...@@@@@@@@@@....@...@@..@@@.@@.@@@@@@@.@@...@@@@.@@@@..@...@@@.@@.@.@@@@@@@.@.@.@@@@@@@..@.@..@@@..
@@@..@..@@.@.@@@.@@@.@@.@@@.@.@.@.@@.@@@@..@@.@.@@.@..@@@@@@.@@@..@@@@@@@@@.@@@@...@@@@@@.@@@@@.@...@@.....@.@.@@.@.@.@@@@@@@.@..@@@@.@.@@.@
@@@@@@@@....@..@.@@@@.@@@@.@@@@.@@@.@@@@.@@@@@@@.@@@@.@.@.@@@@@@..@@@@@..@@@@.@.@@@@@@.@.@.@@@....@...@.@.@.@@....@..@@@@@@@@@@@@@@@@@@.@@@@
@.@@@@@@@@@@...@@@.@.....@.@@@..@@.@.@@.@.@.@@@@@@@@@@@@.@@.@@@@...@.@.@@.@...@@@@..@@@@@@.@@@.@.@@@.@@.@.@@@@@@@@@.@@@...@@@@@@@@.@@@.@@@@@
@@@.@.@@@.@.@@@..@@@..@@@.....@.@.@@@@@..@@@..@@...@.@.@@.@.@@@..@..@@.@.@@..@@@..@@.@@@@..@..@@.@@@@@..@@@@@@.@@@@@@@@@.@@@@...@@..@@@@@@@.
.@.@@@@.@@@@@.@..@@@@....@@.@.@..@@@.@@.@.@.@.@@@@....@.@@@@...@@@@@@@...@@.@..@@.@@.@.@@.@.@@@@@.@.@....@@.@@@.@.@@...@.@@@@@@@.@@.@@@...@@
@@..@@@..@@@@.@@@@@..@.@@.@@@..@.@@@@@@@....@.@@@@.@@..@@...@..@@.@@@.@.@@@@.@@@@.@@..@@.@@@@...@@..@@@@@@@..@@.@@.@@...@@@@.@@@@.@@..@@@@.@
@..@@.@..@.@@@...@@@@.@..@@@.@.@@@@@.@@@.@@@@.@.@.@..@@..@@@.@@@@@...@@.@..@@@.@..@@.@.@@@@@@@@@@@@@@@.@@@@@...@@@.@@.@@.@@@@@@@.@..@.@@...@
@..@..@@@.@.@@@@.@...@@@..@.@@@@.@@@@.@@@.@@.@@@..@@@.@@@.@@@@@@.@.@@@@@@@.@@@..@@.@.@@..@@..@@@@.@.@@@.@@@.@@@..@..@@..@@@@@...@@@@....@@@.
@.@.@@@@.@@.@@@@@@@..@..@.@@@@.@.@..@@@@@..@...@@@..@@@.@.....@@...@..@.@@@.@@..@@.@.@@.@@@@@@@@@@.@.@@.@@@@......@.@.@.@@.@.@@.@@@@@@.@@..@
@.@.@.@@@@@@.@.@@@@.@@@@.@..@@@..@@@@@@@@@@.@@.@@@@..@.@......@.@.@@@@...@@@@@@..@.@@@@@@@@@@@..@.@@@@@.@@.@@@.@@@....@....@@@@@@@.@@.@@.@@@
@@@@@.@@.@..@@@@@@@.@@.@@@.@@.@@@@@@..@..@@@@@@@@@.@@@@@@@.@@@@..@@@@..@@..@@@.@@@..@.@@@..@@@.@.@@@@@@@..@@.@@.@@@.@@.@@@.@@@@@@@@@@@..@@@@
@@@@....@.@.@.@.@.@@@@@.@@..@@@@..@@@.@@@@@@@@@@...@@@..@@@@..@@@@@.@@@.@@.@@@@@.@..@....@.@.@@@...@@@@.@@@@@@.@@.@@@.@@....@.@@@@@@@@...@.@
@.@@.@...@.@@@@@..@@@@.@@@...@@@@@.@@@.@....@@.@@@..@..@@.@.@@@.@@@...@@@.@@..@.@@@.@@@@.@@..@..@.@..@...@@@@...@@@..@..@@@@..@@.@@..@@@@@.@
@@.@@.@@@@.@@@..@@@.@@.@@@.@.@...@@.@@@@.@@...@.@....@.@@@@.@..@@.@@@@@@@@@@@.@@..@@.@@@@@..@.@..@@@@@@@.@.@@.@@@@@@@...@@@@@..@@@@@@.@@@.@@
..@..@@@@@@@@..@@@.@...@.@@@.@@@....@@@@...@@@@@@.@.@@@.@@@@...@@@@...@@.@@.@.@@@@@@@.@..@.@@@@@.@@@@@@@@@@.@@@@@@.@..@@..@@@@@.@@@@@@.@.@@@
..@.@@@@@@..@@@@@.@.@@@..@.@@@@@.@@@.@..@@@@@@@.@@@@.@@@@@@@...@@@@..@.@@.@@@..@.@@@@@@...@@@@@..@..@@.@@@.@@@@@@@@..@@@@@@@@@.@..@.@@@..@.@
.@@@.@@@@@@.@@@@.@@@@@@.@.@@@.@.....@@.@@@@.@..@..@.@.@...@...@.@.@@..@@@@@@@.@@.@@.@.@@.@.@@@@@@@.@@@....@@.@@@@@@@.@@@@@@.....@..@@@.@@@.@
..@...@@.@@@@..@@@@@@@.@.@.@@@@@@@@..@.@@@.@@@.@@@.@@@@@@@..@@@...@@@.@@@..@.@.@@@@@@...@@@.....@@@@@@@..@@@@@@@@@@@..@@@@@..@@@@.@.@.@@@.@@
@.@..@@@.@@@@@@..@.@.@...@@@@@@@..@@@@@@@@@@@@@@..@@.@@.@@...@..@@.@@..@@...@@@...@@@@@@@@@@@@...@@@.@@@@@@@@@...@.@@@....@@@@@@.@@@.@@@@@@@
.@@@.@@@@@@.@@.@@..@@@@@@.@.@..@.@@.@@@@.@@@..@.@@@.@@@@.@@@@@..@@..@.....@.@@@@@@....@@@@@@@@..@@@@@..@..@@.@....@.@@@.@..@..@.@@...@@@@.@@
@@@.@.@@.@@.@..@.@.@@@@.@.@@...@@.@.@.@@@@@...@@@@.@@.@@@..@@.@@@.@@@.@...@@.@.@@.@@.@@...@@.@@..@@.@.@@@@@@@@.@@...@@@@@@@@@@@.@@..@@@@@@..
.@.@.@@..@.@.@@.@@@@@..@@.@@@@.@...@@@.@.@@.@@@.@@@@@@@@..@@..@@@.@@@..@.@@.@.@@@@@.@@@@@@..@@@@@@@@@@@@.@@@@.@@@.@@@.@@@.@@@@..@.@@@@.@@.@.
.@@@.@..@.@@..@@@.@@@@.....@@@@@@@@@@.@.@.@@@.@@@@@....@@@.@@@.@@...@@@.@@@..@.@@.@@@@@@.@...@@.@.@@@.@..@@@@@@..@@@@@..@.@.@..@@.@@@@@@@@@@
.@.@@@.@.@@@.@.@@.@@.@@..@.@@@.@..@@..@@@@@.@.@..@.@..@..@@.@@@.@@.@@...@@@@@@@.@.@@@.@@...@.@@..@.@.@@@@@@@@@@@@@@@@@@@.@.@@@@@..@..@@@@@@.
...@.@.@@.@@@@.@.@@......@.@.@..@@..@@@.@@@@....@@@.@...@.@@.@@@@@@@@@...@@..@.@.@.@@...@@.@@.@...@@.@..@@.@.@....@@..@@.@@@..@@.@.@@@..@@@@
@.@@@...@.@@@@.@@.@..@@@@..@@@@@@@@..@@@...@@@@@.@...@@@@@@@@@@...@@@@@@@@@@.@@@@@@@@@...@@.@@..@@.@@..@...@@@@@@@.@@..@.@.@.@.@@@.@.@.@.@@@
@@.@@.@@@@....@.@...@...@@@@@@@.@@@@@@@@@@@.@@@...@@@@@@@@@@@@@@@.@@..@.@@@.@@@.@@@@..@.@@@@..@@@@..@.@.@@.@@@@@@@.@@@@@@@@.@.@@@@@@@@@@.@@.
@@@@@..@@..@@@@@.@@@.@@@@@.@@@@@@@.@@@@@.@@..@@@.@.@@@@@.@.@@@..@@.@...@@@.@@..@.@.@@@.@.@@@@@@..@@@@.@@@@..@@..@@@.@@@@@.@.@...@@@@.@@...@@
@....@@@@@.@.@@@..@.@.@@.@..@.@@.@@@@.@@@...@@.@@@@..@.@.@.@@.@@.@@.@@@.@.@.....@@@@@.@.@@@..@..@.@.@@.....@@@@@....@..@@@@@@@@@@@@.@@.@@@.@
@@@@@@...@@@..@.@@.@..@.@@@@.@@@@@.@@@@..@@@@.@@@@@@..@..@@@@@@..@.@@@..@.@@.@@@@.@@.@@..@@@@..@..@.@@.@.@@.@@.@@@.@@@.@@@@@@@@....@@.@@.@@.
@@@@@@.@@@.@@@@@@@..@@..@@@.@@@@@@@@@@@@.@@@.@@.@.@@@.@@@.@@@@.@@@@@.@.@.@@@..@@@@@@@@..@@@@@.@@@@@.@@@..@@.@.@@@.@@@@..@@@.........@@@@@@@@
@@@..@.@@@@..@@@@@.@.@@@..@@.@..@@..@@..@.@@@.@@@.@.@.@..@@@.@.@@.@@.@...@@.@@@@.@.@.@@..@...@.@.@@@@...@@@....@@@.@@@@.@.@@@@@@.@@@@.@@@@.@
@@.@@@@@@@@..@.@.@@@@..@.@@@@@.@@@@@@@@@.@@@@@@.@@@@.@@@@@@.@@@@..@@@...@@@.@@@@.@@.@@..@@@@.@.@.@.@@@@@@...@@@.@...@.@.@.@@@@@@@@@@.@@@@@@@
@@@@@.@@..@@.@@.@@@@@@@@.@@@@@...@..@@@@.@@..@.@..@@@..@@.@@@@.@.@@.@.@@@@.@@@@@.@..@@.@@.@@@.@@@@.@@@@..@@@@..@@@@@.@@..@.@@@@@@.@..@@@.@@@
@.@@...@..@@@@@@@.@@..@..@.@@.@@..@...@..@.@.@.@.@@@@..@@@.@.@@@.@..@...@.@@@.@@@@..@@.@@@@@.@@..@@@@.@.@@@....@@@@.@..@.@@@.@.@@..@.@@..@@@
@@@.@@@..@@@@.@..@@@..@@.@@@@@....@.@@@@...@@@@@@..@.@@@..@@@@@@@.@@.@.@@...@.@@@.@..@@..@.....@@@@..@@.@@@@@.@..@.@@@@@@@@..@@@..@@@.@@..@@
.@@@..@.@@.@.@@@@.@@..@.@@@@@@@@.@@.@@@@@@@.@@@...@.@.@@.@.@.@@@@@@@@@..@@@@@..@@...@.@.@@.@@@@@..@@.@..@.......@@@@@....@.@.@@@@.@@..@@@.@.
.@..@@.@@@..@@@.@@@@@@.@.@...@@@@@@..@@.@@@@@@@@.@.@@@@@@@@..@@@@.@@..@@@@@@@@.@@@..@@@@.@.@@.@.@@@.@@@..@@@..@.@@.@..@@@.@@@.@.@@...@.@@.@.
@@@@.@@@@@.@@@.@.@@@.@.@....@..@.@@@@@.@..@@@@...@.@.@@@@..@@.@@@.@@..@@@..@@@.@...@@.@@@@@.@@@.@.@@@.@...@.@..@.@..@@@@@.@@@@@@@@.@@.@@.@..
..@@@..@@@@@@@@@@@@..@@@@.@@@.@@.@@@..@@@.@.@@@@@.@.@@@@.@@@@.@.@@@@@@@@@.@@@.@@..@@@@@..@.@@.@.@@@..@.@.@@..@.@.@@@..@......@@@@.@@@@.@.@@@
@@@@.@..@.@...@.@.@@@@@.@@@..@@@@.@@@..@@@@.@...@@..@@@..@.@@.@@@@@@.@@@.@@@@@@...@@.@@@..@.@@.@.@.@@@@.@@.@@@@.@@@@@@.@@@@@@@@@..@@..@.@.@@
.@.@@@@..@.@.@@@.@..@@@.@.@@@@.@.@.@@..@.@@@@..@...@@@@@@@@@.@@..@.@@@@@@@@.@@..@.@@@.@.@.@@@.@@@@@.@.@@@@@@..@.@.@.@@@@@@.@@.@@@@@.@@.@.@@@
@..@@@@@@@.@@@@@.@.@@@@.@@@..@@.@@@...@..@@@@@.@@.@@@@@..@.@@.@..@@@..@@..@@@@@@@@@.@@@@@..@@@@@@@@@.@..@@.@...@@@.@..@@.@...@@@.@@@.....@@@
...@@@@@@@.@.@@@.@.@@.@@@.@@@@@..@@@@@@@@..@..@.@.@@@.@@@@...@.@@..@..@.@@.@...@@.@@.@.@@@@....@..@@@@@@@@...@@.@.@.@@@@@..@@@@@@.@..@@@.@@@
.@@@.@.@@....@@@..@@@@@@@..@...@@.@@@@.@@@@@.@@.@..@@@..@@.@@@@@.@..@@@..@@@@@@@.@.@@...@@@..@@@@@@..@@@@..@@.@@..@.@@..@@.@@@@.@@@@@@@@@@@@
....@@.@@@.@.@@...@..@.@@@.@...@@@@.@.@@@@@.@@@@...@@..@@.@@@.@..@@....@..@@@@@.@@@.@@@..@.@...@...@.@@@@.@..@@.@.@@@..@.@@@@@@@@@@.@@@@...@
.@@@...@.@@@@....@..@@@@@@@@@@@@.@@@.@@@@@@@@@@@...@.@@.@@.@@.@..@@@@.@@@@@@@.@@@..@@@.@@@@@.@@@..@.@@.@.@.@@@@@@.@@@@@@@.@.@..@@@@@.@@.@@..
.@@@@@@@.@@..@..@@@@@@@@@.@.@@@@@.@@@@.@@@..@@.@@..@@.@@@@..@@@@@@@.@.@@@@@@.@@.@@@@@@@@@@@@@@.@@.@@@@@@@@@@...@..@@...@@@@..@@.@..@..@@@@@.
.@@@@.@@.@@..@@@.@@.@.@@@.@.@.@@....@@@..@@.@@@@@@@@@@.@@@@@.@.@@@...@@@@@@@@....@@.@@@.@....@@@@@.@@@@.@@@..@@...@...@.@@@..@@@.@@@@@@@@@..
@.@@@..@@.@@@..@@.@.@.@..@@@@@@@@@@@@..@.@@.@@@@@@@.@@@@@@@@..@.@@.@.@@@..@@@..@.@@@@@@..@@.@@.@@@@.@@@...@@@@...@.@..@@.@@@.@.@@@@@@@.@@@@.
..@@@@.@@.@.@.@@@.@@@..@..@@@@@@..@.@@@.@@.@.@@@@@.@@.@@@@@...@.@.@@.@.@@@@@.@@@@@@@@@@@@...@.@.@@@..@.@@@@@@..@.@..@@@.@..@.@.@@@.@.@@@....
..@@@.@..@@@.@@@..@@.@.@@@@.@@.@@@@@@@@@@.@@@@.@@.@@@@@.@..@...@@..@@@....@@@.@.@..@@@@@.@..@@..@@.@.@@@@..@@@@@.@.@..@@.@@.@@.@@@@..@@@.@@.
@@.@@.@.@@@@@@@@@.@@.@...@@@@@..@@@@.@.@@@@@@@@.@@@.@@.@...@@..@@@@@.@..@@@@.@@@.@..@@@@@..@@@@@.@@@.@@.@@@@.@@@@@@@.@@.@@.@.@..@.@@..@@@@@@
@.@@..@.@@.@..@@@@@@@.@@.@@.@@@.@.@.@@@...@.@...@.@...@.@@@@@..@.@@@@@@@.@.@.@@..@.@.@@.....@.@@@@@@@@@@@@@.@@.@.@..@.@...@@@..@@@@.@@@@@...
@@@@@@@@@@@@@@.@.@@@@@.@.@@@@@@@@.@@.@.@@@.@@@@@@@..@@@@.@@@@.@@@@.@@.@@@@.@@@@@@@@.@@@@@@@.@@.@.@..@@.@.@@..@..@.@@@.@.@@.@@.@.@.@@.@@@.@@@
@..@...@..@@@@@.@.@@@@@@@@@...@@@.@@@.@@.@@@@@@@.@..@@@.@@.@..@@@@.@@.@@@...@@@@@@@.@.@.@@.@@....@@....@.@@.@@@@..@@@@@@..@..@@@.@.@@@@@@.@.
@.@.@..@..@@..@@@.@..@@...@@@@@@@.@@.@.@..@..@....@@.@@.@..@@@...@@@@@@.@@@@@@.@@.@.....@@..@.@.@.@@@.@@.@.@@..@@@.@@@@@..@@@..@@.@..@..@@@.
@@@@..@.@.@@.@..@@@@@@@..@.@@@.@@.@..@...@@@@@.@.@@@@@..@@.@@@@@@@.@@@@@.....@.@.@..@.@@..@..@@@@@@.@.@..@..@@@@@.@.@@@@.@@@@@..@@.@.@..@.@@
@@..@@@@@@@@@@@@@....@..@@@@@@@.@@@@@@.@@@@.@.@@@@@@@@@@@..@@@@..@.@.@..@@@@..@@.@..@.@@@@@....@@@@@...@@@.@@@...@.@.@.@@@.@.@@@.@.@.@@@.@.@
@@@@.@.@@@...@..@.@..@@@@@@@@@.@.@@..@.@@@..@@@@@@@.@.@.@@@@.@...@@@@@@@@..@.@....@@.@@..@@...@@.@@.@@@.@.@..@.@@..@..@@.@@..@@@@@@@@@.@@@@@
@@.@.@..@@@.@@.@..@.@.@@@@@@@@..@@.@@.@.@@.@.......@.@@...@..@..@.@@.@@@..@@..@..@@@@@@@..@@.@@.@.@@...@@@@@@.@@@@@@.@..@..@@@.@@@.@@.@@@@..
@@@...@....@.@.@.@.@.@@....@@@@@.@@@...@@@@@@.@@@..@@.@@..@.@@.@@@@.....@..@@@.@..@.@@.@@.@@@.@@@.@@@@@@.@@@@@@.@..@@@.@@..@@.@@@@@@@@@..@@@
@@.@@.@.@@@@@.@@.....@@@.@@@@..@@..@.@...@@@..@@.@@@.@@.@@@.@.@@.@.@..@..@@@@@.@.@@@@.@..@.@@.@@..@.@@@@@@@..@@@..@.@@@...@@@..@@@@@......@.
.@@..@@@@@@@.@.@@@@@@@@..@@@@@@@..@.@@@....@@@..@..@@@..@.@.@.@@@@@.....@@.@@@@@..@@@@..@.....@..@@@@.@@@.@@@.@@@@.@@@@.@.@..@.@.@...@@.@.@@
@.@@@.@.@@@@....@.@@@..@@..@@.@@@@@.....@@.@@@@@@@..@@@@@.@.@..@@@@@@@....@.@.@@@@@@.@@@@@@@.@@.@.@@@.@@@@@@@@@.@@@@.@@@.@@@.@@.@.@@.@@.@...
.@@.@.@@@@@.@@....@@@.@@@@@@.@@@.@.@@..@@@.@.@..@.@...@.@@@..@.@......@@@@@@@@@@@.@.@.@.@@@.@.@@....@@@..@@@.@@@@@@@...@@@@@.@@@@@@.@......@
.@@.@@....@..@@@@.@@@.@.@.@.@@.@@@.@@@.@@@.@@...@@.@@@@@.@@@@..@@.@..@@@@@@@@@.@@@@@@@.@..@@@.@.@@...@@@@@@@.@@@@@@@@.@.@@@.@@@@@@.@@@@.@@@@
..@@@@.@.@@...@@..@@@...@@.@@@@@@@@@@@.@@@..@@@.@@.....@@...@@@.@@.@..@..@@.@.@@@.@.@@@.@.@@@@@.@@.@@@..@@@@@@@@@@..@.@@@@@@@@.@@.@@@@..@@@.
.@@.@@@@@@..@@@@@.@.@@@@@@@.@@@@..@@.@.@@...@@@...@..@@....@@.@.@@@.@.@@@..@@@.@@...@.@.@@..@@..@@.@@@@@@@@@.@@.@@@@@@@@@@..@.@@@.@.@@@.@@@.
@.@@.@..@......@@@@@.@@.@@.@@@@@@@@.@.@@.@.@@..@...@...@.@@@.@@@.@@@@@.@..@.@@@@@@@.@@@@@@..@@@@..@@@.@.@@@@..@..@@@@@..@@.@@.@@..@..@@.@@..
@@.@@.@@@@@@.....@@@.@.@@.@@@@.@.@@..@.@.@@.@@@.@..@.@@.@@@@.@@@@@..@@..@@@...@.@.@@@@..@@@...@@@.@@@@@.@..@@@@@@@@@..@@.@@@@@.@@@@@@..@@.@.
....@@@@.@....@@@@@@@@..@@@@@@.@..@@@@..@.@@@@..@.@@@@@@@@.@@@@@@@@@@.@@@@@@@@@@@.@.@@@.@.@@.@@.@@@@.@...@@.@@@@@@@@.@@.@.@@..@@@.@.@.@.@.@@
.@.@.@.@.@@@@@@.@@..@@...@.@@.@@@.@@.@@@.@.@@.@@.@.@@@.@..@@.@......@@@@@...@..@@@@@@@@@.@@@@@@@@@@....@@@@.@...@@@.@@@@.@.@@@@@.@@@...@.@@@
@@.@@.@@@@.@@@@.@..@......@@@.@.@...@@.@@@.@@@@@@@@@@@@@..@@@.@.@...@@@@@.@@.@@@@..@.@@@.@.@@.@@@@.@..@.@@@@.@@..@@.@..@@@.@@@@@.@@...@@@.@.
.@@@@.@@@.@@@@@@@@@@@@@@.@@@@@@@@..@.@@@@@@@.@@.@@@.@.@@.@@@.@@@@@@.@@@@.@@.@@@@.@.@@.@@@..@@@.@.@@@....@@.@..@@@.@.@@@..@@@@.@@..@.@.@@@@.@
@@@..@@@@.@@..@@@@@@@@@..@@.@.@.@@@@@@.@@.@@.@@.@.@@@@@.@@..@.@@@.@.@@@@.@@....@@@@.@...@@.@..@@..@..@@@@@@@@.@.@@@.@@.@..@.@..@.@.@@@...@.@
@.@@@..@..@@@.@@@@@@.@@@@@@@.@.@.@.@@@..@.@@@.@@@@..@..@@.@.@@@@@.@.@@.@.@..@@.@@@@@@.@.@.@@.@@@@@@@.@@@..@@...@@@..@@.@@@.@@@@@@..@@.@@.@@@
.@@@@@.@@@...@@@@.@..@@@..@@..@.@@@@..@........@@@.@@.@@.@.@@@.@@@@...@@@@@@..@@@.@.@...@@.@@.@@.@@@...@.@@@.@@.@.@@.@..@@..@.@@@@@@@@...@@.
@@@...@@@@@@@@@@....@@@@@.@.@.@..@..@.@@...@.@.@..@@@@.@.....@@.@..@..@...@@@@.@@.@@@@@@@.@@.@@.@@@@.@@@@@.@@.@@.@@@@@.@@@...@@@@@.......@..
@@@..@..@@@@@...@@@@@@@@.@@.@@@@@.@@.@@.@@@@...@.@@@@@@@@@@@@@@@..@.@@..@@@.@....@@.@@@@@.@@@.@@@@@..@@@@.@@@@.@@.@....@@@@..@@@@@@@@@@.@..@
@@.@@@@@@@..@@.@@@@..@@@@.@@@@@.@@.@@.@@@@@@@.@@@@@.@.@...@@@..@.@@..@@@@@..@@@@@.@@@@.@@@@.@.@@.@@@@@@.@@@@.@@.@..@.@@@..@.@@@.@@.@@@@.@.@@
..@@..@.@@@@@@.@@.@@@@@@@@@.@..@.@.@@..@.@@@@@@@@@@@@.....@.@..@@@...@@@.@@..@@.@@@.@.@@@@@@.@@@....@@.@@..@@.@@@@@.@@..@@.@@@@@@..@@@.@@..@
@@..@.@.@.@@.@@.@@@@@.@..@@...@.@@@..@@..@@@.@@@..@@.@@@@@@@....@.@@@@@@..@@.@@.@@..@.@@@@@@...@@@@.@@@....@@@..@@..@@..@.@@.@....@@.@.@@@@.
@...@@.@@@.@.@@@.@.@@@@@@@...@@.@@.@@@..@@@@.@@@.@@@.@.@.@@@@@@.@..@@@@@@@@@@.@@.@.@@.@.@.@@@.@@.@@@..@.@@@.@.@.@@@@..@...@..@@@@.@..@.@.@@.
..@@@@...@@@.@@.@.@@@@@@@..@@@.@.@@@@@.@@@@@@@@@.@..@@@@@@.@@@.@...@@.@@@@@@@@.@.@.@..@@@@@..@@@.@.@.@@.@@...@.@@....@@@@@.@@@@.@..@..@@@@.@
.@@.@@...@.@.@..@.@@@@.@@@.@.@.@.@@@..@@@.@@@@@@@@@@@.@.@@@@@.@@@.@.@@.@.@.@.@@.@@@@.@@@.@@@@..@@@@@@@@@@@...@@@@@.@@@@...@...@@.@@.@@.@@.@@
.@...@@@@.@@@.@@..@@@@@@@.@......@@.@..@@@@@@.@@@@.@@@.@@@@..@@...@.@@@@@@@.@.@@..@@.@..@@.@@@@@@..@@@@@@@@@@@@@@...@.@.@@@@@.@@@.@@.@@@..@@
@@.@@.@.@@.@@.@.@@..@@.@@..@...@.@@@@.@@@..@@@@.@@@@@@@@..@@@.@@.@..@@@@.@@@.@..@@@@@@@@@@@..@@@.@...@@..@..@@@@.@@@@@.@@@@@@...@@.@.@.@@.@@
@@.@@@.@@@@@@.@.@@@@@@@.@@@@@@@@@..@@.@..@@@@.@..@.@@.@@@.@.@.@.@@@@.@.@.@.@.@@.@.@.@@@@@@@@@@@..@@......@@@.@@.@@@@@@@@@@@..@..@..@@@@@@@@@
@@@@.@@.@@@.@.@.@@@@..@@@@@@@@@..@..@.@@@.@@@@@..@@@@@.@@@@@..@@@@.@@.@...@@...@@.@..@..@@@...@..@...@@.@@@.@@.@..@@..@@@@@@@@@@@@.@@@@.@@@.

16
2025/go/go.mod Normal file
View File

@@ -0,0 +1,16 @@
module adventofcode2025
go 1.23.2
toolchain go1.23.5
require (
github.com/stretchr/testify v1.11.1
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

11
2025/go/go.sum Normal file
View File

@@ -0,0 +1,11 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

158
2025/go/main.go Normal file
View File

@@ -0,0 +1,158 @@
package main
import (
"fmt"
"time"
// "math/rand"
"os"
// "strings"
// "time"
"adventofcode2025/day01"
"adventofcode2025/day02"
"adventofcode2025/day03"
"adventofcode2025/day04"
"adventofcode2025/utils"
)
// Usage: go run main.go <NN>
// assumes input is in day<NN>/input.txt
func main() {
d := day()
fmt.Printf("Running day %02d\n", d)
start := time.Now()
switch d {
case 1:
fmt.Printf("part 1: %d\n", day01.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day01.Part2(utils.Readfile(d)))
case 2:
fmt.Printf("part 1: %d\n", day02.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day02.Part2(utils.Readfile(d)))
case 3:
fmt.Printf("part 1: %d\n", day03.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day03.Part2(utils.Readfile(d)))
case 4:
fmt.Printf("part 1: %d\n", day04.Part1(utils.Readfile(d)))
fmt.Printf("part 2: %d\n", day04.Part2(utils.Readfile(d)))
// case 6:
// fmt.Printf("part 1: %d\n", day06.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day06.Part2(utils.Readfile(d)))
// case 7:
// fmt.Printf("part 1: %d\n", day07.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day07.Part2(utils.Readfile(d)))
// case 8:
// fmt.Printf("part 1: %d\n", day08.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day08.Part2(utils.Readfile(d)))
// case 9:
// fmt.Printf("part 1: %d\n", day09.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day09.Part2(utils.Readfile(d)))
// case 10:
// fmt.Printf("part 1: %d\n", day10.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day10.Part2(utils.Readfile(d)))
// case 11:
// fmt.Printf("part 1: %d\n", day11.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day11.Part2(utils.Readfile(d)))
// case 12:
// fmt.Printf("part 1: %d\n", day12.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day12.Part2(utils.Readfile(d)))
// case 13:
// fmt.Printf("part 1: %d\n", day13.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day13.Part2(utils.Readfile(d)))
// case 14:
// fmt.Printf("part 1: %d\n", day14.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day14.Part2(utils.Readfile(d)))
// case 15:
// fmt.Printf("part 1: %d\n", day15.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day15.Part2(utils.Readfile(d)))
// case 16:
// fmt.Printf("part 1: %d\n", day16.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day16.Part2(utils.Readfile(d)))
// case 17:
// fmt.Printf("part 1: %s\n", day17.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day17.Part2(utils.Readfile(d)))
// case 18:
// fmt.Printf("part 1: %d\n", day18.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day18.Part2(utils.Readfile(d)))
// case 19:
// fmt.Printf("part 1: %d\n", day19.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day19.Part2(utils.Readfile(d)))
// case 21:
// fmt.Printf("part 1: %d\n", day21.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day21.Part2(utils.Readfile(d)))
// case 22:
// fmt.Printf("part 1: %d\n", day22.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day22.Part2(utils.Readfile(d)))
// case 23:
// fmt.Printf("part 1: %d\n", day23.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day23.Part2(utils.Readfile(d)))
// case 24:
// fmt.Printf("part 1: %d\n", day24.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day24.Part2(utils.Readfile(d)))
// case 25:
// fmt.Printf("part 1: %d\n", day25.Part1(utils.Readfile(d)))
// fmt.Printf("part 2: %d\n", day25.Part2(utils.Readfile(d)))
default:
panic(fmt.Errorf("no such day: %d", d))
}
elapsed := time.Since(start)
fmt.Printf("Execution time: %s\n", elapsed)
}
// Reads day from os.Args.
func day() int {
latest := 3
if len(os.Args) == 1 {
return latest
}
if os.Args[1] == "next" {
genNext(latest + 1)
os.Exit(0)
}
day := utils.MustAtoi(os.Args[1])
return day
}
func genNext(n int) {
os.Mkdir(fmt.Sprintf("day%02d", n), 0755)
f, err := os.Create(fmt.Sprintf("day%02d/day%02d.go", n, n))
utils.PanicOnErr(err)
defer f.Close()
f.WriteString(fmt.Sprintf(`package day%02d
func Part1(input string) int {
return 0
}
func Part2(input string) int {
return 0
}
`, n))
fmt.Printf("wrote day%02d/day%02d.go\n", n, n)
f, err = os.Create(fmt.Sprintf("day%02d/day%02d_test.go", n, n))
utils.PanicOnErr(err)
defer f.Close()
f.WriteString(fmt.Sprintf(`package day%02d
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1("")
require.Equal(t, 0, r)
}
func TestPart2(t *testing.T) {
r := Part2("")
require.Equal(t, 0, r)
}
`, n))
fmt.Printf("wrote day%02d/day%02d_test.go\n", n, n)
utils.GenInputFile(n)
}

View File

@@ -0,0 +1,241 @@
package dijkstra
import (
"math"
"sync"
)
type ItemGraph struct {
Nodes []*Node
Edges map[Node][]*Edge
lock sync.RWMutex
}
// AddNode adds a node to the graph
func (g *ItemGraph) AddNode(n *Node) {
g.lock.Lock()
g.Nodes = append(g.Nodes, n)
g.lock.Unlock()
}
// AddEdge adds an edge to the graph
func (g *ItemGraph) AddEdge(n1, n2 *Node, weight int) {
g.lock.Lock()
if g.Edges == nil {
g.Edges = make(map[Node][]*Edge)
}
ed1 := Edge{
Node: n2,
Weight: weight,
}
ed2 := Edge{
Node: n1,
Weight: weight,
}
g.Edges[*n1] = append(g.Edges[*n1], &ed1)
g.Edges[*n2] = append(g.Edges[*n2], &ed2)
g.lock.Unlock()
}
// dijkstra implement
func getShortestPath(startNode *Node, endNode *Node, g *ItemGraph) ([]Point, int) {
visited := make(map[Point]bool)
dist := make(map[Point]int)
prev := make(map[Point]Point)
//pq := make(PriorityQueue, 1)
//heap.Init(&pq)
q := NodeQueue{}
pq := q.NewQ()
start := Vertex{
Node: startNode,
Distance: 0,
}
for _, nval := range g.Nodes {
dist[nval.Value] = math.MaxInt64
}
dist[startNode.Value] = start.Distance
pq.Enqueue(start)
//im := 0
for !pq.IsEmpty() {
v := pq.Dequeue()
if visited[v.Node.Value] {
continue
}
visited[v.Node.Value] = true
near := g.Edges[*v.Node]
for _, val := range near {
if !visited[val.Node.Value] {
if dist[v.Node.Value]+val.Weight < dist[val.Node.Value] {
store := Vertex{
Node: val.Node,
Distance: dist[v.Node.Value] + val.Weight,
}
dist[val.Node.Value] = dist[v.Node.Value] + val.Weight
//prev[val.Node.Value] = fmt.Sprintf("->%s", v.Node.Value)
prev[val.Node.Value] = v.Node.Value
pq.Enqueue(store)
}
//visited[val.Node.value] = true
}
}
}
// fmt.Println(dist)
// fmt.Println(prev)
pathval := prev[endNode.Value]
var finalArr []Point
finalArr = append(finalArr, endNode.Value)
for pathval != startNode.Value {
finalArr = append(finalArr, pathval)
pathval = prev[pathval]
}
finalArr = append(finalArr, pathval)
// fmt.Println(finalArr)
for i, j := 0, len(finalArr)-1; i < j; i, j = i+1, j-1 {
finalArr[i], finalArr[j] = finalArr[j], finalArr[i]
}
return finalArr, dist[endNode.Value]
}
func getAllShortestPaths(startNode *Node, endNode *Node, g *ItemGraph) ([][]Point, int) {
visited := make(map[Point]bool)
dist := make(map[Point]int)
prev := make(map[Point][]Point) // Store multiple predecessors for each node
q := NodeQueue{}
pq := q.NewQ()
start := Vertex{
Node: startNode,
Distance: 0,
}
for _, n := range g.Nodes {
dist[n.Value] = math.MaxInt64
}
dist[startNode.Value] = start.Distance
pq.Enqueue(start)
// Perform Dijkstra's algorithm
for !pq.IsEmpty() {
v := pq.Dequeue()
if visited[v.Node.Value] {
continue
}
visited[v.Node.Value] = true
near := g.Edges[*v.Node]
for _, edge := range near {
alt := dist[v.Node.Value] + edge.Weight
// Case 1: Found a shorter path
if alt < dist[edge.Node.Value] {
dist[edge.Node.Value] = alt
prev[edge.Node.Value] = []Point{v.Node.Value} // Reset predecessors
pq.Enqueue(Vertex{
Node: edge.Node,
Distance: alt,
})
}
// Case 2: Found an equally short path
if alt == dist[edge.Node.Value] {
// Add the current node as a valid predecessor if not already present
found := false
for _, p := range prev[edge.Node.Value] {
if p == v.Node.Value {
found = true
break
}
}
if !found {
prev[edge.Node.Value] = append(prev[edge.Node.Value], v.Node.Value)
}
}
}
}
// Iteratively reconstruct all paths
var paths [][]Point
stack := []struct {
node Point
path []Point
}{
{node: endNode.Value, path: []Point{}},
}
for len(stack) > 0 {
// Pop the top item from the stack
current := stack[len(stack)-1]
stack = stack[:len(stack)-1]
// Prepend the current node to the path
newPath := append([]Point{current.node}, current.path...)
// If we've reached the start node, save the path
if current.node.X == startNode.Value.X && current.node.Y == startNode.Value.Y {
paths = append(paths, newPath)
continue
}
// Push all predecessors onto the stack
for _, predecessor := range prev[current.node] {
if !Contains(newPath, predecessor) {
stack = append(stack, struct {
node Point
path []Point
}{
node: predecessor,
path: newPath,
})
}
}
}
return paths, dist[endNode.Value]
}
func Contains(slice []Point, value Point) bool {
for _, v := range slice {
if v == value { // Compare values
return true
}
}
return false
}
func CreateGraph(data InputGraph) *ItemGraph {
var g ItemGraph
nodes := make(map[Point]*Node)
for _, v := range data.Graph {
if _, found := nodes[v.Source]; !found {
nA := Node{v.Source}
nodes[v.Source] = &nA
g.AddNode(&nA)
}
if _, found := nodes[v.Destination]; !found {
nA := Node{v.Destination}
nodes[v.Destination] = &nA
g.AddNode(&nA)
}
g.AddEdge(nodes[v.Source], nodes[v.Destination], v.Weight)
}
return &g
}
func GetShortestPath(from, to Point, g *ItemGraph) ([]Point, int) {
nA := &Node{from}
nB := &Node{to}
path, distance := getShortestPath(nA, nB, g)
return path, distance
}
func GetAllShortestPaths(from, to Point, g *ItemGraph) ([][]Point, int) {
nA := &Node{from}
nB := &Node{to}
paths, distance := getAllShortestPaths(nA, nB, g)
return paths, distance
}

View File

@@ -0,0 +1,35 @@
package dijkstra
type Point struct {
X int
Y int
Label string
}
type Node struct {
Value Point
}
type Edge struct {
Node *Node
Weight int
}
type Vertex struct {
Node *Node
Distance int
}
type PriorityQueue []*Vertex
type InputGraph struct {
Graph []InputData
From Point
To Point
}
type InputData struct {
Source Point
Destination Point
Weight int
}

View File

@@ -0,0 +1,65 @@
package dijkstra
import "sync"
type NodeQueue struct {
Items []Vertex
lock sync.RWMutex
}
// Enqueue adds an Node to the end of the queue
func (s *NodeQueue) Enqueue(t Vertex) {
s.lock.Lock()
defer s.lock.Unlock()
if len(s.Items) == 0 {
s.Items = append(s.Items, t)
return
}
var insertFlag bool
for k, v := range s.Items {
// add vertex distance less than travers's vertex distance
if t.Distance < v.Distance {
s.Items = append(s.Items[:k+1], s.Items[k:]...)
s.Items[k] = t
insertFlag = true
}
if insertFlag {
break
}
}
if !insertFlag {
s.Items = append(s.Items, t)
}
}
// Dequeue removes an Node from the start of the queue
func (s *NodeQueue) Dequeue() *Vertex {
s.lock.Lock()
defer s.lock.Unlock()
item := s.Items[0]
s.Items = s.Items[1:len(s.Items)]
return &item
}
//NewQ Creates New Queue
func (s *NodeQueue) NewQ() *NodeQueue {
s.lock.Lock()
defer s.lock.Unlock()
s.Items = []Vertex{}
return s
}
// IsEmpty returns true if the queue is empty
func (s *NodeQueue) IsEmpty() bool {
s.lock.RLock()
defer s.lock.RUnlock()
return len(s.Items) == 0
}
// Size returns the number of Nodes in the queue
func (s *NodeQueue) Size() int {
s.lock.RLock()
defer s.lock.RUnlock()
return len(s.Items)
}

View File

@@ -0,0 +1,77 @@
package grid2d
import (
"strings"
"adventofcode2025/utils"
)
type Grid[T any] struct {
sizeX, sizeY int
matrix [][]T
empty T
}
func NewGrid[T any](sizeX, sizeY int, empty T) *Grid[T] {
matrix := make([][]T, sizeY)
rows := make([]T, sizeX*sizeY)
for i := 0; i < sizeX*sizeY; i++ {
rows[i] = empty
}
j := 0
for i := 0; i < sizeY; i++ {
matrix[i] = rows[j : j+sizeX : j+sizeX]
j += sizeX
}
return &Grid[T]{
sizeX: sizeX,
sizeY: sizeY,
matrix: matrix,
empty: empty,
}
}
func (g *Grid[T]) SizeX() int {
return g.sizeX
}
func (g *Grid[T]) SizeY() int {
return g.sizeY
}
func (g *Grid[T]) Matrix() [][]T {
return g.matrix
}
func (g *Grid[T]) Get(x, y int) T {
if x < 0 || x >= g.sizeX {
return g.empty
}
if y < 0 || y >= g.sizeY {
return g.empty
}
return g.matrix[y][x]
}
func (g *Grid[T]) Set(x, y int, v T) {
if x < 0 || x >= g.sizeX {
panic("invalid x")
}
if y < 0 || y >= g.sizeY {
panic("invalid y")
}
g.matrix[y][x] = v
}
func (g *Grid[T]) StringWithFormatter(formatter func(T, int, int) string) string {
var r strings.Builder
for j := 0; j < g.sizeY; j++ {
for i := 0; i < g.sizeX; i++ {
_, err := r.WriteString(formatter(g.matrix[j][i], i, j))
utils.PanicOnErr(err)
}
_, err := r.WriteRune('\n')
utils.PanicOnErr(err)
}
return r.String()
}

View File

@@ -0,0 +1,63 @@
package utils
import (
"fmt"
"io"
"net/http"
"os"
)
func GenInputFile(day int) string {
var d string
if day < 10 {
d = fmt.Sprintf("0%d", day)
} else {
d = fmt.Sprintf("%d", day)
}
pwd, _ := os.Getwd()
path := fmt.Sprintf("%s/day%s/input.txt", pwd, d)
fi, _ := os.Stat(path)
if fi != nil {
return path
}
fmt.Printf("Creating new input file %v...", path)
f, err := os.Create(path)
if err != nil {
fmt.Println(err)
} else {
defer f.Close()
data := readHttp(2025, day)
_, err := f.WriteString(data)
if err != nil {
fmt.Println(err)
}
}
return path
}
func readHttp(year, day int) string {
fmt.Println("Fetching data into file...")
url := fmt.Sprintf("https://adventofcode.com/%d/day/%d/input", year, day)
session := os.Getenv("sessionAoC")
req, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(err)
}
req.AddCookie(&http.Cookie{Name: "session", Value: session})
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
return string(body)
}

View File

@@ -0,0 +1,56 @@
package inputs
import (
"strings"
"adventofcode2025/utils"
"adventofcode2025/utils/grid2d"
sparsegrid "adventofcode2025/utils/sparseGrid"
)
func ToInts(input string, sep string) []int {
var r []int
for _, line := range strings.Split(input, sep) {
if line != "" {
r = append(r, utils.MustAtoi(line))
}
}
return r
}
func ToGrid2D[T any](input, rowSep, colSep string, empty T, conv func(string) T) *grid2d.Grid[T] {
var width int
lines := strings.Split(input, rowSep)
if colSep == "" {
// If no colSep, width is the length of each line
width = len(lines[0])
} else {
// Use colSep to determine the width of the grid
width = len(strings.Split(lines[0], colSep))
}
grid := grid2d.NewGrid(width, len(lines), empty)
for y, line := range lines {
for x, v := range strings.Split(line, colSep) {
grid.Set(x, y, conv(v))
}
}
return grid
}
func ToSparseGrid[T comparable](input, rowSep, colSep string, empty T, conv func(string) T) *sparsegrid.SparseGrid[T] {
lines := strings.Split(input, rowSep)
grid := sparsegrid.NewGrid(empty)
for y, line := range lines {
for x, v := range strings.Split(line, colSep) {
grid.Set(x, y, conv(v))
}
}
return grid
}

View File

@@ -0,0 +1,47 @@
package memo
import "sync"
type Func func(key interface{}) interface{}
type result struct {
value interface{}
}
type Memo struct {
f Func
cache map[interface{}]result
mu sync.RWMutex // Allows concurrent reads.
}
func New(f Func) *Memo {
return &Memo{
f: f,
cache: make(map[interface{}]result),
}
}
func (memo *Memo) Get(key interface{}) interface{} {
// First, try to read the cache using a read lock.
memo.mu.RLock()
res, ok := memo.cache[key]
memo.mu.RUnlock()
if ok {
return res.value
}
// Compute the result without holding the lock.
computed := memo.f(key)
// Now acquire a write lock to update the cache.
memo.mu.Lock()
// Double-check: another goroutine may have stored the result in the meantime.
res, ok = memo.cache[key]
if !ok {
res.value = computed
memo.cache[key] = res
}
memo.mu.Unlock()
return res.value
}

View File

@@ -0,0 +1,56 @@
package ringbuffer
import (
"sync"
)
type RingBuffer[T any] struct {
buffer []T
size int
mu sync.Mutex
write int
count int
}
// NewRingBuffer creates a new ring buffer with a fixed size.
func NewRingBuffer[T any](size int) *RingBuffer[T] {
return &RingBuffer[T]{
buffer: make([]T, size),
size: size,
}
}
// Add inserts a new element into the buffer, overwriting the oldest if full.
func (rb *RingBuffer[T]) Add(value T) {
rb.mu.Lock()
defer rb.mu.Unlock()
rb.buffer[rb.write] = value
rb.write = (rb.write + 1) % rb.size
if rb.count < rb.size {
rb.count++
}
}
// Get returns the contents of the buffer in FIFO order.
func (rb *RingBuffer[T]) Get() []T {
rb.mu.Lock()
defer rb.mu.Unlock()
result := make([]T, 0, rb.count)
for i := 0; i < rb.count; i++ {
index := (rb.write + rb.size - rb.count + i) % rb.size
result = append(result, rb.buffer[index])
}
return result
}
// Len returns the current number of elements in the buffer.
func (rb *RingBuffer[T]) Len() int {
rb.mu.Lock()
defer rb.mu.Unlock()
return rb.count
}

View File

@@ -0,0 +1,81 @@
package sparsegrid
import (
"fmt"
"strings"
"adventofcode2025/utils"
)
type SparseGrid[T comparable] struct {
minX, maxX, minY, maxY int
data map[string]T
empty T
}
func NewGrid[T comparable](empty T) *SparseGrid[T] {
return &SparseGrid[T]{
minX: utils.MaxInt,
maxX: utils.MinInt,
minY: utils.MaxInt,
maxY: utils.MinInt,
data: map[string]T{},
empty: empty,
}
}
func (g *SparseGrid[T]) SizeX() (int, int) {
return g.minX, g.maxX
}
func (g *SparseGrid[T]) SizeY() (int, int) {
return g.minY, g.maxY
}
func (g *SparseGrid[T]) Visited() int {
return len(g.data)
}
func (g *SparseGrid[T]) Get(x, y int) T {
k := key(x, y)
v, ok := g.data[k]
if !ok {
return g.empty
}
return v
}
func (g *SparseGrid[T]) Set(x, y int, v T) {
k := key(x, y)
current, ok := g.data[k]
if ok && v == current {
return
} else if !ok && v == g.empty {
return
} else if v == g.empty {
delete(g.data, k)
} else {
g.data[k] = v
g.minX = utils.Min(g.minX, x)
g.maxX = utils.Max(g.maxX, x)
g.minY = utils.Min(g.minY, y)
g.maxY = utils.Max(g.maxY, y)
}
}
func (g *SparseGrid[T]) StringWithFormatter(formatter func(T, int, int) string) string {
var r strings.Builder
for j := g.minY; j <= g.maxY; j++ {
for i := g.minX; i <= g.maxX; i++ {
_, err := r.WriteString(formatter(g.Get(i, j), i, j))
utils.PanicOnErr(err)
}
_, err := r.WriteRune('\n')
utils.PanicOnErr(err)
}
return r.String()
}
func key(x, y int) string {
return fmt.Sprintf("%d:%d", x, y)
}

222
2025/go/utils/utils.go Normal file
View File

@@ -0,0 +1,222 @@
package utils
import (
"bufio"
"fmt"
"io"
"os"
"reflect"
"regexp"
"strconv"
"strings"
"golang.org/x/exp/constraints"
)
func PanicOnErr(err error) {
if err != nil {
panic(err)
}
}
const MaxInt = int(^uint(0) >> 1)
const MinInt = ^MaxInt
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
func SliceMinMax[T constraints.Ordered](slice []T) (*T, *T) {
if len(slice) == 0 {
return nil, nil
}
min := &slice[0]
max := &slice[0]
for i, v := range slice {
if v < *min {
min = &slice[i]
}
if v > *max {
max = &slice[i]
}
}
return min, max
}
func MustAtoi(s string) int {
v, err := strconv.Atoi(s)
PanicOnErr(err)
return v
}
// Returns key from map[T]int which has the max value
func MapFindMax(m interface{}) interface{} {
var maxK interface{} = nil
var maxV = MinInt
iter := reflect.ValueOf(m).MapRange()
for iter.Next() {
k := iter.Key()
v := int(iter.Value().Int())
if v > maxV {
maxV = v
maxK = k.Interface()
}
}
return maxK
}
// Returns key from map[T]int which has the min value
func MapFindMin(m interface{}) interface{} {
var minK interface{} = nil
var minV = MaxInt
iter := reflect.ValueOf(m).MapRange()
for iter.Next() {
k := iter.Key()
v := int(iter.Value().Int())
if v < minV {
minV = v
minK = k.Interface()
}
}
return minK
}
func Readfile(day int) string {
filename := fmt.Sprintf("day%02d/input.txt", day)
file, err := os.Open(filename)
PanicOnErr(err)
defer file.Close()
reader := bufio.NewReader(file)
contents, err := io.ReadAll(reader)
PanicOnErr(err)
return strings.TrimSuffix(string(contents), "\n")
}
func ReadfileAsSlice(day int) []string {
filename := fmt.Sprintf("day%02d/input.txt", day)
file, err := os.Open(filename)
PanicOnErr(err)
defer file.Close()
arr := make([]string, 0)
sc := bufio.NewScanner(file)
for sc.Scan() {
arr = append(arr, sc.Text())
}
return arr
}
func ParseToStruct(re *regexp.Regexp, input string, target interface{}) bool {
m := re.FindStringSubmatch(input)
if m == nil {
return false
}
var useOffset bool
for i, name := range re.SubexpNames() {
if i == 0 {
continue
}
var field reflect.Value
if name == "" {
// use offset
if i == 1 {
useOffset = true
} else if !useOffset {
panic("can't mix named and unnamed subexpressions")
}
field = reflect.ValueOf(target).Elem().Field(i - 1)
} else {
// use name
if i == 1 {
useOffset = false
} else if useOffset {
panic("can't mix named and unnamed subexpressions")
}
field = reflect.ValueOf(target).Elem().FieldByName(name)
}
if field.Kind() == reflect.String {
field.SetString(m[i])
} else if field.Kind() == reflect.Int {
v, err := strconv.Atoi(m[i])
PanicOnErr(err)
field.SetInt(int64(v))
} else if field.Kind() == reflect.Uint8 {
if len(m[i]) != 1 {
panic(fmt.Sprintf("expecting 1 char, got: %s", m[i]))
}
field.SetUint(uint64(m[i][0]))
} else {
panic(fmt.Sprintf("unknown kind: %s", field.Kind()))
}
}
return true
}
func MustParseToStruct(re *regexp.Regexp, input string, target interface{}) {
if !ParseToStruct(re, input, target) {
panic(fmt.Errorf("failed to parse: %s", input))
}
}
func CharToLower(c byte) byte {
return strings.ToLower(string(c))[0]
}
func CharToUpper(c byte) byte {
return strings.ToUpper(string(c))[0]
}
func Contains(haystack []string, needle string) bool {
for _, s := range haystack {
if s == needle {
return true
}
}
return false
}
func Abs[T constraints.Signed](x T) T {
if x < 0 {
return -x
}
return x
}
func Gcd(x, y int) int {
if x <= 0 || y <= 0 {
panic(fmt.Errorf("invalid input: %d, %d", x, y))
}
if x == y {
return x
}
if x > y {
return Gcd(x-y, y)
} else {
return Gcd(x, y-x)
}
}
func Sign[T constraints.Signed](x T) int {
if x < 0 {
return -1
} else if x > 0 {
return 1
} else {
return 0
}
}