diff --git a/day10.cr b/day10.cr new file mode 100644 index 0000000..698c1fd --- /dev/null +++ b/day10.cr @@ -0,0 +1,37 @@ +require "advent" +INPUT = input(2020, 10).lines.map(&.to_i32).sort! + +def part1(input) + diff_1 = 0 + diff_3 = 0 + curr = 0 + input << (input.max + 3) + input.each do |i| + diff_1 += 1 if (i - curr) == 1 + diff_3 += 1 if (i - curr) == 3 + curr = i + end + puts diff_1 * diff_3 +end + +def count_ways(input, prev, index, mem, indent = 0) + if m = mem[{prev, index}]? + return m + end + return 0_i64 if input[index] - prev > 3 || index >= input.size + return 1_i64 if index == input.size - 1 + + total = count_ways(input, input[index], index+1, mem, indent + 1) + total += count_ways(input, prev, index+1, mem, indent + 1) + + mem[{prev, index}] = total + return total +end + +def part2(input) + input << (input.max + 3) + count_ways(input, 0, 0, {} of {Int32, Int32} => Int64) +end + +puts part1(INPUT.clone) +puts part2(INPUT.clone) diff --git a/day11.cr b/day11.cr new file mode 100644 index 0000000..e81fca4 --- /dev/null +++ b/day11.cr @@ -0,0 +1,64 @@ +require "advent" +INPUT = input(2020, 11).lines.map(&.chars) + +abstract class Search + def search(current, x, y, dx, dy) + x, y = x + dx, y + dy + return 0 if y < 0 || y >= current.size + return 0 if x < 0 || x >= current[y].size + search_impl(current,x,y,dx,dy) + end + + abstract def search_impl(current, x, y, dx, dy) +end + +class FirstSearch < Search + def search_impl(current, x, y, dx, dy) + return current[y][x] == '#' ? 1 : 0 + end +end + +class SecondSearch < Search + def search_impl(current, x, y, dx, dy) + return 1 if current[y][x] == '#' + return 0 if current[y][x] == 'L' + return search(current, x, y, dx, dy) + end +end + +DIRS = [{-1,-1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1,1}] + +def step(current, step, check, n) + current.each_with_index do |row, y| + row.each_with_index do |seat, x| + step[y][x] = current[y][x] + count = DIRS.sum do |dx, dy| + check.search(current, x, y, dx, dy) + end + step[y][x] = 'L' if seat == '#' && count >= n + step[y][x] = '#' if seat == 'L' && count == 0 + end + end + {step, current} +end + +def run(input, search, n) + current = input + step = input.clone + loop do + current, step = step(current, step, search, n) + break if current.zip_with(step) { |l, r| l == r }.all? + end + current.sum(&.count(&.==('#'))) +end + +def part1(input) + run(input, FirstSearch.new, 4) +end + +def part2(input) + run(input, SecondSearch.new, 5) +end + +puts part1(INPUT.clone) +puts part2(INPUT.clone)