Skip to content

Commit 96461e0

Browse files
author
Abhijit Sarkar
committed
Avoid list concat by using an accumulator
1 parent e31ffe9 commit 96461e0

File tree

5 files changed

+48
-28
lines changed

5 files changed

+48
-28
lines changed

bintree/src/P61A.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import Tree.*
1010

1111
object P61A:
1212
extension [A](t: Tree[A])
13-
def leafList: List[A] = t match
14-
case Empty => List.empty
15-
case Node(value, Empty, Empty) => List(value)
16-
case Node(_, left, right) => left.leafList ++ right.leafList
13+
def leafList: List[A] =
14+
def loop(tree: Tree[A], leaves: List[A]): List[A] =
15+
tree match
16+
case Empty => leaves
17+
case Node(value, Empty, Empty) => value :: leaves
18+
case Node(_, left, right) => loop(left, loop(right, leaves))
19+
20+
loop(t, Nil)

bintree/src/P62.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import Tree.*
1111

1212
object P62:
1313
extension [A](t: Tree[A])
14-
def internalList: List[A] = t match
15-
case Empty => List.empty
16-
case Node(_, Empty, Empty) => List.empty
17-
case Node(value, left, right) => left.internalList ++ (value :: right.internalList)
14+
def internalList: List[A] =
15+
def loop(tree: Tree[A], leaves: List[A]): List[A] =
16+
tree match
17+
case Empty => leaves
18+
case Node(_, Empty, Empty) => leaves
19+
case Node(value, left, right) => loop(left, value :: loop(right, leaves))
20+
21+
loop(t, Nil)

bintree/src/P62B.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ import Tree.*
1212

1313
object P62B:
1414
extension [A](t: Tree[A])
15-
def atLevel(level: Int, tree: Tree[A] = t, currLevel: Int = 1): List[A] = tree match
16-
case Node(value, _, _) if currLevel == level => List(value)
17-
case Node(_, left, right) => atLevel(level, left, currLevel + 1) ++ atLevel(level, right, currLevel + 1)
18-
case Empty => List.empty
15+
def atLevel(level: Int): List[A] =
16+
def loop(tree: Tree[A], currLevel: Int, acc: List[A]): List[A] =
17+
tree match
18+
case Node(value, _, _) if currLevel == level => value :: acc
19+
case Node(_, left, right) => loop(left, currLevel + 1, loop(right, currLevel + 1, acc))
20+
case Empty => acc
21+
22+
loop(t, 1, Nil)

bintree/src/P68.scala

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,31 @@ is yet to be processed.
3535
object P68:
3636
extension [A](t: Tree[A])
3737
def preorder: List[Char] =
38-
t match
39-
case Empty => Nil
40-
case Node(value, left, right) => (value.toString().head :: left.preorder) ++ right.preorder
38+
def loop(tree: Tree[A], acc: List[Char]): List[Char] =
39+
tree match
40+
case Empty => acc
41+
case Node(value, left, right) => value.toString().head :: loop(left, loop(right, acc))
42+
43+
loop(t, Nil)
4144

4245
def inorder: List[Char] =
43-
t match
44-
case Empty => Nil
45-
case Node(value, left, right) => left.inorder ++ (value.toString().head :: right.inorder)
46+
def loop(tree: Tree[A], acc: List[Char]): List[Char] =
47+
tree match
48+
case Empty => acc
49+
case Node(value, left, right) => loop(left, value.toString().head :: loop(right, acc))
50+
51+
loop(t, Nil)
4652

4753
def preInTree(pre: List[Char], in: List[Char]): Tree[Char] =
4854
def loop(pre: List[Char], in: List[Char]): (Tree[Char], List[Char]) =
49-
pre match
50-
case head :: tail if in.size == 1 => (singleton(head), tail)
51-
case head :: tail if in.size > 1 =>
52-
val (leftIn, rightIn) = in.span(_ != head)
53-
val (left, xs) = loop(tail, leftIn)
54-
val (right, ys) = loop(xs, rightIn.tail)
55+
(pre, in) match
56+
case (head :: tail, _ :: Nil) => (singleton(head), tail)
57+
case (head :: tail, _ :: _ :: _) =>
58+
// unchecked needed since the pattern match in val is not exhaustive and may fail.
59+
// "pattern's type is more specialized than the right hand side expression's type"
60+
val (leftIn, (_ :: rightIn)) = (in.span(_ != head): @unchecked)
61+
val (left, xs) = loop(tail, leftIn)
62+
val (right, ys) = loop(xs, rightIn)
5563
(Node(head, left, right), ys)
5664
case _ => (Empty, pre)
5765

bintree/src/P69.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import Tree.*
1919
object P69:
2020
extension [A](t: Tree[A])
2121
def toDotstring: String =
22-
def loop(tree: Tree[A]): DList[Char] =
22+
def loop(tree: Tree[A], acc: List[Char]): List[Char] =
2323
tree match
24-
case Empty => DList.singleton('.')
25-
case Node(value, left, right) => DList.singleton(value.toString().head) ++ loop(left) ++ loop(right)
24+
case Empty => '.' :: acc
25+
case Node(value, left, right) => value.toString().head :: loop(left, loop(right, acc))
2626

27-
loop(t).toList.mkString
27+
loop(t, Nil).mkString
2828

2929
def fromDotstring(s: String): Tree[Char] =
3030
def loop(t: String): (Tree[Char], String) =

0 commit comments

Comments
 (0)