Problem:
Blur

図 1 のような 10×10 のマス目の「布」があり、（1，2）のようにX座標・Y座標の値の対でマス目を示すことにします。座標値は 0 から始まる整数とします。例えば、図 1 の◎の座標は (1, 2) です。
この「布」に染料を少しずつたらして染物を作ります。たらす染料の滴には「大」「中」「小」の 3 サイズがあり、染料の滴の落ちたマス目を中心に図 1 のように周囲も色がつきます。図 1 で☆が中心、○が色のにじむ範囲です。

「布」は、最初は「まっしろ」つまり、どのマス目も色の濃さを示す値が 0 とします。染料の滴が落ちるごとに値が 1 ずつ増えていきます。「小」が（1, 2）、「中」が（3, 2）に落ちた場合、各マス目の値は図 2 の左のようになります。染料がもったいないので、図 2 の右に示すようなにじむ範囲が布の外にはみ出すような染料の落とし方はしないことになっています。また、同じ場所に複数の染料をたらすこともあります。

このような作業を何回か繰り返した結果、布にすばらしい模様が浮かび上がりましたが、残念なことに、うっかり作業経過を記録し忘れてしまいました。どうにもさっぱり思い出せませんが、かろうじて、落とした染料の滴数は覚えていました。あなたは、すばらしい染物を再現しなければなりません。すばらしい染物のデータを読みこんで、どこに、どのような染料をたらしたかを出力するプログラムを作成してください。なお、落とした染料の滴数は 12 以下とします。

入力

入力の形式は以下のとおりです：

最初の 1 行に落とした染料の滴数 n が与えられます。次の行から 10 行に各座標の色の濃さが空白区切りで与えられます。

出力

出力は n 行からなります。染料の滴の「大」を 3、「中」を 2、「小」を 1 で表し、落とした染料ごとに、そのX座標、Y座標、滴の大きさを空白で区切って1行に出力してください。

染料のたらし方はどのような順番で出力しても良いものとします。

入力例1

2
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0 0
0 0 0 1 0 0 0 1 1 1
0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

出力例1

3 2 1
8 4 2

入力例2

6
0 0 1 0 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0
0 1 1 1 1 1 1 1 0 0
0 0 1 1 1 3 1 1 0 0
0 0 1 1 3 1 1 1 0 0
0 0 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 1 0 0

出力例2

2 2 3
7 7 3
6 3 2
3 6 2
4 4 1
5 5 1

Solution in Kotlin (judge verdict: Accepted)

fun main(args:Array<String>):Unit {
        val dropCount = readLine()!!.trim().toInt()
        val cloth = Array(10){readLine()!!.trim().split(' ').map(String::toInt).toIntArray()}
        var drops = search(cloth, dropCount)!!
        while (drops is ImmutableList.Cons){
            println("${drops.head.center.x} ${drops.head.center.y} ${when(drops.head){
                is Drop.Small -> 1
                is Drop.Medium -> 2
                is Drop.Large -> 3
            }}")
            drops = drops.tail
        }
}
fun search(cloth:Array<IntArray>, dropCount:Int):ImmutableList<Drop>?{
    if (dropCount == 0) {
        return if (cloth.all{it.all{it == 0}}) ImmutableList.Nil
        else null
    }
    val point = (0 until cloth.size).flatMap{y -> (0 until cloth.size).map{Point(it, y)}}.find{cloth[it.y][it.x] != 0}
    return when(point){
        null -> null
        else -> {
            drop(point).filter{it.dropArea().all{it.x in 0 until cloth.size && it.y in 0 until cloth.size && cloth[it.y][it.x] > 0}}.forEach {
                it.dropArea().forEach { cloth[it.y][it.x]-- }
                val tail = search(cloth, dropCount - 1)
                when(tail){
                    null -> {
                        it.dropArea().forEach { cloth[it.y][it.x]++ }
                    }
                    else -> return ImmutableList.Cons(it, tail)
                }
            }
            return null
        }
    }
}
fun drop(point:Point):Iterable<Drop>{
    return listOf(Drop.Small(point + Point(0, 1)), Drop.Medium(point + Point(1, 1)), Drop.Large(point + Point(0, 2)))
}
data class Point(val x:Int, val y:Int){
    operator fun plus(that:Point):Point = Point(x + that.x, y + that.y)
}
sealed class Drop(val center:Point){
    protected abstract val relationalDropArea:Iterable<Point>
    fun dropArea():Iterable<Point> = relationalDropArea
    class Small(center:Point):Drop(center){
        override val relationalDropArea: Iterable<Point> = listOf(Point(0, -1), Point(0, 1), Point(-1, 0), Point(1, 0), Point(0, 0)).map{it + center}
    }
    class Medium(center:Point):Drop(center){
        override val relationalDropArea: Iterable<Point> = (-1 .. 1).flatMap{x -> (-1..1).map{Point(x, it)}}.map{it + center}
    }
    class Large(center:Point):Drop(center){
        override val relationalDropArea: Iterable<Point> = (listOf(Point(2, 0), Point(-2, 0), Point(0, 2), Point(0, -2)) + (-1 .. 1).flatMap { x -> (-1 .. 1).map{Point(x, it)} }).map{it + center}
    }
}
sealed class ImmutableList<out T>{
    object Nil:ImmutableList<Nothing>()
    data class Cons<out T>(val head:T, val tail:ImmutableList<T>):ImmutableList<T>()
}