From 0dadb796bc9df1564fd54a4c619e427cc74d7532 Mon Sep 17 00:00:00 2001 From: Alphyron Date: Tue, 10 Dec 2019 12:33:22 +0100 Subject: [PATCH] :sparkles: Finish part 1 of day 10 --- day10/input.txt | 28 +++++++++ day10/main.go | 152 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 day10/input.txt create mode 100644 day10/main.go diff --git a/day10/input.txt b/day10/input.txt new file mode 100644 index 0000000..2dd7815 --- /dev/null +++ b/day10/input.txt @@ -0,0 +1,28 @@ +###..#.##.####.##..###.#.#.. +#..#..###..#.......####..... +#.###.#.##..###.##..#.###.#. +..#.##..##...#.#.###.##.#### +.#.##..####...####.###.##... +##...###.#.##.##..###..#..#. +.##..###...#....###.....##.# +#..##...#..#.##..####.....#. +.#..#.######.#..#..####....# +#.##.##......#..#..####.##.. +##...#....#.#.##.#..#...##.# +##.####.###...#.##........## +......##.....#.###.##.#.#..# +.###..#####.#..#...#...#.### +..##.###..##.#.##.#.##...... +......##.#.#....#..##.#.#### +...##..#.#.#.....##.###...## +.#.#..#.#....##..##.#..#.#.. +...#..###..##.####.#...#..## +#.#......#.#..##..#...#.#..# +..#.##.#......#.##...#..#.## +#.##..#....#...#.##..#..#..# +#..#.#.#.##..#..#.#.#...##.. +.#...#.........#..#....#.#.# +..####.#..#..##.####.#.##.## +.#.######......##..#.#.##.#. +.#....####....###.#.#.#.#### +....####...##.#.#...#..#.##. diff --git a/day10/main.go b/day10/main.go new file mode 100644 index 0000000..555e441 --- /dev/null +++ b/day10/main.go @@ -0,0 +1,152 @@ +package main + +import ( + "bufio" + "log" + "math" + "os" +) + +type Position struct { + X int + Y int +} + +func main() { + file, err := os.Open("input.txt") + if err != nil { + log.Fatal(err) + } + defer file.Close() + + t2 := make([]string, 0) + scanner := bufio.NewScanner(file) + for scanner.Scan() { + t2 = append(t2, scanner.Text()) + } + + field, asteroids := ParseStringSliceToField(t2) + + SolvePzl1(field, asteroids) +} + +func SolvePzl1(field [][]int, asteroids []Position) { + highestFoundAstros := math.MinInt32 + pos := Position{} + + for _, astro := range asteroids { + sum := CountAsteroidsFromPosition(field, astro.X, astro.Y) + if highestFoundAstros < sum { + highestFoundAstros = sum + pos = astro + } + } + + log.Printf("Part1: Found %d Astros at Position(%d,%d) from %d Astros", highestFoundAstros, pos.X, pos.Y, len(asteroids)) +} + +func ParseStringSliceToField(view []string) (field [][]int, asteroids []Position) { + field = make([][]int, 0) + asteroids = make([]Position, 0) + + x, y := 0, 0 + + for i, line := range view { + x = 0 + field = append(field, make([]int, 0)) + for j := 0; j < len(line); j++ { + if "#" == string(line[j]) { + field[i] = append(field[i], 0) + asteroids = append(asteroids, Position{X: x, Y: y}) + } else { + field[i] = append(field[i], -1) + } + x++ + } + y++ + } + return +} + +func CountAsteroidsFromPosition(field [][]int, posX, posY int) (sum int) { + duplicate := Copy2DSlice(field) + steps := make(map[int]int, 0) + + for y := 0; y < len(duplicate); y++ { + for x := 0; x < len(duplicate[y]); x++ { + if x == posX && y == posY { + continue + } + + stepX := x - posX + stepY := y - posY + + gcd := GCD(stepY, stepX) + + if gcd == 0 { + if stepX > 0 { + stepX = 1 + } else if stepX < 0 { + stepX = -1 + } else if stepY > 0 { + stepY = 1 + } else if stepY < 0 { + stepY = -1 + } + } else { + stepX, stepY = stepX/gcd, stepY/gcd + } + + if v, ok := steps[stepX]; ok && v == stepY { + continue + } + steps[stepX] = stepY + + curX, curY := posX, posY + found := false + for true { + curX += stepX + curY += stepY + + if curY < 0 || curX < 0 || curY >= len(duplicate) || curX >= len(duplicate[curY]) { + break + } + + if duplicate[curY][curX] >= 0 { + //log.Printf("(%d,%d) from (%d,%d)", curX, curY, stepX, stepY) + if !found { + found = true + sum++ + } + duplicate[curY][curX] = -2 + } + } + } + } + + return +} + +func Copy2DSlice(matrix [][]int) (duplicate [][]int) { + duplicate = make([][]int, len(matrix)) + for i := range matrix { + duplicate[i] = make([]int, len(matrix[i])) + copy(duplicate[i], matrix[i]) + } + return +} + +// greatest common divisor (GCD) via Euclidean algorithm +func GCD(a, b int) int { + for b != 0 { + t := b + b = a % b + a = t + } + + if a < 0 { + a = a * -1 + } + + return a +}