Compare commits
8 Commits
3128ab673f
...
d09a8af5db
Author | SHA1 | Date |
---|---|---|
|
d09a8af5db | |
|
6e623b617e | |
|
bd45c334b0 | |
|
192ff3878e | |
|
b5cb827be2 | |
|
149b753d22 | |
|
709f4c0532 | |
|
fde1415f34 |
|
@ -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())
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
O....#....
|
||||||
|
O.OO#....#
|
||||||
|
.....##...
|
||||||
|
OO.#O....O
|
||||||
|
.O.....O#.
|
||||||
|
O.#..O.#.#
|
||||||
|
..O..#O..O
|
||||||
|
.......O..
|
||||||
|
#....###..
|
||||||
|
#OO..#....
|
|
@ -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..
|
|
@ -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
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7
|
File diff suppressed because one or more lines are too long
6
main.go
6
main.go
|
@ -3,12 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"sunshine.industries/aoc2023/day13"
|
"sunshine.industries/aoc2023/day15"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.Print("> starting run:")
|
log.Print("> starting run:")
|
||||||
|
|
||||||
result := day13.Run()
|
result := day15.Run()
|
||||||
log.Printf("day13 result: %d\n****\n", result)
|
log.Printf("day15 result: %d\n****\n", result)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue