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