Last active
March 18, 2019 13:26
-
-
Save ikavalio/76890695336738610832f7a2ef9394af to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Solution { | |
def main(args: Array[String]) { | |
println( | |
draw(0, 100 / 2, 100, 16, 0, 63, scala.io.StdIn.readInt(), 1, 5).reverseMap(_.mkString).mkString("\n") | |
) | |
} | |
def mergeResult(l1: List[List[Char]], l2: List[List[Char]]): List[List[Char]] = | |
l1 zip l2 map { p: (List[Char], List[Char]) => p._1 ::: p._2 } | |
/** | |
* xStart - x coordinate of leftmost point that belongs to drawer | |
* xCenter - x coordinate of tree center within bounding box | |
* xEnd - x coordinate of rightmost point that belong to drawer | |
* currHeight - size of trunk of tree fragment (size of fragment is twice the size of trunk) | |
* heightGap - number of already filled rows | |
* yMax - total number of rows | |
* visDepth - number of visible levels | |
* currDepth - current level | |
* maxDepth - max levels | |
*/ | |
def draw(xStart: Int, xCenter: Int, xEnd: Int, currHeight: Int, heightGap: Int, yMax: Int, visDepth: Int, currDepth: Int, maxDepth: Int): List[List[Char]] = { | |
drawTree(xEnd - xStart, xCenter - xStart, currHeight, 2 * currHeight, | |
if (currDepth == maxDepth) yMax - heightGap - 2 * currHeight else 0, currDepth > visDepth | |
) ::: (if (currDepth < maxDepth) { | |
mergeResult( | |
draw(xStart, xCenter - currHeight, xCenter, currHeight / 2, // left half | |
heightGap + 2 * currHeight, yMax, visDepth, currDepth + 1, maxDepth), | |
draw(xCenter, xCenter + currHeight, xEnd, // right half | |
currHeight / 2, heightGap + 2 * currHeight, yMax, visDepth, currDepth + 1, maxDepth) | |
) | |
} else { | |
Nil | |
}) | |
} | |
/** | |
* width - size of fragment along x coordinate | |
* posCenter - x coordinate of center of tree | |
* currHeight - current height of tree's trunk | |
* yPos - y coordinate iterator of figure (2 * currHeight to 0) | |
* yGap - number of placeholder lines to draw after tree | |
* isPlaceholder - if true draw placeholder lines instead of tree | |
*/ | |
def drawTree(width: Int, posCenter: Int, currHeight: Int, yPos: Int, yGap: Int, isPlaceholder: Boolean): List[List[Char]] = { | |
if (isPlaceholder) { | |
yPos match { | |
case n if n > 0 => ("_" * width).toList :: drawTree(width, posCenter, currHeight, yPos - 1, yGap, isPlaceholder) | |
case _ => | |
yGap match { | |
case m if m > 0 => ("_" * width).toList :: drawTree(width, posCenter, currHeight, yPos, m - 1, isPlaceholder) | |
case _ => Nil | |
} | |
} | |
} else { | |
yPos match { | |
case n if n > 0 => | |
n match { | |
case tr if tr > currHeight => | |
(("_" * (posCenter - 1)) + "1" + ("_" * (width - posCenter))).toList :: | |
drawTree(width, posCenter, currHeight, yPos - 1, yGap, isPlaceholder) | |
case br => | |
mergeResult( | |
branch(posCenter - 2, 1, currHeight, isLeft=true), | |
branch(0, width - posCenter - 1, currHeight, isLeft=false) | |
) ::: (if (yPos == 1) drawTree(width, posCenter, currHeight, 0, yGap, isPlaceholder=true) else Nil) | |
} | |
case _ => Nil | |
} | |
} | |
} | |
def branch(padLeft: Int, padRight: Int, items: Int, isLeft: Boolean): List[List[Char]] = { | |
items match { | |
case 0 => Nil | |
case _ => | |
(("_" * padLeft) + "1" + ("_" * padRight)).toList :: ( | |
if (isLeft) branch(padLeft - 1, padRight + 1, items - 1, isLeft) | |
else branch(padLeft + 1, padRight - 1, items - 1, isLeft) | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment