144 lines
2.6 KiB
Go
144 lines
2.6 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func mustAtoi(line string) int {
|
||
|
i, _ := strconv.Atoi(line)
|
||
|
return i
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
start := time.Now()
|
||
|
partOne()
|
||
|
duration := time.Since(start)
|
||
|
partTwo()
|
||
|
duration2 := time.Since(start)
|
||
|
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
||
|
}
|
||
|
|
||
|
func makeScanner(test bool) *bufio.Scanner {
|
||
|
var f *os.File
|
||
|
if test {
|
||
|
f, _ = os.Open("inputs/testinput")
|
||
|
} else {
|
||
|
f, _ = os.Open("inputs/input")
|
||
|
}
|
||
|
reader := bufio.NewReader(f)
|
||
|
return bufio.NewScanner(reader)
|
||
|
}
|
||
|
|
||
|
type point struct {
|
||
|
x int
|
||
|
y int
|
||
|
}
|
||
|
|
||
|
func partOne() {
|
||
|
scanner := makeScanner(false)
|
||
|
|
||
|
// parse points
|
||
|
points := make(map[point]struct{}, 0)
|
||
|
for scanner.Scan() {
|
||
|
line := scanner.Text()
|
||
|
if line == "" {
|
||
|
break
|
||
|
}
|
||
|
p := strings.Split(line, ",")
|
||
|
points[point{
|
||
|
x: mustAtoi(p[0]),
|
||
|
y: mustAtoi(p[1]),
|
||
|
}] = struct{}{}
|
||
|
}
|
||
|
|
||
|
// make first fold
|
||
|
scanner.Scan()
|
||
|
f := strings.Split(scanner.Text(), "=")
|
||
|
orientation := strings.Split(f[0], " ")[2]
|
||
|
crease := mustAtoi(f[1])
|
||
|
if orientation == "y" {
|
||
|
for p := range points {
|
||
|
if p.y > crease {
|
||
|
delete(points, p)
|
||
|
points[point{x: p.x, y: p.y - ((p.y - crease) * 2)}] = struct{}{}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if orientation == "x" {
|
||
|
for p := range points {
|
||
|
if p.x > crease {
|
||
|
delete(points, p)
|
||
|
points[point{x: p.x - ((p.x - crease) * 2), y: p.y}] = struct{}{}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fmt.Println(len(points))
|
||
|
}
|
||
|
|
||
|
func partTwo() {
|
||
|
scanner := makeScanner(false)
|
||
|
|
||
|
// parse points
|
||
|
points := make(map[point]struct{}, 0)
|
||
|
for scanner.Scan() {
|
||
|
line := scanner.Text()
|
||
|
if line == "" {
|
||
|
break
|
||
|
}
|
||
|
p := strings.Split(line, ",")
|
||
|
points[point{
|
||
|
x: mustAtoi(p[0]),
|
||
|
y: mustAtoi(p[1]),
|
||
|
}] = struct{}{}
|
||
|
}
|
||
|
// do folds
|
||
|
for scanner.Scan() {
|
||
|
line := scanner.Text()
|
||
|
f := strings.Split(line, "=")
|
||
|
orientation := strings.Split(f[0], " ")[2]
|
||
|
crease := mustAtoi(f[1])
|
||
|
if orientation == "y" {
|
||
|
for p := range points {
|
||
|
if p.y > crease {
|
||
|
delete(points, p)
|
||
|
points[point{x: p.x, y: p.y - ((p.y - crease) * 2)}] = struct{}{}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if orientation == "x" {
|
||
|
for p := range points {
|
||
|
if p.x > crease {
|
||
|
delete(points, p)
|
||
|
points[point{x: p.x - ((p.x - crease) * 2), y: p.y}] = struct{}{}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// find outer bounds of letters
|
||
|
maxy, maxx := 0, 0
|
||
|
for p := range points {
|
||
|
if p.y > maxy {
|
||
|
maxy = p.y
|
||
|
}
|
||
|
if p.x > maxx {
|
||
|
maxx = p.x
|
||
|
}
|
||
|
}
|
||
|
// print letters
|
||
|
for y := 0; y <= maxy; y++ {
|
||
|
for x := 0; x <= maxx; x++ {
|
||
|
if _, ok := points[point{x: x, y: y}]; ok {
|
||
|
fmt.Printf("#")
|
||
|
} else {
|
||
|
fmt.Printf(" ")
|
||
|
}
|
||
|
}
|
||
|
fmt.Printf("\n")
|
||
|
}
|
||
|
}
|