DEV Community

Discussion on: AoC Day 2: Inventory Management System

Collapse
 
aspittel profile image
Ali Spittel

Python solutions!

part 1

from collections import Counter

with open('input.txt', 'r') as f:
    twice = 0
    thrice = 0
    for line in f:
        counts = Counter(line).values()
        if 2 in counts:
            twice += 1
        if 3 in counts:
            thrice += 1
    print(twice * thrice)

part 2 -- this one feels clunky to me.

with open('input.txt', 'r') as f:
    boxes = [box.strip() for box in f]

def check_differences(box1, box2):
    difference_idx = -1
    for idx, letter in enumerate(box1):
        if letter != box2[idx]:
            if difference_idx < 0:
                difference_idx = idx
            else:
                return False
    return box1[0:difference_idx] + box1[difference_idx+1:]


def find_one_difference(boxes):
    for idx, box in enumerate(boxes):
        for box2 in boxes[idx+1:]:
            diff = check_differences(box, box2)
            if diff:
                return diff

print(find_one_difference(boxes))
Collapse
 
jbristow profile image
Jon Bristow

As a lispy thinker, my brain wants to tell you to make those for loops into comprehensions, but my work brain is telling me that my coworkers would have me drawn and quartered to make your "find-one-difference" a one-liner!

Kudos on how neat this looks. I find python and ruby to be difficult to make look "clean" when I write it.

Collapse
 
rpalo profile image
Ryan Palo

10 points for the variable name β€œthrice!”

Collapse
 
easyaspython profile image
Dane Hillard

My part one ended up looking super similar!

#!/usr/bin/env python

from collections import Counter


if __name__ == '__main__':
    box_ids_with_two_duplicate_letters = 0
    box_ids_with_three_duplicate_letters = 0
    with open('1-input.txt') as box_file:
        for box_id in box_file:
            fingerprint = Counter(box_id)
            if 2 in fingerprint.values():
                box_ids_with_two_duplicate_letters += 1
            if 3 in fingerprint.values():
                box_ids_with_three_duplicate_letters += 1

    print(box_ids_with_two_duplicate_letters * box_ids_with_three_duplicate_letters)

I ended up using zip to help with the comparison if the strings in part 2:

#!/usr/bin/env python

from collections import Counter


def find_similar_box_ids(all_box_ids):
    for box_id_1 in all_box_ids:
        for box_id_2 in all_box_ids:
            # This is kind of a naive Levenshtein distance!
            letter_pairs = zip(box_id_1, box_id_2)
            duplicates = list(filter(lambda pair: pair[0] == pair[1], letter_pairs))
            if len(duplicates) == len(box_id_1) - 1:
                return ''.join(pair[0] for pair in duplicates)


if __name__ == '__main__':
    with open('2-input.txt') as box_file:
        all_box_ids = box_file.read().splitlines()
    print(find_similar_box_ids(all_box_ids))
Collapse
 
aspittel profile image
Ali Spittel

Nice! Definitely think that's the easiest way to do number 1. Zip also makes sense for the second, though not using it allowed me to do the early return!

Thread Thread
 
easyaspython profile image
Dane Hillard

True!