122 lines
2.2 KiB
Go
122 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
inputBytes, _ := os.ReadFile("input.txt")
|
|
input := strings.Split(string(inputBytes), "\n")
|
|
|
|
log.Println("Puzzle 1:", puzzle1(input))
|
|
log.Println("Puzzle 2:\n" + puzzle2(input))
|
|
}
|
|
|
|
func puzzle1(input []string) int {
|
|
grid := fold(input, false)
|
|
count := 0
|
|
for _, row := range grid {
|
|
for _, cell := range row {
|
|
if cell == 1 {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func puzzle2(input []string) string {
|
|
grid := fold(input, true)
|
|
res := ""
|
|
for _, row := range grid {
|
|
for _, cell := range row {
|
|
if cell == 1 {
|
|
res += "#"
|
|
} else {
|
|
res += " "
|
|
}
|
|
}
|
|
res += "\n"
|
|
}
|
|
return res
|
|
}
|
|
|
|
func fold(input []string, puzzle2 bool) [][]int {
|
|
// Parse input
|
|
xs := []int{}
|
|
ys := []int{}
|
|
folds := []string{}
|
|
for _, line := range input {
|
|
if line == "" {
|
|
continue
|
|
}
|
|
if strings.HasPrefix(line, "fold along") {
|
|
folds = append(folds, strings.TrimPrefix(line, "fold along "))
|
|
continue
|
|
}
|
|
parts := strings.Split(line, ",")
|
|
x, _ := strconv.Atoi(parts[0])
|
|
xs = append(xs, x)
|
|
y, _ := strconv.Atoi(parts[1])
|
|
ys = append(ys, y)
|
|
}
|
|
// Get maximum x and y
|
|
var maxX, maxY int
|
|
for _, x := range xs {
|
|
if x > maxX {
|
|
maxX = x
|
|
}
|
|
}
|
|
for _, y := range ys {
|
|
if y > maxY {
|
|
maxY = y
|
|
}
|
|
}
|
|
// Create grid
|
|
grid := make([][]int, maxY+1)
|
|
for i := range grid {
|
|
grid[i] = make([]int, maxX+1)
|
|
}
|
|
// Fill grid
|
|
for i, x := range xs {
|
|
grid[ys[i]][x] = 1
|
|
}
|
|
// Fold grid
|
|
for fi, f := range folds {
|
|
if fi > 0 && !puzzle2 {
|
|
break
|
|
}
|
|
parts := strings.Split(f, "=")
|
|
p, _ := strconv.Atoi(parts[1])
|
|
xl := len(grid[0])
|
|
yl := len(grid)
|
|
if parts[0] == "x" {
|
|
// Copy all points from right of the fold to the left and shrink the grid
|
|
for j := 0; j < yl; j++ {
|
|
for i := 0; i+p < xl && p-i >= 0; i++ {
|
|
if grid[j][p+i] == 1 {
|
|
grid[j][p-i] = 1
|
|
}
|
|
}
|
|
// Shrink row
|
|
grid[j] = grid[j][:p]
|
|
}
|
|
} else {
|
|
// Copy all points from bottom of the fold to the top
|
|
for j := 0; j+p < yl && p-j >= 0; j++ {
|
|
for i := 0; i < xl; i++ {
|
|
if grid[p+j][i] == 1 {
|
|
grid[p-j][i] = 1
|
|
}
|
|
}
|
|
}
|
|
// Shrink grid
|
|
grid = grid[:p]
|
|
}
|
|
}
|
|
return grid
|
|
}
|