Hacker Rank 30 - Fractal Tree
Published 2025-09-23
Ill just put the code here and if you have any questions please feel free to post in the comments.
defmodule Solution do
def run(print \\ true) do
read()
|> print(print, "read")
|> build_tree_helper()
|> print(print, "build_tree_helper")
|> print_tree()
end
@doc """
Reads the input and turns the value into an integer
"""
def read() do
IO.read(:stdio, :all)
|> String.trim()
|> String.to_integer()
end
@doc """
Starts the recursive function to compute the value for any given row, column.
"""
def build_tree_helper(depth) do
build_tree(depth, 0, 0, [])
end
@doc """
Runs through each row column. Checks every depth against each row column up to the depth
we are given
"""
def build_tree(_depth, 63, _col, list), do: list
def build_tree(depth, row, 100, list), do: build_tree(depth, row + 1, 0, list)
def build_tree(depth, row, column, list) do
character = is_one_at_depths(row, column, depth) # <- use this instead
build_tree(depth, row, column + 1, [character | list])
end
@doc """
Uses function to return the set of values for height, row_mid, and column_mid(list).
"""
def build_values(depth) do
%{
height: div(32, trunc(:math.pow(2, depth))),
row_mid: row_mid(depth),
column_mid: column_mid(depth)
}
end
@doc """
Sets all the mid points of any given Y based off the depth given
"""
def column_mid(1), do: [49]
def column_mid(depth) when depth > 1 do
prev = column_mid(depth - 1)
offset = div(32, trunc(:math.pow(2, depth - 1))) # height of previous depth
Enum.flat_map(prev, fn mid ->
[mid - offset, mid + offset]
end)
end
@doc """
Sets the mid point of the Y for a given depth.
"""
def row_mid(depth) do
offsets = [47, 23, 11, 5, 2]
Enum.at(offsets, depth - 1)
end
@doc """
Given a set of values for the height, row mid-point, and a list of column mid-points, will
determine if the row/column given is meant to be a "1" or a "_"
"""
def is_one(row, column, %{height: height, row_mid: row_mid, column_mid: column_mid}) do
cond do
row <= row_mid + height and row > row_mid and Enum.member?(column_mid, column) -> "1"
row < row_mid and row >= row_mid - height and
Enum.any?(column_mid, fn col ->
offset = row_mid - row
column == col - offset or column == col + offset
end) -> "1"
row == row_mid and Enum.member?(column_mid, column) -> "1"
true -> "_"
end
end
@doc """
Will check every value set for each depth against the row/column given.
"""
def is_one_at_depths(row, column, max_depth) do
Enum.any?(1..max_depth, fn depth ->
values = build_values(depth)
is_one(row, column, values) == "1"
end)
|> set_ones()
end
@doc """
Changes the true false values of the Enum.any? to useful characters.
"""
defp set_ones(true), do: "1"
defp set_ones(false), do: "_"
@doc """
Prints the final version of the diagram
"""
defp print_tree(list) do
list
|> Enum.reverse()
|> Enum.chunk_every(100)
|> Enum.each(&IO.puts(Enum.join(&1)))
end
@doc """
Used to debug the code as we build each step.
"""
defp print(data, false, _label), do: data
defp print(data, true, label) do
IO.inspect(data, label: label)
end
end
Solution.run(false)