mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
103 lines
3.1 KiB
Go
103 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/alexchao26/advent-of-code-go/util"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
// need to read the input.txt file and split each line into a slice
|
|
input := util.ReadFile("../input.txt")
|
|
stringSlice := strings.Split(input, "\n")
|
|
|
|
// split into a 2D grid with each character
|
|
gridSlice := make([][]string, len(stringSlice))
|
|
for i, str := range stringSlice {
|
|
gridSlice[i] = strings.Split(str, "")
|
|
}
|
|
|
|
// will be the final result value
|
|
var result int
|
|
var finalCoords [2]int
|
|
// iterate through entire slice, for each asteroid found, call a helper function
|
|
for rowIndex, rowSlice := range gridSlice {
|
|
for colIndex, element := range rowSlice {
|
|
if element == "#" {
|
|
// # are "asteroids", . are empty space
|
|
// helper function will return how many asteroids are "findable" from the current asteroid
|
|
visibleFromElement := visibleFromAsteroid(gridSlice, rowIndex, colIndex)
|
|
|
|
// take max of return of helper function at end of each loop
|
|
if result < visibleFromElement {
|
|
result = visibleFromElement
|
|
finalCoords[0], finalCoords[1] = rowIndex, colIndex
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// print out the max found
|
|
fmt.Printf("best asteroid for the station: row[%v] col[%v]\n", finalCoords[0], finalCoords[1]) // [13, 11]
|
|
fmt.Println("from 13, 11 (y, x)", result)
|
|
}
|
|
|
|
// helper function will take, x and y coordinates, and the 2D slice
|
|
// will create a two maps of floats to booleans
|
|
// (one map to cover left side of asteroid, one map to cover right side of asteroid)
|
|
// so that anything that is blocked will not be double counted
|
|
// and edge case handling for planets vertically above or below the current asteroid
|
|
func visibleFromAsteroid(grid [][]string, row, col int) (result int) {
|
|
// make the two maps
|
|
leftMap, rightMap := make(map[float64]bool), make(map[float64]bool)
|
|
// make the two booleans for up and down. zero value is false
|
|
var upBool, downBool bool
|
|
|
|
// iterate through every element of the grid slices
|
|
for rowIndex, rowSlice := range grid {
|
|
for colIndex, element := range rowSlice {
|
|
// NOTE this control flow is _GROSS_. Better solution in part2 solution
|
|
// ensure element is an asteroid & not the asteroid that the helper function is being run on
|
|
if element == "#" && !(row == rowIndex && col == colIndex) {
|
|
rise := rowIndex - row
|
|
run := colIndex - col
|
|
|
|
// handle if the found asteroid is directly above the inputted row/col asteroid
|
|
if run == 0 {
|
|
if rise < 0 {
|
|
// check down
|
|
// note that up and down are semantically "flipped" due to the 2 row being "above" the 0 row
|
|
if !downBool {
|
|
downBool = true
|
|
result++
|
|
}
|
|
} else {
|
|
if !upBool {
|
|
upBool = true
|
|
result++
|
|
}
|
|
}
|
|
} else {
|
|
slope := float64(rise) / float64(run)
|
|
// handle left or right map
|
|
if run < 0 {
|
|
// leftMap
|
|
if _, inLeftMap := leftMap[slope]; !inLeftMap {
|
|
leftMap[slope] = true
|
|
result++
|
|
}
|
|
} else {
|
|
// rightMap
|
|
if _, inRightMap := rightMap[slope]; !inRightMap {
|
|
rightMap[slope] = true
|
|
result++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|