AOC-2024/14/main.go
2024-12-15 00:16:28 +01:00

239 lines
4.4 KiB
Go

package main
import (
"bufio"
"fmt"
"image"
"image/color"
"image/png"
"os"
"strconv"
"time"
)
const FILE_PATH = "./input.txt"
const WIDTH = 101
const HEIGHT = 103
//const FILE_PATH = "./sample.txt"
//const WIDTH = 11
//const HEIGHT = 7
func LoadInput(filename string) ([]string, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
return nil, err
}
return lines, nil
}
type Vector2 struct {
x int
y int
}
type Robot struct {
p Vector2
v Vector2
}
type structuredInput = []Robot
func TransformInput(lines []string) structuredInput {
var result = make([]Robot, 0)
var j int
var m int
var numbX int
var numbY int
var position Vector2
var temp Robot
for i := 0; i < len(lines); i++ {
j = 2
for ; j < len(lines[i]); j++ {
if lines[i][j] == ',' {
break
}
}
numbX, _ = strconv.Atoi(lines[i][2:j])
m = j + 1
for ; j < len(lines[i]); j++ {
if lines[i][j] == ' ' {
break
}
}
numbY, _ = strconv.Atoi(lines[i][m:j])
position = Vector2{numbX, numbY}
m = j + 3
for ; j < len(lines[i]); j++ {
if lines[i][j] == ',' {
break
}
}
numbX, _ = strconv.Atoi(lines[i][m:j])
numbY, _ = strconv.Atoi(lines[i][j+1:])
temp = Robot{position, Vector2{numbX, numbY}}
result = append(result, temp)
}
return result
}
func Part1(input structuredInput) int {
var result = 0
var robots = make([]Robot, 0)
var temp Robot
for _, robot := range input {
temp = Robot{Vector2{robot.p.x, robot.p.y}, Vector2{robot.v.x, robot.v.y}}
robots = append(robots, temp)
}
for i := 0; i < len(input); i++ {
robots[i].p.x += 100 * robots[i].v.x
robots[i].p.y += 100 * robots[i].v.y
for robots[i].p.x < 0 {
robots[i].p.x += WIDTH
}
for robots[i].p.y < 0 {
robots[i].p.y += HEIGHT
}
for robots[i].p.x >= WIDTH {
robots[i].p.x -= WIDTH
}
for robots[i].p.y >= HEIGHT {
robots[i].p.y -= HEIGHT
}
}
var count = 0
var quads = make([]int, 0)
for offsetY := 0; offsetY < 2; offsetY++ {
for offsetX := 0; offsetX < 2; offsetX++ {
count = 0
for y := 0 + (offsetY * (HEIGHT/2 + 1)); y < (HEIGHT/2)+(offsetY*(HEIGHT/2+1)); y++ {
for x := 0 + (offsetX * (WIDTH/2 + 1)); x < (WIDTH/2)+(offsetX*(WIDTH/2+1)); x++ {
for _, robot := range robots {
if robot.p.x == x && robot.p.y == y {
count++
}
}
}
}
quads = append(quads, count)
}
}
result = 1
for _, quadCount := range quads {
result *= quadCount
}
return result
}
func simulateSecond(robots []Robot) []Robot {
for i := 0; i < len(robots); i++ {
robots[i].p.x += robots[i].v.x
robots[i].p.y += robots[i].v.y
for robots[i].p.x < 0 {
robots[i].p.x += WIDTH
}
for robots[i].p.y < 0 {
robots[i].p.y += HEIGHT
}
for robots[i].p.x >= WIDTH {
robots[i].p.x -= WIDTH
}
for robots[i].p.y >= HEIGHT {
robots[i].p.y -= HEIGHT
}
}
return robots
}
func Part2(input structuredInput) int {
var result = 0
var robots = make([]Robot, 0)
var temp Robot
var count int
for _, robot := range input {
temp = Robot{Vector2{robot.p.x, robot.p.y}, Vector2{robot.v.x, robot.v.y}}
robots = append(robots, temp)
}
var img *image.Gray
for i := 0; i < 10000; i++ {
img = image.NewGray(image.Rect(0, 0, WIDTH, HEIGHT))
robots = simulateSecond(robots)
count = 0
for y := 0; y < HEIGHT; y++ {
for x := 0; x < WIDTH; x++ {
count = 0
for _, robot := range robots {
if robot.p.x == x && robot.p.y == y {
count++
}
}
if count == 0 {
img.Set(x, y, color.White)
} else {
img.Set(x, y, color.Black)
}
}
}
f, _ := os.Create("./images/" + strconv.Itoa(i+1) + ".png")
defer f.Close()
png.Encode(f, img)
}
// Find result manualy
result = 6876
return result
}
func main() {
var start time.Time
var elapsed time.Duration = 0
input, err := LoadInput(FILE_PATH)
if err != nil {
fmt.Println("Error loading input:", err)
return
}
structuredInput := TransformInput(input)
fmt.Println("Structured Input:", structuredInput)
start = time.Now()
fmt.Println("Solution Part 1: ", Part1(structuredInput))
elapsed = time.Since(start)
fmt.Printf("Part 1 took %s\n", elapsed)
start = time.Now()
fmt.Println("Solution Part 2: ", Part2(structuredInput))
elapsed = time.Since(start)
fmt.Printf("Part 2 took %s\n", elapsed)
}