Last active
December 15, 2022 04:55
-
-
Save DavidEGrayson/d7466b6d2356e05f820706b0175ffa7d to your computer and use it in GitHub Desktop.
Revisions
-
DavidEGrayson revised this gist
Dec 15, 2022 . 1 changed file with 122 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,122 @@ # SLOWER VERSION OF MY CODE that uses a "hash set". $width = 1000 $height = 200 $rocks = {} $sand = {} def coords_in_bounds?(coords) (0...$width).include?(coords[0]) && (0...$height).include?(coords[1]) end def read(coords) return '#' if $rocks[coords] return 'o' if $sand[coords] ' ' end def draw(coords, char) raise if !coords_in_bounds?(coords) #$rocks.delete(coords) #$sand.delete(coords) $rocks[coords.dup.freeze] = true if char == '#' $sand[coords.dup.freeze] = true if char == 'o' end def draw_rock_line(start, dest) start = start.dup while true draw(start, '#') if start[0] < dest[0] start[0] += 1 elsif start[0] > dest[0] start[0] -= 1 elsif start[1] < dest[1] start[1] += 1 elsif start[1] > dest[1] start[1] -= 1 else break end end end # NOT NEEDED TO SOLVE THE PROBLEM. This is just for testing the slow/naive way. def add_sand(start) coords = start while true grain_fell = false support_coords = [ [coords[0], coords[1] + 1], [coords[0] - 1, coords[1] + 1], [coords[0] + 1, coords[1] + 1], ] support_coords.each do |sc| return false if !coords_in_bounds?(sc) if read(sc) == ' ' coords = sc grain_fell = true break end end if !grain_fell draw(coords, 'o') return true end end end # NOT NEEDED TO SOLVE THE PROBLEM. This is just for testing the slow/naive way. def slow_fill(coords) while read(coords) == ' ' add_sand(coords) or return end end # Fast recursive function that tries to place a sand grain at the specified # point by recursively filling the three spots in the row below that support it. # Returns true if successful. def fill(coords) x, y = coords if !coords_in_bounds?(coords) false elsif '#o'.include?(read(coords)) true elsif fill([x, y + 1]) && fill([x - 1, y + 1]) && fill([x + 1, y + 1]) draw(coords, 'o') true else draw(coords, '~') false end end File.foreach('input.txt') do |line| coord_strings = line.split(' -> ') coords = nil coord_strings.each do |coord_string| next_coords = coord_string.split(',').map(&:to_i) raise if next_coords.size != 2 draw_rock_line(coords, next_coords) if coords coords = next_coords end end # Part 2, with hardcoded floor height. draw_rock_line([0, 184], [$width - 1, 184]) # fill([500, 0]) slow_fill([500, 0]) #$world.each_line { |line| puts line[450..600] } (0...$height).each do |y| (450...600).each do |x| print read([x, y]) end puts end puts $sand.size -
DavidEGrayson created this gist
Dec 15, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,106 @@ $width = 1000 $height = 200 $world = (' ' * $width + "\n") * $height def coords_in_bounds?(coords) (0...$width).include?(coords[0]) && (0...$height).include?(coords[1]) end def read(coords) raise if !coords_in_bounds?(coords) $world[coords[1] * ($width + 1) + coords[0]] end def draw(coords, char) raise if !coords_in_bounds?(coords) $world[coords[1] * ($width + 1) + coords[0]] = char end def draw_rock_line(start, dest) start = start.dup while true draw(start, '#') if start[0] < dest[0] start[0] += 1 elsif start[0] > dest[0] start[0] -= 1 elsif start[1] < dest[1] start[1] += 1 elsif start[1] > dest[1] start[1] -= 1 else break end end end # NOT NEEDED TO SOLVE THE PROBLEM. This is just for testing the slow/naive way. def add_sand(start) coords = start while true grain_fell = false support_coords = [ [coords[0], coords[1] + 1], [coords[0] - 1, coords[1] + 1], [coords[0] + 1, coords[1] + 1], ] support_coords.each do |sc| return false if !coords_in_bounds?(sc) if read(sc) == ' ' coords = sc grain_fell = true break end end if !grain_fell draw(coords, 'o') return true end end end # NOT NEEDED TO SOLVE THE PROBLEM. This is just for testing the slow/naive way. def slow_fill(coords) add_sand(coords) while read(coords) == ' ' end # Fast recursive function that tries to place a sand grain at the specified # point by recursively filling the three spots in the row below that support it. # Returns true if successful. def fill(coords) x, y = coords if !coords_in_bounds?(coords) false elsif '#o'.include?(read(coords)) true elsif fill([x, y + 1]) && fill([x - 1, y + 1]) && fill([x + 1, y + 1]) draw(coords, 'o') true else draw(coords, '~') false end end File.foreach('input.txt') do |line| coord_strings = line.split(' -> ') coords = nil coord_strings.each do |coord_string| next_coords = coord_string.split(',').map(&:to_i) raise if next_coords.size != 2 draw_rock_line(coords, next_coords) if coords coords = next_coords end end # Part 2, with hardcoded floor height. draw_rock_line([0, 184], [$width - 1, 184]) fill([500, 0]) # slow_fill([500, 0]) $world.each_line { |line| puts line[450..600] } puts $world.count('o')