2025-01-27 16:04:04 -06:00
|
|
|
!module LOT
|
|
|
|
|
|
|
|
!import "lib/base.tri" Lib
|
|
|
|
|
2025-01-26 15:33:12 -06:00
|
|
|
main = exampleTwo
|
2025-01-03 11:42:45 -06:00
|
|
|
-- Level Order Traversal of a labelled binary tree
|
|
|
|
-- Objective: Print each "level" of the tree on a separate line
|
|
|
|
--
|
2025-01-26 14:50:15 -06:00
|
|
|
-- We model labelled binary trees as nested lists where values act as labels. We
|
|
|
|
-- require explicit notation of empty nodes. Empty nodes can be represented
|
|
|
|
-- with an empty list, `[]`, which evaluates to a single node `t`.
|
2025-01-03 11:42:45 -06:00
|
|
|
--
|
|
|
|
-- Example tree inputs:
|
|
|
|
-- [("1") [("2") [("4") t t] t] [("3") [("5") t t] [("6") t t]]]]
|
|
|
|
-- Graph:
|
|
|
|
-- 1
|
|
|
|
-- / \
|
|
|
|
-- 2 3
|
|
|
|
-- / / \
|
|
|
|
-- 4 5 6
|
|
|
|
|
2025-01-27 16:04:04 -06:00
|
|
|
label = \node : Lib.head node
|
2025-01-20 20:10:14 -06:00
|
|
|
|
2025-01-27 16:04:04 -06:00
|
|
|
left = (\node : Lib.if (Lib.emptyList? node)
|
2025-01-20 20:10:14 -06:00
|
|
|
[]
|
2025-01-27 16:04:04 -06:00
|
|
|
(Lib.if (Lib.emptyList? (Lib.tail node))
|
2025-01-20 20:10:14 -06:00
|
|
|
[]
|
2025-01-27 16:04:04 -06:00
|
|
|
(Lib.head (Lib.tail node))))
|
2025-01-20 20:10:14 -06:00
|
|
|
|
2025-01-27 16:04:04 -06:00
|
|
|
right = (\node : Lib.if (Lib.emptyList? node)
|
2025-01-20 20:10:14 -06:00
|
|
|
[]
|
2025-01-27 16:04:04 -06:00
|
|
|
(Lib.if (Lib.emptyList? (Lib.tail node))
|
2025-01-20 20:10:14 -06:00
|
|
|
[]
|
2025-01-27 16:04:04 -06:00
|
|
|
(Lib.if (Lib.emptyList? (Lib.tail (Lib.tail node)))
|
2025-01-20 20:10:14 -06:00
|
|
|
[]
|
2025-01-27 16:04:04 -06:00
|
|
|
(Lib.head (Lib.tail (Lib.tail node))))))
|
2025-01-20 20:10:14 -06:00
|
|
|
|
2025-01-27 16:04:04 -06:00
|
|
|
processLevel = Lib.y (\self queue : Lib.if (Lib.emptyList? queue)
|
2025-01-20 20:10:14 -06:00
|
|
|
[]
|
2025-01-27 16:04:04 -06:00
|
|
|
(Lib.pair (Lib.map label queue) (self (Lib.filter
|
|
|
|
(\node : Lib.not? (Lib.emptyList? node))
|
|
|
|
(Lib.lconcat (Lib.map left queue) (Lib.map right queue))))))
|
2025-01-20 20:10:14 -06:00
|
|
|
|
2025-01-26 08:52:28 -06:00
|
|
|
levelOrderTraversal_ = \a : processLevel (t a t)
|
2025-01-20 20:10:14 -06:00
|
|
|
|
2025-01-27 16:04:04 -06:00
|
|
|
toLineString = Lib.y (\self levels : Lib.if (Lib.emptyList? levels)
|
2025-01-20 20:10:14 -06:00
|
|
|
""
|
2025-01-27 16:04:04 -06:00
|
|
|
(Lib.lconcat
|
|
|
|
(Lib.lconcat (Lib.map (\x : Lib.lconcat x " ") (Lib.head levels)) "")
|
|
|
|
(Lib.if (Lib.emptyList? (Lib.tail levels)) "" (Lib.lconcat (t (t 10 t) t) (self (Lib.tail levels))))))
|
2025-01-20 20:10:14 -06:00
|
|
|
|
2025-01-26 08:52:28 -06:00
|
|
|
levelOrderToString = \s : toLineString (levelOrderTraversal_ s)
|
2025-01-03 11:42:45 -06:00
|
|
|
|
2025-01-27 16:04:04 -06:00
|
|
|
flatten = Lib.foldl (\acc x : Lib.lconcat acc x) ""
|
2025-01-03 11:42:45 -06:00
|
|
|
|
2025-01-27 16:04:04 -06:00
|
|
|
levelOrderTraversal = \s : Lib.lconcat (t 10 t) (flatten (levelOrderToString s))
|
2025-01-23 15:46:40 -06:00
|
|
|
|
|
|
|
exampleOne = levelOrderTraversal [("1")
|
|
|
|
[("2") [("4") t t] t]
|
|
|
|
[("3") [("5") t t] [("6") t t]]]
|
2025-01-20 20:10:14 -06:00
|
|
|
|
2025-01-23 15:46:40 -06:00
|
|
|
exampleTwo = levelOrderTraversal [("1")
|
|
|
|
[("2") [("4") [("8") t t] [("9") t t]]
|
|
|
|
[("6") [("10") t t] [("12") t t]]]
|
|
|
|
[("3") [("5") [("11") t t] t] [("7") t t]]]
|