Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:2025:scala:l05 [2025/03/30 22:12]
ldaniel
pp:2025:scala:l05 [2025/04/04 15:09] (current)
tpruteanu
Line 53: Line 53:
 Given the implementation of binary trees from the previous lab: Given the implementation of binary trees from the previous lab:
 <code scala> <code scala>
-trait BinaryTree { +trait BTree
-    override def toString: String = super.toString:​ String +
-}+
  
-case object TVoid extends ​BinaryTree { +case object TVoid extends ​BTree 
-    ​override ​def toStringString ​"​-"​+ 
 +case class Node(left: BTree, info: Int, right: BTree) extends BTree 
 + 
 +def leaf_node(value ​Int) : BTree 
 +  Node(TVoid, value, TVoid)
 } }
  
-case class Node(leftBinaryTreeinfo: Int, right: BinaryTree) extends BinaryTree { +object BTreePrinter { 
-  override def toString: String ​= { +  ​case class PrintInfo(lenIntcenter: Int, textList[String])
-    def printTree( +
-                   tree: BinaryTree,​ +
-                   ​prefix:​ String = "",​ +
-                   ​isLeft:​ Boolean = true +
-                 ): String = +
-      tree match { +
-        case TVoid => +
-          ""​ +
-        case Node(l, value, r) => +
-          val rightStr = +
-            printTree(r,​ prefix + (if (isLeft && prefix.nonEmpty) "​│ ​  "​ else " ​   "), isLeft = false) +
-          val nodeStr = +
-            prefix + (if (tree != this) if (isLeft) "​└── " else "​┌── " else " ​   ") + value.toString + "​\n"​ +
-          val leftStr = +
-            printTree(l,​ prefix + (if (isLeft) " ​   " else "​│ ​  "​)) +
-          rightStr + nodeStr + leftStr +
-      }+
  
-    '​\n' ​printTree(this)+  def pp(tree: BTree): PrintInfo = tree match { 
 +    case TVoid => PrintInfo(3,​ 2, List("​Nil"​)) 
 + 
 +    case Node(left, value, right) => 
 +      val strValue = value.toString 
 +      val ppL = pp(left) 
 +      val ppR = pp(right) 
 +      val nlen = ppL.len + ppR.len + 1 
 +      val ncenter = ppL.len + 1 
 + 
 +      require(strValue.length <= nlen, "Nice try"​) 
 + 
 +      val alignedX = " " * (ncenter - (strValue.length / 2) - 1) + strValue 
 +      val centerLine = " " * (ncenter - 1) + "​|"​ 
 +      val dottedLine = " " * (ppL.center - 1) + "​-"​ * (nlen - ppL.center - (ppR.len - ppR.center + 1) + 2) 
 +      val downLines = " " * (ppL.center - 1) + "​|"​ + " " * (nlen - ppL.center - (ppR.len - ppR.center +1)) + "​|"​ 
 + 
 +      val combinedLines = zipPad("",​(l,​ r) => l ++ (" " * (ppL.len - l.size + 1 )) +r, ppL.text, ppR.text) 
 +       
 +      PrintInfo(nlen, ncenter, alignedX :: centerLine :: dottedLine :: downLines :: combinedLines)
   }   }
 +  def zipPad[A](pad:​ A, f: (A, A) => A, left: List[A], right: List[A]): List[A] = (left, right) match {
 +    case (Nil, Nil) => Nil
 +    case (x :: xs, Nil) => x :: zipPad(pad, f, xs, List(pad))
 +    case (Nil, y :: ys) => f(pad, y) :: zipPad(pad, f, List(pad), ys)
 +    case (x :: xs, y :: ys) => f(x, y) :: zipPad(pad, f, xs, ys)
 +  }
 +
 +  def printTree(tree:​ BTree): String = "​\n"​ + pp(tree).text.mkString("​\n"​)
 } }
  
-def leaf_node(value Int: BinaryTree = +extension(tBTree) { 
-    Node(TVoid, value, TVoid)+  def toStringTree:​ String = BTreePrinter.printTree(t)
 } }
 +
 </​code>​ </​code>​
  
Line 93: Line 106:
 <code scala> <code scala>
 val arborica = Node(Node(leaf_node(-1),​ 5, TVoid), 1, Node(leaf_node(4),​ 2, Node(leaf_node(3),​ 6, leaf_node(7)))) val arborica = Node(Node(leaf_node(-1),​ 5, TVoid), 1, Node(leaf_node(4),​ 2, Node(leaf_node(3),​ 6, leaf_node(7))))
 +arborica.toStringTree
 </​code>​ </​code>​