diff --git a/docs/day16.md b/docs/day16.md new file mode 100644 index 0000000..9a34fb3 --- /dev/null +++ b/docs/day16.md @@ -0,0 +1,96 @@ + +## Day 16: Reindeer Maze + +It's time again for the Reindeer Olympics! This year, the big event is the Reindeer Maze, where the Reindeer compete for the lowest score. + +You and The Historians arrive to search for the Chief right as the event is about to start. It wouldn't hurt to watch a little, right? + +The Reindeer start on the Start Tile (marked `S`) facing East and need to reach the End Tile (marked `E`). They can move forward one tile at a time (increasing their score by `1` point), but never into a wall (`#`). They can also rotate clockwise or counterclockwise 90 degrees at a time (increasing their score by `1000` points). + +To figure out the best place to sit, you start by grabbing a map (your puzzle input) from a nearby kiosk. For example: + +```txt +############### +#.......#....E# +#.#.###.#.###.# +#.....#.#...#.# +#.###.#####.#.# +#.#.#.......#.# +#.#.#####.###.# +#...........#.# +###.#.#####.#.# +#...#.....#.#.# +#.#.#.###.#.#.# +#.....#...#.#.# +#.###.#.#.#.#.# +#S..#.....#...# +############### +``` + +There are many paths through this maze, but taking any of the best paths would incur a score of only `7036`. This can be achieved by taking a total of `36` steps forward and turning 90 degrees a total of `7` times: + +```txt +############### +#.......#....E# +#.#.###.#.###^# +#.....#.#...#^# +#.###.#####.#^# +#.#.#.......#^# +#.#.#####.###^# +#..>>>>>>>>v#^# +###^#.#####v#^# +#>>^#.....#v#^# +#^#.#.###.#v#^# +#^....#...#v#^# +#^###.#.#.#v#^# +#S..#.....#>>^# +############### +``` + +Here's a second example: + +```txt +################# +#...#...#...#..E# +#.#.#.#.#.#.#.#.# +#.#.#.#...#...#.# +#.#.#.#.###.#.#.# +#...#.#.#.....#.# +#.#.#.#.#.#####.# +#.#...#.#.#.....# +#.#.#####.#.###.# +#.#.#.......#...# +#.#.###.#####.### +#.#.#...#.....#.# +#.#.#.#####.###.# +#.#.#.........#.# +#.#.#.#########.# +#S#.............# +################# +``` + +In this maze, the best paths cost `11048` points; following one such path would look like this: + +```txt +################# +#...#...#...#..E# +#.#.#.#.#.#.#.#^# +#.#.#.#...#...#^# +#.#.#.#.###.#.#^# +#>>v#.#.#.....#^# +#^#v#.#.#.#####^# +#^#v..#.#.#>>>>^# +#^#v#####.#^###.# +#^#v#..>>>>^#...# +#^#v###^#####.### +#^#v#>>^#.....#.# +#^#v#^#####.###.# +#^#v#^........#.# +#^#v#^#########.# +#S#>>^..........# +################# +``` + +Note that the path shown above includes one 90 degree turn as the very first move, rotating the Reindeer from facing East to facing North. + +Analyze your map carefully. What is the lowest score a Reindeer could possibly get? \ No newline at end of file diff --git a/src/day16/day16.go b/src/day16/day16.go new file mode 100644 index 0000000..ea462c3 --- /dev/null +++ b/src/day16/day16.go @@ -0,0 +1,130 @@ +package day16 + +import ( + "slices" + "strings" +) + +const EMPTY = '.' +const END = 'E' +const START = 'S' + +type direction uint8 + +const ( + EAST direction = iota + SOUTH + WEST + NORTH +) + +type point struct { + x, y int +} + +func (p point) valid(w, h int) bool { + return p.x >= 0 && p.y >= 0 && p.x < w && p.y < h +} + +type maze struct { + emptySpaces map[point]bool + start point + end point + width int + height int +} + +type thread struct { + p point + dir direction + moves uint + turns uint +} + +func (t thread) cost() uint { + return t.moves + 1000*t.turns +} + +func Solve(input string) uint { + m := parseInput(input) + return solve(m) +} + +func parseInput(input string) maze { + var result maze + result.emptySpaces = make(map[point]bool) + + result.height = len(input) + for j, line := range strings.Split(input, "\n") { + result.width = len(line) + for i, r := range line { + if r == EMPTY || r == START || r == END { + result.emptySpaces[point{x: i, y: j}] = true + if r == START { + result.start = point{x: i, y: j} + } else if r == END { + result.end = point{x: i, y: j} + } + } + } + } + return result +} + +func solve(m maze) uint { + seenSpaces := make(map[point]uint) + seenSpaces[m.start] = 1 + threads := []thread{{p: m.start, dir: EAST}} + var solution uint = 0 + + for { + nextThreads := make([]thread, 0) + for _, t := range threads { + if t.p == m.end { + if solution == 0 || t.cost() < solution { + solution = t.cost() + } + } else { + nextThreads = append(nextThreads, calcNextMoves(m, t, seenSpaces)...) + } + } + + if len(nextThreads) == 0 { + if solution == 0 { + panic("No solution with no more spaces to check") + } + return solution + } + for i, t := range nextThreads { + if solution > 0 && t.cost() >= solution { + nextThreads = slices.Delete(nextThreads, i, i) + } + if seenSpaces[t.p] == 0 || t.cost() < seenSpaces[t.p] { + seenSpaces[t.p] = t.cost() + } + } + threads = nextThreads + } +} + +func calcNextMoves(m maze, curr thread, seenSpaces map[point]uint) []thread { + nextMoves := make([]thread, 0) + possibilities := []thread{{p: point{x: curr.p.x + 1, y: curr.p.y}, dir: EAST, moves: curr.moves, turns: curr.turns}, + {p: point{x: curr.p.x, y: curr.p.y + 1}, dir: SOUTH, moves: curr.moves, turns: curr.turns}, + {p: point{x: curr.p.x - 1, y: curr.p.y}, dir: WEST, moves: curr.moves, turns: curr.turns}, + {p: point{x: curr.p.x, y: curr.p.y - 1}, dir: NORTH, moves: curr.moves, turns: curr.turns}} + for i, t := range possibilities { + if t.p.valid(m.width, m.height) && m.emptySpaces[t.p] { + t.moves++ + if i%2 != int(curr.dir)%2 { + t.turns++ + } else if int(curr.dir) != i { + t.turns += 2 + } + if seenSpaces[t.p] == 0 || t.cost() < seenSpaces[t.p] { + nextMoves = append(nextMoves, t) + } + } + } + return nextMoves +} diff --git a/src/day16/day16_test.go b/src/day16/day16_test.go new file mode 100644 index 0000000..96295d3 --- /dev/null +++ b/src/day16/day16_test.go @@ -0,0 +1,199 @@ +package day16 + +import ( + "testing" +) + +func TestSampleOne(t *testing.T) { + input := `############### +#.......#....E# +#.#.###.#.###.# +#.....#.#...#.# +#.###.#####.#.# +#.#.#.......#.# +#.#.#####.###.# +#...........#.# +###.#.#####.#.# +#...#.....#.#.# +#.#.#.###.#.#.# +#.....#...#.#.# +#.###.#.#.#.#.# +#S..#.....#...# +###############` + result := Solve(input) + if result != 7036 { + t.Errorf("Calculated solution was not expected") + } +} + +func TestSampleTwo(t *testing.T) { + input := `################# +#...#...#...#..E# +#.#.#.#.#.#.#.#.# +#.#.#.#...#...#.# +#.#.#.#.###.#.#.# +#...#.#.#.....#.# +#.#.#.#.#.#####.# +#.#...#.#.#.....# +#.#.#####.#.###.# +#.#.#.......#...# +#.#.###.#####.### +#.#.#...#.....#.# +#.#.#.#####.###.# +#.#.#.........#.# +#.#.#.#########.# +#S#.............# +#################` + result := Solve(input) + if result != 11048 { + t.Errorf("Calculated solution was not expected") + } +} + +func TestPart1(t *testing.T) { + input := `############################################################################################################################################# +#.....#.......#.............#.........#.......................#.......#...#...............#.....#.#.................................#.#....E# +#.#####.###.###.#######.###.#.#.#######.#.###.#####.###.#######.#.###.###.#.#####.#####.###.#.#.#.#.#####.###.#.###.#######.###.#.#.#.#.#.#.# +#.......#...#...#.....#.#.#.#.#.#...#...#.....#...#.#...#.......#...#.#...#...#...#.#...#...............#...#...#.#.......#.#...#.#.#...#.#.# +#########.#.#.###.#####.#.#.#.#.#.#.#.#########.#.#.###.#.#########.#.#.#.#.###.#.#.#.###.###.#####.###.###.#.#.#.###.###.#.#.###.#.#.###.#.# +#.......#.#.#.#...#...#.#.#.#.#...#.....#.......#.#...#.#.#...#...#.#...#.#.#...#.....#...#.#...#...#.....#.#.....#.....#.#...#...#.#.#...#.# +#.#####.#.###.#.#.#.#.#.#.#.###########.#######.#.###.#.#.###.#.#.#.#.#####.#.###.###.#.###.###.#.###.#.###.#.#.#.#.#.#.#.#.#.#.###.###.##### +#...#...#.......#.#.#...#.#...........................#.#.#...#.#...#.#.....#.#.....#.#...#...#.....................#.#.#...................# +#.#.#.#######.#####.#####.###########.#######.#####.#.###.#.###.#######.#####.###.#.#.###.#.#.#.#.#######.###.#.#####.#.#.#.#.###.###.#.###.# +#.#...#.....#.#...#...#.......#.......#.....#...#...#.....#.#...#.....#...#...#.....#...#...#.#...#.......#...#.#...#.#.#.#.#...#.#...#...#.# +#.#.###.###.###.#.#.#.###.###.#.#.#####.###.###.#.#########.#.###.###.###.#.###.#.###.#######.#####.#######.#.#.#.#.#.###.###.#.#.#.#######.# +#.#.....#.......#.#.#...#.#...#.#...#...#.#.#.#.#.......#...#...#...#.......................#...#.#.#.....#.#.....#.#.........#...#.#.....#.# +#.###.###########.#####.#.#####.#.#.#.#.#.#.#.#.###.###.#.#.###.###.#########.###.#.#.#.###.#.#.#.#.#####.#.#.#.#####.#######.#####.#.###.#.# +#...#...................#.....#.#.#.#.#.#.....#.....#.#...#.#.#...#.....#...#.....#.#.#.#.#.....#.#.....#.#...#.#.........#...........#.....# +#.#.#.#.###.#.###############.#.#.#.#.#.#############.#####.#.###.#####.#.#.#####.#.#.#.#.#######.#####.#.###.#.#.###.###.#.#.###.########### +#.#.#.#.#.#.#.#.....#.......#.#...#...#...............#...#...#.#...#...#.#.......#.#.#.#.......#...#...#.....#.#.#.......#.#...#.#.........# +#.#.###.#.#.###.###.###.#.#.#.###.#.#####.###.###.###.#.#.###.#.#.###.###.###.###.#.#.#.###.###.###.#.###.#####.#.#.#.###.#.#.#.###.#######.# +#.#.....#.#...#.#.#...#.#.#.#...#.#.#...#...#...#...#...#...#...#.....#...#...#.......#.....#.#.....#...#.......#...#.#...#...#...#.#.#.....# +#.#######.###.#.#.###.#.#.#.#.#.#.###.#.#####.#.#.#.#########.#.#######.#.#.#.#.#############.#####.###.#########.#####.###.#####.#.#.#.#.### +#.#.......#.#.....#...#.#.#...#.#.#...#.....#.#.#.#.........#.#.........#.#.#.#.#.................#.#.#...#.......#.........#...#...#.#.....# +#.#.#####.#.#######.#####.#######.#.#####.#.###.#.#########.#.#.#########.#.#.#.###.#######.#.#####.#.###.#.#######.#.###.###.#.#####.###.#.# +#.#.....#.......#...#...#...#.....#.#...........#.#.......#...#.#...#.....#.#.#...#.#.......#.#...#...#...#.....#...#...#.#.................# +#.#####.#######.#.###.#.###.#.#####.#######.#####.#.#.###.#####.#.#.###.###.#.###.###.#####.###.#.###.#.#######.#.#####.#.#####.#.#.###.#.#.# +#.#...#.#.....#...#...#...#.#.......#.....#.#.....#.#...#.#...#.#.#...#.#...#.#.#...#.#...#.#...#...#.#.........#.....#.#.......#...#...#.#.# +#.#.#.#.#.###.#.###.#####.#.#.#####.#.###.###.#########.###.#.#.#.###.#.#.###.#.###.#.#.#.###.###.###.###############.#.###########.#.###.#.# +#.#.#.#.#.#.....#...#...#...#.....#...#.#...#.#...#...#.#...#.#...#...#.#.#.#.#.........#.#...#.#.....#.......#.......#.........#...#.#.....# +#.#.#.#.#.#######.###.#.#.#.#####.###.#.###.#.#.#.#.#.#.#.###.#####.#####.#.#.#########.#.#.###.#######.#######.###############.#.###.#.#.### +#.#.#...#.........#...#.#.#.....#...#...#.#.....#...#...#.#.#...#...#.....#.#.....#.....#...#.....#.....#.....#...#...#...#.....#...#.#.#...# +#.#.#########.#######.#.#.#.###.###.###.#.###########.###.#.###.#.###.#.###.#####.#.#########.#.#.###.#.#.###.#.#.#.#.#.#.#.#######.#.#.#.#.# +#...#...#...#.......#.#.#.#.#.....#.......#...#.....#.#...#...#.#...#...#.......#...#.....#...#.#.....#.#...#...#...#...#...#...............# +###.#.#.#.#.#######.#.#.#.#.#.#######.#####.#.#.###.###.###.###.#.#.###.#.#.#.#.#####.#.###.###.###.#######.#####.###########.#.###.#.####### +#...#.#...#...#...#...#.#.#.#.......#.....#.#.....#.....#...#...#.#...#...#.#...#.....#...#...#.#.........#.....#.........#...#.....#...#...# +#.#.#.#######.###.#####.#.#.#######.#####.#.#####.#######.#.#.#######.#.###.#.###.#.###.#.###.#.#.#######.#####.#.#######.#.#####.#####.#.#.# +#.#...#.....#...#.....#...#...#...#.....#...#...#.#...#...#...........#.....#.#...#...#.#.....#...#.#...#.#...#...#.....#.#.#.....#...#...#.# +#.#.###.###.###.#.###.#.#.###.#.###.#########.#.#.#.#.#.#####.#.#########.#.#.###.###.###########.#.#.#.#.#.#.###.###.#.#.#.#.###.#.#.#####.# +#.#.#...#.#...#.....#...#.#.#...#...#.........#.#...#.#...#...#.....#...#...#...#...#...........#...#.#.#...#...#...#.#...#.......#.#.......# +#.#.#.###.###.#####.#.###.#.###.#.###.#####.###.###.#.###.#.#.###.#.#.#.#######.#.#.###########.#####.#.#####.#.###.#.###########.#.######### +#.#.#.#.....#.#...#.#...#.#.#...#.....#...#.#...#.....#...#.#.....#...#...#...#.#.#.....#...#...#.....#.........#...#.......#.....#.........# +#.#.#.#####.#.###.#.#####.#.#.#########.###.#.#.#.###.#.###.###########.#.#.###.#.#####.#.#.#.###.#########.#####.#########.#####.#########.# +#.#.#.#.....#...#.#.....#.............#...#.#...#.#...#...#.......#.#...#.#.#...#.....#.#...#.#...#.........#.....#.............#...#.......# +###.#.#.#######.#.#####.#.#.#####.###.###.#.#.###.#.#####.#######.#.#.###.#.#.#########.###.#.#.###.#####.#.#.#####.#.#########.#.###.#.###.# +#...#.#.......#...#.....#.#.#.......#.....#.#.....#.#.......#.......#.#.#...#.........#...#.#.#.....#.....#.#...#...#.........#.#.#...#...#.# +#.#.#.#.#####.###.#.#####.###.###.#.###.###.#######.#.#####.#.#####.#.#.###.#########.###.#.#.#.#####.#####.###.#####.#######.#.#.#.###.#.#.# +#.#...#.....#...#.#.#.........#...#.#...#...#.....#.#.#.....#...#...#.#.....#.......#.....#.#.#.....#...#...#.#.....#.#.#.........#.#.....#.# +#.#.#.###.#####.#.#.###.#######.###.#.###.#.#.###.###.###.#####.#.###.#.#####.###.#.#######.#.#####.#.#.#.###.#####.#.#.#.#####.#.#.#.#.#.#.# +#.#.#.#...#...#...#...........#.#.....#...#.#...#.....#...#.....#...#.#.....#.#.#.#.#.......#.......#.#.#...#...#...#...#...#...#...#...#.#.# +#.###.###.#.#.#.#.###.#######.#.#######.###.###.#######.###.#######.#.#####.#.#.#.###.###.#############.###.#.#.#.#####.###.#.###.###.#.###.# +#...#...#.#.#...#.....#...#.....#.......#.....#...#.....#...#.....#.#...#...#...#.......#...#...........#.#...#.#.....#...#.#...#.#...#.....# +#.#.#.#.###.###.#.#####.#.#######.###############.###.#.#.###.#.#.#.###.#.#####.###.###.###.#.#######.#.#.#####.#####.#.###.###.#.#####.###.# +#.#.#.#.....#...#.#.....#...#...#.#.............#.....#.#...#.#.#.....#.#.#...#...#.......#...#.......#.....#...#...#...#...#...#...........# +###.#########.#.#.#.#######.#.#.#.#.#########.#########.###.###.###.###.###.#.###.###.#.#######.###########.#.###.#.#####.###.###.#.#.#.#.### +#...#.....#...#.#.........#...#.#...#...#.#...#...........#...#.......#.....#...#...#.#...#.......#.....#...#...#.#.....#.#.#.#.....#...#...# +#.###.###.#.#####.#######.#####.#.###.#.#.#.###.#############.#####.#.#########.###.#####.#.#.###.#####.#.#####.#.#######.#.#.#########.###.# +#.#...#.....#.....#...#...#...#.#.#...#...#.....#.............#...#.#...#.....#...#...#...#.....#.....#.......#.#.#.......#.#.#...........#.# +#.#.#######.#.#####.#.#.###.#.#.#.#.#.###########.#############.#.###.#.#.###.###.###.#.#.#.###.#####.#########.#.#.#######.#.#.#######.#.#.# +#.........#.#...#.#.#.#.#.#.#...#...#.............#.....#.......#.#...#.#.#.#...#.....#.#.#...#.......#.......#...#.#.......#.#.......#.#...# +#.#######.#.###.#.#.#.#.#.#.###.#####.#############.#.###.#.#####.#.###.#.#.###.#######.#####.#######.#.###.#.#.###.#.#####.#.#.#####.#.#.### +#...#.....#.#...#.#.#...#.#...#.#...#.#.......#.....#.....#...#...#.#...#.#...#.#...............#.....#...#.#...#...#.....#.#.#...#...#.....# +#.#.#.#######.###.#.#####.###.###.#.#.#.#.#.#.#.#############.#.###.#.###.###.#.#.#####.#.#.#.#.###.#####.#.#####.###.###.###.###.#.###.#.### +#.#.#.......#...#.#.#.......#.#...#...#...#.#.#...#.....#.....#.#...#...#...#.....#.#...#.#.#.#.......#...#.#.....#.#.#...#...#...#.#.......# +###.#.#####.###.#.#.#.#.#####.#.#########.#.#.###.#.#.###.#####.#.#####.###.#.#####.#.###.#.#####.#.#.#.###.#.#####.#.#.#.#.#######.#.#.#.#.# +#...#.....#...#...#.#.#...#...#.#.......#.#.#...#.....#...#...#.#...#.#.....#.#...#.....#.#.#.....#...#.....#...#...#.#.#.#.#.......#...#.#.# +#.#.#########.###.#.#.###.#.#.#.#.###.###.#.###.#####.#.#####.#.#.#.#.###.#####.#.#######.#.#.#####.#######.###.###.#.#.#.#.#.#########.#.#.# +#.#.........#...#.#.#...#.#.....#...#.....#...#.....#.#.#.....#.#.#.#.....#.....#...#.....#...#...#.#.......#.......#.#.....#.....#.......#.# +#.#.#######.###.#.#.#####.#######.#.#########.#####.###.###.###.#.#.###.###.#######.#.#.#######.#.#.#.#.#.###.###.###.#######.###.###.#.#.#.# +#.#...#...#...#...#.......#.......#.....#.........#...#...#...#.#.#...#.#.#...#...#...#.......#.#.#...#.#.#.#.#.....#.#.......#.............# +#.###.#.#.###.###########.#.###########.#.#.#####.###.#.#.#.#.#.#.###.#.#.###.#.#.#.###.#.###.###.#.###.#.#.#.#####.#.###.#####.###.#.#.##### +#...#...#.#.#.#...#.....#.#...#...........#.......#...#.#.#.#...#...#.#...#...#.#...#.....#.....#.......#...#...........#.#.......#.#...#...# +#.#.#####.#.#.#.#.#.###.#.###.#####.#######.#.#####.###.#.###.#####.#.#####.#########.#####.###.#######.###.###.#.#.###.#.#.#####.#.#.###.#.# +#.#.#.......#.#.#...#...#...#...#...#.....#.#.......#...#...#...#...#.#...#...#...#...#.......#...#.....#...#...#.#...#.#...#...#.#.#.....#.# +#.#.#.#######.#.#####.#####.###.#.#.#.###.#.#############.#.###.#.###.#.#.#.#.#.#.#.#####.###.###.#######.###.###.#####.#####.#.#.#.#.#####.# +#.#.#.#.#.....#.#...#.....#...#.#...#...#.#...#...........#.#...#...#.#.#.#.#...#...#...#.#.#...#...........#...#...#...#.....#.#.#.#.#...#.# +#.#.#.#.#.#####.#.#.#####.###.#.#.#.###.#.###.#.#.#####.###.#.#######.###.#.#####.#.#.#.#.#.###.###########.###.###.#.###.#####.#.#.#.###.#.# +#.#.....#...#...#.#...#...#...#.#.#...#.#.....#...#...#.#...#.........#...#.#.#...#...#.#.#.......#.......#...#...#.#.#.#.#...#...#.#.....#.# +###########.#.###.#.###.#.#.###.#.###.#.#######.#.###.#.#.###.#########.#.#.#.#.#######.#.#.#.#####.#####.###.###.#.#.#.#.#.#.#####.#######.# +#.........#.......#.#...#.#.....#...#.#...#...#.#.#...#.#.#...#.......#.#...#.#.#.........#.....#...#.....#.....#.#...#...#.#.#.....#.......# +#.#######.###########.#.#.#######.###.###.#.#.###.#.###.#.###.#.#####.#.###.#.#.#.#########.#.###.###.#########.#.###.#####.#.#.#####.#.##### +#.................#...#.#...#.....#...#...#.#.....#.#...#...#.#.#.....#...#...#...#...#.#.....#...#...#.......#.#...#.......#...#.#...#.#...# +#.#.#.#.###.###.#.#.###.#.###.#####.#.#.###.#######.#.#####.###.#.###.###.###.#####.#.#.#.#####.###.#.#.#.###.###.#.#############.#.#.###.#.# +#...#.#...#...#.#...#...............#.#.#.....#.....#.....#.#...#...#.#.#.#...#...#.#.#...#.....#.....#.#.#.#...#.#.#.....#.......#.#.....#.# +#.###.###.###.#.#.#.###.###.#####.#.#.#.###.#.#.#.#.#####.#.#.#####.#.#.#.#####.#.#.#.#####.#####.#######.#.###.###.#.#####.###.#.#.###.#.#.# +#...#.#.#.#...#...#...#...#.#.....#.#.#...#.#.#.#.#.....#.#...#...#.#...#.......#...#...#...#...#.#.......#...#...#.#.#...#...#.#.#.#...#.#.# +###.#.#.#.#.#.#####.#.#.###.#.###.#.#####.###.###.#######.#.###.#.#.###############.###.#.###.###.#####.###.#####.#.#.#.#.#.#.#.###.#.#.#.#.# +#...#.#.#...#.....#.#.#.#...#.#...#.....#.....#...#.......#.#...#...#.........#.......#...#.......#.....#.........#.#...#...#.#.....#.#...#.# +#.###.#.###.###.#.#.#.###.###.#######.#########.#.#.#######.#.#######.#######.#.###.#######.#######.#####.#########.#.#####.#.#######.#.###.# +#.#...#.....#...#...#.#...#.#.......#...........#.#.#.......#.#.......#...#...#...#.....#.#...#.#.....#...#.........#.......#.#.......#.#...# +###.#.#######.#######.#.###.#.#####.#.###.#.#####.#.#######.#.#.#####.###.#.#####.###.#.#.###.#.#.###.#.#######.#.###.#.###.#.#.#######.#.### +#...#.#.....#...#...#...#...#.#.#.....#.#.#.#...#.#...#...#.#.#.#.......#.#.....#...#.#.....#.#...#...#.......#.#.#...#.#...#...#.....#.#...# +#.#.###.###.###.#.#.#####.#.#.#.#.###.#.#.###.#.#####.#.#.#.#.#.#.#####.#.#####.###.#.#.#####.#.###.#########.###.#.###.#########.#####.###.# +#.#.#...#.....#.#.#.#...#.#.#...#.#.....#.....#.....#...#.#.#.#...#.#...#...#...#...#.#.#.....#.#...#...#.......#.#...#...........#.....#...# +#.###.###.###.#.#.#.#.#.###.###.#.#########.#####.#####.#.#.#.#####.#.#####.#.#.#.###.###.#######.###.###.#.###.#.#########.#######.#####.### +#.......#...#.#...#...#.#.....#.#.........#.....#.......#.#.#.......#.#.....#.#.#...#...#.#.......#...#...#...#.#.#...#.....#...........#...# +#.#####.###.###########.#.#####.#####.#.#.#.#.#.###.#####.###.#.###.#.#.#####.#####.###.#.#.#.#####.#.#.#.#.###.#.#.#.#.#####.#########.#.#.# +#.#...#...#.......#.....#...#.......#...#...#.#...#.#.........#.......#.....#.......#.#.....#.#.....#.....#.#...#.....#.#.......#.....#.#...# +###.#.###.#.###.###.#######.#.#############.#.#####.#.###############.#.###.#########.#.###.#.#############.#.#######.#.#.###.###.###.###.#.# +#...#...#.#.#...#...#.....#.#.#...........#.#.....#...#.#...#.......#.#...#.............#...#.......#.....#.#.........#.#...#.....#.....#.#.# +#.#####.#.#.#.###.###.###.#.#.#.#########.###.###.#####.#.#.#.#####.#.###.#######.#######.#########.#.###.#.###########.###.#.#.#######.#.#.# +#.....#.#.#.#...#.#.#...#.#...#.....#...#...#.#.........#.#...#...#.#.#.#.....................#.....#...#...#.....#.........#.#.#...#.....#.# +#.###.#.#.#.###.#.#.#.#.#.#########.#.#.###.###.#####.###.#####.#.#.#.#.#.#####.#############.#.###.#.#.###.#.#####.#########.###.#.#####.#.# +#.#...#.#...#...#.#...#.#...........#.#.........#.....#...#.....#.#.#.#.......#.#.......#...#...#.....#...#.#.#.........#...#.#...#...#...#.# +#.#.###.###.#.###.#.###.#############.###########.#.###.#####.###.#.#.#####.#.#.#.###.###.#.#.###.#####.#.#.#.#.#######.#.#.#.#.#####.###.#.# +#.#...#.......#...#...#.#.......#.....#.....#.....#.....#.....#...#...#...#.#.#.#.#...#...#.#.#...#...#.#...#...#...#...#.#.#.#.....#...#...# +#.###.#####.#.#.#######.#######.#.#####.###.#.#############.###.#######.#.###.#.#.###.#.###.#.#.###.#.#.#.#######.#.#.#####.#.#.#######.#.### +#...#...#...#.#.#.......#.......#...#.....#.#...#.........#.#...#.......#...#.....#.....#.#...#.#...#...#.......#.#.#.......#...#.......#...# +#######.###.#.#.###.#####.#####.###.#####.#####.#####.###.#.###.###.#.#####.#######.#####.#######.#############.#.#.#####.#.#####.#######.#.# +#.......#...#.#...#...........#.#...#.....#.....#...#.#...#...#...#.#...#...........#.....#.....#.#.....#.....#.#.#.#.......#.....#.....#...# +#.#######.#.#.###.#.#.#######.###.###.#####.#.###.#.#.#.#####.###.#####.#.###.#########.#.###.#.#.#.#####.#.###.#.#.#########.#####.###.#.### +#.....#.#.......#...#...#...#.....#...#.....#.....#...#.....#...#.......#.....#.........#.....#...#.......#...#.#.#.........#...#.....#.#.#.# +#.###.#.#.#.#########.#.#.#.#######.###.#######.###########.#.#.#################.#################.#########.#.#.#.#######.###.#.###.###.#.# +#.#.#.#.....#.........#.#.#.....#...#...#.............#...#...#.#.#.......#...............#.......#...#.#...#...#.#.#...#.#.#...#...#...#.#.# +#.#.#.###.###.###.#.#.#.#.###.#.#.#.#.#####.#######.#.#.#.###.#.#.#.###.#.#.#.#######.###.#.###.#####.#.#.#.#####.###.#.#.#.#.#######.#.#.#.# +#...#...#.#...#.#...#.#.#...#.....#.#.#.....#.....#.#...#...#.#.#.....#.#.#.#.#.......#.....#.#.....#.#...#.......#.....#...#.#.....#.#.#.#.# +#.#.###.#.#.###.#####.#.###########.#.#.#####.#.#.#.###.#.###.#.#####.#.#.###.#.###.#########.#.#.#.#.#.#######.#.#.###.#.###.#.#.#.###.#.#.# +#.#.....#.#.#.......#.......#.......#...#.....#.#...#.....#...#...#...#.#...#.#...#.#.......#...#.#.......#...#.#.#.#...#.#...#.#.......#...# +#.#.#.#####.#.#.#####.#####.#.#####.###.###.###.#####.#####.#####.#.###.###.#.#####.#.#####.#####.###.###.#.#.#.#.#.#.###.#.###.###########.# +#.#...#...#.#.#...#.......#...#...#.#.....#.#...#.....#...#.....#.#...#.#.#.#.....#.....#...#.....#...#.....#.#.#.#.#...#...#...#...#.....#.# +###.#.#.#.#.#####.#.###.#########.#.###.#.###.#.#######.#.###.#.#.#.###.#.#.#.###.#######.#.#.#####.#.#######.#.#.#.###.#######.#.#.#.###.#.# +#.....#.#...#...#.#...#.#.........#.....#...#.#.#.....#.#.....#...#...#.#.#.#.#.#.......#.#.........#.....#...#.......#.#.....#...#...#...#.# +#.#.###.#####.#.#.###.###.#####.#.#########.#.###.###.#.###.#.#####.#.#.#.#.#.#.#######.#.#.###.###.#####.###.#########.#.###.###.#####.###.# +#.#...#.#.....#...#.#...#...#...#.#.......#.#.#...#...#...#.#.....#.#...#.#.#...#.......#.#...#...#.#...#...#.#.......#...#.#.....#.....#...# +#.#.#.#.#.#######.#.###.###.#.###.###.#.###.#.#.###.###.###.#####.#.#####.#.###.#.#.#.###.###.###.#.#.#####.###.#####.#.###.#####.#.#####.### +#...#...#.....#.#.....#...#.#.#.#...#.#...#.#...#.#.....#...#...#...#.....#.#.....#.#.......#...#...#.....#.....#.....#...#.....#.#.........# +#.#.#####.###.#.#####.###.#.#.#.###.#####.#.#.#.#.#######.#####.#####.#.#.#.#.###.#.#.#####.###.#########.#######.#######.#.###.#.########### +#.#.....#...#.#.#.....#...#.#.#...........#.#...#.#.......#...........#.#.#.#...#...#.....#...#.#.......#...........#...#...#...#...........# +#.#.###.###.#.#.#.#####.###.#.#####.#######.#.###.#.#######.#########.###.#.#.###.#######.###.#.#.#.#.#.###.###.###.#.#######.###.#########.# +#...#...#.#.#.#.#.....#...#.#.#...#.#.....#.#.....#...#.............#.....#.#.....#.....#...#.#.#.#.#.........#.#...#.#.....#.#.....#.....#.# +###.#.###.#.#.#.#.#.#.###.#.#.#.#.#.#.###.#.#####.#.#.#.#####.#.###.###.###.#.#.###.#.#####.#.#.###.#########.#.#.#.#.#.#.#.#.###.#.#.#.###.# +#...#.#.................#.#.#...#.#.#...#.#.#.....#...#.#...#.#...#...#.#...#.#.#...#.....#.#.#...#.....#...#.#.......................#...#.# +#.#.#.#.#####.#.#.#.###.#.#.#.###.###.#.#.#.#.#####.###.###.#.#.#.###.###.#####.#.#.#.###.#.#.###.#####.#.#.#.#.#.#.#####.#.#####.#.#.#.#.#.# +#.#...#.#.....#...#.....#.#.#...#...#...#...#.#...#...#.....#.....#.......................#.#...#.....#.#.#...#.#.#.....#.#.#...#.....#.#.#.# +#.#######.#####.#.#####.#.#.#.#.###.#.#######.#.#.#.#.#########.###.###.#####.###.###.#.###.###.#####.#.#.#####.#.#.###.#.#.#.###.#####.#.#.# +#.......#.#.............#.#...#...#.#.#.#...#...#...#.........#...#.#...#.....#.#.#.#...#...............#.....#.....................#.......# +#######.#.#.#####.#######.###.###.#.#.#.#.#.#####.#.###.#####.#.###.#.#####.###.#.#.#.###.###.#####.#########.#.#####.###.#####.#.#.#.#.##### +#.#...#...#.#.......#.......#.#...#.#.#...#.......................#.#.......#.#...#.#...#...#.....#...#.........#.....#.......#.#...#.......# +#.#.#.#####.#.#.#####.#####.#.#.#.#.#.#####.#.#####.#.###.#.###.#.#.#########.#.###.#.#.###.#.###.###.#########.#.#########.#.#.#.#.###.###.# +#...#.....#.#.#...#...#.....#...#.#.#.#...#...#.....#.#.#...#...#.#.#.........#.......#...#.#...#...#.......#...#.#.......#.#.........#...#.# +#.#######.#.#.###.#.#.#######.###.#.#.#.#.#####.###.#.#.###.#.###.#.#.#######.#######.###.#.#######.#######.#####.#.#####.#######.###.#.#.#.# +#.#.....#...#...#.#.#.#...........#...#.#.........................#.#.....#.#.#.....#.#...#.......#...#.....#...#.....#.#...#.....#.......#.# +#.###.#.#########.#.###.#############.#.#####.###.#.#.#########.###.#####.#.#.#.#.###.#.#########.###.#.#####.#.#.###.#.###.#.###.#####.###.# +#S....#...........#.....................#.........#.............#...........#...#.....#...............#.......#.......#.......#.............# +#############################################################################################################################################` + result := Solve(input) + if result != 134588 { + t.Errorf("Calculated solution was not expected") + } +}