package main import ( "AOC2022/helper" "fmt" "os" "strings" ) func main() { args := os.Args[1:] lines := helper.ReadTextFile(args[0]) points := getPoints(lines) //scannedXPoints := make(map[int]bool) 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 } } } 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} } func getScannedPointsForTagetY(points [][2][2]int, targetyRange [2]int, targetxRange [2]int) map[[2]int]bool { scannedYPoints := make(map[[2]int]bool) for _, pointPair := range points { 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:], ":") sensorStringNumbers := helper.StringSliceToIntSlice(strings.Split(stringParts[0], ", y=")) beaconStringNumbers := helper.StringSliceToIntSlice(strings.Split(strings.ReplaceAll(stringParts[1], " closest beacon is at x=", ""), ", y=")) intPair[0] = [2]int{sensorStringNumbers[0], sensorStringNumbers[1]} intPair[1] = [2]int{beaconStringNumbers[0], beaconStringNumbers[1]} points[i] = intPair } return points }