Last active
December 4, 2024 02:24
-
-
Save stilist/5bc42309fb92a220053cd683aacb1318 to your computer and use it in GitHub Desktop.
Advent of Code 2024
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 characters
File.read(File.expand_path('~/Downloads/day 1 input.txt')) | |
.split(/\n/) | |
.reduce([]) {|m,l|l.split.map(&:to_i).each_with_index.map {(m[_2]||[])<<_1}} | |
.map(&:sort) | |
.each_cons(2) | |
.map {_1.zip(_2)} | |
.flatten(1) | |
.map {(_1-_2).abs} | |
.sum |
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 characters
# The largest integer is 99, which fits in 7 bits (0-127) | |
INTEGER_BITS = 7 | |
# @see https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan | |
def popcount(n) | |
c = 0 | |
while n > 0 do | |
n &= n-1 | |
c += 1 | |
end | |
c | |
end | |
# Map a line like '61 63 64 67 69 72 74 81' to an array of integers, and map the integers into a | |
# continuous series of bits | |
def to_bitmap(levels) = levels.reduce(0) {(_1<<INTEGER_BITS)|_2} | |
def count_invalid_levels(bitmap, member_count, window) | |
# Compare integer N with integer N + window by shifting a copy right INTEGER_BITS * | |
# window bits | |
delta_from_previous_sample = ((bitmap&(0b1<<INTEGER_BITS*(member_count-window))-1)-(bitmap>>INTEGER_BITS)).abs | |
# `...member_count-1` excludes the leftmost member--the leftmost bitmap integer is implicitly | |
# compared with itself and thus will never differ | |
# | |
# XOR the bits of the rightmost member (after shifting) and see if the result is all 1s--if so | |
# the member is all 0s, meaning it matches the previous member | |
unchanged = (0...member_count-1).reduce(0) {_1<<(INTEGER_BITS*_2)|(((delta_from_previous_sample>>INTEGER_BITS*_2)^0b1111111)&0b1111111==0b1111111?1:0)} | |
# Mask off bits 1 and 2, equivalent to decimal 0-3; ANDing with it will preserve bitmap members | |
# larger than 3 | |
only_unsafe = delta_from_previous_sample&0b1111100_1111100_1111100_1111100_1111100_1111100_1111100_1111100 | |
# `#reduce` ensures that a bit set anywhere in bits 3-7 ends up filling bit 1 so the mask | |
# detects it | |
unsafe = (1...INTEGER_BITS).reduce(only_unsafe) {_1|_1>>_2}&0b0000001_0000001_0000001_0000001_0000001_0000001_0000001_0000001 | |
popcount(unchanged|unsafe) | |
end | |
def process(input) | |
input.split(/\n/) | |
.map {_1.split.map(&:to_i)} | |
.select{(to_bitmap(_1)-to_bitmap(_1.sort)==0?1:0)<<1|(to_bitmap(_1)-to_bitmap(_1.sort.reverse)==0?1:0)&0b11>0} | |
.map{[to_bitmap(_1),_1.count]} | |
.filter{count_invalid_levels(*_1, 1)==0} | |
.length | |
end | |
puts process(File.read(File.expand_path('~/Downloads/day 2 input.txt'))) | |
#=> 598 | |
puts process('7 6 4 2 1 | |
1 2 7 8 9 | |
9 7 6 2 1 | |
1 3 2 4 5 | |
8 6 4 4 1 | |
1 3 6 7 9') | |
#=> 2 |
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 characters
File.read(File.expand_path('~/Downloads/day 2 input.txt')) | |
.split(/\n/) | |
.map {_1.split.map(&:to_i)} | |
.filter {_1 ==_1.sort||_1 == _1.sort.reverse} | |
.filter {|r|r.each_cons(2).filter {(_1-_2).abs<1||(_1-_2).abs>3}.empty?} | |
.length |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment