OK, the first day was awesome, I'm super excited about all of the solutions people posted. And I'm learning a lot! We've got a solid 20 people on the DEV leaderboard, which means there are still spots for 180 more -- use code 224198-25048a19 to join!
On to Day 2!
Day 2 of Advent of Code, and I'm pretty sure that Google is tired of me asking it questions every 15 seconds about "How Do I Do X in Rust."
Today's challenge involves an inventory system. Boxes have IDs that are a jumble of letters, and we've got a warehouse full of boxes to check. The first part asks us to analyze the frequency of letters in each ID. The second part gets into Hamming Distances, which are a familiar sight after mentoring on Exercism.
I got both parts working, and even part 2 ran pretty fast, but I'm not algorithmically happy with the double-loop (O(n^2)) runtime. Did anybody come up with anything tricky to do it more efficiently?
I'm going to post my solution in the comments like the rest of the cool kids.
How'd everybody else do?
Oldest comments (64)
Part 1
You can probably see my Python shining through as I implemented a custom Counter struct to help me out.
Part 2
Double for loop boooooooo! But it works and it's fast enough for now. I'm pretty happy with the mileage I got out of Iterators for this part.
I love how you've used enumerate and skip together in your nested for loop. I struggled to find a clean solution like this.
Thanks! Yeah, I originally had a very manual nested for-loop set up, but after I got the tests passing, I decided to make an effort to do everything I could with iterators instead :) I've decided that the iterator module in Rust is where most of the magic that I'm missing from Python and Ruby lives.
This was still bothering me, but I found the
Itertoolscrate and thetuple_combinationsmethod. Check out my updated solution in the thread.Itertoolsmakes iterators even more powerful.This is very well documented and clear, easy-to-read code. This also makes me want to jump into Rust again (I've only hobbied around with it here and there).
Thanks! That really encouraging!
PHP
Ended up learning about a bunch of useful array functions like
array_values,array_count_valuesandarray_diff_assocfor this one!Part 1:
Part 2:
I lost about 10 minutes to my son stalling getting into bed.
Kotlin Solution
Answer 1
Once again a fairly straightforward opener. Just run through, do some simple frequency checking and spit back the results. I think this is technically O(n2) but it moved fast enough for me. (And in a more lazy language, it ends up being closer to O(n) anyway)
Answer 2
As Ryan said, this is just Hamming distance with the added wrinkle that you need to throw away the differences while counting them. Lots of optimization room here, but once again, we shave off just under half the possibilities by only doing unique combinations and going from a raw
n^2to(n*(n+1))/2.At around 10 ms (calculated by shuffling my input 1000 times), I don't think there's an easy way to make this noticeably faster at this point without a more esoteric method.
Part 1
Part 2
And from the output, I just copied and pasted the necessary characters that matched. That was faster than comming up with a custom method to do so.
Nice! Did you implement editdistance yourself, or is that an external library?
It is external. I found it via a quick google search. The edit distance measures how many operations - insertion, deletion or substitution - it takes to get from one string to the other. Since all the strings in the puzzle input have the same length, insertion and deletion do not come into play and it works out perfectly.
Ok thatโs cool, just checking. Neat!
We need better cover images ๐
I was kind of hoping that the magical resizing was an automated resizing thing that happens and not one of you guys fixing it for me. I can actually put a background on it and scale it. What are the optimal dimensions? Is the white text on black ok or should I come up with something more fancy? I have very little aesthetic skill, so Iโd appreciate any suggestions you or anyone else has.
Ryan, do you want me to design something? The only hard part is that I probably won't be up at midnight most nights to add specifics. Do you have any design software? If so, I can transfer you a file! We could also use Canva.
That would be amazing! I have a Figma account, but thatโs it. Iโve never heard of Canva and pretty sure I donโt have any design software, but if you tell me the best way to handle it, Iโll happily do whatever you suggest. Iโm happy to learn.
Cool -- sending you a DM via /connect!
Part 1 in Ruby:
I enjoyed playing around with the one liner
which produces a frequency chart something like this:
i.e. there are exactly 2 occurrences of the letter s in
strPart 2 in Ruby
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!
I am using Advent of Code to learn Golang, and here is the solution I came up with. Suggestions for improvements are always welcome!
Part 1:
Part 2:
My idea was to use a dictionary and store the subnames and see if we encounter one we have already visited. Since there should only be one match we can immediately return it. I learned a lot about using maps in Golang!
I am also using Python that I have more experience with to cross check solutions. I have tried to implement it with readability in mind, not performance.
Part 1:
Part 2:
My solution with Python, not sure about the second part, not the most fastest solution I think regarding of performance.
Nice! Donโt forget about collections.Counter for part 1! I didnโt know about difflib though. Cool!
Thanks for the hint! Will do that later!
My edited solution for part one with collections Counter
Python solutions!
part 1
part 2 -- this one feels clunky to me.
My part one ended up looking super similar!
I ended up using
zipto help with the comparison if the strings in part 2: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!
True!
10 points for the variable name โthrice!โ
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.
So this was a pain. I also ended up with a double loop (O(n2)) and couldn't think of anything better.
One thing I discovered during part two was that Crystal has Levenshtein distance as part of the standard library. It might have been a bit heavy going for what I needed, but it did the trick!
Bring on day 3!
High five for a beefy standard library! Thatโs awesome ๐