aboutsummaryrefslogtreecommitdiff
path: root/day10/part2
diff options
context:
space:
mode:
Diffstat (limited to 'day10/part2')
-rwxr-xr-xday10/part2101
1 files changed, 101 insertions, 0 deletions
diff --git a/day10/part2 b/day10/part2
new file mode 100755
index 0000000..f931a36
--- /dev/null
+++ b/day10/part2
@@ -0,0 +1,101 @@
+#!/usr/bin/env ruby
+
+input = $stdin.readlines.map(&:strip).map(&:chars)
+ .map{ |l| l.map{ |c| c == "#" } }
+
+H = input.length
+W = input[0].length
+
+def count(grid, x, y, angles)
+ c = 0
+ angles.each do |dx, dy|
+ tx = x
+ ty = y
+ loop do
+ tx += dx
+ ty += dy
+ break if tx < 0 || tx >= W
+ break if ty < 0 || ty >= H
+ if grid[ty][tx] then
+ c += 1
+ break
+ end
+ end
+ end
+ c
+end
+
+def rotate(n, arr)
+ arr.map do |x, y|
+ case n
+ when 1
+ [-y, x]
+ when 2
+ [-x, -y]
+ when 3
+ [y, -x]
+ end
+ end
+end
+
+def coords_of(n, grid, x, y, angles)
+ c = 0
+ loop do
+ tx = x
+ ty = y
+ angles.each do |dx, dy|
+ s = 1
+ loop do
+ tx = x + s*dx
+ ty = y + s*dy
+ break if tx < 0 || tx >= W
+ break if ty < 0 || ty >= H
+ if grid[ty][tx] then
+ c += 1
+ return [tx, ty] if c == 200
+ break
+ else
+ s += 1
+ end
+ end
+ end
+ end
+end
+
+angles = []
+(0...W).each do |x|
+ (0...H).each do |y|
+ angles << [x, -y] if x.gcd(y) == 1
+ end
+end
+
+angles.sort! do |a,b|
+ b[0].to_f/b[1] <=> a[0].to_f/a[1]
+end
+
+angles.shift
+
+angles = angles +
+ rotate(1, angles) +
+ rotate(2, angles) +
+ rotate(3, angles)
+
+maxcount = 0
+stationx = nil
+stationy = nil
+(0...H).each do |y|
+ (0...W).each do |x|
+ if input[y][x] then
+ c = count(input, x, y, angles)
+ if c > maxcount
+ maxcount = c
+ stationx = x
+ stationy = y
+ end
+ end
+ end
+end
+
+asteroid200 = coords_of(200, input, stationx, stationy, angles)
+
+puts (100 * asteroid200[0]) + asteroid200[1]