Skip to content

Instantly share code, notes, and snippets.

@mgates
Created December 12, 2019 13:55
Show Gist options
  • Save mgates/4b6c647a18cfcb5acdc315ebf8fa693b to your computer and use it in GitHub Desktop.
Save mgates/4b6c647a18cfcb5acdc315ebf8fa693b to your computer and use it in GitHub Desktop.
advent 2019 day 10
require 'set'
class Ug
def foo(input)
astroids = Set.new
input.lines.map(&:chomp).each_with_index do |line, x|
line.chars.each_with_index do |char, y|
astroids << [y,x] if char == "#"
end
end
counts = {}
astroids.each_with_index do |station, idx|
puts "#{idx} / #{astroids.count}"
sights = (astroids - [station]).find_all do |candidate|
((astroids - [station]) - [candidate]).none? do |blocker|
is_blocked = is_blocked?(station, candidate, blocker)
is_blocked
end
end
#puts "#{station}: #{sights}"
counts[station] = sights.count
end
puts counts.sort_by(&:last).to_h.inspect
end
def is_blocked?(station, candidate, blocker)
return false if station == blocker
return false if candidate == blocker
station_to_blocker = dist(station.first, station.last, blocker.first, blocker.last)
blocker_to_candidate = dist(blocker.first, blocker.last, candidate.first, candidate.last)
is_blocked = dist(station.first, station.last, candidate.first, candidate.last).round(5) == (station_to_blocker + blocker_to_candidate).round(5)
end
def slope(xa, ya, xb, yb)
(yb.to_f - ya.to_f) / (xb.to_f - xa.to_f)
rescue ZeroDivisionError
-Float::INFINITY
end
def dist(xa, ya, xb, yb)
((xb - xa)**2 + (yb - ya)**2) ** 0.5
end
Astroid = Struct.new(:x, :y, :slope, :dist)
def do_it_better(input, station)
station = Astroid.new(station.first, station.last, nil, nil)
astroids = Set.new
input.lines.map(&:chomp).each_with_index do |line, y|
line.chars.each_with_index do |char, x|
astroids << Astroid.new(x, y, slope(station.x, station.y, x, y), dist(station.x, station.y, x, y)) if char == "#"
end
end
astroids.reject!{|ast| ast.x == station.x && ast.y == station.y}
max_x = astroids.max_by(&:x)
max_y = astroids.max_by(&:y)
vaporized_count = 0
top_right = astroids.find_all {|ast| ast.x >= station.x && ast.y <= station.y}
bottom_right = astroids.find_all {|ast| ast.x >= station.x && ast.y > station.y}
bottom_left = astroids.find_all {|ast| ast.x < station.x && ast.y > station.y}
top_left = astroids.find_all {|ast| ast.x < station.x && ast.y <= station.y}
puts top_right.group_by(&:slope).sort_by(&:first).map{|s,opts| opts.min_by(&:dist)}#.map{|slope, opts| opts.sort_by(&:dist)}
puts bottom_right.group_by(&:slope).sort_by(&:first).map{|s,opts| opts.min_by(&:dist)}#.map{|slope, opts| opts.sort_by(&:dist)}
puts bottom_left.group_by(&:slope).sort_by(&:first).map{|s,opts| opts.min_by(&:dist)}#.map{|slope, opts| opts.sort_by(&:dist)}
puts top_left.group_by(&:slope).sort_by(&:first).map{|s,opts| opts.min_by(&:dist)}#.map{|slope, opts| opts.sort_by(&:dist)}
end
def depricated
#ug, just convert to polar coord
while true
puts "ROTATION"
exit if vaporized_count > 210
last_angle = nil
#first 1/8th
(station.first.upto(max_x)).each do |x|
(0.upto(station.last)).each do |y|
puts "Checking #{[x, y].inspect}"
next unless astroids.include?([x,y])
puts "it's an astroid"
slope = slope(station.first, station.last, x, y)
if slope != :it_s_cool
if slope > -1
next
end
end
puts "it's in the zone"
next if astroids.any? do |blocker|
is_blocked?(station, [x,y], blocker)
end
next if last_angle == slope
last_angle = slope
vaporized_count += 1
puts "BAM #{vaporized_count}:#{slope} : #{[x,y].inspect}"
astroids.delete([x,y])
end
end
# next quarter
(0.upto(max_y)).each do |y|
(max_x.downto(station.first)).each do |x|
next unless astroids.include?([x,y])
slope = slope(station.first, station.last, x, y)
next if slope > 1
next if astroids.any? do |blocker|
is_blocked?(station, [x,y], blocker)
end
next if last_angle == slope
last_angle = slope
vaporized_count += 1
puts "#{vaporized_count}:#{slope} : #{[x,y].inspect}"
astroids.delete([x,y])
end
end
# next (bottom) quarter
(max_x.downto(station.first)).each do |x|
(max_y.downto(0)).each do |y|
next unless astroids.include?([x,y])
slope = slope(station.first, station.last, x, y)
if slope != :it_s_cool
if slope > -1
next
end
end
next if astroids.any? do |blocker|
is_blocked?(station, [x,y], blocker)
end
next if last_angle == slope
last_angle = slope
vaporized_count += 1
puts "#{vaporized_count}:#{slope} : #{[x,y].inspect}"
astroids.delete([x,y])
end
end
# next (left) quarter
(0.upto(station.first)).each do |x|
(max_y.downto(0)).each do |y|
next unless astroids.include?([x,y])
slope = slope(station.first, station.last, x, y)
next if slope > -1
next if astroids.any? do |blocker|
is_blocked?(station, [x,y], blocker)
end
next if last_angle == slope
last_angle = slope
vaporized_count += 1
puts "#{vaporized_count}:#{slope} : #{[x,y].inspect}"
astroids.delete([x,y])
end
end
# last 8th
(0.upto(station.last)).each do |y|
(0.upto(station.first)).each do |x|
next unless astroids.include?([x,y])
slope = slope(station.first, station.last, x, y)
next if slope > -1
next if astroids.any? do |blocker|
is_blocked?(station, [x,y], blocker)
end
next if last_angle == slope
last_angle = slope
vaporized_count += 1
puts "#{vaporized_count}:#{slope} : #{[x,y].inspect}"
astroids.delete([x,y])
end
end
end
end
end
#Ug.new.foo(ARGF.read)
Ug.new.do_it_better(ARGF.read, [26, 29])
#Ug.new.do_it_better(ARGF.read, [11, 13])
.#..#
.....
#####
....#
...##
......#.#.
#..#.#....
..#######.
.#.#.###..
.#..#.....
..#....#.#
#..#....#.
.##.#..###
##...#..#.
.#....####
#.#...#.#.
.###....#.
.#....#...
##.#.#.#.#
....#.#.#.
.##..###.#
..#...##..
..##....##
......#...
.####.###.
.#..##.###...#######
##.############..##.
.#.######.########.#
.###.#######.####.#.
#####.##.#.##.###.##
..#####..#.#########
####################
#.####....###.#.#.##
##.#################
#####.##.###..####..
..######..##.#######
####.##.####...##..#
.#####..#.######.###
##...#.##########...
#.##########.#######
.####.#.###.###.#.##
....##.##.###..#####
.#.#.###########.###
#.#.#.#####.####.###
###.##.####.##.#..##
#.....#...#.........###.#........#..
....#......###..#.#.###....#......##
......#..###.......#.#.#.#..#.......
......#......#.#....#.##....##.#.#.#
...###.#.#.......#..#...............
....##...#..#....##....#...#.#......
..##...#.###.....##....#.#..##.##...
..##....#.#......#.#...#.#...#.#....
.#.##..##......##..#...#.....##...##
.......##.....#.....##..#..#..#.....
..#..#...#......#..##...#.#...#...##
......##.##.#.#.###....#.#..#......#
#..#.#...#.....#...#...####.#..#...#
...##...##.#..#.....####.#....##....
.#....###.#...#....#..#......#......
.##.#.#...#....##......#.....##...##
.....#....###...#.....#....#........
...#...#....##..#.#......#.#.#......
.#..###............#.#..#...####.##.
.#.###..#.....#......#..###....##..#
#......#.#.#.#.#.#...#.#.#....##....
.#.....#.....#...##.#......#.#...#..
...##..###.........##.........#.....
..#.#..#.#...#.....#.....#...###.#..
.#..........#.......#....#..........
...##..#..#...#..#...#......####....
.#..#...##.##..##..###......#.......
.##.....#.......#..#...#..#.......#.
#.#.#..#..##..#..............#....##
..#....##......##.....#...#...##....
.##..##..#.#..#.................####
##.......#..#.#..##..#...#..........
#..##...#.##.#.#.........#..#..#....
.....#...#...#.#......#....#........
....#......###.#..#......##.....#..#
#..#...##.........#.....##.....#....
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment