ramziabbyad1
Pattern matching nested tuples
This is listed as one of the “Hard” problem in 7 languages 7 weeks book. "Represent a tree of sentences as tuples. Traverse the tree, presenting an indented list.
I think I have solved it, but I’m wondering if there is a cleaner way to do this without all the conditionals. Thanks!
Book example:
{“See spot run.”, {“See spot sit”, “See spot run”}} will print
See spot run.
See spot sit
See spot run
And my example:
TreeRecurse.print_tree({"See spot.", {{"See spot sit.", {"Sitting down.", {"Run spot", {"Runnn!"}}}}, "See spot run."}}, "")
will produce the output:
See spot.
See spot sit.
Sitting down.
Run spot
Runnn!
See spot run.
defmodule TreeRecurse do
def print_tree({leaf}, indent), do: IO.puts "#{indent}#{leaf}"
def print_tree({root,{lone}},indent) do
IO.puts "#{indent}#{root}"
if is_tuple(lone) do
print_tree(lone, indent <> " ")
else
print_tree({lone}, indent <> " ")
end
end
def print_tree({root,{left,right}},indent) do
IO.puts "#{indent}#{root}"
if is_tuple(left) do
print_tree(left, indent <> " ")
else
print_tree({left}, indent <> " ")
end
if is_tuple(right) do
print_tree(right, indent <> " ")
else
print_tree({right}, indent <> " ")
end
end
end
Marked As Solved
zevv
This is a nice fit for a case with some guards:
def print_tree2(t, indent) do
case t do
{a, b} when is_binary(a) ->
IO.puts "#{indent}#{a}"
print_tree2(b, indent <> " ")
{a, b} when is_binary(b) ->
print_tree2(a, indent <> " ")
IO.puts "#{indent}#{b}"
{a} when is_binary(a) ->
IO.puts "#{indent}#{a}"
end
end
Also Liked
mudasobwa
I always prefer function clauses instead of conditionals (if/2, case/2, cond/1) whenever possible.
defmodule TreeRecurse do
@indent 2
def print_tree(tree, indent \\ 0, acc \\ []) do
tree
|> traverse_tree(indent, acc)
|> Enum.join("\n")
|> IO.puts()
end
defp traverse_tree(leaf, indent, acc) when is_binary(leaf),
do: [indented(leaf, indent) | acc]
defp traverse_tree({leaf}, indent, acc),
do: traverse_tree(leaf, indent, acc)
defp traverse_tree({head, tail}, indent, acc) when is_binary(head) and is_binary(tail),
do: [indented(head, indent), indented(tail, indent) | acc]
defp traverse_tree({head, tail}, indent, acc) when is_binary(head),
do: [indented(head, indent) | traverse_tree(tail, indent + 1, acc)] ++ acc
defp traverse_tree({head, tail}, indent, acc) when is_binary(tail),
do: traverse_tree(head, indent + 1, acc) ++ [indented(tail, indent) | acc]
defp traverse_tree({head, tail}, indent, acc),
do: traverse_tree(head, indent + 1, acc) ++ traverse_tree(tail, indent + 1, acc) ++ acc
defp indented(input, indent) when is_number(indent),
do: ' ' |> List.duplicate(indent * @indent) |> to_string() |> Kernel.<>(input)
end
Last Post!
ramziabbyad1
Love it, thanks! I figured out that in the end I would need to pattern match a string, so this is exactly what I was looking for. I ended up pattern match “” <> string, but from what I read about unicode strings is_binary or a binary pattern match may be more robust. See my updated solution:
def print_tree("" <> string, indent), do: IO.puts "#{indent}#{string}"
def print_tree({leaf}, indent), do: IO.puts "#{indent}#{leaf}"
def print_tree({root,{lone}},indent) do
IO.puts "#{indent}#{root}"
print_tree(lone, indent <> " ")
end
def print_tree({root,{left,right}},indent) do
IO.puts "#{indent}#{root}"
print_tree(left, indent <> " ")
print_tree(right, indent <> " ")
end
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security









