Last active
April 6, 2018 23:13
-
-
Save chartsai/9f32d6430a825f9296b376b60758192f to your computer and use it in GitHub Desktop.
OO NineNine
This file contains 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
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