Compare commits
12 Commits
37ee3e99da
...
762e72744c
Author | SHA1 | Date |
---|---|---|
|
762e72744c | |
|
85dd9a31e3 | |
|
d4c162db33 | |
|
adcb2417ff | |
|
4d346a23db | |
|
6398a4d468 | |
|
42b587918e | |
|
c187a03076 | |
|
cdf5a38512 | |
|
3a43f90431 | |
|
7032666476 | |
|
65d6c13016 |
|
@ -0,0 +1,109 @@
|
|||
package day11
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Run() int64 {
|
||||
fmt.Println("hello day 11")
|
||||
|
||||
filename := "day11/input"
|
||||
bytes, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
panic(fmt.Sprint("cannot read file ", filename))
|
||||
}
|
||||
|
||||
text := strings.TrimSpace( string(bytes) )
|
||||
starCoords := make([]StarCoord, 0)
|
||||
|
||||
lines := strings.Split(text, "\n")
|
||||
|
||||
nonEmptyRows := make(map[int]any)
|
||||
nonEmptyCols := make(map[int]any)
|
||||
|
||||
for rowNum, line := range lines {
|
||||
for colNum, symb := range line {
|
||||
if symb == '#' {
|
||||
starCoords = append(starCoords, StarCoord{rowNum, colNum})
|
||||
nonEmptyCols[colNum] = struct{}{}
|
||||
nonEmptyRows[rowNum] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emptyRowsAbove := make([]int, len(lines))
|
||||
emptyColsToTheLeft := make([]int, len(lines))
|
||||
|
||||
for rowNum, _ := range lines {
|
||||
if rowNum > 0 {
|
||||
emptyRowsAbove[rowNum] = emptyRowsAbove[rowNum-1]
|
||||
}
|
||||
_, isRowNonempty := nonEmptyRows[rowNum]
|
||||
if !isRowNonempty {
|
||||
emptyRowsAbove[rowNum] += 1
|
||||
}
|
||||
}
|
||||
|
||||
for colNum, _ := range lines[0] {
|
||||
if colNum > 0 {
|
||||
emptyColsToTheLeft[colNum] = emptyColsToTheLeft[colNum-1]
|
||||
}
|
||||
_, isColNonempty := nonEmptyCols[colNum]
|
||||
if !isColNonempty {
|
||||
emptyColsToTheLeft[colNum] += 1
|
||||
}
|
||||
}
|
||||
|
||||
var distanceSum int64
|
||||
for i := 0; i < len(starCoords); i++ {
|
||||
for j := i+1; j < len(starCoords); j++ {
|
||||
// calc distance between stars i and j
|
||||
starA := starCoords[i]
|
||||
starB := starCoords[j]
|
||||
|
||||
maxRow := starA.Row
|
||||
minRow := starB.Row
|
||||
|
||||
if maxRow < minRow {
|
||||
maxRow, minRow = minRow, maxRow
|
||||
}
|
||||
|
||||
var multiplier int64
|
||||
multiplier = 1000000 - 1
|
||||
|
||||
emptyRowsBetween := int64(emptyRowsAbove[maxRow]) - int64(emptyRowsAbove[minRow])
|
||||
|
||||
rowDistance := int64(maxRow) - int64(minRow) + emptyRowsBetween*multiplier
|
||||
|
||||
maxCol := starA.Col
|
||||
minCol := starB.Col
|
||||
if maxCol < minCol {
|
||||
maxCol, minCol = minCol, maxCol
|
||||
}
|
||||
|
||||
emptyColsBetween := int64(emptyColsToTheLeft[maxCol]) - int64(emptyColsToTheLeft[minCol])
|
||||
|
||||
colDistance := int64(maxCol) - int64(minCol) + emptyColsBetween*multiplier
|
||||
|
||||
distance := rowDistance + colDistance
|
||||
log.Printf("between stars %d %+v and %d %+v distance is %d. emptyColsBetween %d ; emptyRowsBetween %d\n", i, j, starA, starB, distance, emptyColsBetween, emptyRowsBetween)
|
||||
distanceSum += int64(distance)
|
||||
}
|
||||
}
|
||||
|
||||
// oh, i have list of all stars, i can just iterate over them and
|
||||
// only keep rowNums for which there are stars. yeah
|
||||
|
||||
fmt.Println(starCoords)
|
||||
fmt.Println(emptyRowsAbove)
|
||||
fmt.Println(emptyColsToTheLeft)
|
||||
|
||||
return distanceSum
|
||||
}
|
||||
|
||||
type StarCoord struct {
|
||||
Row, Col int
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
...#......
|
||||
.......#..
|
||||
#.........
|
||||
..........
|
||||
......#...
|
||||
.#........
|
||||
.........#
|
||||
..........
|
||||
.......#..
|
||||
#...#.....
|
|
@ -0,0 +1,140 @@
|
|||
........................#...............................................#................................#................................#.
|
||||
....#..............#......................#............#....................................................................#...............
|
||||
................................#.............................................................#.............................................
|
||||
.........#.....................................#...................#........................................................................
|
||||
....................................................#.......................#..............................#................................
|
||||
..#................................................................................................#................#......................#
|
||||
.........................................................#.........................#.....#..................................................
|
||||
..................................#.............................#...............................................#.............#.............
|
||||
.......#.....#...........................#..............................................................#.............................#.....
|
||||
......................#...............................#................................................................#....................
|
||||
............................#.................#........................#.....................................#..............................
|
||||
....#.................................#...............................................#.....................................................
|
||||
...............#...........................................................#............................................................#...
|
||||
..................................#...........................................................#...................#...........#.............
|
||||
....................................................................................................................................#.......
|
||||
................................................................#................#..........................#...............................
|
||||
...#..............#........#.........#.............#........................................................................................
|
||||
.........................................................#.............#.............#..............#...................#...................
|
||||
........#...................................................................................................................................
|
||||
..............................................................................................#.................................#........#..
|
||||
....................#.......................................#.....................................................#.........................
|
||||
#..............................#.......#......#...................................#......#..................................................
|
||||
...........#.......................................#......................................................................#.................
|
||||
.......................................................................................................................................#....
|
||||
............................................................................................................................................
|
||||
.........................#...................................#...............................#..............................................
|
||||
..................................#.......................................................................#.............#...................
|
||||
.........................................#...........................#...............................#.........#..........................#.
|
||||
............#......#............................................#...............................#...................................#.......
|
||||
.............................#.....................................................#........................................................
|
||||
....#........................................#...............................#.................................................#............
|
||||
......................#............................#.....#.........#........................................................................
|
||||
.........................................................................................................#..................................
|
||||
.......#........................#................................................#..........................................................
|
||||
...............................................#..........................#................#..........................................#.....
|
||||
.#................#.............................................................................................#......#....................
|
||||
..............................................................................................................................#.............
|
||||
..........................#........................#.............................................#..........................................
|
||||
.............#..........................#............................................#..............................#.......................
|
||||
........#..............................................#.....................#..........................#..................#................
|
||||
............................................................#.....#..................................................................#......
|
||||
....................#.........................#..........................#..................#...................#...........................
|
||||
..............................#...................................................#................#........................................
|
||||
.........................................#..............................................#..................................................#
|
||||
.#........#.........................................#.....................................................#.....................#...........
|
||||
.........................................................#.........................................................#........................
|
||||
......#...........................#.........................................................................................................
|
||||
................................................#........................................................................................#..
|
||||
...................................................................#...............#........................................................
|
||||
.....................#................................#..............................................................................#......
|
||||
...........#................................................................................#.....#.........................................
|
||||
....#........................#............................................#..............................................#..................
|
||||
................#.......#........................................................#........................................................#.
|
||||
#...................................................................................................................#.......................
|
||||
....................#...................#..............#.................................#...................#..............................
|
||||
.............#....................#.................................................#..................#...................#................
|
||||
.................................................................................................................#.....................#....
|
||||
................................................................................#...........................................................
|
||||
.......................#.............#....................#.................................................................................
|
||||
.......#.............................................................................................#..............#.......................
|
||||
...................#.....................................................................................................................#..
|
||||
......................................................#..................#.......................................................#..........
|
||||
..........................#..................................................................#..............................................
|
||||
............#.................................#.........................................#...................#............#..................
|
||||
.....................#......................................#......................................................#..........#.............
|
||||
.#.........................................................................#......#...................#.....................................
|
||||
............................................................................................................................................
|
||||
................................#...........................................................#...............................................
|
||||
........................................#..........................#..................................................#.................#...
|
||||
....#........................................#.....................................................#.............................#..........
|
||||
..........................................................#.................................................................................
|
||||
...............#............................................................................................................................
|
||||
..........#............#............................#.............................#...........................................#......#......
|
||||
....................................#........................................................#...............#..............................
|
||||
...........................................#..............................#...............................................................#.
|
||||
.#...........................#.......................................................................#......................................
|
||||
.........................................................#...........#....................................#.................................
|
||||
......#.......#...................#...........................#.......................#.........#..................#........................
|
||||
............................................................................#.........................................................#.....
|
||||
.....................#.........................................................................................#........#...................
|
||||
..........................#.............................................#................#........................................#.........
|
||||
............................................................................................................................................
|
||||
....#.....#.....#..................................#.........#.....................#....................#...................................
|
||||
........................................#.....................................................................................#.............
|
||||
...............................................................................................#............................................
|
||||
.......#........................#...........................................#............................................................#..
|
||||
....................#......#....................#...........................................................................................
|
||||
.........................................................#...........#..........#.............................#...........#.................
|
||||
......................................................................................#.....................................................
|
||||
....................................................................................................#................#..........#.....#.....
|
||||
............#.........#.....................#...............#..............................................#................................
|
||||
.......#............................#.......................................................................................................
|
||||
.......................................................................#......................#................#...................#........
|
||||
............................................................................................................................................
|
||||
........................................................................................................................#...................
|
||||
..........#..........#.......................#.........................................................................................#....
|
||||
...................................................................#.................#...........#..........................................
|
||||
........................................#................#..................................................................................
|
||||
................#....................................................................................................#......................
|
||||
............................................................................................................................................
|
||||
.......#....................#.................................................................#...............#.........................#...
|
||||
.................................#...........#.....#...........................................................................#............
|
||||
...........#.......................................................#....................#...................................................
|
||||
........................................#...............................................................................#...................
|
||||
............................................................................................................................................
|
||||
.....................................................................................................#......................................
|
||||
................#.........................................#..................#................................................#.......#.....
|
||||
....#................................#.............#...................................#.....................#.......#......................
|
||||
.........................#......................................#...........................................................................
|
||||
...........................................................................................#.......#........................................
|
||||
..........#.....................#..............#........................#...................................................................
|
||||
..#.........................................................................................................................................
|
||||
....................#.....................................#.......................#.........................................................
|
||||
..........................#.............#...............................................................................#.........#.........
|
||||
......................................................................................#.....................................................
|
||||
.....................................................................#..........................#...........................................
|
||||
.......#.........#...........................................................#.......................#........#............#............#...
|
||||
........................#....................................#..............................................................................
|
||||
.......................................#............................................#....................#.........................#........
|
||||
..............................................#....................................................................#........................
|
||||
..............#..................#.....................................#..........................#.........................................
|
||||
..........................................#..........#..........................#...........................................................
|
||||
.....#......................................................................................#................#..............................
|
||||
.....................#................................................................#.......................................#.............
|
||||
.....................................................................#......................................................................
|
||||
...........#.....#............................#.....................................................................................#.......
|
||||
................................#.....#..........................#........#..........................................#....................#.
|
||||
...........................#.................................................................#........#.......#.............................
|
||||
#...........................................................................................................................................
|
||||
........#........................................#...................................#......................................................
|
||||
.............................................................................................................................#..............
|
||||
.................................#..............................#........................#.........#........#...............................
|
||||
............#.....#..........................#.......................#....................................................................#.
|
||||
........................#........................................................#..........................................................
|
||||
............................................................#..............#......................................#.........................
|
||||
...#........................................................................................#...............................................
|
||||
...........................................................................................................#......................#.........
|
||||
..........#.......................................................................................#.........................................
|
||||
......................#................#............................................#.................................................#.....
|
||||
...........................#.....................#........#...................................................#.............................
|
|
@ -0,0 +1,184 @@
|
|||
package day12
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Run() int {
|
||||
fmt.Println("hello day 12.")
|
||||
|
||||
start := time.Now()
|
||||
|
||||
filename := "day12/input"
|
||||
bytes, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error reading file %s\n", filename))
|
||||
}
|
||||
|
||||
result := 0
|
||||
text := string(bytes)
|
||||
text = strings.TrimSpace(text)
|
||||
|
||||
// testMask, testBlocks := ReadLine(".??..??...?##. 1,1,3")
|
||||
// blocksSum := 0
|
||||
// for _, block := range testBlocks {
|
||||
// blocksSum += block
|
||||
// }
|
||||
// testVariants := generatePermutations("", len(testMask), testBlocks, blocksSum, testMask)
|
||||
// fmt.Printf("for mask %s and blocks %+v\n", testMask, testBlocks)
|
||||
// for _, variant := range testVariants {
|
||||
// fmt.Println(variant)
|
||||
// }
|
||||
|
||||
var wg sync.WaitGroup
|
||||
lines := strings.Split(text, "\n")
|
||||
wg.Add(len(lines))
|
||||
|
||||
matches := make(chan int)
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(matches)
|
||||
}()
|
||||
|
||||
for i, line := range lines {
|
||||
go func(line string, lineNum int){
|
||||
mask, blockLengs := ReadLine(line)
|
||||
|
||||
blockLengthSum := 0
|
||||
for _, blockLen := range blockLengs {
|
||||
blockLengthSum += blockLen
|
||||
}
|
||||
|
||||
memo := make(map[string]int)
|
||||
variantsCount := generatePermutations("", len(mask), blockLengs, blockLengthSum, mask, memo)
|
||||
|
||||
log.Printf("%d : for line %s blocks %+v matches %d\n", lineNum, mask, blockLengs, variantsCount)
|
||||
matches <- variantsCount
|
||||
wg.Done()
|
||||
}(line, i)
|
||||
}
|
||||
|
||||
num := 0
|
||||
for match := range matches {
|
||||
num += 1
|
||||
result += match
|
||||
log.Printf("%d. intermediate: %d\n", num, result)
|
||||
fmt.Printf("%d\n", result)
|
||||
}
|
||||
|
||||
end := time.Now()
|
||||
|
||||
diff := end.Sub(start)
|
||||
log.Printf("> calculated for %s", diff.String())
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func myRepeat(line, sep string, amount int) string {
|
||||
acc := ""
|
||||
for i := 0; i < amount; i++ {
|
||||
acc += sep
|
||||
acc += line
|
||||
}
|
||||
acc, _ = strings.CutPrefix(acc, sep)
|
||||
|
||||
return acc
|
||||
}
|
||||
|
||||
// ???.### 1,1,3
|
||||
func ReadLine(line string) (string, []int) {
|
||||
firstSplit := strings.Split(line, " ")
|
||||
if len(firstSplit) != 2 {
|
||||
panic(fmt.Sprintf("error splitting %s into 2", line))
|
||||
}
|
||||
mask := firstSplit[0]
|
||||
mask = myRepeat(mask, "?", 5)
|
||||
blocks := firstSplit[1]
|
||||
blocks = myRepeat(blocks, ",", 5)
|
||||
// log.Printf(">> repeating blocks %s", blocks)
|
||||
blockLengthStrings := strings.Split(blocks, ",")
|
||||
blockLengs := make([]int, len(blockLengthStrings))
|
||||
|
||||
for i, blockLenStr := range blockLengthStrings {
|
||||
num, err := strconv.Atoi(blockLenStr)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error extracting num %s from %s\n", blockLenStr, line))
|
||||
}
|
||||
blockLengs[i] = num
|
||||
}
|
||||
|
||||
return mask, blockLengs
|
||||
}
|
||||
|
||||
func generatePermutations(curString string, targetLength int, blockLengths []int, blockLengthsSum int, mask string, memo map[string]int) int {
|
||||
|
||||
memoKey := fmt.Sprintf("%+v|%d", blockLengths, len(curString))
|
||||
memoized, memoFound := memo[memoKey]
|
||||
if memoFound {
|
||||
return memoized
|
||||
}
|
||||
|
||||
// fmt.Printf("> entering with \n%s\nfor map \n%s\n\n", curString, mask)
|
||||
// time.Sleep(time.Second)
|
||||
if !isVariantMatchesMask(curString, mask) {
|
||||
return 0
|
||||
}
|
||||
|
||||
// log.Printf("> entering with %s\n", curString)
|
||||
if len(blockLengths) == 0 {
|
||||
if len(curString) > targetLength {
|
||||
return 0
|
||||
}
|
||||
variant := curString + strings.Repeat(".", targetLength-len(curString))
|
||||
if !isVariantMatchesMask(variant, mask) {
|
||||
return 0
|
||||
}
|
||||
memo[memoKey] = 1
|
||||
return 1
|
||||
}
|
||||
|
||||
nextBlock := blockLengths[0]
|
||||
restBlocks := blockLengths[1:]
|
||||
|
||||
if len(curString) + blockLengthsSum + len(blockLengths) - 1 > targetLength {
|
||||
return 0
|
||||
}
|
||||
|
||||
isLast := len(restBlocks) == 0
|
||||
rightPointRepeat := 1
|
||||
if isLast {
|
||||
rightPointRepeat = 0
|
||||
}
|
||||
|
||||
whenPass := curString + "."
|
||||
whenAdd := curString + strings.Repeat("#", nextBlock) + strings.Repeat(".", rightPointRepeat)
|
||||
|
||||
passCount := generatePermutations(whenPass, targetLength, blockLengths, blockLengthsSum, mask, memo)
|
||||
addCount := generatePermutations(whenAdd, targetLength, restBlocks, blockLengthsSum-nextBlock, mask, memo)
|
||||
|
||||
memo[memoKey] = passCount + addCount
|
||||
return passCount + addCount
|
||||
}
|
||||
|
||||
func isVariantMatchesMask(variant, mask string) bool {
|
||||
if len(mask) < len(variant) {
|
||||
log.Printf("mask %s is less than variant %s\n", mask, variant)
|
||||
}
|
||||
maskRunes := []rune(mask)
|
||||
for i, symb := range variant {
|
||||
if maskRunes[i] == '?' {
|
||||
continue
|
||||
}
|
||||
if maskRunes[i] != symb {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#.#.### 1,1,3
|
||||
.#...#....###. 1,1,3
|
||||
.#.###.#.###### 1,3,1,6
|
||||
####.#...#... 4,1,1
|
||||
#....######..#####. 1,6,5
|
||||
.###.##....# 3,2,1
|
|
@ -0,0 +1,6 @@
|
|||
???.### 1,1,3
|
||||
.??..??...?##. 1,1,3
|
||||
?#?#?#?#?#?#?#? 1,3,1,6
|
||||
????.#...#... 4,1,1
|
||||
????.######..#####. 1,6,5
|
||||
?###???????? 3,2,1
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,104 @@
|
|||
#+title: Notes
|
||||
* i guess let's generate all possible? and short circuit when they are not matching mask
|
||||
how do i generate all possible?
|
||||
|
||||
i take length of the mask, that's max size
|
||||
then for each step, either put . or put n # from the input.
|
||||
|
||||
add to current string, and do 2 recursive calls, one with diminished 'queue', one with same
|
||||
* wrong answer on input
|
||||
it's too high
|
||||
|
||||
and log shows:
|
||||
|
||||
2023/12/12 15:07:52 for line ???#?.?#?#.?#???#..? blocks [4 4 5 1] matches 2
|
||||
|
||||
and it should be 0
|
||||
** huh, nope this looks good:
|
||||
testMask := "???#?.?#?#.?#???#..?"
|
||||
testBlocks := []int{4,4,5,1}
|
||||
testVariants := generatePermutations("", len(testMask), testBlocks, 14, testMask)
|
||||
fmt.Printf("for mask %s and blocks %+v\n", testMask, testBlocks)
|
||||
fmt.Println(testVariants)
|
||||
|
||||
for mask ???#?.?#?#.?#???#..? and blocks [4 4 5 1]
|
||||
[####..####..#####..# .####.####..#####..#]
|
||||
** let's check this : for line ??????#???????? blocks [7 2] matches 21
|
||||
** or this for line ?????.??#????? blocks [3 3 2 1] matches 3
|
||||
looks ok
|
||||
** this for line ??..??#?????#?##? blocks [1 1 1 1 4] matches 15
|
||||
looks good
|
||||
** for line ?#??#??#???.??.??.? blocks [1 2 3 1 1 1] matches 20
|
||||
seems ok
|
||||
** for line ???????#??.????####? blocks [1 1 1 1 1 6] matches 58
|
||||
bingo?
|
||||
|
||||
for mask ???????#??.????####? and blocks [1 1 1 1 1 6]
|
||||
#.#.#..#.#.######...
|
||||
#.#.#..#.#..######..
|
||||
#.#.#..#.#...######.
|
||||
#.#.#..#.#....######
|
||||
#.#.#..#...#.######.
|
||||
#.#.#..#...#..######
|
||||
#.#.#..#....#.######
|
||||
#.#..#.#.#.######...
|
||||
#.#..#.#.#..######..
|
||||
#.#..#.#.#...######.
|
||||
#.#..#.#.#....######
|
||||
#.#..#.#...#.######.
|
||||
#.#..#.#...#..######
|
||||
#.#..#.#....#.######
|
||||
#.#....#.#.#.######.
|
||||
#.#....#.#.#..######
|
||||
#.#....#.#..#.######
|
||||
#..#.#.#.#.######...
|
||||
#..#.#.#.#..######..
|
||||
#..#.#.#.#...######.
|
||||
#..#.#.#.#....######
|
||||
#..#.#.#...#.######.
|
||||
#..#.#.#...#..######
|
||||
#..#.#.#....#.######
|
||||
#..#...#.#.#.######.
|
||||
#..#...#.#.#..######
|
||||
#..#...#.#..#.######
|
||||
#...#..#.#.#.######.
|
||||
#...#..#.#.#..######
|
||||
#...#..#.#..#.######
|
||||
#....#.#.#.#.######.
|
||||
#....#.#.#.#..######
|
||||
#....#.#.#..#.######
|
||||
.#.#.#.#.#.######...
|
||||
.#.#.#.#.#..######..
|
||||
.#.#.#.#.#...######.
|
||||
.#.#.#.#.#....######
|
||||
.#.#.#.#...#.######.
|
||||
.#.#.#.#...#..######
|
||||
.#.#.#.#....#.######
|
||||
.#.#...#.#.#.######.
|
||||
.#.#...#.#.#..######
|
||||
.#.#...#.#..#.######
|
||||
.#..#..#.#.#.######.
|
||||
.#..#..#.#.#..######
|
||||
.#..#..#.#..#.######
|
||||
.#...#.#.#.#.######.
|
||||
.#...#.#.#.#..######
|
||||
.#...#.#.#..#.######
|
||||
..#.#..#.#.#.######.
|
||||
..#.#..#.#.#..######
|
||||
..#.#..#.#..#.######
|
||||
..#..#.#.#.#.######.
|
||||
..#..#.#.#.#..######
|
||||
..#..#.#.#..#.######
|
||||
...#.#.#.#.#.######.
|
||||
...#.#.#.#.#..######
|
||||
...#.#.#.#..#.######
|
||||
* well, maybe overnight will calculate.
|
||||
but i guess i needed to check whether blocks are 'always' taking full width
|
||||
then i'll only need to calculate once, and then multiply
|
||||
** for example
|
||||
2023/12/12 20:40:41 699 : for line ??#?????#???.? ???#?????#???.????#?????#???.????#?????#???.????#?????#???.? blocks [3 1 2 1 3 1 2 1 3 1 2 1 3 1 2 1 3 1 2 1] matches 38294856
|
||||
|
||||
??#?? ???#?? ?.?
|
||||
3,1,2,1 - 10+3 = 13
|
||||
|
||||
lowest s ###.#.##.#..... - plenty of space for additional
|
|
@ -0,0 +1,226 @@
|
|||
package day13
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Run() int {
|
||||
filename := "day13/input"
|
||||
fmt.Println("hello day 13.", filename)
|
||||
bytes, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error reading file %s", filename))
|
||||
}
|
||||
allText := string(bytes)
|
||||
fieldTexts := strings.Split(allText, "\n\n")
|
||||
|
||||
result := 0
|
||||
for _, fieldText := range fieldTexts {
|
||||
field := ReadField(fieldText)
|
||||
result += Calc(field)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Calc(field Field) int {
|
||||
verticals, horizontals := field.initMirrors()
|
||||
fmt.Println(field.String())
|
||||
fmt.Printf("field width %d and height %d\n", len(field.Symbols[0]), len(field.Symbols))
|
||||
|
||||
for rowNum, row := range field.Symbols {
|
||||
for colNum, symb := range row {
|
||||
for _, horizontalMirrorUnderCheck := range horizontals {
|
||||
// if horizontalMirrorUnderCheck.Smaller != 4 {
|
||||
// continue
|
||||
// }
|
||||
mirroredRow, shouldCheck := horizontalMirrorUnderCheck.reflectCoord(rowNum)
|
||||
// log.Println("for mirror", horizontalMirrorUnderCheck.String())
|
||||
// log.Printf("> checking row %d and mirrored %d; should %t\n", rowNum, mirroredRow, shouldCheck)
|
||||
if shouldCheck {
|
||||
// log.Printf("checking horizontal mirror %+v", horizontalMirrorUnderCheck)
|
||||
// log.Printf("in should check for row %d, col %d, mirrored row %d\n", rowNum, colNum, mirroredRow)
|
||||
mirroredSymb := field.Symbols[mirroredRow][colNum]
|
||||
isMirrored := symb == mirroredSymb
|
||||
if !isMirrored {
|
||||
// log.Printf("found not mirrored : %s != %s\n", string(symb), string(mirroredSymb))
|
||||
horizontalMirrorUnderCheck.FailedLineChecks[rowNum] += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// whole row got checked.
|
||||
// let's mark successful line check for all that didn't fail this line check
|
||||
for _, horizontalMirror := range horizontals {
|
||||
_, failedCheckReported := horizontalMirror.FailedLineChecks[rowNum]
|
||||
if !failedCheckReported {
|
||||
horizontalMirror.SuccessfulLineChecks[rowNum] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rowsAboveHorizontals := 0
|
||||
for _, mirr := range horizontals {
|
||||
fmt.Println("horizontal: ", mirr.String())
|
||||
if mirr.isFullMirror() {
|
||||
log.Printf(">> found perfect Horizontal %+v\n", mirr)
|
||||
rowsAboveHorizontals += (mirr.Smaller + 1)
|
||||
}
|
||||
}
|
||||
|
||||
for colNum, _ := range field.Symbols[0] {
|
||||
for rowNum, row := range field.Symbols {
|
||||
symb := row[colNum]
|
||||
for _, verticalMirrorUnderCheck := range verticals {
|
||||
// if verticalMirrorUnderCheck.Smaller != 8 {
|
||||
// continue
|
||||
// }
|
||||
mirroredCol, shouldCheck := verticalMirrorUnderCheck.reflectCoord(colNum)
|
||||
if shouldCheck {
|
||||
// log.Printf("checking vertical mirror %+v", verticalMirrorUnderCheck)
|
||||
// log.Printf("in should check for row %d, col %d, mirrored col %d\n", rowNum, colNum, mirroredCol)
|
||||
mirroredSymb := field.Symbols[rowNum][mirroredCol]
|
||||
isMirrored := symb == mirroredSymb
|
||||
if !isMirrored {
|
||||
// log.Printf("found not mirrored : %s != %s\n", string(symb), string(mirroredSymb))
|
||||
verticalMirrorUnderCheck.FailedLineChecks[colNum] += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// whole row got checked.
|
||||
// let's mark successful line check for all that didn't fail this line check
|
||||
for _, verticalMirror := range verticals {
|
||||
_, failedCheckReported := verticalMirror.FailedLineChecks[colNum]
|
||||
if !failedCheckReported {
|
||||
verticalMirror.SuccessfulLineChecks[colNum] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
colsToLeftOfHorizontals := 0
|
||||
for _, mirr := range verticals {
|
||||
fmt.Println("vertical: ", mirr.String())
|
||||
if mirr.isFullMirror() {
|
||||
log.Printf(">> found perfect Vertical %+v\n", mirr)
|
||||
colsToLeftOfHorizontals += (mirr.Smaller + 1)
|
||||
}
|
||||
}
|
||||
|
||||
result := colsToLeftOfHorizontals + 100*rowsAboveHorizontals
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
Symbols [][]rune
|
||||
}
|
||||
|
||||
func ReadField(fieldText string) Field {
|
||||
fieldText = strings.TrimSpace(fieldText)
|
||||
lines := strings.Split(fieldText, "\n")
|
||||
|
||||
symbols := make([][]rune, len(lines))
|
||||
for i, line := range lines {
|
||||
symbols[i] = []rune(line)
|
||||
}
|
||||
|
||||
return Field{
|
||||
Symbols: symbols,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Field) String() string {
|
||||
text := "\n"
|
||||
for _, row := range f.Symbols {
|
||||
text += string(row)
|
||||
text += "\n"
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
func (f *Field) initMirrors() (vertical []Mirror, horizontal []Mirror) {
|
||||
height := len(f.Symbols)
|
||||
width := len(f.Symbols[0])
|
||||
amountHorizontal := height - 1
|
||||
amountVertical := width - 1
|
||||
horizontal = make([]Mirror, amountHorizontal)
|
||||
vertical = make([]Mirror, amountVertical)
|
||||
|
||||
for rowNum := 0; rowNum < amountHorizontal; rowNum++ {
|
||||
maxDist := min(rowNum, height - 1 - (rowNum+1))
|
||||
// log.Println("maxDist ", maxDist, "for rowNum ", rowNum)
|
||||
horizontal[rowNum] = Mirror{
|
||||
Smaller: rowNum,
|
||||
Bigger: rowNum + 1,
|
||||
SuccessfulLineChecks: make(map[int]any),
|
||||
FailedLineChecks: make(map[int]int),
|
||||
MaxDistToCheck: maxDist,
|
||||
}
|
||||
}
|
||||
|
||||
for colNum := 0; colNum < amountVertical; colNum++ {
|
||||
maxDist := min(colNum, width - 1 - (colNum+1))
|
||||
vertical[colNum] = Mirror{
|
||||
Smaller: colNum,
|
||||
Bigger: colNum + 1,
|
||||
SuccessfulLineChecks: make(map[int]any),
|
||||
FailedLineChecks: make(map[int]int),
|
||||
MaxDistToCheck: min(colNum, maxDist),
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Mirror struct {
|
||||
// located between lines
|
||||
Smaller, Bigger int
|
||||
MaxDistToCheck int // how many steps from mirrow have to be checked to confirm
|
||||
// i.e if mirror between 0 and 1 - only rows 0 & 1 have to be checked, row 2 is 'mirrored' outside of the field and 'ok'
|
||||
// value 0 means one step from 'mirror' so rows 0 and 1
|
||||
SuccessfulLineChecks map[int]any
|
||||
FailedLineChecks map[int]int // from line num, to amount of errors in that line
|
||||
}
|
||||
|
||||
func (m *Mirror)isFullMirror() bool {
|
||||
correctFailedLinesCount := len(m.FailedLineChecks) == 2
|
||||
if correctFailedLinesCount {
|
||||
for failedLine, failedSymbols := range m.FailedLineChecks {
|
||||
reflectedLine, _ := m.reflectCoord(failedLine)
|
||||
doublyReflected, _ := m.reflectCoord(reflectedLine)
|
||||
// log.Printf(">>>> checking failed line %d, reflected is %d; doubly %d. amount failed is %d\n", failedLine, reflectedLine, doublyReflected, failedSymbols)
|
||||
if failedSymbols == 1 && (doublyReflected == failedLine) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Mirror)String() string {
|
||||
return fmt.Sprintf("Mirror (full %t) between %d and %d. successful lines: %+v ; failed lines: %+v. Max check dist: %d\n",
|
||||
m.isFullMirror(), m.Smaller, m.Bigger, m.SuccessfulLineChecks, m.FailedLineChecks, m.MaxDistToCheck)
|
||||
}
|
||||
|
||||
func (m *Mirror) reflectCoord(coord int) (reflected int, shouldCheck bool) {
|
||||
dist := m.Smaller - coord
|
||||
|
||||
// _, distConfirmed := m.SuccessfulLineChecks[dist]
|
||||
// if distConfirmed {
|
||||
// // log.Printf("> getting dist confirmed for coord %d ; dist %d\n", coord, dist)
|
||||
// return 0, false // either line already fully confirmed, or failed. no need for additional checks
|
||||
// }
|
||||
|
||||
reflected = m.Bigger + dist
|
||||
if dist < 0 {
|
||||
dist = coord - m.Bigger
|
||||
reflected = m.Smaller - dist
|
||||
}
|
||||
|
||||
shouldCheck = dist <= m.MaxDistToCheck
|
||||
|
||||
return reflected, shouldCheck
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#.##..##.
|
||||
..#.##.#.
|
||||
##......#
|
||||
##......#
|
||||
..#.##.#.
|
||||
..##..##.
|
||||
#.#.##.#.
|
||||
|
||||
#...##..#
|
||||
#....#..#
|
||||
..##..###
|
||||
#####.##.
|
||||
#####.##.
|
||||
..##..###
|
||||
#....#..#
|
|
@ -0,0 +1,7 @@
|
|||
#.##..##.
|
||||
..#.##.#.
|
||||
##......#
|
||||
##......#
|
||||
..#.##.#.
|
||||
..##..##.
|
||||
#.#.##.#.
|
|
@ -0,0 +1,7 @@
|
|||
#...##..#
|
||||
#....#..#
|
||||
..##..###
|
||||
#####.##.
|
||||
#####.##.
|
||||
..##..###
|
||||
#....#..#
|
File diff suppressed because it is too large
Load Diff
6
main.go
6
main.go
|
@ -3,12 +3,12 @@ package main
|
|||
import (
|
||||
"log"
|
||||
|
||||
"sunshine.industries/aoc2023/day10"
|
||||
"sunshine.industries/aoc2023/day13"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.Print("> starting run:")
|
||||
|
||||
result := day10.Run()
|
||||
log.Printf("day10 result: %d\n****\n", result)
|
||||
result := day13.Run()
|
||||
log.Printf("day13 result: %d\n****\n", result)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue