feat: Day 3
This commit is contained in:
parent
a216d73e9e
commit
e7795b324e
2 changed files with 76 additions and 0 deletions
34
puzzles/03_1/main.rb
Normal file
34
puzzles/03_1/main.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
def run(f)
|
||||||
|
len = 0
|
||||||
|
bits = []
|
||||||
|
|
||||||
|
f.each do |line|
|
||||||
|
if len == 0
|
||||||
|
# Skip the trailing newline character and convert to 0-based index
|
||||||
|
len = line.length() - 2
|
||||||
|
0.upto(len) { |n| bits[n] = [0, 0] }
|
||||||
|
end
|
||||||
|
|
||||||
|
len.downto(0) { |n|
|
||||||
|
digit = Integer(line[n])
|
||||||
|
bits[n][digit] += 1
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
gamma = 0
|
||||||
|
epsilon = 0
|
||||||
|
|
||||||
|
len.downto(0) { |n|
|
||||||
|
# Since we iterated from left to right on the input
|
||||||
|
# we need to do the same when building the integers
|
||||||
|
width = len - n
|
||||||
|
|
||||||
|
if bits[n][0] > bits[n][1]
|
||||||
|
gamma += 1 << width
|
||||||
|
else
|
||||||
|
epsilon += 1 << width
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
return gamma * epsilon
|
||||||
|
end
|
42
puzzles/03_2/main.rb
Normal file
42
puzzles/03_2/main.rb
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
def find(lines, index, search)
|
||||||
|
if index > (lines.first.length() - 2)
|
||||||
|
raise "Invalid index"
|
||||||
|
end
|
||||||
|
|
||||||
|
bits = [0, 0]
|
||||||
|
|
||||||
|
# Count the occurrences of each digit at the index
|
||||||
|
lines.each do |line|
|
||||||
|
digit = Integer(line[index])
|
||||||
|
bits[digit] += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# Not the most expressive way to do this, but should get the job done
|
||||||
|
if search == 1
|
||||||
|
# Return most common value, or 1 on a tie
|
||||||
|
target = bits[0] > bits[1] ? 0 : 1
|
||||||
|
else
|
||||||
|
# Return least common value, or 0 on a tie
|
||||||
|
target = bits[0] <= bits[1] ? 0 : 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# Filter lines to only the ones that have the target value at `index`
|
||||||
|
lines = lines.filter { |line| line[index] == target.to_s }
|
||||||
|
|
||||||
|
# If there's only one left, we found our value.
|
||||||
|
# Otherwise, continue filtering at the next index
|
||||||
|
if lines.length() == 1
|
||||||
|
return lines.first
|
||||||
|
else
|
||||||
|
return find(lines, index + 1, search)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run(f)
|
||||||
|
lines = f.readlines()
|
||||||
|
# This should filter down to a single number, which we need to convert from a base 2 bit string
|
||||||
|
oxygen = find(lines, 0, 1).to_i(2)
|
||||||
|
co2 = find(lines, 0, 0).to_i(2)
|
||||||
|
|
||||||
|
return oxygen * co2
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue