I saw someone on the Clojurian's Slack talking about AoC day 3, and made the statement "mutable arrays FTW!" This made me think to try using the core.matrix library. I'm always looking for excuses to get better at using that library, since it can give direct GPU access when doing linear algebra.
This uses the same lines function as the last 2 days, and as-long is a trivial wrapping of Java interop so I can map it over the numbers found in each line. I could have just mapped an anonymous function, but I just wish Clojure would include as-long/as-double by default, which is why I named it.
My parsing is far more effort than is needed. Someone else pointed out that the regular nature of the input meant that I could just have split the line with: (re-seq #"\d+" s)
I decided to leave mine alone, partly because it's what I came up with, and partly because it's defensive programming. This puzzle is fine, but in the real world my code will one day see a file containing data that breaks simplistic parsing. That's not saying that my code is solid: for instance, I never check if the rectangles are within the 1000x1000 boundaries, but I like to practice at least a little bit of defensive coding.
The loop is destructuring the parse results then iterating until it's done. Then comes the nice part of core.matrix: pulling out a submatrix (the current rectangle) and updating it. The final line uses the nice trick of using eq to represent booleans as 0/1 and adding them. I learnt to count up booleans that way via APL.
This part was actually easier, and ran significantly faster!
In an imperative language I would update the elements of the submatrix as I checked for overlaps. I could do that here too, but the code above is just much cleaner.
As it is, it keeps a set of the ids that currently don't overlap. The ereduce step first assumes that the current id won't overlap and adds it to the set. Then it checks if each cell has been written to, and if so it removes from the set the id of that cell, and the id that is being processed right now. Then the assign! updates the whole rectangle with the current id.
I liked using core.matrix here. It forced me to go through the docs to look for useful functions (like eq), and I also learnt some interesting gotchas with the library, which will be valuable to know.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I saw someone on the Clojurian's Slack talking about AoC day 3, and made the statement "mutable arrays FTW!" This made me think to try using the core.matrix library. I'm always looking for excuses to get better at using that library, since it can give direct GPU access when doing linear algebra.
Part the First
This uses the same
lines
function as the last 2 days, andas-long
is a trivial wrapping of Java interop so I can map it over the numbers found in each line. I could have just mapped an anonymous function, but I just wish Clojure would include as-long/as-double by default, which is why I named it.My parsing is far more effort than is needed. Someone else pointed out that the regular nature of the input meant that I could just have split the line with:
(re-seq #"\d+" s)
I decided to leave mine alone, partly because it's what I came up with, and partly because it's defensive programming. This puzzle is fine, but in the real world my code will one day see a file containing data that breaks simplistic parsing. That's not saying that my code is solid: for instance, I never check if the rectangles are within the 1000x1000 boundaries, but I like to practice at least a little bit of defensive coding.
The loop is destructuring the parse results then iterating until it's done. Then comes the nice part of core.matrix: pulling out a submatrix (the current rectangle) and updating it. The final line uses the nice trick of using
eq
to represent booleans as 0/1 and adding them. I learnt to count up booleans that way via APL.Part the Second
This part was actually easier, and ran significantly faster!
In an imperative language I would update the elements of the submatrix as I checked for overlaps. I could do that here too, but the code above is just much cleaner.
As it is, it keeps a set of the ids that currently don't overlap. The
ereduce
step first assumes that the current id won't overlap and adds it to the set. Then it checks if each cell has been written to, and if so it removes from the set the id of that cell, and the id that is being processed right now. Then theassign!
updates the whole rectangle with the current id.I liked using core.matrix here. It forced me to go through the docs to look for useful functions (like
eq
), and I also learnt some interesting gotchas with the library, which will be valuable to know.