Compare commits

...

2 Commits

Author SHA1 Message Date
Danila Fedorin bbaedda944 Add day 14 solution in Chapel 2022-12-13 21:58:59 -08:00
Danila Fedorin 7fed659932 Add day 14 solutions 2022-12-13 21:26:38 -08:00
3 changed files with 178 additions and 0 deletions

67
day14.chpl Normal file
View File

@ -0,0 +1,67 @@
use IO, Set;
proc parseCoord(s: string) {
const (x, _, y) = s.partition(",");
return (x : int, y : int);
}
proc (set((int,int))).draw((x1, y1), (x2, y2)) {
for x in (min(x1,x2)..max(x1,x2)) {
for y in (min(y1,y2)..max(y1,y2)) {
this.add((x,y));
}
}
}
iter ((int,int)).nextPositions() {
yield this + (0,1);
yield this + (-1,1);
yield this + (1,1);
}
var occupied = new set((int, int));
for line in stdin.lines().strip() {
const coords = parseCoord(line.split(" -> "));
for idx in 0..#(coords.size-1) {
occupied.draw(coords[idx], coords[idx+1]);
}
}
const maxHeight = max reduce [(x, y) in occupied] y;
const initialPos = (500, 0);
config const hasWall = false;
var grainCount = 0;
do {
// Start a new grain of sand, but give up if there's already one there.
var pos = initialPos;
if occupied.contains(pos) then break;
// Make the grain fall
var abyss = false;
do {
var moved = false;
for checkPos in pos.nextPositions() {
// Check for falling past the floor
if checkPos[1] > maxHeight + 10 {
abyss = true;
break;
}
// Try moving, but only if the position is clear and not on the floor.
if !occupied.contains(checkPos) &&
!(hasWall && checkPos[1] == maxHeight + 2) {
pos = checkPos;
moved = true;
break;
}
}
} while moved;
// If we stopped because we fell off, don't count the last grain.
if !abyss {
grainCount += 1;
occupied.add(pos);
}
} while !abyss;
writeln(grainCount);

57
day14a.cr Normal file
View File

@ -0,0 +1,57 @@
require "advent"
INPUT = input(2022, 14).lines
occupied = {} of Tuple(Int32, Int32) => Bool
INPUT.each do |line|
points = line.split("->").map &.split(",").map(&.to_i32)
points.each_cons_pair do |p1,p2|
x1, y1 = p1
x2, y2 = p2
dx = (x2-x1).sign
dy = (y2-y1).sign
((x2-x1).abs+1).times do |nx|
((y2-y1).abs+1).times do |ny|
pos = {x1 + nx*dx, y1 + ny*dy}
occupied[pos] = true
end
end
end
end
max_height = occupied.max_of do |k,v|
x, y = k
y
end
puts "Max height: #{max_height}"
def each_place(pos, &block)
x, y = pos
yield ({x+1, y+1})
yield ({x-1, y+1})
yield ({x, y+1})
end
puts occupied
count = 0
overflow = false
until overflow
pos = {500, 0}
moved = false
loop do
moved = false
each_place(pos) do |check|
next if occupied[check]?
pos = check
moved = true
end
overflow = true if pos[1] > max_height
break unless moved
break if overflow
end
occupied[pos] = true
count += 1
end
puts count-1

54
day14b.cr Normal file
View File

@ -0,0 +1,54 @@
require "advent"
INPUT = input(2022, 14).lines
occupied = {} of Tuple(Int32, Int32) => Bool
INPUT.each do |line|
points = line.split("->").map &.split(",").map(&.to_i32)
points.each_cons_pair do |p1,p2|
x1, y1 = p1
x2, y2 = p2
dx = (x2-x1).sign
dy = (y2-y1).sign
((x2-x1).abs+1).times do |nx|
((y2-y1).abs+1).times do |ny|
pos = {x1 + nx*dx, y1 + ny*dy}
occupied[pos] = true
end
end
end
end
max_height = occupied.max_of do |k,v|
x, y = k
y
end
puts "Max height: #{max_height}"
def each_place(pos, &block)
x, y = pos
yield ({x+1, y+1})
yield ({x-1, y+1})
yield ({x, y+1})
end
puts occupied
count = 0
until occupied[{500,0}]?
pos = {500, 0}
moved = false
loop do
moved = false
each_place(pos) do |check|
next if occupied[check]? || check[1] == max_height+2
pos = check
moved = true
end
break unless moved
end
occupied[pos] = true
count += 1
end
puts count