re: AoC Day 2: Inventory Management System VIEW POST


Part 1 in Ruby:

have_two_letters = 0
have_three_letters = 0

File.open('./input.txt', 'r').each do |str|
  freq = str.split('').group_by(&:itself).map {|k,v| [v.size, k] }.to_h
  have_two_letters += 1 if freq[2]
  have_three_letters += 1 if freq[3]

puts have_three_letters * have_two_letters

I enjoyed playing around with the one liner

str.split('').group_by(&:itself).map {|k,v| [v.size, k] }.to_h

which produces a frequency chart something like this:

{1=>"j", 4=>"f", 2=>"s"}

i.e. there are exactly 2 occurrences of the letter s in str

Part 2 in Ruby

lines = File.read('./input.txt').split("\n");

def get_shared_letters(str1, str2)
  differences = 0
  same_letters = nil
  str1.split('').each_with_index do |letter, i|
    if letter != str2[i]
      differences += 1 
      same_letters = str1.dup

  differences === 1 ? same_letters : nil

lines.each_with_index do |str1, i1|
  lines.each_with_index do |str2, i2|
    next if i2 === i1

    shared = get_shared_letters str1, str2
    puts shared if shared

Not happy about the double loop through the input file... but also can't think of a way to avoid it! It occurred to me that sorting the list first might improve the chances of finding a match earlier in the loop since all similar strings would be together, but thinking about it, perhaps there's equal chance that the similar strings would end up being sorted to the bottom of the list and it wouldn't help at all :/

Another thought - many of the input strings are v. similar, maybe they could be grouped into sets early on (e.g. based on the first 4 chars or something) and then you only look for similar strings in the same set?

Going to read into hamming distances now!

Code of Conduct Report abuse