So I’ve started learning Elixir. I took on the Advent of Code challenges, and solved the first day. I’ve skimmed a few books on elixir/erlang, and have had some exposure to FP constructs (including a pleasant semester of Prolog at uni 10 years ago ).
I came up with the following solution to the day 1 problem. The two test functions showcase what the requirements are (and hopefully the implementation is written such a way what it will be immediately obvious).
Now, after I solved this I searched online to see what other people did. Here are some linked examples:
Reddit Thread
Github 1
Github 2
In those links I see the obvious Enum.reduce
approach plus some approaches that seem really weird. I took a classic recursive approach with pattern matching, but only because it’s the feature I prominently remember and I didn’t remember how to write the case
construct, so I wanted to see if it would be possible. I have to confess when this code worked, I giggled a bit
So my question is, is this code considered idiomatic Elixir? The Pythonista in me really likes this code, even if it is a bit more verbose than other solutions. Could I rewrite it to be more idiomatic but keeping the same recursive approach?
Thanks!
defmodule Day1 do
def santa(s) do
l = String.codepoints(s)
santa(l, 0)
end
defp santa([], n) do
n
end
defp santa(["(" | tail], n) do
santa(tail, n + 1)
end
defp santa([")" | tail], n) do
santa(tail, n - 1)
end
def test_santa do
IO.puts(santa("(())") == 0)
IO.puts(santa("()()") == 0)
IO.puts(santa("(((") == 3)
IO.puts(santa("(()(()(") == 3)
IO.puts(santa("))(((((") == 3)
IO.puts(santa("())") == -1)
IO.puts(santa("))(") == -1)
IO.puts(santa(")))") == -3)
IO.puts(santa(")())())") == -3)
end
def solve do
IO.puts "and now, the punchline"
{:ok, input} = File.read "day1.input.txt"
IO.puts(santa input)
IO.puts(basement input)
end
def basement(s) do
basement(String.codepoints(s), 0, 0)
end
defp basement(_, pos, -1) do
pos
end
defp basement(["(" | tail], pos, floor) do
basement(tail, pos + 1, floor + 1)
end
defp basement([")" | tail], pos, floor) do
basement(tail, pos + 1, floor - 1)
end
def test_basement do
IO.puts(basement(")") == 1)
IO.puts(basement("()())") == 5)
end
end
Day1.solve