Day 13 solution
This commit is contained in:
15
README.md
15
README.md
@@ -129,3 +129,18 @@ The solution for "twelve" is:
|
|||||||
Found 5157 paths through the cave system
|
Found 5157 paths through the cave system
|
||||||
Found 144309 paths through the cave system
|
Found 144309 paths through the cave system
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Day thirteen
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ./aoc2021 --thirteen
|
||||||
|
The solution for "thirteen" is:
|
||||||
|
There are 837 dots after 1 fold
|
||||||
|
#### ### #### ## # # ## # # # #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
### # # # # ## # #### # #
|
||||||
|
# ### # # ## # # # # # # #
|
||||||
|
# # # # # # # # # # # # #
|
||||||
|
#### # #### ### # # ## # # ##
|
||||||
|
This is the activation code
|
||||||
|
```
|
||||||
|
3
main.go
3
main.go
@@ -14,6 +14,7 @@ import (
|
|||||||
"unsupervised.ca/aoc2021/seven"
|
"unsupervised.ca/aoc2021/seven"
|
||||||
"unsupervised.ca/aoc2021/six"
|
"unsupervised.ca/aoc2021/six"
|
||||||
"unsupervised.ca/aoc2021/ten"
|
"unsupervised.ca/aoc2021/ten"
|
||||||
|
"unsupervised.ca/aoc2021/thirteen"
|
||||||
"unsupervised.ca/aoc2021/three"
|
"unsupervised.ca/aoc2021/three"
|
||||||
"unsupervised.ca/aoc2021/twelve"
|
"unsupervised.ca/aoc2021/twelve"
|
||||||
"unsupervised.ca/aoc2021/two"
|
"unsupervised.ca/aoc2021/two"
|
||||||
@@ -58,6 +59,8 @@ func main() {
|
|||||||
day = eleven.Init("eleven/input.txt")
|
day = eleven.Init("eleven/input.txt")
|
||||||
case "twelve":
|
case "twelve":
|
||||||
day = twelve.Init("twelve/input.txt")
|
day = twelve.Init("twelve/input.txt")
|
||||||
|
case "thirteen":
|
||||||
|
day = thirteen.Init("thirteen/input.txt")
|
||||||
default:
|
default:
|
||||||
fmt.Printf("%q does not have a solution.\n", flagParts[1])
|
fmt.Printf("%q does not have a solution.\n", flagParts[1])
|
||||||
help()
|
help()
|
||||||
|
1030
thirteen/input.txt
Normal file
1030
thirteen/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
26
thirteen/main.go
Normal file
26
thirteen/main.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package thirteen
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Thirteen struct {
|
||||||
|
manual manual
|
||||||
|
}
|
||||||
|
|
||||||
|
func Init(filepath string) *Thirteen {
|
||||||
|
thirteen := &Thirteen{
|
||||||
|
manual: manual{},
|
||||||
|
}
|
||||||
|
|
||||||
|
thirteen.manual.load(filepath)
|
||||||
|
return thirteen
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Thirteen) Answer() string {
|
||||||
|
_, dots := foldGrid(d.manual.folds[0], d.manual.dots)
|
||||||
|
return fmt.Sprintf("There are %d dots after 1 fold", dots)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Thirteen) FollowUp() string {
|
||||||
|
d.manual.fold()
|
||||||
|
return "This is the activation code"
|
||||||
|
}
|
183
thirteen/manual.go
Normal file
183
thirteen/manual.go
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
package thirteen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type axis rune
|
||||||
|
|
||||||
|
const (
|
||||||
|
x axis = 'x'
|
||||||
|
y axis = 'y'
|
||||||
|
)
|
||||||
|
|
||||||
|
type fold struct {
|
||||||
|
axis axis
|
||||||
|
index int
|
||||||
|
}
|
||||||
|
|
||||||
|
type manual struct {
|
||||||
|
dots map[int]map[int]bool
|
||||||
|
folds []fold
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *manual) load(filename string) error {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
|
||||||
|
m.dots = map[int]map[int]bool{}
|
||||||
|
m.folds = []fold{}
|
||||||
|
scanningDots := true
|
||||||
|
for scanner.Scan() {
|
||||||
|
if scanner.Text() == "" {
|
||||||
|
scanningDots = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if scanningDots {
|
||||||
|
var dotX, dotY int
|
||||||
|
if count, err := fmt.Sscanf(scanner.Text(), "%d,%d", &dotX, &dotY); count != 2 || err != nil {
|
||||||
|
return fmt.Errorf("expected 2 values, found %d: %w", count, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.dots[dotX] == nil {
|
||||||
|
m.dots[dotX] = map[int]bool{}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.dots[dotX][dotY] = true
|
||||||
|
} else {
|
||||||
|
var foldAxis axis
|
||||||
|
var foldIndex int
|
||||||
|
|
||||||
|
if count, err := fmt.Sscanf(scanner.Text(), "fold along %c=%d", &foldAxis, &foldIndex); count != 2 || err != nil {
|
||||||
|
return fmt.Errorf("scanning %q, expected 2 values, found %d: %w", scanner.Text(), count, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.folds = append(m.folds, fold{
|
||||||
|
axis: foldAxis,
|
||||||
|
index: foldIndex,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func gridSize(grid map[int]map[int]bool) (xSize, ySize int) {
|
||||||
|
for x, col := range grid {
|
||||||
|
if x > xSize {
|
||||||
|
xSize = x
|
||||||
|
}
|
||||||
|
for y := range col {
|
||||||
|
if y > ySize {
|
||||||
|
ySize = y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Increment Size to reflect 0 indexed arrays
|
||||||
|
xSize++
|
||||||
|
ySize++
|
||||||
|
|
||||||
|
return xSize, ySize
|
||||||
|
}
|
||||||
|
|
||||||
|
func countDots(grid map[int]map[int]bool) int {
|
||||||
|
dots := 0
|
||||||
|
for _, col := range grid {
|
||||||
|
for _, v := range col {
|
||||||
|
if v {
|
||||||
|
dots++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dots
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *manual) fold() {
|
||||||
|
grid := m.dots
|
||||||
|
|
||||||
|
for _, inst := range m.folds {
|
||||||
|
grid, _ = foldGrid(inst, grid)
|
||||||
|
}
|
||||||
|
|
||||||
|
printGrid(grid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func foldGrid(inst fold, grid map[int]map[int]bool) (map[int]map[int]bool, int) {
|
||||||
|
newGrid := map[int]map[int]bool{}
|
||||||
|
|
||||||
|
maxX, maxY := gridSize(grid)
|
||||||
|
if inst.axis == x {
|
||||||
|
// Copy the first rows
|
||||||
|
for copyX := 0; copyX < inst.index; copyX++ {
|
||||||
|
if newGrid[copyX] == nil {
|
||||||
|
newGrid[copyX] = map[int]bool{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for copyY := 0; copyY < maxY; copyY++ {
|
||||||
|
newGrid[copyX][copyY] = grid[copyX][copyY]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the folded values
|
||||||
|
for foldX := inst.index + 1; foldX < maxX; foldX++ {
|
||||||
|
targetX := inst.index - (foldX - inst.index)
|
||||||
|
for targetY := 0; targetY < maxY; targetY++ {
|
||||||
|
if grid[foldX][targetY] {
|
||||||
|
newGrid[targetX][targetY] = grid[foldX][targetY]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// initialize all X maps
|
||||||
|
for k := range grid {
|
||||||
|
newGrid[k] = map[int]bool{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the first rows
|
||||||
|
for copyY := 0; copyY < inst.index; copyY++ {
|
||||||
|
for copyX := 0; copyX < maxX; copyX++ {
|
||||||
|
if newGrid[copyX] == nil {
|
||||||
|
newGrid[copyX] = map[int]bool{}
|
||||||
|
}
|
||||||
|
|
||||||
|
newGrid[copyX][copyY] = grid[copyX][copyY]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the folded values
|
||||||
|
for foldY := inst.index + 1; foldY < maxY; foldY++ {
|
||||||
|
targetY := inst.index - (foldY - inst.index)
|
||||||
|
for targetX := 0; targetX < maxX; targetX++ {
|
||||||
|
if grid[targetX][foldY] {
|
||||||
|
newGrid[targetX][targetY] = grid[targetX][foldY]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newGrid, countDots(newGrid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func printGrid(grid map[int]map[int]bool) {
|
||||||
|
maxX, maxY := gridSize(grid)
|
||||||
|
|
||||||
|
for y := 0; y < maxY; y++ {
|
||||||
|
row := ""
|
||||||
|
for x := 0; x < maxX; x++ {
|
||||||
|
if grid[x][y] {
|
||||||
|
row += "#"
|
||||||
|
} else {
|
||||||
|
row += " "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(row)
|
||||||
|
}
|
||||||
|
}
|
58
thirteen/manual_test.go
Normal file
58
thirteen/manual_test.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package thirteen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_read(t *testing.T) {
|
||||||
|
m := manual{}
|
||||||
|
if err := m.load("test_input.txt"); err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
dots := countDots(m.dots)
|
||||||
|
folds := len(m.folds)
|
||||||
|
|
||||||
|
if dots != 18 {
|
||||||
|
t.Logf("Expected 18 dots, found %d", dots)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
if folds != 2 {
|
||||||
|
t.Logf("Expected 2 folds, found %d", folds)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
x, y := gridSize(m.dots)
|
||||||
|
|
||||||
|
if x != 11 || y != 15 {
|
||||||
|
t.Logf("Expected 11x15, found %dx%d", x, y)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_fold(t *testing.T) {
|
||||||
|
m := manual{}
|
||||||
|
m.load("test_input.txt")
|
||||||
|
|
||||||
|
printGrid(m.dots)
|
||||||
|
fmt.Println("")
|
||||||
|
grid, dots := foldGrid(m.folds[0], m.dots)
|
||||||
|
|
||||||
|
printGrid(grid)
|
||||||
|
if dots != 17 {
|
||||||
|
t.Logf("Expected 17 dots after fold, found %d", dots)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
grid, dots = foldGrid(m.folds[1], grid)
|
||||||
|
|
||||||
|
fmt.Println("")
|
||||||
|
printGrid(grid)
|
||||||
|
if dots != 16 {
|
||||||
|
t.Logf("Expected 16 dots after fold, found %d", dots)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
31
thirteen/scatch
Normal file
31
thirteen/scatch
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#.##..#..#.
|
||||||
|
#...#......
|
||||||
|
......#...#
|
||||||
|
#...#......
|
||||||
|
.#.#..#.###
|
||||||
|
...........
|
||||||
|
...........
|
||||||
|
|
||||||
|
#..#..#..#.
|
||||||
|
....#.#...#
|
||||||
|
....#......
|
||||||
|
##....#.##.
|
||||||
|
...#....#.#
|
||||||
|
...........
|
||||||
|
...........
|
||||||
|
|
||||||
|
...#..#..#.
|
||||||
|
....#......
|
||||||
|
...........
|
||||||
|
#..........
|
||||||
|
...#....#.#
|
||||||
|
...........
|
||||||
|
...........
|
||||||
|
...........
|
||||||
|
...........
|
||||||
|
...........
|
||||||
|
.#....#.##.
|
||||||
|
....#......
|
||||||
|
......#...#
|
||||||
|
#..........
|
||||||
|
#.#........
|
21
thirteen/test_input.txt
Normal file
21
thirteen/test_input.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
6,10
|
||||||
|
0,14
|
||||||
|
9,10
|
||||||
|
0,3
|
||||||
|
10,4
|
||||||
|
4,11
|
||||||
|
6,0
|
||||||
|
6,12
|
||||||
|
4,1
|
||||||
|
0,13
|
||||||
|
10,12
|
||||||
|
3,4
|
||||||
|
3,0
|
||||||
|
8,4
|
||||||
|
1,10
|
||||||
|
2,14
|
||||||
|
8,10
|
||||||
|
9,0
|
||||||
|
|
||||||
|
fold along y=7
|
||||||
|
fold along x=5
|
Reference in New Issue
Block a user