2022-12-16 00:29:33 +01:00
package main
import (
"AOC2022/helper"
"fmt"
2022-12-16 02:20:08 +01:00
"os"
2022-12-16 00:29:33 +01:00
"strings"
)
func main ( ) {
2022-12-16 02:20:08 +01:00
args := os . Args [ 1 : ]
lines := helper . ReadTextFile ( args [ 0 ] )
2022-12-16 00:29:33 +01:00
points := getPoints ( lines )
//scannedXPoints := make(map[int]bool)
2022-12-16 02:20:08 +01:00
scannedPoints := getScannedPointsForTagetY ( points , [ 2 ] int { 2000000 , 2000000 } , [ 2 ] int { - 100000000 , 100000000 } )
fmt . Println ( len ( scannedPoints ) - 1 )
part2 ( points )
}
// Fichtes Solution
func part2 ( points [ ] [ 2 ] [ 2 ] int ) {
scannerWithDistances := [ ] [ 3 ] int { }
for _ , scannedPoint := range points {
distance := helper . ManHattanDistance ( scannedPoint [ 0 ] , scannedPoint [ 1 ] )
scannerWithDistances = append ( scannerWithDistances , [ 3 ] int { scannedPoint [ 0 ] [ 0 ] , scannedPoint [ 0 ] [ 1 ] , distance } )
}
startPoint := [ 2 ] int { 0 , 0 }
finish := false
for ! finish {
scanner := checkIfPointIsInScannerReach ( startPoint , scannerWithDistances )
if scanner [ 2 ] == - 1 {
finish = true
} else {
distanceToTargetY := helper . Abs ( scanner [ 1 ] - startPoint [ 1 ] )
widthOnTargetY := helper . Abs ( distanceToTargetY - scanner [ 2 ] )
newXValue := scanner [ 0 ] + widthOnTargetY + 1
if newXValue > 4000000 {
startPoint = [ 2 ] int { 0 , startPoint [ 1 ] + 1 }
} else {
startPoint [ 0 ] = newXValue
2022-12-16 00:29:33 +01:00
}
}
}
2022-12-16 02:20:08 +01:00
fmt . Println ( startPoint [ 0 ] * 4000000 + startPoint [ 1 ] )
}
func checkIfPointIsInScannerReach ( point [ 2 ] int , scanners [ ] [ 3 ] int ) [ 3 ] int {
for _ , scannerWithDistance := range scanners {
if helper . ManHattanDistance ( point , [ 2 ] int { scannerWithDistance [ 0 ] , scannerWithDistance [ 1 ] } ) <= scannerWithDistance [ 2 ] {
return scannerWithDistance
}
}
return [ 3 ] int { 0 , 0 , - 1 }
2022-12-16 00:29:33 +01:00
}
func getScannedPointsForTagetY ( points [ ] [ 2 ] [ 2 ] int , targetyRange [ 2 ] int , targetxRange [ 2 ] int ) map [ [ 2 ] int ] bool {
scannedYPoints := make ( map [ [ 2 ] int ] bool )
2022-12-16 02:20:08 +01:00
for _ , pointPair := range points {
2022-12-16 00:29:33 +01:00
sensor := pointPair [ 0 ]
beacon := pointPair [ 1 ]
distanceToSensor := helper . ManHattanDistance ( sensor , beacon )
distanceToTargetYLowest := helper . Abs ( sensor [ 1 ] - targetyRange [ 0 ] )
distanceToTargetYHighest := helper . Abs ( sensor [ 1 ] - targetyRange [ 1 ] )
if sensor [ 1 ] >= targetyRange [ 1 ] && distanceToSensor >= distanceToTargetYHighest {
i := targetyRange [ 1 ]
for i >= targetyRange [ 1 ] - ( distanceToSensor - distanceToTargetYHighest ) && i >= targetyRange [ 0 ] {
setPointsForTargetY ( distanceToSensor , i , targetxRange , sensor , & scannedYPoints )
i --
}
}
if sensor [ 1 ] <= targetyRange [ 0 ] && distanceToSensor >= distanceToTargetYLowest {
i := targetyRange [ 0 ]
for i <= targetyRange [ 0 ] + ( distanceToSensor - distanceToTargetYLowest ) && i <= targetyRange [ 1 ] {
setPointsForTargetY ( distanceToSensor , i , targetxRange , sensor , & scannedYPoints )
i ++
}
}
if sensor [ 1 ] >= targetyRange [ 0 ] && sensor [ 1 ] <= targetyRange [ 1 ] {
i := sensor [ 1 ]
for i <= targetyRange [ 1 ] && i <= sensor [ 1 ] + distanceToSensor {
setPointsForTargetY ( distanceToSensor , i , targetxRange , sensor , & scannedYPoints )
i ++
}
i = sensor [ 1 ]
for i >= targetyRange [ 0 ] && i >= sensor [ 1 ] - distanceToSensor {
setPointsForTargetY ( distanceToSensor , i , targetxRange , sensor , & scannedYPoints )
i --
}
}
}
return scannedYPoints
}
func setPointsForTargetY ( distanceToSensor , targetY int , targetxRange , sensor [ 2 ] int , scannedYPoints * map [ [ 2 ] int ] bool ) {
distanceToTargetY := helper . Abs ( sensor [ 1 ] - targetY )
widthOnTargetY := helper . Abs ( distanceToTargetY - distanceToSensor )
i := sensor [ 0 ] - widthOnTargetY
if i < targetxRange [ 0 ] {
i = targetxRange [ 0 ]
}
for i <= sensor [ 0 ] + widthOnTargetY && i <= targetxRange [ 1 ] {
( * scannedYPoints ) [ [ 2 ] int { i , targetY } ] = true
i ++
}
}
func getPoints ( lines [ ] string ) [ ] [ 2 ] [ 2 ] int {
points := make ( [ ] [ 2 ] [ 2 ] int , len ( lines ) )
for i , line := range lines {
intPair := [ 2 ] [ 2 ] int { }
stringParts := strings . Split ( line [ 12 : ] , ":" )
2022-12-18 19:39:49 +01:00
sensorStringNumbers := helper . StringSliceToIntSlice ( strings . Split ( stringParts [ 0 ] , ", y=" ) )
beaconStringNumbers := helper . StringSliceToIntSlice ( strings . Split ( strings . ReplaceAll ( stringParts [ 1 ] , " closest beacon is at x=" , "" ) , ", y=" ) )
2022-12-16 00:29:33 +01:00
intPair [ 0 ] = [ 2 ] int { sensorStringNumbers [ 0 ] , sensorStringNumbers [ 1 ] }
intPair [ 1 ] = [ 2 ] int { beaconStringNumbers [ 0 ] , beaconStringNumbers [ 1 ] }
points [ i ] = intPair
}
return points
}