Previous:
Advent of Code 2016 – Day 5( Java 8)
Advent of Code 2016 – Day 4 (Perl 6)
Advent of Code 2016 – Day 3 (Clojure)
Advent of Code – Day 2 (Python 3)
Advent Of Code 2016 – Day 1(Haskell)
Day 6
Start: 12/7/2016
Finish 12/7/2016
Language: Julia
SPOILER ALERT: If you have any inkling, any whatsoever, to work on the Advent of Code…. DO NOT READ THIS BLOG POST. DO NOT LOOK AT MY GITHUB PROJECT. It is no fun if you’re not solving it yourself, and you’ll feel so much better about yourself if you can figure it out without looking up an answer. This blog post is not to give away the answer, but instead, is there for people to learn from.
As always, the following code is in my GitHub: https://github.com/pviafore/AdventOfCode2016
The Challenge
So I decided to take a stab at Julia this time around. I was doing some column based reading of text, and I thought Julia’s arrays on steroids might give me something.
I was happy with how nicely this fit together, let’s take a look:
function getHighestCount(chars)
dict = Dict()
for char in chars
dict[char] = get(dict, char, 0) + 1
end
return sort(collect(dict), by= tuple -> last(tuple), rev=true)[1]
end
f = open("../day6.txt")
lines = readlines(f)
chars = map(s -> split(strip(s), ""), lines)
reshaped = hcat(chars...)
columns = map(x -> getHighestCount(reshaped[x,:]), 1:length(reshaped[:,1]))
answer = *(map(c -> c[1], columns)...)
println(answer)
close(f)
That’s it, 16 lines of code.
Main processing part is straight-forward again (once you know Julia syntax).
f = open("../day6.txt")
lines = readlines(f)
chars = map(s -> split(strip(s), ""), lines)
reshaped = hcat(chars...)
columns = map(x -> getHighestCount(reshaped[x,:]), 1:length(reshaped[:,1]))
answer = *(map(c -> c[1], columns)...)
println(answer)
close(f)
First we read the lines in, then map a split over them so we get a whole bunch of char arrays. With 624, 8 byte arrays, I decided to hcat the values, so that I ended up with a 624×8 array of characters. Then, using Julia’s n-dimensional array slicing, I did this
columns = map(x -> getHighestCount(reshaped[x,:]), 1:length(reshaped[:,1]))
We’ll take a look at getHighestCount in a bit, but for now, just know that it retrieves the letter of the most frequency. So in essence, we are getting the highest frequency of a column of the original text.
Then we map over the returned tuples and use the * to concatenate all of them together
*(map(c -> c[1], columns)...)
Looking at getHighestCount, it was simply a dictionary that tracked frequency, and then sorted by the values in reverse order.
function getHighestCount(chars)
dict = Dict()
for char in chars
dict[char] = get(dict, char, 0) + 1
end
return sort(collect(dict), by= tuple -> last(tuple), rev=true)[1]
end
And that was it.
Part 2
This part was almost laughably easy. I turned getHighestCount into a getLowestCount, and removed the rev=true argument in the sort. That’s it. All there was. It is great when all you have to do to gain functionality is delete code.
function getLowestCount(chars)
dict = Dict()
for char in chars
dict[char] = get(dict, char, 0) + 1
end
return sort(collect(dict), by= tuple -> last(tuple))[1]
end
Wrap-up
I’m not going to pretend I understand a lot of Julia’s n-dimensional mathematics, but I can definitely recognize how it would be a boon in numerical computing. At first, I wished there was a few more things in the standard library (I spent a lot of time looking for group_by, chunk_by, frequency counts, and so on) but in the end, I couldn’t find them (they may have very well been there), and it led me to what I think was a very Julian solution.
I grade myself as an A on this one. I solved this in about an hour and a half, and that included skimming back through 7 more languages in 7 weeks to refresh myself on Julia.
Next up, it looks like Regex will help me out again, so I’m going to take a stab in ECMAScript 2016+/Javascript.
15 thoughts on “Advent of Code Day 6 (Julia)”