Compare commits

...

8 Commits

Author SHA1 Message Date
efim d09a8af5db day15, part2 2023-12-15 15:05:19 +00:00
efim 6e623b617e day15, example two 2023-12-15 15:04:50 +00:00
efim bd45c334b0 day15, part1 2023-12-15 14:15:18 +00:00
efim 192ff3878e day15, example 2023-12-15 14:13:36 +00:00
efim b5cb827be2 day14, part2 2023-12-14 11:57:31 +00:00
efim 149b753d22 day14, example two 2023-12-14 11:56:42 +00:00
efim 709f4c0532 day14, too slow. need memo? 2023-12-14 11:47:03 +00:00
efim fde1415f34 day14, example 2023-12-14 11:30:03 +00:00
7 changed files with 479 additions and 3 deletions

216
day14/dayFourteen.go Normal file
View File

@ -0,0 +1,216 @@
package day14
import (
"fmt"
"log"
"os"
"strings"
)
func Run() int {
fmt.Println("hello day 14")
field := ReadPlatform("day14/input")
fmt.Println(field.String())
// fmt.Printf("> lines for field %+v\n", field.UpIndices())
// field.Move(field.Height(), field.UpIndices())
cycles := 1000000000
states := make(map[string]int)
// 2023/12/14 11:50:32 >>> found loop. known state after 10 equal to one after 3
var loopLen, initialStretch int
for i := 1; i <= cycles; i++ {
field.DoSpinCycle()
// fmt.Println(field.String())
stringRepr := field.String()
prevIter, known := states[stringRepr]
if known {
log.Printf(">>> found loop. known state after %d equal to one after %d", i, prevIter)
initialStretch = prevIter
loopLen = i - prevIter
break
}
states[stringRepr] = i
if i % 100000 == 0 {
log.Print("done ", i, " cycles")
}
}
// field is already in a 'loop' state.
// so we've already done 'initial stretch' so to make field in same state as after 'cycles'
// i only need to check rest of (cycles - initialStretch)
movesToMake := (cycles - initialStretch)%loopLen
log.Printf(">>> data: initial steps %d, loop len %d. to do same as %d iterations i need %d", initialStretch, loopLen, cycles, movesToMake)
for i := 1; i <= movesToMake; i++ {
field.DoSpinCycle()
// fmt.Println(field.String())
}
// north rock load
return field.NorthLoad()
}
const Rock rune = 'O'
const Wall rune = '#'
const Space rune = '.'
type Platform struct {
Rocks [][]rune
}
func (p *Platform) Height() int {
return len(p.Rocks)
}
func (p *Platform) Width() int {
return len(p.Rocks[0])
}
func ReadPlatform(filename string) Platform {
bytes, err := os.ReadFile(filename)
if err != nil {
panic(fmt.Sprint("cannot read file: ", filename))
}
text := string(bytes)
text = strings.TrimSpace(text)
lines := strings.Split(text, "\n")
rocks := make([][]rune, len(lines))
for i, line := range lines {
rocks[i] = []rune(line)
}
return Platform{
Rocks: rocks,
}
}
func (p *Platform) String() string {
text := "\n"
for _, row := range p.Rocks {
text += string(row)
text += "\n"
}
return text
}
type Coord struct{ Row, Col int }
// indices for moving UP, from down to up
func (p *Platform) UpIndices() [][]Coord {
lines := make([][]Coord, 0)
for col := 0; col < p.Width(); col++ {
line := make([]Coord, 0)
for row := 0; row < p.Height(); row++ {
line = append(line, Coord{Row: row, Col: col})
}
lines = append(lines, line)
}
return lines
}
// indices for moving DOWN, from up to down
func (p *Platform) DownIndices() [][]Coord {
lines := make([][]Coord, 0)
for col := 0; col < p.Width(); col++ {
line := make([]Coord, 0)
for row := p.Height() - 1; row >= 0; row-- {
line = append(line, Coord{Row: row, Col: col})
}
lines = append(lines, line)
}
return lines
}
// indices for moving RIGHT from right to left
func (p *Platform) RightIndices() [][]Coord {
lines := make([][]Coord, 0)
for row := 0; row < p.Height(); row++ {
line := make([]Coord, 0)
for col := p.Width() - 1; col >= 0; col-- {
line = append(line, Coord{Row: row, Col: col})
}
lines = append(lines, line)
}
return lines
}
// indices for moving LEFT, from left to right
func (p *Platform) LeftIndices() [][]Coord {
lines := make([][]Coord, 0)
for row := 0; row < p.Height(); row++ {
line := make([]Coord, 0)
for col := 0; col < p.Width(); col++ {
line = append(line, Coord{Row: row, Col: col})
}
lines = append(lines, line)
}
return lines
}
func (p *Platform) SymbAt(coord Coord) rune {
return p.Rocks[coord.Row][coord.Col]
}
func (p *Platform) SetSymbAt(coord Coord, symb rune) {
p.Rocks[coord.Row][coord.Col] = symb
}
func (p *Platform) Move(n int, lines [][]Coord) {
for _, line := range lines {
moveSize := 0
for i, coord := range line {
symb := p.SymbAt(coord)
switch symb {
case Space:
moveSize += 1
if moveSize > n {
moveSize = n
}
case Wall:
moveSize = 0
case Rock:
if moveSize == 0 {
continue
}
// get coord for moveSize back. and set that to 'o'
// and set current to '.'
// panic if that place is not '.' i guess
moveTo := line[i-moveSize]
symbAtTarget := p.SymbAt(moveTo)
if symbAtTarget != Space {
panic(fmt.Sprintf("attempting to move %+v to %+v, target symbol is %s, not '.'",
coord, moveTo, string(symbAtTarget)))
}
p.SetSymbAt(moveTo, Rock)
p.SetSymbAt(coord, Space)
}
}
}
}
func (p *Platform) NorthLoad() int {
total := 0
height := p.Height()
for i, row := range p.Rocks {
for _, symb := range row {
if symb == Rock {
total += (height - i)
}
}
}
return total
}
func (p *Platform) DoSpinCycle() {
// north, west, south, east - till the end
p.Move(p.Height(), p.UpIndices())
p.Move(p.Width(), p.LeftIndices())
p.Move(p.Height(), p.DownIndices())
p.Move(p.Width(), p.RightIndices())
}

10
day14/example Normal file
View File

@ -0,0 +1,10 @@
O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....

100
day14/input 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..

148
day15/dayFifteen.go Normal file
View File

@ -0,0 +1,148 @@
package day15
import (
"fmt"
"log"
"os"
"regexp"
"slices"
"strconv"
"strings"
)
func Run() int {
fmt.Println("hello day 15")
log.Println("hello day 15")
filename := "day15/input"
bytes, err := os.ReadFile(filename)
if err != nil {
panic(fmt.Sprint("error reading file ", filename))
}
text := string(bytes)
text = strings.TrimSpace(text)
instructions := strings.Split(text, ",")
result := 0
boxes := make([]Box, 256)
for i, box := range boxes {
box.Focals = make(map[string]int)
boxes[i] = box
}
for _, instructionStr := range instructions {
i := ReadInstruction(instructionStr)
box := boxes[i.Box]
box.Act(i)
boxes[i.Box] = box
// result += ASCIIStringHash(instruction)
}
for i, box := range boxes {
if len(box.Labels) != 0 {
log.Printf("%d box %+v final state\n", i, box)
}
result += (i + 1) * box.FocusingPower()
}
return result
}
type Box struct {
Labels []string
Focals map[string]int
}
func (b *Box)Act(i Instruction) {
log.Printf("for box %+v instruction \n%s\n", b, i.String())
switch i.Action {
case Put:
_, found := b.Focals[i.Label]
if !found {
b.Labels = append(b.Labels, i.Label)
}
b.Focals[i.Label] = i.LensFocal
case Remove:
_, found := b.Focals[i.Label]
if !found {
return
}
index := slices.Index(b.Labels, i.Label)
delete(b.Focals, i.Label)
b.Labels = slices.Delete(b.Labels, index, index+1)
}
log.Printf("result : %+v\n", b)
return
}
func (b *Box)FocusingPower() int {
result := 0
for i, label := range b.Labels {
result += (i + 1) * b.Focals[label]
}
return result
}
type Action rune
const (
Put Action = '='
Remove = '-'
)
type Instruction struct {
Label string
Box int
Action Action
LensFocal int
}
func (i *Instruction) String() string {
operation := ""
switch i.Action {
case Put:
operation = "put into"
case Remove:
operation = "remove from"
}
return fmt.Sprintf("%s\t\t%d of focal %d %s", operation, i.Box, i.LensFocal, i.Label)
}
func ReadInstruction(str string) Instruction {
result := Instruction{}
re := regexp.MustCompile(`(?P<label>\D+)(?P<operation>[=\-])(?P<focal>\d*)`)
// log.Println("in str ", str)
fields := re.FindStringSubmatch(str)
// log.Printf("in %s found %+v", str, fields)
operation := fields[2]
operationRune := []rune(operation)[0]
result.Action = Action(operationRune)
if operationRune == '=' {
focalStr := fields[3]
focal, err := strconv.Atoi(focalStr)
if err != nil {
panic(fmt.Sprint("error reading focal from ", str))
}
result.LensFocal = focal
}
result.Label = fields[1]
result.Box = ASCIIStringHash(result.Label)
return result
}
func ASCIIStringHash(str string) int {
result := 0
for _, symb := range str {
result += int(symb)
result *= 17
result %= 256
}
return result
}

1
day15/example Normal file
View File

@ -0,0 +1 @@
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7

1
day15/input Normal file

File diff suppressed because one or more lines are too long

View File

@ -3,12 +3,12 @@ package main
import (
"log"
"sunshine.industries/aoc2023/day13"
"sunshine.industries/aoc2023/day15"
)
func main() {
log.Print("> starting run:")
result := day13.Run()
log.Printf("day13 result: %d\n****\n", result)
result := day15.Run()
log.Printf("day15 result: %d\n****\n", result)
}