Skip to content

Instantly share code, notes, and snippets.

@rayshih
Forked from chartsai/NineNine.kt
Last active April 6, 2018 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rayshih/1b47a4c08c37d6edfb391152a0c5f1c7 to your computer and use it in GitHub Desktop.
Save rayshih/1b47a4c08c37d6edfb391152a0c5f1c7 to your computer and use it in GitHub Desktop.
FP NineNine
package ninenine
// ----- Data -----
sealed class NineNine
data class Item(val x: Int, val y: Int): NineNine()
data class Col(
val x: Int,
val n: Int
): NineNine() {
val items =
IntRange(1, n)
.map { Item(x, it) }
.toList()
}
data class Grid(
val m: Int,
val n: Int,
val sections: Int = if (m >= 6) 2 else 1
): NineNine() {
val cols = IntRange(1, m)
.map { Col(it, n) }
.toList();
}
// ----- Format -----
val Int.digit: Int
get() = toString().length
fun getFormatter(o: NineNine) =
when (o) {
is Item -> Pair(o.x, o.y)
is Col -> Pair(o.x, o.n)
is Grid -> Pair(o.m, o.n)
}
.let {
"%${it.first.digit}d x %${it.second.digit}d = %${(it.first * it.second).digit}d"
}
// ----- Grid print functions -----
fun printBlock(cols: List<Col>, height: Int, formatter: String) = repeat(height) { r ->
cols.dropLast(1).forEach { col ->
printItem(col.items[r], formatter + " ")
}
printItem(cols.last().items[r], formatter + "\n")
}
fun printGrid(grid: Grid, formatter: String = getFormatter(grid)) {
repeat(grid.sections) { it
val start = it * grid.m / grid.sections
val end = (it + 1) * grid.m / grid.sections
printBlock(grid.cols.subList(start, end), grid.n, formatter)
println()
}
}
// ----- Col print function -----
fun printCol(col: Col, formatter: String = getFormatter(col)) {
col.items.forEach {
printItem(it, formatter)
print("\n")
}
}
// ----- Item print function -----
fun printItem(item: Item, formatter: String) {
print(formatter.format(item.x , item.y, item.x * item.y))
}
// ----- NineNine print function (polymorphism) -----
fun print99(o: NineNine, formatter: String = getFormatter(o)) {
when (o) {
is Item -> printItem(o, formatter)
is Col -> printCol(o, formatter)
is Grid -> printGrid(o, formatter)
}
}
fun main(args: Array<String>) {
Grid(10, 10, 2).let { print99(it) } // (1 ~ 5), (6 ~ 10)
Grid(12, 10, 3).let { print99(it) } // (1 ~ 4) + (5 ~ 8) + (9 ~ 12)
Col(3, 12).let { print99(it) } // 3 x 1 = 3 ... 3 x 12 = 36
println()
println()
// Customized formatter:
Item(7, 2).let { print99(it, "%d * %d -> %2d") } // 7 * 2 -> 14
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment