AOC-2024/08/main.go
2024-12-08 12:46:45 +01:00

206 lines
3.7 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"time"
)
const FILE_PATH = "./input.txt"
//const FILE_PATH = "./sample.txt"
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 structuredInput = [][]byte
func TransformInput(lines []string) structuredInput {
var result = make([][]byte, 0)
for _, line := range lines {
result = append(result, []byte(line))
}
return result
}
type Vector2 struct {
x int
y int
}
func isInBounds(position Vector2, bounds Vector2) bool {
return position.x >= 0 && position.x < bounds.x && position.y >= 0 && position.y < bounds.y
}
func add(a Vector2, b Vector2) Vector2 {
return Vector2{a.x + b.x, a.y + b.y}
}
func sub(a Vector2, b Vector2) Vector2 {
return Vector2{a.x - b.x, a.y - b.y}
}
func mult(a Vector2, s int) Vector2 {
return Vector2{a.x * s, a.y * s}
}
func Part1(input structuredInput) int {
var result = 0
var positions []Vector2
var found bool
var antennas = make(map[byte][]Vector2)
var signals = make(map[Vector2]bool)
var bounds = Vector2{len(input[0]), len(input)}
var a Vector2
var b Vector2
var dif Vector2
var point Vector2
for y := 0; y < len(input); y++ {
for x := 0; x < len(input[y]); x++ {
if input[y][x] == '.' {
continue
}
positions, found = antennas[input[y][x]]
if !found {
positions = make([]Vector2, 0)
}
antennas[input[y][x]] = append(positions, Vector2{x, y})
}
}
for _, value := range antennas {
for i := 0; i < len(value)-1; i++ {
for j := i + 1; j < len(value); j++ {
a = value[i]
b = value[j]
dif = sub(a, b)
point = add(dif, a)
if isInBounds(point, bounds) {
signals[point] = true
}
dif = sub(b, a)
point = add(dif, b)
if isInBounds(point, bounds) {
signals[point] = true
}
}
}
}
result = len(signals)
return result
}
func Part2(input structuredInput) int {
var result = 0
var positions []Vector2
var found bool
var antennas = make(map[byte][]Vector2)
var signals = make(map[Vector2]bool)
var bounds = Vector2{len(input[0]), len(input)}
var a Vector2
var b Vector2
var dif Vector2
var point Vector2
for y := 0; y < len(input); y++ {
for x := 0; x < len(input[y]); x++ {
if input[y][x] == '.' {
continue
}
positions, found = antennas[input[y][x]]
if !found {
positions = make([]Vector2, 0)
}
antennas[input[y][x]] = append(positions, Vector2{x, y})
}
}
for _, value := range antennas {
for i := 0; i < len(value)-1; i++ {
for j := i + 1; j < len(value); j++ {
a = value[i]
b = value[j]
dif = sub(a, b)
point = a
for isInBounds(point, bounds) {
signals[point] = true
point = add(point, dif)
}
dif = sub(b, a)
point = b
for isInBounds(point, bounds) {
signals[point] = true
point = add(point, dif)
}
}
}
}
result = len(signals)
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)
}