Skip to content

Instantly share code, notes, and snippets.

@chartsai
Last active April 6, 2018 23:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chartsai/9f32d6430a825f9296b376b60758192f to your computer and use it in GitHub Desktop.
Save chartsai/9f32d6430a825f9296b376b60758192f to your computer and use it in GitHub Desktop.
OO NineNine
package ninenine
interface NineNine {
fun print99(formatter: String)
}
class Table(internal val width: Int, internal val height: Int, private val sections: Int = if (width >= 6) 2 else 1) : NineNine {
private val lists = IntRange(1, width).map { Sheet(it, height) }.toList()
override fun print99(formatter: String) {
for (i in 0 until sections) {
val start = i * width / sections
val end = (i + 1) * width / sections
BlockPrinter(start, end).printBlockly(formatter)
println()
}
}
private inner class BlockPrinter(private val start: Int, private val end: Int) {
internal fun printBlockly(formatter: String) {
val iterators = (start until end).map { lists[it].iterator() }
repeat(height) {
iterators.map {
it.next().print99(formatter)
print(if (it == iterators.last()) "\n" else " ")
}
}
}
}
}
class Sheet(internal val x: Int, internal val height: Int): NineNine, Iterable<Item> {
private val items = IntRange(1, height).map { Item(x, it) }.toList()
override fun print99(formatter: String) = items.forEach {
it.print99(formatter)
print(if (it == items.last()) "" else "\n")
}
override fun iterator(): Iterator<Item> = items.iterator()
}
class Item(internal val x: Int, internal val y: Int) : NineNine {
override fun print99(formatter: String) = print(formatter.format(x , y, x * y))
}
private inline fun <reified C : NineNine> C.print99() {
val formatter = when (this) {
is Table -> formatterHelper(width, height)
is Sheet -> formatterHelper(x, height)
is Item -> formatterHelper(x, y)
else -> TODO("This function doesn't support ${C::class} yet")
}
print99(formatter)
}
private fun formatterHelper(x: Int, y: Int) = "%${x.digit}d x %${y.digit}d = %${(x * y).digit}d"
private val Int.digit: Int
get() = toString().length
fun main(args: Array<String>) {
var nineNine: NineNine
nineNine = Table(10, 10, 2)
nineNine.print99() // (1 ~ 5), (6 ~ 10)
nineNine = Table(12, 10, 3)
nineNine.print99() // (1 ~ 4) + (5 ~ 8) + (9 ~ 12)
nineNine = Sheet(3, 12)
nineNine.print99() // 3 x 1 = 3 ... 3 x 12 = 36
println()
println()
// Customized formatter:
nineNine = Item(7, 2)
nineNine.print99("%d * %d -> %2d") // 7 * 2 -> 14
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment