Compare commits

...

2 Commits

Author SHA1 Message Date
0034691f2a 2024 day1 2024-12-01 08:02:28 +00:00
2584df5496 finish 2023 2024-12-01 08:01:55 +00:00
25 changed files with 2442 additions and 1 deletions

16
2023/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",
"args": ["16"],
"program": "${fileDirname}"
}
]
}

95
2023/go/day14/day14.go Normal file
View File

@@ -0,0 +1,95 @@
package day14
import (
_ "adventofcode2023/utils"
"adventofcode2023/utils/grid2d"
"adventofcode2023/utils/inputs"
"fmt"
_ "strings"
)
func Part1(input string) int {
grid := inputs.ToGrid2D[rune](input, "\n", "", ' ', func(c string) rune { return rune(c[0])})
// fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
slide(grid)
// fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
return score(grid)
}
func Part2(input string) int {
grid := inputs.ToGrid2D[rune](input, "\n", "", ' ', func(c string) rune { return rune(c[0])})
// fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
x:= 0
for j:=0;j<125;j++ {
for i:=0;i<4;i++ {
slide(grid)
grid = rotate(grid)
}
if score(grid) == 101375 {
fmt.Println(j, j - x)
x = j
}
}
fmt.Println(score(grid))
for j:=999999840+125;j<1000000000;j++ {
for i:=0;i<4;i++ {
slide(grid)
grid = rotate(grid)
}
if score(grid) == 101375 {
fmt.Println(j, j - x)
x = j
}
}
// fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
return score(grid)
}
func slide(grid *grid2d.Grid[rune]) {
G := grid.Matrix()
R := len(G)
C := len(G[0])
for c:=0;c<C;c++ {
for r:=0;r<R;r++ {
for dr:=0;dr<R;dr++ {
if G[dr][c]=='O' && dr>0 && G[dr-1][c]=='.' {
G[dr][c]='.'
G[dr-1][c] = 'O'
}
}
}
}
}
func rotate(grid *grid2d.Grid[rune]) *grid2d.Grid[rune] {
G := grid.Matrix()
R := len(G)
C := len(G[0])
New := grid2d.NewGrid[rune](R, C, '?')
NG := New.Matrix()
for r:=0;r<R;r++ {
for c:=0;c<C;c++ {
NG[c][R-1-r] = G[r][c]
}
}
return New
}
func score(grid *grid2d.Grid[rune]) int {
ans := 0
G := grid.Matrix()
R := len(G)
C := len(G[0])
for r:=0;r<R;r++ {
for c:=0;c<C;c++ {
if G[r][c]=='O' {
ans += len(G)-r
}
}
}
return ans
}

View File

@@ -0,0 +1,37 @@
package day14
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1(
`O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....`)
require.Equal(t, 136, r)
}
func TestPart2(t *testing.T) {
r := Part2(
`O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....`)
require.Equal(t, 64, r)
}

100
2023/go/day14/input.txt Normal file
View File

@@ -0,0 +1,100 @@
O...#.O......#...##....O#.#.OO...O.#OO#.....#O.O.....#......#.OO...O...O..O#O#....#...O..O...O.....O
.OO......O.OO.O.#.#O.O...#.##OO.....#.#O#...OOOOO..##O#O..O#O.##O...#O....O#.#.OO....#.........O.O.O
......O.O.O.....O.#.#.#OO#O#.O...O.#.......#O....#.O.#....OOO...#....O#O.......#......O...O##...O...
O...##O..#....OO.OO....O...O...O#..##.OOO..O..#OO....###....OO.O.O...........O...O..O.....#.#..O.O#.
............#.#.##O.O.#.#OO#........O..O.O..##....O.#..#O..O...O#.#.#.........O...........OO......O.
#.OO........#..#O.#......#....#....#......OO..OO...O#...#...#..##..O#.O......#.#..O..#O#...#..#.O#.O
O.O.##...........O...O..O...O.OO.......##....#...O.....##...#.....OO...O.O#...OO..........O...O..#O.
.O##....#.O#O....O.O.#.#O.O#..OO..##..#OO.#...#......#.#O#.....O...O#.O...#..O.#.#......#.##.O....O.
.........#..#.O..O..O.O...#.#.O...#.OOO.##..#.O.....OO#....O...OOO#.O#....##O..#.O.O.....O.O.O.O..O.
......#O.....OOO###.O..O####O.#.O...............#..O......##O...#.#..###...O....#O...OO.OO.O......O.
#.O....#.O..#O...#...#...O....OOO.#O.#.#..#.....#.#..OO..#OO.......#OO.OOO....O.#O.#.O......####..O.
OOOO...#.OO.#....O...O.O...##....#OO...O.##.O.....###..O........OO..O.O.......#.#...O..#..O.#..O....
OOO..##....O...O.....O#..O.O.#..O..#.#.#..O........O..#OOO.....#....O#OO.#.#.....O..#..O...O..O.#OO#
...##.#.##.#O....O#..O..O.........#.#.#O...O.......O...O#..OOOO....O...O.OO#.O.##...#....O..O.......
....##.###OOO.O...#.......OO....OOO....O.OO#..O.#..OO....OO......O..OO...OOO.OO#...#..OOO..O.###O...
O###O.....O.O.#O#.O.O#O.O###.....O..O........#....#..O#..#.#..O...........#......#OO........O..O####
.#.#.OOO.O.......#O..O.#..O.OO.OO.O..O.#.#...O.O.OO..##..O...#...#O#..O.........O.O..O.O#....O..#O..
.#..#O.#O..#.O.O.O...#OO....#...O....O..O.O...#..#.##O.O..O..#O.....OO##...O#.......O#O.#..........#
#O...#.#OO.O...#O...O...#.#.O#..#.O#.###.#......O..O....#..#.OO..#....O..O.O....#.O.O.O.#..O..OOO..O
O.....#...#.#OOO.OOOO..#O.O.#...O.##..OO..#O...#.....OO#..#.#...O##OO...O.....O..#...#...........O.O
.##.O#.O..#O#.O##.O.#.........##.O......#OO...OO.......#...#O.O#...O..#.#...O..#...#O...O.#....OO.OO
.O#OO.O..#...#..O..O...##.O....###O.....O...#.#OOO...OO...O.......#.#.#.OO....#OO.#..O..........OO..
.....#OO.O..O.O.O...O.O#.#.O...O..#...O##.......#......#O...#.#.#....#..O.O..#..........O..#.#..#O..
...O.O.O.OO...O#..O..OO..O#.#.O.#OO..O.O..OO..O#...#.O#...O.......#..#..O..##..O..#O......O.OO...O.O
#.O....O.O.#...O.....O.....O#......#.#..OO...#.....O.#.#.O...#.#....#....O#.O.#......#OOO.O...O#....
...OOO......#..O..O#.......#....O#OO..#O.#.#...#...O.O..OO..#.O...O..#.....OO..O..#...#.O...O#..O.OO
#OO.OO#.OOO...##............O....O.O..#.##.#.O.........##...#O.O..#................#..O.O.O#O.O#..##
.O.O.O##..#O.O#O...##.#OO#...#.OO#..O...O#...O....O#..OO....O....#...O...#OO.OO#O....#..O..#OO....O.
.OO.#.......#...O...OO..#..OO.O.O.OO#O.O.O...O....O#..#.O.........O..#.O...#.#...O.O......O........O
.O....##..#....#.....O.#...O.O.#....#....OOOO...O.O###.O........O.....O.O..#.##OOO.O.......#.#.O..O.
.#.....O...#.O...#........#...#....#OO.O...O#O........OOO...#.O....OOO#.O.....OO....#.#...#..OO..#..
OO.OO...O..#..#O....O.O....OOOOO.#O.#O.O...#.O....O#.O.O.#O.#...#..O...O.#O.O.#..O....OOO......#.O#.
.O##..OO.....#.OO..#..O..#...#.#........O..OO...#O..O....#..O..O#.....O#..##O..O#.##.#...#.O..O.O.O.
..#...#O.....OO#.....O..#.#O.#.#..#..O.....#...OO.#.....O..O.O##.O.....OOOO.#O.....O.#..O........#.#
.#.#O..O.O..#..O##.....O.OO...##.........O...####..O..O....#O..O.....##........O.#..#.#OO.#..O.##.O#
#...#.O....OO......#O...#O..O#..#O#O.#..#.....OO....OO#..#O....O.O..#.O.#.....O#.O.OO..O#.O.O..O.O#.
OO....OO......#O........#O...#.#..O##....O#..#.#O.O.#....O..O..O.O....O.......#..OOO#.........O....O
O.....#O.OO##......#O##..O..O...##..O..........O..OO.O..#O....O..OOO#OO.##..#....O#..#...O.O.O...O..
.............#.#.#.O...#.#..#......O.#.O..#....#..##....#.##.##.#.O...O.O..#.#.#...OO....O..#O..#..O
.O.#.....O.O..O..##O...OO.#.O....#..#.#...O.O#...#O.O.OO...O..#..OO...O...O...O.....#.O..O#..#.#..OO
.....O..OO......#.#.#.O.##.OO...O..O.#..#...#OO....OOO......O.OO.#.O..O#O...O.#......OO##O.O.#O..O..
O##O.#.#..#..OO.O.........#O.#..O.#.##.O#..OOOO..#....O...O.........O..O..###...O...O.#.....O..##.O.
..O...#O#O.O...O.#..#O.......OO...........#...#..##.O......#..O.O.#OO.OO.#O....#.O.....O..#..#.#..#.
O#..O..##O#....O..OOO..OO...#O..O.O...O#O...OO.O##.O#O..#......OO##O.##...OOO.O..#....O##O..#......#
..#O...O..O.O...#..O.O...#O.....O.O......##OO#..O......#..O.#.O......OO.#O........O.....OO...O...O.O
........OO.#.OO..O......#...#...#..OOOO.OO.#....O.OO...O.##.....O.O....#O.#.OO..##.##..#.#O#.OO...O#
....#......#O.OO.....OOO....OO..O.O.O....##..O..O.O#.O....O.#O.#O.....O..O........#O.....O.O.....O#.
#.O#.O#......##.....O.#O...###...##....#O#.#.#....OO...O..#.O....O..#..#..O..........O......#.O.O...
.O.#..O#.OO....O.#...#O....#....OO......#O.O..#O..........O.#..#...#OOO........#.#.........O.#..O...
#OO.OO..O..O.O.#O.O.....O.##..#.O#..#.O....#........#.OOO#.#.....#.#.......O#..##..#.OO....O#O#.....
.......#O.O....#.OOO..OO...O...#....O..#.#....OO..O....O.#.O.#O#..O#.#.O..O......##...OO..#....O.#..
.O..O#.#OO.O.O.O.##...O..O.O..O.##O...#.O..O..O..O..O.....O...#..OO#O..O###...#...#....O##.OO...#...
#O....#...##..O..#...#OO.O.O.#......O...O.#.#O..O...O....OOO..O.O..O...O.OO...O...#..O....O#.###....
....#..O.....##.O.......##.##..OOO.O.#.#.....#....O..#..O....#....O...#.O..O#..O##...#.##....O.#OO##
O....O...OO.O........#..O...#..#.....O......O.O.OO.OO..#....O..O.............##.O.....##O#.OOO......
........#.O.####O.OO.#.O..O.O.#.#....OO#.......O..#....##.OOO..O.O.O..#.O.#...O.O.O..O.##O..O#....O.
...#....#.....O....O.O.O##.O..#O.OO...#.##.O..###OO##.O......#..##.OO...O.......O.......#..O.#.O..O.
.O.O...O......OO.#....#O..O.O.O..OO.O..O##O...O....O..OO.#..O....O..#.O..OO.OO....O#O..#.O..#O...#.#
..O#O.#O..#...##..#.O...OO..O#.......#..O........#.OO#..O#.#.#O....##...O.........O......OO#.....O.#
....OO.......###..O#.....O##..#O..#..#.O.....##.......##..O#O....#....#O.O..#..#..O.###O..#.O#......
O..##..O...#..O...O#OOO....#.O##O.#........#.O..O.#..#.OO.#O.#.....##.O..O.O....#..#..OO....#..#..##
.#...O.OO#O.O..O.##O..O#...##...O....OO.O#....#...#O.O#....O..........#....#............##.......#..
.O.#........##O...#O..O..O....OO#O....#.O..OO.##..O..OO#.###OO.....#..#.......O.#.....OO........OO.#
.OO...O.#..##.....OO..O.O.O.#.###.##.O.#..O..#..O..O...##.#......O....O.O.........O..#.O.O#O.#O...#.
#..#.#..O...##.....OO#O.OOO.....#...#.....##.#...O....O....#..OO#.#.OO....#.....O.O...O#.#..#..O#O.O
.O#.O.#..O..O#...OO...O...O#...O..O..#.O..#...O#.#....O......O#...O...OO.O##.#O....O....#OO....#O...
OO..OOO.O......OO...OO#O...#.#.#O.OOO#....#.OO#.#.O.#......O.O.OO#..O..#..O.O#.O#.O....O..O...O.....
...OO....O...#OO#..#..O.#O#....O.....OO.O.#.OO##.....#..O#.OO..#.#.O#..#..O.#..O....#....O.#O...OO#O
..#.......OO..##.O#...O#....O.#.O..##..#O.......#O#......O..O.........O#..#OO..O..#O.#.#.O.O#.#OO#.O
...#O#...O...OO...OO..OO...#OO...O...##.O....##.#O##.O....#..O#..O.....O.......###.#.OO#...O......#.
.O.OO#O##O##...#..#....#..#O...O#..O.O##......#........#O.........#.O....O..#..O.....O..#......O.#.#
..#....#.O.O.O..O.....O.O#O.O..#......O............O.........O#.O....#.O#..O..O.#OO.....#......O...#
OO...#..O..O##.#.#O.O.#.#....O....O...O.#..O##...O...#.O...#.O.OO...#........O#O..O.O.O..O.....#.O..
.OOO....#...O..O.....O..O...O...O..O...O#...#O....O.O...#..OO##.O.#..O..........O#..#..#..OO#.....#.
O..#..O#....#O..##O..#.#.......OO..O..#...O....O.#....O..O.##........O...O..OO...#....OO#..O.#.#.#..
O#O.O.O#.#OO#..OO.O.#......#.....#.......##.O..#.O..#..OO..O.#.#.O.O.O#.#......O....####OO#.#O#OO.#.
.#.....O#..O#O#..OO...#.O.#....#.#..##....O##....#.........##OO...##...O......#.OO...#O....O.O.O#O..
O......#.O....O...O.....OO.#....#O.##....#.O.O...O..#...O....#.O....O.O....#.OO.#.......#...#..#...O
...#OO..#......#..OO.O.O.##.O....O.##O##.OO#O.O.O..O.#O#O.OO...........O...###.#......O..#..#O#..OOO
O..O.#..O.OO.O...OO.OO..OOOO....O...#....##.OO.O.....#.......O.O........O.#.......#.......#..#.O..O.
.OO.##...#O..O#....O....#..O#....#.....O...O#.....OOO#.....................#..#..#..#O.......O.#OO..
.#OO..O....O..#.....#O...OO.#....#.#.O...O.#........O...O..O..OO#..#.....#.......OOOOO.OO....O....O.
.O#...#.......O.O...O.O.O#...OO.O#...O#O.O.#......#......O..O##.##.....O.....##...........O#...O....
.#.O.O#.....O.#..OO......#O.#..O..O.O.O..#.#...O##.#O..OOO......#...#..OO...O.#.....#O.OOO...#.O..##
.........O..##OO.#OOOO.O.O..OOO...OO.#.....#...O.#O##..O#..#.#..#...#..O.O...#OO.O...O...#O...#..#..
.#.#O.#...#OO.O.........O#..O...OO#.....O....OOOO#.....O.O....#...O...........O#.#.O..O.#.O.#.O.#.#.
......O.#...O.....O.O..O#...O.#........#.O...O.O....#..O#....O.#.O.O....O...#OO...#........OO..O.O.O
....O.O..OO.....#...OOOO.O#............O#OO....OOOOOO..#..#O#..#.#.O.OO.#O.....O.#......##..O#..#O..
..#......#...#O.#..#.#....OOO#...O.#....O..#O.....O.....O.O......O.......O.O..O..O.OO.O.#OO..O#...#.
.O.#.O.OO..O#.O#OO..........O.......O..#..#.#..O...#...##.....####...#........##O.......#....#...O##
........#.#.O.#O.......#O...O...#.#O..#OOO..#O..###...O.#.#O...O.O#..O..O...O.O....###.OO.#OO..O.#.O
..#O....#..O..####.O#...O....O.#O.##.O....O.O......O#O...OO###...O..#........#.#O.O#OO.......#.....O
....O.....#.#.O.#..O.#O.#.#O.#.......OO.....OOO...O.O..#.#....#..O.O..#.OO.O..O..OO##.....#.O..OO#O.
O#O..OO.O....OO.#O......O......#...#.....O.#OO.#.....OO..O#.O..O.O...#....O.O..OO.O....#....OO..O...
...O.....##....#....#....#......O#O..OO.....OO#O.OO......#OO.......O.#..###OO...#.O..OO.#.O.O#OO..#.
.O.#.O..#O.....#.#O....##OO.#O..##..##.##...#OO.O.#O#..O..O.O..O..##O.O.....O.OOO..#..#O..O#..OO...O
..##O#O.O.#.........O....O.OO#O#O.....O.....O#O.OO.O......O.O.OO......#.....O.O.O.O.O.....#.O.......
.....#OO.#O........O#....O.#OO.OO........#.O....O.OOOOOO.#.#O......O.#...O#.O.O..OO.....O.OO...#.O.#
.....#................OO..OOOO..#.....O.###O.O...O..#O..........OO.#...OO.O#...O......O..OOOO.#..###
O.....O...#O.#..........#O......O..OOO#....O.OOOO....O..#..#O....O.....O#..O..#.O.O....#OO.#....#O..

80
2023/go/day15/day15.go Normal file
View File

@@ -0,0 +1,80 @@
package day15
import (
"adventofcode2023/utils"
_ "fmt"
"strings"
)
type Lens struct {
label string
fl int
}
func Part1(input string) int {
ans := 0
seqs := strings.Split(input, ",")
for _,seq := range seqs {
ans += hash(seq)
}
return ans
}
func Part2(input string) int {
Boxes := [256][]Lens{}
cmds := strings.Split(input, ",")
for _,cmd := range cmds {
if cmd[len(cmd)-1] == '-' {
label := cmd[:len(cmd)-1]
hash := hash(label)
nl := []Lens{}
for _, lens := range Boxes[hash] {
if lens.label != label {
nl = append(nl, lens)
}
}
Boxes[hash] = nl
} else {
tokens := strings.Split(cmd, "=")
label := tokens[0]
fl := utils.MustAtoi(tokens[1])
hash := hash(label)
nl := []Lens{}
if len(Boxes[hash]) == 0 {
Boxes[hash] = append(Boxes[hash], Lens{label:label, fl:fl})
} else {
found := false
for _, lens := range Boxes[hash] {
if lens.label == label {
nl = append(nl, Lens{label:label, fl:fl})
found = true
} else {
nl = append(nl, lens)
}
}
Boxes[hash] = nl
if ! found {
Boxes[hash] = append(Boxes[hash], Lens{label:label, fl:fl})
}
}
}
}
ans := 0
for i, box := range Boxes {
for j, lens := range box {
ans += (i+1) * (j +1) * lens.fl
}
}
return ans
}
func hash(in string) int {
result := 0
for _, letter := range in {
result += int(letter)
result = result * 17
result = result % 256
}
return result
}

View File

@@ -0,0 +1,17 @@
package day15
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1("rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7")
require.Equal(t, 1320, r)
}
func TestPart2(t *testing.T) {
r := Part2("rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7")
require.Equal(t, 145, r)
}

1
2023/go/day15/input.txt Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

202
2023/go/day16/day16.go Normal file
View File

@@ -0,0 +1,202 @@
package day16
import (
_ "adventofcode2023/utils"
"adventofcode2023/utils/grid2d"
_ "adventofcode2023/utils/grid2d"
"adventofcode2023/utils/inputs"
"fmt"
_ "strings"
)
type Tile struct {
object rune
energized int
}
type Beam struct {
dir rune
r int
c int
rm bool
}
var startBeams []Beam
func Part1(input string) int {
beams := []Beam{}
beams = addBeam(beams, Beam{'s', 0, 3, false})
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
return score(grid, beams)
}
func Part2(input string) int {
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
G := grid.Matrix()
R := len(G)
C := len(G[0])
ans := 0
for r:=0;r<R;r++{
beams := []Beam{}
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
beams = addBeam(beams, Beam{'e', r, 0, false})
ans = max(ans, score(grid, beams))
beams = []Beam{}
beams = addBeam(beams, Beam{'w', r, C-1, false})
grid = inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
ans = max(ans, score(grid, beams))
}
for c:=0;c<C;c++{
beams := []Beam{}
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
beams = addBeam(beams, Beam{'s', 0, c, false})
ans = max(ans, score(grid, beams))
beams = []Beam{}
beams = addBeam(beams, Beam{'n', R-1, c, false})
grid = inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
ans = max(ans, score(grid, beams))
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func score(grid *grid2d.Grid[Tile], beams []Beam) int {
fmt.Println(grid.StringWithFormatter(func(t Tile, x int, y int) string { return string(t.object)}))
G := grid.Matrix()
R := len(G)
C := len(G[0])
fmt.Println("r:", R, "c:", C, "tiles:", R*C )
for i:=0;i<1000;i++ {
beams = rmBeams(beams)
fmt.Println(i, ":", len(beams), ":", energy(G))
for i, _ := range beams {
r := beams[i].r
c := beams[i].c
if r >= 0 && r < R && c >= 0 && c < C {
G[r][c].energized++
switch beams[i].dir {
case 'n':
tile := &G[r][c]
switch tile.object {
case '.':
beams[i].r--
case '|':
beams[i].r--
case '-':
beams[i].dir = 'e'
beams[i].c++
beams = addBeam(beams, Beam{'w', beams[i].r, beams[i].c-1, false})
case '\\':
beams[i].dir = 'w'
beams[i].c--
case '/':
beams[i].dir = 'e'
beams[i].c++
}
case 'e':
tile := &G[r][c]
switch tile.object {
case '.':
beams[i].c++
case '-':
beams[i].c++
case '|':
beams[i].dir = 'n'
beams[i].r--
beams = addBeam(beams, Beam{'s', beams[i].r+1, beams[i].c, false})
case '\\':
beams[i].dir = 's'
beams[i].r++
case '/':
beams[i].dir = 'n'
beams[i].r--
}
case 's':
tile := &G[r][c]
switch tile.object {
case '.':
beams[i].r++
case '|':
beams[i].r++
case '-':
beams[i].dir = 'e'
beams[i].c++
beams = addBeam(beams, Beam{'w', beams[i].r, beams[i].c-1, false})
case '\\':
beams[i].dir = 'e'
beams[i].c++
case '/':
beams[i].dir = 'w'
beams[i].c--
}
case 'w':
tile := &G[r][c]
switch tile.object {
case '.':
beams[i].c--
case '-':
beams[i].c--
case '|':
beams[i].dir = 'n'
beams[i].r--
beams = addBeam(beams, Beam{'s', beams[i].r+1, beams[i].c, false})
case '\\':
beams[i].dir = 'n'
beams[i].r--
case '/':
beams[i].dir = 's'
beams[i].r++
}
}
} else {
beams[i].rm = true
}
}
fmt.Println(grid.StringWithFormatter(func(t Tile, x int, y int) string { if t.energized > 0 {return "#"}; return "."}))
}
fmt.Println(grid.StringWithFormatter(func(t Tile, x int, y int) string { if t.energized > 0 {return "#"}; return "."}))
return energy(G)
}
func rmBeams(slice []Beam) []Beam {
var result []Beam
for _, value := range slice {
if ! value.rm {
result = append(result, value)
}
}
return result
}
func addBeam(beams []Beam, beam Beam) []Beam {
for _, value := range startBeams {
if value == beam { return beams }
}
startBeams = append(startBeams, beam)
for _, value := range beams {
if value == beam { return beams }
}
return append(beams, beam)
}
func energy(G [][]Tile) int {
ans := 0
R := len(G)
C := len(G[0])
for r:=0;r<R;r++ {
for c:=0;c<C;c++ {
if G[r][c].energized > 0 {
ans++
}
}
}
return ans
}

68
2023/go/day16/day16.py Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/python3
import sys
import re
from copy import deepcopy
from math import gcd
from collections import defaultdict, Counter, deque
D = open(sys.argv[1]).read().strip()
L = D.split('\n')
G = [[c for c in row] for row in L]
R = len(G)
C = len(G[0])
DR = [-1, 0, 1, 0]
DC = [ 0, 1, 0,-1]
def step(r,c,d):
return (r+DR[d], c+DC[d], d)
def score(sr,sc,sd):
POS = [(sr,sc,sd)]
SEEN = set()
SEEN2 = set()
while True:
NP = []
if not POS:
break
for (r,c,d) in POS:
#print(r,c,d)
if 0<=r<R and 0<=c<C:
SEEN.add((r,c))
if (r,c,d) in SEEN2:
continue
SEEN2.add((r,c,d))
ch = G[r][c]
if ch=='.':
NP.append(step(r,c,d))
elif ch=='/':
# up right down left
NP.append(step(r,c,{0:1, 1:0, 2:3, 3:2}[d]))
elif ch=='\\':
NP.append(step(r,c,{0:3, 1:2, 2:1, 3:0}[d]))
elif ch=='|':
if d in [0,2]:
NP.append(step(r,c,d))
else:
NP.append(step(r, c, 0))
NP.append(step(r, c, 2))
elif ch=='-':
if d in [1,3]:
NP.append(step(r,c,d))
else:
NP.append(step(r, c, 1))
NP.append(step(r, c, 3))
else:
assert False
POS = NP
return len(SEEN)
print(score(0,0,1))
ans = 0
for r in range(R):
ans = max(ans, score(r,0,1))
ans = max(ans, score(r,C-1,3))
for c in range(C):
ans = max(ans, score(0,c,2))
ans = max(ans, score(R-1,c,0))
print(ans)

View File

@@ -0,0 +1,37 @@
package day16
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1(
`.|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|...`)
require.Equal(t, 46, r)
}
func TestPart2(t *testing.T) {
r := Part2(
`.|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|...`)
require.Equal(t, 51, r)
}

110
2023/go/day16/input.txt Normal file
View File

@@ -0,0 +1,110 @@
\.......................\..........................................-..................-.../................-..
....../.......\...-......-.|...\..............\.................|............././....-........................
...............-...-........................................\......\..-.............|......-....\....-........
..\..|.|...........................-.|........................................./.|....|................|......
|../................|............................................................\........../..\..............
........\............../................/..........................\...\....|............./....-.........\\...
.................-...-...................\../........-|.................../......-...........|................
........-............/...|-............-.....\.|..............-....-../\../..................\...\././........
........................-|................................................................-........-..........
-......./.................|.....\.................\.....//............-........./..../....|...................
....-.............-........-..........-|.......|...../...\...................\.....................|..........
...|...\.........|.................|.....|....-....\.......\./........................-.../..../.....-........
....|....-.-..............\.........|.......................-.......-..............\................/.........
.....|.\...........-.................-.-........../...\............|...............|...|......./.......|...../
.....\.........................-.../..-./...\...................../......\...-.......|.\........-|............
............|.....................................-....../....\.............../-...|...\..\................./.
......-./|....../............|.........\............-../...-......./.\..\....../......|/...\..................
................................|.......|..-..../.............................../.-..................-..-/..|.
...............................-......./......................|./...............-............./....../........
..................../....................\........\...........................-............/.../..............
.|||......../.................|.................../..\............................-......./..|...|/.-.........
......-......./\....../.........|....../.......-...............|.\........-............/.../..................
.....................-.\/|................//.../.........|.|......\.-..|.........|.........\..................
.........................\/.......|.|............................|........|.............................././..
.................................|.................\../..|/.................\.................-...-........-/.
......................-...-.........../...........................\....\......-..-.......\.-....\....|........
......-......../..............\/..................\..|........-..............|...-...../......|...............
|.......|.../....|..............//.....................|..........|/......../................|................
...|.|..................../|..../.-.......-...........|.....|./....\......-......-................|...........
......\/./.|\..../|.|..|..........-....|...........|.-.|...................-.\.....|....................\.....
......../.\......................|.....|...........|.........../.......|....|...|.......-......../......\...-.
...|...-...||......-..|..-...........|.-.................|.................................-..................
..............-.\.-........|......\..........................................\./.\........../.....|...........
../\.........|...............|............|.\/.-/.................-....|...-.................-.....|..../.....
....................../......../..../-.....\........................\..-.\....|....-.........../-.............
.................................|................|.........|................../|.....|....\\............/.\..
...///./.....\.................|/.....................\...................-............|................|.....
............-...........................--........\................/.............-\................\.....-.../
...............\.........../|............................|.....................\...-...\.....................-
...\.............|.............|................\............\|...../...|.........................|...........
..................|......|..........-.-..............\.........................\..............................
....-................../.........../...|................/...............|./.|.../....\..../......./......//...
...../....../..............................|...\../..........-..........-........-..//..../...................
...............-......|......................|./........./............/..-...........|../.....-........-./....
..\.........................|...-.......\.................|..............-........\....-.............-....|...
.......|......|....../........\...........|......-........../......-..................../....................\
.......................|....-..|........./.|.-...............|..\......\.....-.......\...-/....|/.........\...
\......\..-.....................\..........................\................................../...........\...
-....-......../............................................................../.\.......|..............|....-..
........|......................|.............-....\................................./..\.......|..........-...
...-...............|........./......\...../.......|...|...............\.../...\.../......|.....-.\......\.....
............./.....|......................|.....................................\...||.................-....|.
./.....-................/........|./....-......../......./..............\..................................\..
.../..../\........-..........................|.-/.|..\................\\-.......|......./...||.......|........
.....-.........................-...............\...........|.............-.\.../.|......-.|......../...-.....-
......\....................|...../......................|.../......-..|............|......./.../.........|....
...|...........-....................................../.|............./....|..../........./.....\../..........
....../.../................\........................\...\....\......\............../|...............\.-.......
./....\.../.............|............................-.../............../............/...........\...|........
............................|.................|/..........//.........../..-...............|...................
.....\......\.................|.....|...\-./...............\................|....../.....-..\........-....-...
........................./-........\................./........-/.|....-.......\............-/\......|.\...-...
..../../..|.|...............\.......................................-.........................................
...........|...................................................-...-......|..................\............../.
/....|......................................................................|\.../.......-...........-...|....
......|.-.\......-........|.....-..|.\..............-......./......-|.........................-...............
............\......................................|........................|.-...............................
.........-.........../....\./....../.-...-..//.........../.......\\...........................................
........\......../............./...-......\.../..|..|............................../......../..\..............
--.........|.....-...|............../...|.......|..............\|............|.........................|.-....
-\......./..............-....-....\...|.-........\/.\./............-/...\........|-.........../../...\........
.\|\..............-......-.\...-....\..........................\........|...........-......./.............../.
..........................|...\..../.../..........\.............-...//...............\..................-.....
........./..........................\............|-.....|..-...|......../........-...........................\
.......\.../.....\....../.......|..|...............-......................|....-...................-.|........
......|.......\.../..............................-..............................|......-.-...................\
/.....|.......-............/|.....|-......./..../......-........../..|......../.-..\..../....../...|..........
............/..--..........-............\.......\................\........................../../....|.........
..|..-................|.|..|................/.......\............-//.......................\..\...............
.......................-......-..................|....\................-......\.|....\....|..../../|.-........
........................-..................-...........................-..-................-................|.
/.\....|.-.................................\..-.....\./.........../-.|..............\..\.....--|/....\........
.......-..-../..................\..--|..............|...............|\........|...--................|./.\.....
..........|................-.......|..................................................|...................|...
-.-..|....-.|........-./...|.-.........\.....\/........-........\........../................./.../........\...
..................../...|/......................................../............\.|./../................/\|....
...//.........................\....../..............\../.......-..\....|......................................
............................./..|./../.........-/..\..........................................................
......\.....|..................|..................\.....\.-..\...../............................../...........
..........\...........-..........-.....-....\/................../.................................\.....|..\..
..../.\...................................\............\...\....|.................|.....................-.....
...........-...........................\.......|-../.|....|.....|......................-...../................
.......|.........\..............|....\...-......../...........-.....-..-...........-..................\...\.|.
...........|.......................|....-..........\............................\.................../.\.......
..../.................\.......-..|.................../........................|...............\...........-.|.
............./..|.-\..../.....-............-....|..\......|......../............-.........|................\..
...................\...\/......\............|......................\....|...................-./-..............
..-\...........|.................../.....|....|............................-..|............\.............\....
.|.....\....\........|..................\...............|..-/.........|.-/...........-............-...........
.....\...../......-............|........./..|............-........................\....-......................
......\......../........|..............\...-..-...|.......................................................|...
...................|.................................\.....\...........................|../.|.-......-........
..................|..............\.....\............|........../....../...............\.........\.............
..|...........-..../....\.........--...\................../.............-...-....................-..../....|..
.|...\...................|......-...........-\..........\.....|.....|..........|.........|....|-../...........
.............\|...................../\...............\....../.......-....\.....................-..............
.......//.....................\....\......\......\.........|...................../......../.........\......-..
.\./.........-...-./-.\.............../......|................................\|....\...../....-..............
.......|......../......../......./.........../...............|............................../..|......../.....
............./.........|.....-./.........../....-......./|......-................|............................

View File

@@ -20,6 +20,9 @@ import (
"adventofcode2023/day11"
"adventofcode2023/day12"
"adventofcode2023/day13"
"adventofcode2023/day14"
"adventofcode2023/day15"
"adventofcode2023/day16"
@@ -70,6 +73,15 @@ func main() {
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)))
default:
panic(fmt.Errorf("no such day: %d", d))
}
@@ -77,7 +89,7 @@ func main() {
// Reads day from os.Args.
func day() int {
latest := 12
latest := 15
if len(os.Args) == 1 {
return latest
}

16
2024/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",
"args": ["16"],
"program": "${fileDirname}"
}
]
}

54
2024/go/day01/day01.go Normal file
View File

@@ -0,0 +1,54 @@
package day01
import (
"adventofcode2024/utils"
"sort"
"strings"
)
func Part1(input string) int {
var list1, list2 []int
num := 0
lines := strings.Split(input, "\n")
for _, line := range lines {
fields := strings.Fields(line)
// Convert the fields to integers
val1 := utils.MustAtoi(fields[0])
val2 := utils.MustAtoi(fields[1])
// Append to the respective slices
list1 = append(list1, val1)
list2 = append(list2, val2)
}
sort.Ints(list1)
sort.Ints(list2)
for i := 0; i < len(list1); i++ {
num += utils.Abs(list1[i] - list2[i])
}
return num
}
func Part2(input string) int {
var list1 []int
list2 := make(map[int]int)
num := 0
lines := strings.Split(input, "\n")
for _, line := range lines {
fields := strings.Fields(line)
// Convert the fields to integers
val1 := utils.MustAtoi(fields[0])
val2 := utils.MustAtoi(fields[1])
// Append to the respective slices
list1 = append(list1, val1)
list2[val2]++
}
for i := 0; i < len(list1); i++ {
num += list1[i] * list2[list1[i]]
}
return num
}

View File

@@ -0,0 +1,17 @@
package day01
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)
}

1000
2024/go/day01/input.txt Normal file

File diff suppressed because it is too large Load Diff

5
2024/go/go.mod Normal file
View File

@@ -0,0 +1,5 @@
module adventofcode2024
go 1.19
require golang.org/x/exp v0.0.0-20221208152030-732eee02a75a

2
2024/go/go.sum Normal file
View File

@@ -0,0 +1,2 @@
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw=
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=

84
2024/go/main.go Normal file
View File

@@ -0,0 +1,84 @@
package main
import (
"fmt"
// "math/rand"
"os"
// "strings"
// "time"
"adventofcode2024/utils"
"adventofcode2024/day01"
)
// 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)
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)))
default:
panic(fmt.Errorf("no such day: %d", d))
}
}
// Reads day from os.Args.
func day() int {
latest := 1
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,77 @@
package grid2d
import (
"strings"
"adventofcode2024/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(2024, 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,45 @@
package inputs
import (
"strings"
"adventofcode2024/utils"
"adventofcode2024/utils/grid2d"
sparsegrid "adventofcode2024/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] {
lines := strings.Split(input, rowSep)
grid := grid2d.NewGrid(len(lines[0]), 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,81 @@
package sparsegrid
import (
"fmt"
"strings"
"adventofcode2024/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
2024/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
}
}