day10: some cleanup

This commit is contained in:
alexchao26
2020-08-03 20:04:23 -04:00
parent 40f4e54bc2
commit 936489e620
5 changed files with 50 additions and 135 deletions
+14 -44
View File
@@ -1,24 +1,21 @@
package main
import (
"bufio"
"adventofcode/util"
"fmt"
"log"
"os"
"path/filepath"
"strings"
)
func main() {
// need to read the input.txt file (one folder up)
// it will be a 2D slice coming from readInputFile now
stringSlice := readInputFile("../input.txt")
// fmt.Println(stringSlice, len(stringSlice))
// 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, "")
}
// fmt.Println(gridSlice, len(gridSlice))
// will be the final result value
var result int
@@ -29,9 +26,7 @@ func main() {
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)
// fmt.Println("visible:", visibleFromElement)
// take max of return of helper function at end of each loop
if result < visibleFromElement {
@@ -43,53 +38,30 @@ func main() {
}
// print out the max found
fmt.Println("result: ", result)
fmt.Println("best asteroid for the station is at row, col", finalCoords) // [13, 11]
fmt.Println("from 13, 11 (y, x)", visibleFromAsteroid(gridSlice, 13, 11))
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)
}
func readInputFile(path string) []string {
// var pixelString string
pixelSlice := make([]string, 0)
absPath, _ := filepath.Abs(path)
file, err := os.Open(absPath)
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// pixelString = line
pixelSlice = append(pixelSlice, line)
}
// return pixelString
return pixelSlice
}
// helper function will take, x and y coordinates, and the 2D slices?
// 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)
// 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
// will need edge case handling for planets vertically above or below the current asteroid
// and edge case handling for planets vertically above or below the current asteroid
func visibleFromAsteroid(grid [][]string, row, col int) (result int) {
// fmt.Println(grid)
// make the two maps
leftMap, rightMap := make(map[float64]bool), make(map[float64]bool)
// make the two booleans for up and down. nil value is false
// 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
// fmt.Println("avoid zero division")
// handle if the found asteroid is directly above the inputted row/col asteroid
if run == 0 {
if rise < 0 {
@@ -107,7 +79,6 @@ func visibleFromAsteroid(grid [][]string, row, col int) (result int) {
}
} else {
slope := float64(rise) / float64(run)
// fmt.Println(slope)
// handle left or right map
if run < 0 {
// leftMap
@@ -127,6 +98,5 @@ func visibleFromAsteroid(grid [][]string, row, col int) (result int) {
}
}
// fmt.Println(leftMap, rightMap, upBool, downBool)
return result
}
+6 -20
View File
@@ -10,7 +10,7 @@ import (
)
/*
Overall approach...
Overall approach:
- need to make a map of some kind
make it a slice where each element is a struct
- each struct will contain:
@@ -36,8 +36,8 @@ type Asteroid struct {
func main() {
// read input.txt file, split it into a slice of lines
contents := util.ReadFile("../input.txt") // test/example case @ "./test.txt"
stringSlice := strings.Split(contents, "\n")
input := util.ReadFile("../input.txt")
stringSlice := strings.Split(input, "\n")
// generate 2D grid of each character from stringSlice
inputGrid := make([][]string, len(stringSlice))
@@ -45,18 +45,7 @@ func main() {
inputGrid[i] = strings.Split(str, "")
}
//* tests while building the TangetAndDistance function
// fmt.Println(trig.TangentAndDistance(13, 11, 0, 11)) // 0 13
// fmt.Println(trig.TangentAndDistance(13, 11, 15, 11)) // 180 2
// fmt.Println(trig.TangentAndDistance(13, 11, 13, 16)) // 90 5
// fmt.Println(trig.TangentAndDistance(13, 11, 13, 9)) // 270 2
// fmt.Println(trig.TangentAndDistance(1, 1, 0, 2)) // 45 some sqrt
// fmt.Println(trig.TangentAndDistance(1, 1, 2, 2)) // 135 some sqrt
// fmt.Println(trig.TangentAndDistance(1, 1, 2, 0)) // 225 some sqrt
// fmt.Println(trig.TangentAndDistance(1, 1, 0, 0)) // 315 some sqrt
allAsteroids := makeAsteroidsSlice(inputGrid)
// fmt.Println(allAsteroids)
// need to start this just to the left of zero to get that as the first input
lastDegreeUsed := 359.999999
@@ -105,9 +94,6 @@ func main() {
// if we pass over 360, subtract 360
lastDegreeUsed -= 360
}
// fmt.Println(minDegDiff)
// fmt.Println("lastAsteroid", i, lastAsteroid)
// fmt.Println(indexOfAsteroidToDelete, allAsteroids[indexOfAsteroidToDelete])
}
// print the last used asteroid
@@ -125,13 +111,13 @@ func makeAsteroidsSlice(grid [][]string) []Asteroid {
// if an asteroid is found...
if element == "#" && !(rowIndex == 13 && colIndex == 11) {
// calculate the degree and dist
degree, dist := trig.TangentAndDistance(13, 11, rowIndex, colIndex)
// degree, dist := trig.TangentAndDistance(13, 11, rowIndex, colIndex)
// create an instance of an Asteroid struct and append it to the result slice
ast := Asteroid{
x: rowIndex,
y: colIndex,
degOffVert: degree,
distance: dist,
degOffVert: trig.AngleOffVertical(13, 11, rowIndex, colIndex),
distance: trig.Distance(13, 11, rowIndex, colIndex),
}
result = append(result, ast)
}
-20
View File
@@ -1,20 +0,0 @@
.#..##.###...#######
##.############..##.
.#.######.########.#
.###.#######.####.#.
#####.##.#.##.###.##
..#####..#.#########
####################
#.####....###.#.#.##
##.#################
#####.##.###..####..
..######..##.#######
####.##.####...##..#
.#####..#.######.###
##...#.##########...
#.##########.#######
.####.#.###.###.#.##
....##.##.###..#####
.#.#.###########.###
#.#.#.#####.####.###
###.##.####.##.#..##
+29 -51
View File
@@ -1,62 +1,40 @@
package trig
import (
"math"
)
// TangentAndDistance docz
// startX will "always" be 13
// startY will "always" be 11
// 0 <= angleOffVery < 360
func TangentAndDistance(startX, startY, endX, endY int) (angleOffVert, distance float64) {
rise, run := float64(endX)-float64(startX), float64(endY)-float64(startY)
// fmt.Println(rise, run)
// edge cases for verticals
if run == 0 && rise < 0 {
return 0, -1 * rise // endXY is up
}
if run == 0 && rise > 0 {
return 180, rise // endXY is down
}
// handle left or right?
if rise == 0 && run < 0 {
return 270, -1 * run // left
}
if rise == 0 && run > 0 {
return 90, run // right
}
// not verticals
// calculate return distance
distance = rise*rise + run*run
distance = math.Sqrt(distance)
// calculate arctangent which will be in radians
// determine quadrent
if rise < 0 && run > 0 { // top right
angleOffVert = -1 * math.Atan(run/rise) * 180 / math.Pi
} else if rise > 0 && run > 0 { // bottom right
angleOffVert = 90 + math.Atan(rise/run)*180/math.Pi
} else if rise > 0 && run < 0 { // bottom left
angleOffVert = 180 + -1*math.Atan(run/rise)*180/math.Pi
} else if rise < 0 && run < 0 { // top left
angleOffVert = 270 + math.Atan(rise/run)*180/math.Pi
}
return angleOffVert, distance
}
import "math"
/*
AngleOffVertical takes in two 2D points, it calculates the angle
between the line between then and a vertical line. The angle
returned is to the right of the vertical, i.e. from the vertical
and through the (mathematical) first quadrant
between the line and a vertical line (straight up from origin)
NOTE: "up"/"top" and "down" are lexically flipped b/c of drawing a grid
where 0, 0 is the top left corner and higher numbers physically go DOWN
but lexically increase/go UP 🤦‍♂️
*/
func AngleOffVertical(startX, startY, endX, endY int) float64 {
rise := float64(endX) - float64(startX)
run := float64(endY) - float64(startY)
return 0
var angle float64
// basically a big if/elseif/else block
switch {
case run == 0 && rise < 0: // up
angle = 0
case run == 0 && rise > 0: // down
angle = 180
case rise == 0 && run < 0: // left
angle = 270
case rise == 0 && run > 0: // right
angle = 90
case rise < 0 && run > 0: // top right
angle = -1 * math.Atan(run/rise) * 180 / math.Pi
case rise > 0 && run > 0: // bottom right
angle = 90 + math.Atan(rise/run)*180/math.Pi
case rise > 0 && run < 0: // bottom left
angle = 180 + -1*math.Atan(run/rise)*180/math.Pi
case rise < 0 && run < 0: // top left
angle = 270 + math.Atan(rise/run)*180/math.Pi
}
return angle
}
// Distance calculates the distance between two sets of 2D coordinates via Pythagorean's theorem