Overview
My Solution
DEV Leaderboards
Overview
After my post last night, @aspittel suggested that we start a daily discussion post ch...
For further actions, you may consider blocking this person and/or reporting abuse
So excited about this 🙌🏻!
Python
Part 1
Part 2
I also learned about itertools.cycle through reading the Reddit solutions, that would make it so that I don't need the
while True:
Ah! So good. The clean-ness of Python never stops making me happy!
Using a
set
was a good idea. I didn't think of that, but it would be a lot faster for checking whether or not an item was present.I'm going to offer unsolicited suggestions, but feel free to totally ignore them if you already knew about them (probable) or don't like them, since your solution already looks really nice.
Awesome! Yes, thank you! Found out about itertools.cycle this morning -- feels super niche but still really cool.
Part one could also be a one-liner!
I'd also suggest to use a context manager (the
with
keyword) for clean opening and closing of files.Part 1:
Part 2:
Also: "Hey checkout my Github Repo!"
True! Always forget to do that since I really only do file handling for code challenges at this point.
Golang solution
Part 1
Part 2
I also wrote solutions in Python that look very similar to Ali's, so I decided to run a little benchmark test using today's input from the Advent of Code website. Here are the results
Woah, nice! Am I reading this right, that the Python is significantly faster than Go? Or is this including compilation each time?
Python is significantly faster than running
go run myfile.go
. However, that's not Go's intended use case, really. That's more for debugging along the way, sincego run
does include the compilation each time.I think it's interesting to compare the difference between
go run
and executing the compiled go executable, so the third set of each (ex:./1_1
) is go running the resulting compiled executable 100 times.Ooooh ok that makes sense. Cool!
Also, I am not a regular Go programmer. I've started doing challenges in Go just for my own amusement, but I would definitely not assume that whatever solution I come up with is optimal 😅
Hi jess!
Just a small advert: you should defer f.Close() after check if there's an error.
Also: Check out my GitHub Repo.
Oh, if this were production code I totally would, but I'm really only building these solutions to solve the problem, and not looking to make them infinitely extensible.
Is it normal that part 2 is killing my CPU :D ? It's been running for minutes in Elixir but nada.
Anyhow, I've tried day 1 with all three languages which is not a great idea!
I just googled the parts of the various languages I needed
Clojure
part 1
I kind of hated it, I still don't have syntax highlighting nor formatting for some reason in VSCode and the REPL is quite slow to start (I didn't try with ClojureScript)
part 2
I'm not sure it's correct, I had to kill it because it was hogging the CPU
Elixir
part 1
Well, this was the easiest one
part 2
Again, I'm not sure it's correct, it just kills my computer
Rust
part 1
There's a bit of fiddling with types and syntax but the compiler it's quite helpful when you type stuff that doesn't make sense. It can get in the way of me doing the excercises :D
part 2
Well, this ran for half a second a produced the correct answer
What am I doing wrong with Clojure and Elixir :D ?
I've put Day 1 on Github: github.com/rhymes/aoc2018/tree/mas...
At a glance, in the Elixir part two solution it looks like the list of numbers is just being passed through as is. So, it is never moving on to the rest of the numbers and instead the sum is just adding the first number in the list over and over.
Because
repeated_numbers
is never reassigned the recursive callfind_total(repeated_numbers, totals, sum)
is passing the unchanged list of all the numbers through to the next iteration.That's probably it, I thought that:
would take 1 number (and hence move the cursor).
It does, but because Elixir is immutable it returns a new list with the first element from
repeated_numbers
instead of mutating (changing in place)repeating_numbers
Also, this line
hd(Enum.take(repeated_numbers, 1))
could be rewritten ashd(repeated_numbers)
to get the same functionality. The more "Elixir way to write that would be to use pattern matching. Something like[head | tail] = repeated_numbers
Here is some more info on pattern matching, if you're interested. I think it is super cool!Thank you! :-)
I have to get used again to immutability and transformation instead of mutability and assignment :D
On the Clojure pt 2, you're effectively running an endless loop. You always take the first element from the cycled number collection, so you'll never hit the exit condition.
To avoid this while using the approach you chose, add a third
numbers
binding to the loop, and pass(rest numbers)
when recuring, while computing total using(first numbers)
.Thanks! I then solved it thanks to this post
Advent of Code 2018 - Day 1
Christopher Kruse
exactly like you said. You can see my version here github.com/rhymes/aoc2018/blob/mas...
I totally thought my elixir one was dead at first too, so I kept killing it. Only about a 15 second run time though I'm just impatient. lemme look at yours!
Please do, I found a solution at the end, using
reduce_while
, instead of recursion:I feel like I should get through the tutorial at least :D
I wanted to solve these ones in bash, which I've been focussing on learning lately. First challenge was great, found a simple oneliner:
But part 2 was a nightmare. Super slow. Ended up using JS in the end, but would still love to know anyone's thoughts on how this could be optimised. Wasn't watching the clock but think it took >20 mins to run!
It's collecting previously computed frequencies in an array, and checking for the frequency in the array each time a new frequency is computed. Is it the maths that's likely to be so slow, or the looping, or both?
Woah, this is awesome! Yeah the second parts always seem to need some fancier algorithmic trick to speed them up.
You might look into using an associative array, as those provide a much faster lookup time and you don’t have to loop through every value each time? I don’t know if that will be enough though.
Unfortunately, associative arrays only appeared in Bash4. That's fine for Linux, but doesn't appear on Macs unless you manually install it (boo!).
Good caveat to note, thanks!
P.S. Getting Bash 4 on MacOS is a very good idea 😬
First version, with Elixir, was ~15 seconds, to do what ended up being 130+ iterations on part two.
After some careful matching down to a more or less more-than-binary tree, I got it to about 10 seconds.
... then I went nuts and decided to see if I could do it with JUST sending messages aaaaaaand boy does Elixir do well with that, because I got it to 1.5 seconds total.
I just doublechecked and it is still hitting that loop the same number of times. 137991.
Did it with Elixir too. I found the Stream module to be quite useful, especially for the first part. For the second part, I'm not sure my approach is best, but at least it is working.
If you want to check my repo: github.com/JPYamamoto/advent_of_co...
Yeah, that's what I started with and definitely what I would like actually use for anything. It's soooooooo much more readable like how you have it! The trick with named Processes I did totally works here but I suspect would become insanely complex or fail as soon as you needed data that relied on the other data too, instead of just "has this been seen before" :D
Also, I suspect there's a way to do the second part with Streams and avoid having so much information in memory as I did with my approach. Maybe something that takes advantage of
Stream.cycle
andStream.scan
. But not sure how to implement it. I'll let you know if I figure it out. 😀Yeah, I kept my memory footprint relatively low I think even in version one because I read everything into the IO stream and then just kept throwing that list around, which wasn't greaaaaaaaaaaaat but.
Wow, nice!
Thanks! I rechecked it like five times because I was so surprised.
github.com/aleph-naught2tog/aoc_18...
Thanks for making this post and sharing your solutions!
Here are my solutions in Elixir and JavaScript.
To start a couple functions to parse the input.
Part one's solutions.
Part two's solutions.
This solution takes advantage of Elixir's recursion, pattern matching, and multiple function clauses.
I made two solutions to part two in JavaScript the first uses a more imperative approach, and the second was meant to mimic the Elixir solution using recursion. The issue with that is JavaScript not being tail call optimized. In order to get around that I used a trampoline function and a while loop. Though, that approach is insanely slow.
Wow, this is really cool! I completed day one too, but my code is nowhere near that clean. Could you recommend any resources that helped you get into Elixir?
Thanks! This sounds like a cop-out answer but the Elixir docs are a great resource. elixir-lang.org/
I'd also be happy to answer any questions you have.
Awesome, this is a nice place to discuss the solutions! This is mine, in Elixir:
Common code (used by both part 1 and part 2):
Part 1
Part 2
If you want, you could check out my full repo on GitHub.
That's a good idea !
Ruby
Part 1
Part 2
Hi Davis.. Just starting on the #adventofcode series.
Just curious how you are reading the inputs. E.g. first problem says the input is on adventofcode.com/2018/day/1/input
Will you be using Nokigiri or something similar to read the URL and parse the page to get the inputs?
Sorry if this sounds dumb.. But am wondering how you going to download the file?
Thanks
Node.js
First, I created an async generator that read the input file stream chunk by chunk and
yield
each number line by line.Then part 1 was pretty straight forward:
This approach made part 2 ugly because I had to find a way to re-open the file stream and loop back through the inputs. Using a set over an array really helped with performance.
Putting it all together:
Full code: github.com/MattMorgis/Advent-Of-Co...
I also did mine in JS but I decided to use the
readline
interface to read each line individually and spend less memory by not loading the entire file in the memory at once.I haven't trying using
for await (... of ...)
with thereadline
interface. Maybe I'll try that next. If anyone would like to try it please post it here.Here are my solutions:
My solution in JavaScript / Node 11, using the
readline
interface:readLines.js
01a.js
01b.js
Readline doesn't work with async iterators and
for await
yet, but it just landed in 11.x staging.Once it is released, my
streamToFrequencies
generator won't be needed.Also,
createReadStream
only reads the file in 256 byte chunks at a time (or whatever you set thehighwatermark
to be, it does not read the entire file into memory.readFile
would, however.To read more about async iterators and generators and the
for await
syntax, check out 2ality.com/2018/04/async-iter-node...Thanks a bunch @mattmorgis !
Thanks for sharing, here are my solutions in Elixir and Racket.
I'm not sure if the Racket code is idiomatic, so, any advice is more than welcome.
Elixir
Racket
Unit tests for Racket:
I'm doing AoC with Rust too and the solution I came up with looks almost exactly like yours.
Part 1
Part 2: I used a HashSet
Instead of changing the main.rs file every day, I'll suggest creating a separate file for each day inside
src/bin
directory. That way, you can execute them usingcargo run --bin day_1
. Small but well thought out features like this is why I love Rust so much. For example, you can look at my repo at github.com/shritesh/advent-of-codeI hope to get through all of the challenges this year and learn from everyone here.
Oooh! Good idea! I’m definitely doing that. Thanks!
F# - this is my first brush with F# and .NET in general, so pointers are more'n welcome!
Common code:
Part 1:
part 2:
Entry point:
Part 2 is sloooow. How would you optimize this?
Nice!! For optimizing part 2, I would use a set! O(1) to check if an item is in it!
Aha! Thanks so much, it's blazingly fast now:
I guess the Tour of F# page shouldn't be my only learning resource :)
Kotlin Solution!
Part 1
Please exuse my tricked out kotlin, I've added some personal extension functions to let me think about list comprehensions more simply.
Part 2
I made a silly mistake, and lost about an hour trying to figure out where I went wrong. I should set up my test runners ahead of day 2 so I don't end up with this same kind of typo.
Part 2 is "slow", but it's still under
a minute5 seconds to brute force through 150 iterations (or so) of the cycle.Ali's tweet and the Advent of Code project inspired me to update a long-latent blog, and make my first actual post on DEV! Thanks to both of you for the inspiration, and here's a not-quite-fully successful implementation in Clojure w/ write-up: dev.to/ballpointcarrot/advent-of-c...
I made my way here by following @ASpittel. Thanks Ali.
I just finished at Clojure/conj, so it made sense to do today in Clojure. I should consider another language though, since AoC is always a good way to stretch yourself in something new.
Clojure
As per Ryan's suggestions, I pulled the read-file/split operation into it's own
lines
operation. I also pulled each puzzle into it's own function.This highlights something that bugs me about Clojure... there is no built-in function to read a number from a string. It's simple to call out to Java like I just did, but I think there should be something built into the language.
This second puzzle needed something more than a single operation. My first thought was using a
reduce
function, but then I realized that I needed to keep going through the input over and over until completion, andreduce
works on the entire input... unless I created a transducer, which is too much work for something this simple. I probably should have thought about usingloop
in the first place.PHP
Part 1:
Part 2:
Clojure:
(
utils/read-file
just slurps and splits by newlines)Part 1:
Part 2:
Pt 2 JS/Node Solution:
I'm enjoying reading everyone's solutions. After doing last year's in Haskell I'm using Kotlin to try to improve my knowledge of the language and libraries. I'm also avoiding using an IDE, as auto-suggest and magic building don't teach you what's really going on under the hood.
I know the idea is to avoid everyone's github but I'm writing notes on my solutions at github.com/neilgall/adventofcode2018
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:
I am also using Python that I have more experience with to cross check solutions.
Part 1:
Part 2
Hmm... I just took the input and stuck it in an array rather than reading it from disk. That's not hard to do in Swift though, maybe I'll go back and add in the file loading.
In any case, here is what I did in my Playground!
Swift
Part 1
This one was super easy in Swift via it's
reduce(_:_:)
function. Given that I had theInts
in anArray
, it was a one liner. I added some context to the output because why not?For those of you new to Swift, this version of
reduce
has two inputs. The first one is the starting value for the accumulator and the second is the closure of what to do with the values from the collection. This is simply a shorthand syntax for adding all the values in a collection together and returning it. The long version looks like this:Part 2
This part was a bit tougher and my first attempt had all kinds of bad smells like breaking to function labels and such. Eventually I wrapped it all up in a closure that takes an
Array
ofInt
values and then returns a singleInt
with the first repeated number.Essentially this is a for-loop version of the
reduce
operation, but then I also maintain a history of the values in aSet
and check to see if this is a value we've run into before.I solved the second one with a closure instead of a regular function because I've been teaching myself more about them lately.
Thanks! The explanations are really interesting too!
Hi there!
I've used Javascript.
Here's my part one solution:
I just read the input from file, parsed to a int array and used the
reduce
function.Talking about the second part, I've user a dictionary to store frequencies and retrieve them quickly (access is O(1)), cycling in a circular manner through the provided diffs:
I'm planning to do this in Go too, since I'd love to practice this language, but I haven't much time for now :(
I'm doing this in C++ this year, but as we are proposing original solutions with very expressive languages, I'll show a solution in OCaml :)
OCaml
Part 1
Part 2
Using lists is not very efficient but the code is quite short, that is nice.
1.1
A bit overcomplicated. Didn't know parseInt parses signs too 😅
1.2
The first result is the solution, not quite sure why it prints so many other results after that even if I set matchFound = true though 🤔
C#
Part 1
Part 2
This seemed easiest to do in
awk
:Part 1
Part 2
awk
's arrays are basically hashes/associative arrays, so you can just use the frequencies as keys much like the Python dictionary solutions. Becauseawk
is really focused on processing a list of files, this uses a hack on the built-in variable that tracks where on that listawk
has gotten to, so it only stops once it's found the duplicate.Thanks for this Ryan! I've joined the leaderboard. Good luck to everyone!
Here's my solution in Crystal, both parts are included as one class:
There are also tests here.
Hi Ryan.. Just starting on the #adventofcode series.
Just curious how you are reading the inputs. E.g. first problem says the input is on adventofcode.com/2018/day/1/input
Do you parse the page to get the inputs?
Or copy/paste and store it as a file? Sorry if this sounds dumb.. But am wondering how you are downloading the file?
Thanks
No problem! That would be slick to have it download the page for me, but I just go to the link and copy the text. I've got a directory in my project called
data
, and each day's input asday1.txt
,day2.txt
, etc. Then I just change the filename that I'm reading.Let me know if this helps or if you have other questions :)
Thanks. The data folder makes sense.
A little late to starting on this, but I am excited to get going!
JS
Part 1 (A little bit trolly)
Part 2 (could probably use some optimizations)
I just wanted to confess that Day 1 Part 1 I just used a spreadsheet. That got the answer, but then I used my program to proceed.
Honestly, you could argue that Excel is a highly parallel GUI-based programming tool. I’d say that’s fair. 😀
Three different PHP solutions - two of them code-golfed: particleflux.codes/post/2018/adven...
TLDR:
Super cool idea! Just joined the private leaderboard!