We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Post 48
Hacker Rank 22 - Tree Functions
Published on: 2025-07-17
Tags:
elixir, Side Project, Hacker Rank
defmodule Solution do def run(print \\ true) do read() |> print(print, "read") |> event_helper() end # Reads input from stdin, splits it into steps def read do IO.read(:stdio, :all) |> String.split("\n", trim: true) |> Enum.map(&String.split(&1, " ", trim: true)) end # Initializes the tree and processes each event def event_helper([_ | steps]) do Enum.reduce( steps, %{ tree: %{ 0 => %{ value: 0, left: nil, right: nil, parent: nil, children: [] } }, current: 0, next_id: 1 }, fn step, acc -> event(step, acc) end ) end # Change the value of the current node def event(["change", val], %{current: node} = acc) do value = String.to_integer(val) put_in(acc, [:tree, node, :value], value) end # Print the value of the current node def event(["print"], %{current: node} = acc) do IO.puts(acc.tree[node].value) acc end # Move to the left sibling of the current node def event(["visit", "left"], %{current: node, tree: tree} = acc) do put_in(acc, [:current], tree[node].left) end # Move to the right sibling of the current node def event(["visit", "right"], %{current: node, tree: tree} = acc) do put_in(acc, [:current], tree[node].right) end # Move to the parent of the current node def event(["visit", "parent"], %{current: node, tree: tree} = acc) do put_in(acc, [:current], tree[node].parent) end # Visit the Nth child (1-based index) of the current node def event(["visit", "child", index], %{current: node, tree: tree} = acc) do idx = String.to_integer(index) - 1 new_id = Enum.at(tree[node].children, idx) put_in(acc, [:current], new_id) end # Insert a new node to the left of the current node def event(["insert", "left", val], %{current: node, next_id: id, tree: tree} = acc) do value = String.to_integer(val) parent = tree[node].parent new_node = %{ value: value, parent: parent, children: [], left: tree[node].left, right: node } acc = if new_node.left != nil do put_in(acc, [:tree, new_node.left, :right], id) else acc end acc = put_in(acc, [:tree, node, :left], id) index = Enum.find_index(tree[parent].children, &(&1 == node)) children = List.insert_at(tree[parent].children, index, id) acc = put_in(acc, [:tree, parent, :children], children) put_in(acc, [:tree, id], new_node) |> Map.update!(:next_id, &(&1 + 1)) end # Insert a new node to the right of the current node def event(["insert", "right", val], %{current: node, next_id: id, tree: tree} = acc) do value = String.to_integer(val) parent = tree[node].parent new_node = %{ value: value, parent: parent, children: [], left: node, right: tree[node].right } acc = if new_node.right != nil do put_in(acc, [:tree, new_node.right, :left], id) else acc end acc = put_in(acc, [:tree, node, :right], id) index = Enum.find_index(tree[parent].children, &(&1 == node)) children = List.insert_at(tree[parent].children, index + 1, id) acc = put_in(acc, [:tree, parent, :children], children) put_in(acc, [:tree, id], new_node) |> Map.update!(:next_id, &(&1 + 1)) end # Insert a new child node as the first child of the current node def event(["insert", "child", val], %{current: node, next_id: id, tree: tree} = acc) do value = String.to_integer(val) old_first = List.first(tree[node].children) new_node = %{ value: value, parent: node, children: [], left: nil, right: old_first } acc = if old_first do put_in(acc, [:tree, old_first, :left], id) else acc end children = [id | tree[node].children] acc = put_in(acc, [:tree, node, :children], children) put_in(acc, [:tree, id], new_node) |> Map.update!(:next_id, &(&1 + 1)) end # Delete the current node and all its descendants def event(["delete"], %{current: node, tree: tree} = acc) do parent = tree[node].parent left = tree[node].left right = tree[node].right # Recursive function to collect all descendants collect = fn collect, id -> Enum.reduce(tree[id].children, [id], fn c, acc -> acc ++ collect.(collect, c) end) end to_delete = collect.(collect, node) new_tree = Map.drop(tree, to_delete) # Remove node from parent's children list updated_children = List.delete(tree[parent].children, node) new_tree = put_in(new_tree, [parent, :children], updated_children) # Update left and right sibling pointers new_tree = if left, do: put_in(new_tree, [left, :right], right), else: new_tree new_tree = if right, do: put_in(new_tree, [right, :left], left), else: new_tree %{acc | tree: new_tree, current: parent} end # Optional print helper for debugging defp print(data, true, label), do: IO.inspect(data, label: label) defp print(data, false, _), do: data end Solution.run(false)
