Skip to content

Instantly share code, notes, and snippets.

@abdallaadelessa
Last active June 3, 2019 15:57
Show Gist options
  • Save abdallaadelessa/2ac85a8ae14284c24d55a0c698412a7a to your computer and use it in GitHub Desktop.
Save abdallaadelessa/2ac85a8ae14284c24d55a0c698412a7a to your computer and use it in GitHub Desktop.
import java.lang.StringBuilder
/**
* Pyramid generator
*
* Develop a function which generates a pyramid:
*
* fun pyramidGenerator(levels: Int): List<String>
*
* "levels" is a positive integer.
* The function returns a List<String> representing the pyramid shape with n levels.
* The stones are represented by "#" character
* The air is represented by a space character.
* Make sure the generated pyramid has spaces on both the left and right hand sides.
*
*
* pyramid(1)
* '#'
*
* pyramid(2)
* ' # '
* '###'
*
* pyramid(3)
* ' # '
* ' ### '
* '#####'​
*/
fun main() {
pyramidGenerator(10).print()
}
fun pyramidGenerator(levels: Int) =
levels.run { 1.rangeTo(Math.abs(this)) }
.run { Pyramid(this, 1 until last * 2) { y -> y * 2 - 1 } }
.run { build() }
private fun List<String>.print() = forEach { System.out.println(it) }
//region Pyramid Logic
private const val STONE = "#"
private const val AIR = " "
private data class Pyramid(
private val yAxisRange: IntRange,
private val xAxisRange: IntRange,
private val numOfStonesPerRowFormula: (Int) -> Int
) {
private val yValueToAmountOfAirPerRowSideMap: MutableMap<Int, Int> = mutableMapOf()
private val xAxisPointsCount = xAxisRange.last
private fun calculateAmountOfAirPerRow(y: Int) = xAxisPointsCount - numOfStonesPerRowFormula(y)
private fun calculateAmountOfAirPerRowSide(y: Int): Int = calculateAmountOfAirPerRow(y) / 2
private fun calculateOrGetTheAmountOfAirPerRowSide(y: Int) =
yValueToAmountOfAirPerRowSideMap[y] ?: calculateAmountOfAirPerRowSide(y).apply {
yValueToAmountOfAirPerRowSideMap[y] = this
}
private fun isAir(x: Int, y: Int) = x <= calculateOrGetTheAmountOfAirPerRowSide(y)
|| x > (xAxisPointsCount - calculateOrGetTheAmountOfAirPerRowSide(y))
fun build() = ArrayList<String>().apply {
yAxisRange.forEach { y ->
add(StringBuilder().apply {
xAxisRange.forEach { x ->
append(if (isAir(x, y)) AIR else STONE)
}
}.toString())
}
}
}
//endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment