I have a question in Part 1. Let me show my solution first:
defmodule Day21.Part1 do
def solve(), do: root()
@external_resource "#{__DIR__}/day21.txt"
for <<monkey::binary-4, ": ", expr::binary>> <- File.stream!(hd @external_resource),
monkey = String.to_atom(monkey) do
@compile {:inline, [{monkey, 0}]}
defp unquote(monkey)() do
unquote(Code.string_to_quoted!(expr))
end
end
end
I can get the result calling Day21.Part1.solve()
(though it returns a float instead of an integer).
My question is, when I try disassembling the module (thanks to @isaac-rstor for teaching me this feature) and extract the instructions of solve/0
,
Day21.Part1
|> :code.get_object_code()
|> elem(1)
|> :beam_disasm.file()
|> elem(5)
|> Enum.find(fn tuple ->
list = Tuple.to_list(tuple)
match?([:function, :solve | _], list)
end)
I get
{:function, :solve, 0, 789,
[
{:line, 3},
{:label, 788},
{:func_info, {:atom, Day21.Part1}, {:atom, :solve}, 0},
{:label, 789},
{:allocate, 0, 0},
{:line, 2},
{:call, 0, {Day21.Part1, :wvvv, 0}},
{:call, 0, {Day21.Part1, :whqc, 0}},
{:move, {:float, 83056452926300.0}, {:x, 0}},
{:deallocate, 0},
:return
]}
You can see the result in the :move
instruction, that’s expected. The question is why there are still 2 :call
s to the other functions? Why the instructions are not just
{:function, :solve, 0, 789,
[
{:line, 3},
{:label, 788},
{:func_info, {:atom, Day21.Part1}, {:atom, :solve}, 0},
{:label, 789},
{:line, 2},
{:move, {:float, 83056452926300.0}, {:x, 0}},
:return
]}