Created
April 6, 2018 20:43
-
-
Save chartsai/d359faf8ab065b4d7b291ce2d59e15c8 to your computer and use it in GitHub Desktop.
sealed doesn't work with reified QQ
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
package ninenine | |
sealed class NineNine { | |
abstract 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) | |
} | |
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