Note: This topic is to talk about Day 2 of the Advent of Code 2019 .
There is a private leaderboard for elixirforum members. You can join it by following this link and entering the following code:
39276-eeb74f9a
Note: This topic is to talk about Day 2 of the Advent of Code 2019 .
There is a private leaderboard for elixirforum members. You can join it by following this link and entering the following code:
39276-eeb74f9a
Here is my solution.
This is my take. It’s not super fast (takes about 2 sec on my machine for part 2), but does the job.
The most interesting part to me is instruction execution. I define the instruction mapping, and then have a generic exec function which interprets the instruction, fetching the correct amount of arguments based on the arity.
Nice solution based on Stream
, and Function.info/1
I’ve never thought about before
Here’s my version.
I did the input parsing in compile time so it was a bit faster. I found that in later puzzles the input might take more time to parse (it happened before).
I’m learning Elixir, and didn’t know about Enum.find
; I couldn’t figure out how to do an early return from inside for noun <- 0..100, verb <- 0..100, do: ...
, so I picked a terrible way to do handle it: spawn 10k processes! (I finished reading the Concurrent Programming section of Programming Elixir last night.)
What’s interesting is that I read sasajuric’s solution, adapted it, and it seems to run slower (!) than what I have: 175769 microseconds for my part2, 682567 for theirs. Maybe it’s because of all the destructuring? Both solutions in one file.
Here is mine: https://github.com/egze/aoc/blob/master/lib/aoc/y2019/d2.ex
Thanks @NobbZ for the boilerplate.
I’m learning Elixir currently, and here is my mine: https://gitlab.com/KonradBorowski/advent_of_code_2019/blob/master/lib/day2.ex
I’m pretty sure it can be improved, but I quite like what I have here.
Finaly I found some time to do it. And a small typo took me half an hour to figure out the problem… I did for noun <- 0..99, verb <- 0..9 do … end
…
That’s cool. Didn’t know about :array
from Erlang.
My first guess would be that your solution is faster b/c you’re using spawn, which means you’re leveraging multiple cores. The Enum.find
version is sequential.
How about we get a little private leaderboard for elixirforum going? Because the public leader board is insane, people solve the challenges in minutes. wtf
Here’s mine solution: https://github.com/pozhega/AoC/blob/master/lib/aoc/Y2019/d2.ex
Mine: https://github.com/keathley/advent_of_code_2019/blob/master/day2.exs.
I did something similar to @sasajuric on part 2 using the pattern of generating all possible VMs as a stream and then using Enum.find
to get the one that you want: https://github.com/keathley/advent_of_code_2019/blob/master/day2.exs#L66-L74.
That’s one of my favorite patterns in elixir.
Nice idea!
Feel free to join!
39276-eeb74f9a
Cool. Let’s make this the official one?
@bjorng Could you include it in your posts please? Here is the link to join a private leaderboard: https://adventofcode.com/2019/leaderboard/private
Just had time to finish mine: aoc2019/lib/aoc2019/day2.ex at master · alvises/aoc2019 · GitHub
I had refactored it a bit after seeing @sasajuric solution, liked the comprehension + Enum.find
. In my first version I did it with an excessively complicated Stream.iteration
+ Enum.reduce_while
.
Guys, weren’t the first two days of the aoc2018 much easier? The first day was just a sum of nums if I remember correctly… I’m curious to see what they come out increasing the difficulty
What the score is based on? (just joined, I hope is fine )
It’s not all that difficult to also generate permutations lazily:
0..99
|> Stream.flat_map(fn noun -> Stream.map(0..99, &{noun, &1}) end)
My first version used this approach, but then I decided to switch to for
b/c I think it communicates the intention a bit better.
We have n
users in the group, so a star is up to n
points worth.
The m
th person that gets a star will receive n-m+1
points, as there are 2 stars per day, max score per day is 2 * n
.
So full score for the first person, one point less for the second, etc.
Yeah for sure. I didn’t spend much time optimizing since its still a pretty low set of inputs and the algorithm is O(n).
My solution:
defmodule GravAssist do
def calc([op, _, _ | rest], a \\ 12, b \\ 2) do
hd(execute([op, a, b | rest]))
end
def execute(bytecode) when is_list(bytecode), do: execute(:array.from_list(bytecode))
def execute(bytecode), do: eval(bytecode, 0)
defp eval(bytecode, ic) do
case :array.get(ic, bytecode) do
99 -> :array.to_list(bytecode)
op when op in 1..2 ->
pos_a = :array.get(ic + 1, bytecode)
pos_b = :array.get(ic + 2, bytecode)
pos_r = :array.get(ic + 3, bytecode)
result = compute(op, :array.get(pos_a, bytecode), :array.get(pos_b, bytecode))
new_bc = :array.set(pos_r, result, bytecode)
eval(new_bc, ic + 4)
_ -> :error
end
end
defp compute(1, a, b), do: a + b
defp compute(2, a, b), do: a * b
end
data =
IO.read(:line)
|> String.split(",")
|> Enum.map(&String.to_integer(String.trim(&1)))
IO.inspect(GravAssist.calc(data), label: :sol1)
for(a <- 0..99,
b <- 0..99,
19690720 == GravAssist.calc(data, a, b),
do: {a, b})
|> IO.inspect(label: :sol2)