package examples.longerExamples

import java.util.*

/**
 * Let's Walk Through a Maze.
 *
 * Imagine there is a maze whose walls are the big 'O' letters.
 * Now, I stand where a big 'I' stands and some cool prize lies
 * somewhere marked with a '$' sign. Like this:
 *
 *    OOOOOOOOOOOOOOOOO
 *    O               O
 *    O$  O           O
 *    OOOOO           O
 *    O               O
 *    O  OOOOOOOOOOOOOO
 *    O           O I O
 *    O               O
 *    OOOOOOOOOOOOOOOOO
 *
 * I want to get the prize, and this program helps me do so as soon
 * as I possibly can by finding a shortest path through the maze.
 *
 * @author Edwin.Wu
 * @version 2018/2/3 下午7:10
 * @since JDK1.8
 */

/**
 * Declare a point class.
 */
data class Point(val i: Int, val j: Int)

/**
 * This function looks for a path from max.start to maze.end through
 * free space (a path does not go through walls). One can move only
 * straight up, down, left or right, no diagonal moves allowed.
 */
fun findPath(maze: Maze): List<Point>? {
    val previous = hashMapOf<Point, Point>()

    val queue = LinkedList<Point>()
    val visited = hashSetOf<Point>()

    queue.offer(maze.start)
    visited.add(maze.start)
    while (!queue.isEmpty()) {
        val cell = queue.poll()
        if (cell == maze.end) break

        for (newCell in maze.neighbors(cell.i, cell.j)) {
            if (newCell in visited) continue
            previous.put(newCell, cell)
            queue.offer(newCell)
            visited.add(cell)
        }
    }

    if (previous[maze.end] == null) return null

    val path = arrayListOf<Point>()
    var current = previous[maze.end]!!
    while (current != maze.start) {
        path.add(0, current)
        current = previous[current]!!
    }
    return path
}

/**
 * Find neighbors of the (i, j) cell that are not walls
 */
fun Maze.neighbors(i: Int, j: Int): List<Point> {
    val result = arrayListOf<Point>()
    addIfFree(i - 1, j, result)
    addIfFree(i, j - 1, result)
    addIfFree(i + 1, j, result)
    addIfFree(i, j + 1, result)
    return result
}

fun Maze.addIfFree(i: Int, j: Int, result: MutableList<Point>) {
    if (i !in 0..height - 1) return
    if (j !in 0..width - 1) return
    if (walls[i][j]) return

    result.add(Point(i, j))
}

/**
 * A data class that represents a maze
 */
class Maze(
        // Number or columns
        val width: Int,
        // Number of rows
        val height: Int,
        // true for a wall, false for free space
        val walls: Array<BooleanArray>,
        // The starting point (must not be a wall)
        val start: Point,
        // The target point (must not be a wall)
        val end: Point
) {
}

/** A few maze examples here */
fun main(args: Array<String>) {
    walkThroughMaze("I  $")
    walkThroughMaze("I O $")
    walkThroughMaze("""
    O  $
    O
    O
    O
    O           I
  """)
    walkThroughMaze("""
    OOOOOOOOOOO
    O $       O
    OOOOOOO OOO
    O         O
    OOOOO OOOOO
    O         O
    O OOOOOOOOO
    O        OO
    OOOOOO   IO
  """)
    walkThroughMaze("""
    OOOOOOOOOOOOOOOOO
    O               O
    O$  O           O
    OOOOO           O
    O               O
    O  OOOOOOOOOOOOOO
    O           O I O
    O               O
    OOOOOOOOOOOOOOOOO
  """)
}

// UTILITIES

fun walkThroughMaze(str: String) {
    val maze = makeMaze(str)

    println("Maze:")
    val path = findPath(maze)
    for (i in 0..maze.height - 1) {
        for (j in 0..maze.width - 1) {
            val cell = Point(i, j)
            print(
                    if (maze.walls[i][j]) "O"
                    else if (cell == maze.start) "I"
                    else if (cell == maze.end) "$"
                    else if (path != null && path.contains(cell)) "~"
                    else " "
            )
        }
        println("")
    }
    println("Result: " + if (path == null) "No path" else "Path found")
    println("")
}

/**
 * A maze is encoded in the string s: the big 'O' letters are walls.
 * I stand where a big 'I' stands and the prize is marked with
 * a '$' sign.
 *
 * Example:
 *
 *    OOOOOOOOOOOOOOOOO
 *    O               O
 *    O$  O           O
 *    OOOOO           O
 *    O               O
 *    O  OOOOOOOOOOOOOO
 *    O           O I O
 *    O               O
 *    OOOOOOOOOOOOOOOOO
 */
fun makeMaze(s: String): Maze {
    val lines = s.split('\n')
    val longestLine = lines.toList().maxBy { it.length } ?: ""
    val data = Array(lines.size) { BooleanArray(longestLine.length) }

    var start: Point? = null
    var end: Point? = null

    for (line in lines.indices) {
        for (x in lines[line].indices) {
            val c = lines[line][x]
            when (c) {
                'O' -> data[line][x] = true
                'I' -> start = Point(line, x)
                '$' -> end = Point(line, x)
            }
        }
    }

    return Maze(longestLine.length, lines.size, data,
            start ?: throw IllegalArgumentException("No starting point in the maze (should be indicated with 'I')"),
            end ?: throw IllegalArgumentException("No goal point in the maze (should be indicated with a '$' sign)"))
}

Compiled from "Maze.kt"
public final class examples.longerExamples.Maze {
  private final int width;

  private final int height;

  private final boolean[][] walls;

  private final examples.longerExamples.Point start;

  private final examples.longerExamples.Point end;

  public examples.longerExamples.Maze(int, int, boolean[][], examples.longerExamples.Point, examples.longerExamples.Point);
    Code:
       0: aload_3
       1: ldc           #9                  // String walls
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload         4
       8: ldc           #17                 // String start
      10: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      13: aload         5
      15: ldc           #19                 // String end
      17: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      20: aload_0
      21: invokespecial #22                 // Method java/lang/Object."<init>":()V
      24: aload_0
      25: iload_1
      26: putfield      #26                 // Field width:I
      29: aload_0
      30: iload_2
      31: putfield      #29                 // Field height:I
      34: aload_0
      35: aload_3
      36: putfield      #32                 // Field walls:[[Z
      39: aload_0
      40: aload         4
      42: putfield      #35                 // Field start:Lexamples/longerExamples/Point;
      45: aload_0
      46: aload         5
      48: putfield      #37                 // Field end:Lexamples/longerExamples/Point;
      51: return

  public final int getWidth();
    Code:
       0: aload_0
       1: getfield      #26                 // Field width:I
       4: ireturn

  public final int getHeight();
    Code:
       0: aload_0
       1: getfield      #29                 // Field height:I
       4: ireturn

  public final boolean[][] getWalls();
    Code:
       0: aload_0
       1: getfield      #32                 // Field walls:[[Z
       4: areturn

  public final examples.longerExamples.Point getStart();
    Code:
       0: aload_0
       1: getfield      #35                 // Field start:Lexamples/longerExamples/Point;
       4: areturn

  public final examples.longerExamples.Point getEnd();
    Code:
       0: aload_0
       1: getfield      #37                 // Field end:Lexamples/longerExamples/Point;
       4: areturn
}

Compiled from "Maze.kt"
public final class examples.longerExamples.MazeKt {
  public static final java.util.List<examples.longerExamples.Point> findPath(examples.longerExamples.Maze);
    Code:
       0: aload_0
       1: ldc           #11                 // String maze
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #19                 // class java/util/HashMap
       9: dup
      10: invokespecial #23                 // Method java/util/HashMap."<init>":()V
      13: astore_1
      14: new           #25                 // class java/util/LinkedList
      17: dup
      18: invokespecial #26                 // Method java/util/LinkedList."<init>":()V
      21: astore_2
      22: new           #28                 // class java/util/HashSet
      25: dup
      26: invokespecial #29                 // Method java/util/HashSet."<init>":()V
      29: astore_3
      30: aload_2
      31: aload_0
      32: invokevirtual #35                 // Method examples/longerExamples/Maze.getStart:()Lexamples/longerExamples/Point;
      35: invokevirtual #39                 // Method java/util/LinkedList.offer:(Ljava/lang/Object;)Z
      38: pop
      39: aload_3
      40: aload_0
      41: invokevirtual #35                 // Method examples/longerExamples/Maze.getStart:()Lexamples/longerExamples/Point;
      44: invokevirtual #42                 // Method java/util/HashSet.add:(Ljava/lang/Object;)Z
      47: pop
      48: aload_2
      49: invokevirtual #46                 // Method java/util/LinkedList.isEmpty:()Z
      52: ifne          154
      55: aload_2
      56: invokevirtual #50                 // Method java/util/LinkedList.poll:()Ljava/lang/Object;
      59: checkcast     #52                 // class examples/longerExamples/Point
      62: astore        4
      64: aload         4
      66: aload_0
      67: invokevirtual #55                 // Method examples/longerExamples/Maze.getEnd:()Lexamples/longerExamples/Point;
      70: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      73: ifne          154
      76: aload_0
      77: aload         4
      79: invokevirtual #63                 // Method examples/longerExamples/Point.getI:()I
      82: aload         4
      84: invokevirtual #66                 // Method examples/longerExamples/Point.getJ:()I
      87: invokestatic  #70                 // Method neighbors:(Lexamples/longerExamples/Maze;II)Ljava/util/List;
      90: invokeinterface #76,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      95: astore        5
      97: aload         5
      99: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     104: ifeq          48
     107: aload         5
     109: invokeinterface #84,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     114: checkcast     #52                 // class examples/longerExamples/Point
     117: astore        6
     119: aload_3
     120: aload         6
     122: invokevirtual #87                 // Method java/util/HashSet.contains:(Ljava/lang/Object;)Z
     125: ifne          97
     128: aload_1
     129: aload         6
     131: aload         4
     133: invokevirtual #91                 // Method java/util/HashMap.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     136: pop
     137: aload_2
     138: aload         6
     140: invokevirtual #39                 // Method java/util/LinkedList.offer:(Ljava/lang/Object;)Z
     143: pop
     144: aload_3
     145: aload         4
     147: invokevirtual #42                 // Method java/util/HashSet.add:(Ljava/lang/Object;)Z
     150: pop
     151: goto          97
     154: aload_1
     155: aload_0
     156: invokevirtual #55                 // Method examples/longerExamples/Maze.getEnd:()Lexamples/longerExamples/Point;
     159: invokevirtual #95                 // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     162: ifnonnull     167
     165: aconst_null
     166: areturn
     167: new           #97                 // class java/util/ArrayList
     170: dup
     171: invokespecial #98                 // Method java/util/ArrayList."<init>":()V
     174: astore        4
     176: aload_1
     177: aload_0
     178: invokevirtual #55                 // Method examples/longerExamples/Maze.getEnd:()Lexamples/longerExamples/Point;
     181: invokevirtual #95                 // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     184: dup
     185: invokestatic  #102                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     188: checkcast     #52                 // class examples/longerExamples/Point
     191: astore        5
     193: aload         5
     195: aload_0
     196: invokevirtual #35                 // Method examples/longerExamples/Maze.getStart:()Lexamples/longerExamples/Point;
     199: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     202: ifne          231
     205: aload         4
     207: iconst_0
     208: aload         5
     210: invokevirtual #105                // Method java/util/ArrayList.add:(ILjava/lang/Object;)V
     213: aload_1
     214: aload         5
     216: invokevirtual #95                 // Method java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
     219: dup
     220: invokestatic  #102                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     223: checkcast     #52                 // class examples/longerExamples/Point
     226: astore        5
     228: goto          193
     231: aload         4
     233: checkcast     #72                 // class java/util/List
     236: areturn

  public static final java.util.List<examples.longerExamples.Point> neighbors(examples.longerExamples.Maze, int, int);
    Code:
       0: aload_0
       1: ldc           #121                // String <this>
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #97                 // class java/util/ArrayList
       9: dup
      10: invokespecial #98                 // Method java/util/ArrayList."<init>":()V
      13: astore_3
      14: aload_0
      15: iload_1
      16: iconst_1
      17: isub
      18: iload_2
      19: aload_3
      20: checkcast     #72                 // class java/util/List
      23: invokestatic  #125                // Method addIfFree:(Lexamples/longerExamples/Maze;IILjava/util/List;)V
      26: aload_0
      27: iload_1
      28: iload_2
      29: iconst_1
      30: isub
      31: aload_3
      32: checkcast     #72                 // class java/util/List
      35: invokestatic  #125                // Method addIfFree:(Lexamples/longerExamples/Maze;IILjava/util/List;)V
      38: aload_0
      39: iload_1
      40: iconst_1
      41: iadd
      42: iload_2
      43: aload_3
      44: checkcast     #72                 // class java/util/List
      47: invokestatic  #125                // Method addIfFree:(Lexamples/longerExamples/Maze;IILjava/util/List;)V
      50: aload_0
      51: iload_1
      52: iload_2
      53: iconst_1
      54: iadd
      55: aload_3
      56: checkcast     #72                 // class java/util/List
      59: invokestatic  #125                // Method addIfFree:(Lexamples/longerExamples/Maze;IILjava/util/List;)V
      62: aload_3
      63: checkcast     #72                 // class java/util/List
      66: areturn

  public static final void addIfFree(examples.longerExamples.Maze, int, int, java.util.List<examples.longerExamples.Point>);
    Code:
       0: aload_0
       1: ldc           #121                // String <this>
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_3
       7: ldc           #132                // String result
       9: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: iconst_0
      13: iload_1
      14: if_icmpgt     35
      17: iload_1
      18: aload_0
      19: invokevirtual #135                // Method examples/longerExamples/Maze.getHeight:()I
      22: iconst_1
      23: isub
      24: if_icmpgt     31
      27: iconst_1
      28: goto          36
      31: iconst_0
      32: goto          36
      35: iconst_0
      36: ifne          40
      39: return
      40: iconst_0
      41: iload_2
      42: if_icmpgt     63
      45: iload_2
      46: aload_0
      47: invokevirtual #138                // Method examples/longerExamples/Maze.getWidth:()I
      50: iconst_1
      51: isub
      52: if_icmpgt     59
      55: iconst_1
      56: goto          64
      59: iconst_0
      60: goto          64
      63: iconst_0
      64: ifne          68
      67: return
      68: aload_0
      69: invokevirtual #142                // Method examples/longerExamples/Maze.getWalls:()[[Z
      72: iload_1
      73: aaload
      74: iload_2
      75: baload
      76: ifeq          80
      79: return
      80: aload_3
      81: new           #52                 // class examples/longerExamples/Point
      84: dup
      85: iload_1
      86: iload_2
      87: invokespecial #145                // Method examples/longerExamples/Point."<init>":(II)V
      90: invokeinterface #146,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      95: pop
      96: return

  public static final void main(java.lang.String[]);
    Code:
       0: aload_0
       1: ldc           #152                // String args
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #154                // String I  $
       8: invokestatic  #158                // Method walkThroughMaze:(Ljava/lang/String;)V
      11: ldc           #160                // String I O $
      13: invokestatic  #158                // Method walkThroughMaze:(Ljava/lang/String;)V
      16: ldc           #162                // String \n    O  $\n    O\n    O\n    O\n    O           I\n
      18: invokestatic  #158                // Method walkThroughMaze:(Ljava/lang/String;)V
      21: ldc           #164                // String \n    OOOOOOOOOOO\n    O $       O\n    OOOOOOO OOO\n    O         O\n    OOOOO OOOOO\n    O         O\n    O OOOOOOOOO\n    O        OO\n    OOOOOO   IO\n
      23: invokestatic  #158                // Method walkThroughMaze:(Ljava/lang/String;)V
      26: ldc           #166                // String \n    OOOOOOOOOOOOOOOOO\n    O               O\n    O$  O           O\n    OOOOO           O\n    O               O\n    O  OOOOOOOOOOOOOO\n    O           O I O\n    O               O\n    OOOOOOOOOOOOOOOOO\n
      28: invokestatic  #158                // Method walkThroughMaze:(Ljava/lang/String;)V
      31: return

  public static final void walkThroughMaze(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #169                // String str
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #173                // Method makeMaze:(Ljava/lang/String;)Lexamples/longerExamples/Maze;
      10: astore_1
      11: ldc           #175                // String Maze:
      13: getstatic     #181                // Field java/lang/System.out:Ljava/io/PrintStream;
      16: swap
      17: invokevirtual #186                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      20: aload_1
      21: invokestatic  #188                // Method findPath:(Lexamples/longerExamples/Maze;)Ljava/util/List;
      24: astore_2
      25: iconst_0
      26: istore_3
      27: aload_1
      28: invokevirtual #135                // Method examples/longerExamples/Maze.getHeight:()I
      31: iconst_1
      32: isub
      33: istore        4
      35: iload_3
      36: iload         4
      38: if_icmpgt     188
      41: iconst_0
      42: istore        5
      44: aload_1
      45: invokevirtual #138                // Method examples/longerExamples/Maze.getWidth:()I
      48: iconst_1
      49: isub
      50: istore        6
      52: iload         5
      54: iload         6
      56: if_icmpgt     167
      59: new           #52                 // class examples/longerExamples/Point
      62: dup
      63: iload_3
      64: iload         5
      66: invokespecial #145                // Method examples/longerExamples/Point."<init>":(II)V
      69: astore        7
      71: aload_1
      72: invokevirtual #142                // Method examples/longerExamples/Maze.getWalls:()[[Z
      75: iload_3
      76: aaload
      77: iload         5
      79: baload
      80: ifeq          88
      83: ldc           #190                // String O
      85: goto          144
      88: aload         7
      90: aload_1
      91: invokevirtual #35                 // Method examples/longerExamples/Maze.getStart:()Lexamples/longerExamples/Point;
      94: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      97: ifeq          105
     100: ldc           #191                // String I
     102: goto          144
     105: aload         7
     107: aload_1
     108: invokevirtual #55                 // Method examples/longerExamples/Maze.getEnd:()Lexamples/longerExamples/Point;
     111: invokestatic  #59                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     114: ifeq          122
     117: ldc           #193                // String $
     119: goto          144
     122: aload_2
     123: ifnull        142
     126: aload_2
     127: aload         7
     129: invokeinterface #194,  2          // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
     134: ifeq          142
     137: ldc           #196                // String ~
     139: goto          144
     142: ldc           #198                // String
     144: astore        8
     146: getstatic     #181                // Field java/lang/System.out:Ljava/io/PrintStream;
     149: aload         8
     151: invokevirtual #201                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     154: iload         5
     156: iload         6
     158: if_icmpeq     167
     161: iinc          5, 1
     164: goto          59
     167: ldc           #203                // String
     169: getstatic     #181                // Field java/lang/System.out:Ljava/io/PrintStream;
     172: swap
     173: invokevirtual #186                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     176: iload_3
     177: iload         4
     179: if_icmpeq     188
     182: iinc          3, 1
     185: goto          41
     188: new           #205                // class java/lang/StringBuilder
     191: dup
     192: invokespecial #206                // Method java/lang/StringBuilder."<init>":()V
     195: ldc           #208                // String Result:
     197: invokevirtual #212                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     200: aload_2
     201: ifnonnull     209
     204: ldc           #214                // String No path
     206: goto          211
     209: ldc           #216                // String Path found
     211: invokevirtual #212                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     214: invokevirtual #220                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     217: getstatic     #181                // Field java/lang/System.out:Ljava/io/PrintStream;
     220: swap
     221: invokevirtual #186                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     224: ldc           #203                // String
     226: getstatic     #181                // Field java/lang/System.out:Ljava/io/PrintStream;
     229: swap
     230: invokevirtual #186                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     233: return

  public static final examples.longerExamples.Maze makeMaze(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #225                // String s
       3: invokestatic  #17                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #227                // class java/lang/CharSequence
      10: iconst_1
      11: newarray       char
      13: astore_2
      14: aload_2
      15: iconst_0
      16: bipush        10
      18: castore
      19: aload_2
      20: iconst_0
      21: iconst_0
      22: bipush        6
      24: aconst_null
      25: invokestatic  #233                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[CZIILjava/lang/Object;)Ljava/util/List;
      28: astore_1
      29: aload_1
      30: checkcast     #235                // class java/lang/Iterable
      33: invokestatic  #241                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
      36: checkcast     #235                // class java/lang/Iterable
      39: astore        4
      41: iconst_0
      42: istore        5
      44: aload         4
      46: invokeinterface #242,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      51: astore        6
      53: aload         6
      55: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      60: ifne          71
      63: new           #244                // class java/util/NoSuchElementException
      66: dup
      67: invokespecial #245                // Method java/util/NoSuchElementException."<init>":()V
      70: athrow
      71: aload         6
      73: invokeinterface #84,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      78: astore        7
      80: aload         6
      82: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      87: ifne          95
      90: aload         7
      92: goto          165
      95: aload         7
      97: checkcast     #223                // class java/lang/String
     100: astore        8
     102: iconst_0
     103: istore        9
     105: aload         8
     107: invokevirtual #248                // Method java/lang/String.length:()I
     110: istore        8
     112: aload         6
     114: invokeinterface #84,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     119: astore        9
     121: aload         9
     123: checkcast     #223                // class java/lang/String
     126: astore        10
     128: iconst_0
     129: istore        11
     131: aload         10
     133: invokevirtual #248                // Method java/lang/String.length:()I
     136: istore        10
     138: iload         8
     140: iload         10
     142: if_icmpge     153
     145: aload         9
     147: astore        7
     149: iload         10
     151: istore        8
     153: aload         6
     155: invokeinterface #81,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     160: ifne          112
     163: aload         7
     165: checkcast     #223                // class java/lang/String
     168: dup
     169: ifnonnull     175
     172: pop
     173: ldc           #203                // String
     175: astore_2
     176: iconst_0
     177: istore        4
     179: aload_1
     180: invokeinterface #251,  1          // InterfaceMethod java/util/List.size:()I
     185: istore        5
     187: iload         5
     189: anewarray     #253                // class "[Z"
     192: astore        6
     194: iload         4
     196: iload         5
     198: if_icmpge     222
     201: iload         4
     203: istore        7
     205: aload         6
     207: iload         7
     209: aload_2
     210: invokevirtual #248                // Method java/lang/String.length:()I
     213: newarray       boolean
     215: aastore
     216: iinc          4, 1
     219: goto          194
     222: aload         6
     224: astore_3
     225: aconst_null
     226: astore        4
     228: aconst_null
     229: astore        5
     231: iconst_0
     232: istore        6
     234: aload_1
     235: checkcast     #255                // class java/util/Collection
     238: invokeinterface #256,  1          // InterfaceMethod java/util/Collection.size:()I
     243: istore        7
     245: iload         6
     247: iload         7
     249: if_icmpge     388
     252: iconst_0
     253: istore        8
     255: aload_1
     256: iload         6
     258: invokeinterface #259,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     263: checkcast     #227                // class java/lang/CharSequence
     266: invokeinterface #260,  1          // InterfaceMethod java/lang/CharSequence.length:()I
     271: istore        9
     273: iload         8
     275: iload         9
     277: if_icmpge     382
     280: aload_1
     281: iload         6
     283: invokeinterface #259,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     288: checkcast     #223                // class java/lang/String
     291: iload         8
     293: invokevirtual #264                // Method java/lang/String.charAt:(I)C
     296: istore        10
     298: iload         10
     300: lookupswitch  { // 3
                    36: 363
                    73: 347
                    79: 336
               default: 376
          }
     336: aload_3
     337: iload         6
     339: aaload
     340: iload         8
     342: iconst_1
     343: bastore
     344: goto          376
     347: new           #52                 // class examples/longerExamples/Point
     350: dup
     351: iload         6
     353: iload         8
     355: invokespecial #145                // Method examples/longerExamples/Point."<init>":(II)V
     358: astore        4
     360: goto          376
     363: new           #52                 // class examples/longerExamples/Point
     366: dup
     367: iload         6
     369: iload         8
     371: invokespecial #145                // Method examples/longerExamples/Point."<init>":(II)V
     374: astore        5
     376: iinc          8, 1
     379: goto          273
     382: iinc          6, 1
     385: goto          245
     388: new           #31                 // class examples/longerExamples/Maze
     391: dup
     392: aload_2
     393: invokevirtual #248                // Method java/lang/String.length:()I
     396: aload_1
     397: invokeinterface #251,  1          // InterfaceMethod java/util/List.size:()I
     402: aload_3
     403: aload         4
     405: dup
     406: ifnonnull     421
     409: pop
     410: new           #266                // class java/lang/IllegalArgumentException
     413: dup
     414: ldc_w         #268                // String No starting point in the maze (should be indicated with \'I\')
     417: invokespecial #270                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     420: athrow
     421: aload         5
     423: dup
     424: ifnonnull     439
     427: pop
     428: new           #266                // class java/lang/IllegalArgumentException
     431: dup
     432: ldc_w         #272                // String No goal point in the maze (should be indicated with a \'$\' sign)
     435: invokespecial #270                // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
     438: athrow
     439: invokespecial #275                // Method examples/longerExamples/Maze."<init>":(II[[ZLexamples/longerExamples/Point;Lexamples/longerExamples/Point;)V
     442: areturn
}


package de.soniro.nonogramsolver

import de.soniro.nonogramsolver.Cell.*

enum class Cell(val char: Char) {
    FILL('\u2588'),
    EMPTY(' '),
    NOT_FILLED('X'),
    UNKNOWN('?');

    override fun toString(): String = "$char"
}

class Nonogram(val rows: Array<IntArray>, val columns: Array<IntArray>) {

    val grid: Array<Array<Any>>
    private val columnOffset: Int
    private val rowOffset: Int

    init {
        columnOffset = longestSubArray(rows)
        rowOffset = longestSubArray(columns)
        grid = Array(numberOfRows()) { row ->
            Array<Any>(numberOfColumns()) { column ->
                if (row > columnOffset && column > rowOffset) UNKNOWN else EMPTY
            }
        }
        writeColumns()
        writeRows()
    }

    private fun writeColumns() =
        (rowOffset downTo 1).forEach { i ->
            (0..columns.size - 1).forEach { j ->
                if (columns[j].size >= i) {
                    grid[rowOffset - i][columnOffset + j] = columns[j][columns[j].size - i]
                }
            }
        }

    private fun writeRows() =
        (columnOffset downTo 1).forEach { i ->
            (0..rows.size - 1).forEach { j ->
                if (rows[j].size >= i) {
                    grid[rowOffset + j][columnOffset - i] = rows[j][rows[j].size - i]
                }
            }
        }

    private fun numberOfColumns(): Int = columnOffset + columns.size

    private fun numberOfRows(): Int = rowOffset + rows.size

    private fun longestSubArray(array: Array<IntArray>): Int = array.maxBy { it.size }!!.size

    fun print() = grid.forEach { row ->
        row.forEach { cell -> print("$cell ") }
        println()
    }

    fun fillTrivialRows() =
        rows.forEachIndexed { index, row -> fillRowIfTrivial(index, row) }

    fun fillRowIfTrivial(currentRowIndex: Int, row: IntArray) {
        if (row.sum() + row.size - 1 == columns.size) {
            var index = columnOffset
            val rowIndex = rowOffset + currentRowIndex
            row.forEach { value ->
                repeat(value) {
                    grid[rowIndex][index] = FILL
                    index++
                }
                if (index < numberOfColumns() - 1) {
                    grid[rowIndex][index] = NOT_FILLED
                    index++
                }
            }
        }
    }

    fun fillTrivialColumns() {
        for ((currentColumnIndex, column) in columns.withIndex()) {
            if (column.sum() + column.size - 1 == rows.size) {
                var index = rowOffset
                val columnIndex = columnOffset + currentColumnIndex
                for (value in column) {
                    repeat(value) {
                        grid[index][columnIndex] = FILL
                        index++
                    }
                    if (index < numberOfRows() - 1) {
                        grid[index][columnIndex] = NOT_FILLED
                        index++
                    }
                }
            }
        }
    }

    fun writeColumn(columnWithContent: Array<Cell>, columnIndex: Int) {
        columnWithContent.forEachIndexed { cellIndex, cell ->
            grid[cellIndex + rowOffset][columnIndex] = cell
        }
    }
}

Compiled from "Nonogram.kt"
public final class de.soniro.nonogramsolver.Nonogram {
  private final int[][] rows;

  private final int[][] columns;

  private final java.lang.Object[][] grid;

  private final int columnOffset;

  private final int rowOffset;

  public de.soniro.nonogramsolver.Nonogram(int[][], int[][]);
    Code:
       0: aload_1
       1: ldc           #9                  // String rows
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #17                 // String columns
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokespecial #20                 // Method java/lang/Object."<init>":()V
      16: aload_0
      17: aload_1
      18: putfield      #23                 // Field rows:[[I
      21: aload_0
      22: aload_2
      23: putfield      #25                 // Field columns:[[I
      26: nop
      27: aload_0
      28: aload_0
      29: aload_0
      30: getfield      #23                 // Field rows:[[I
      33: invokespecial #29                 // Method longestSubArray:([[I)I
      36: putfield      #33                 // Field columnOffset:I
      39: aload_0
      40: aload_0
      41: aload_0
      42: getfield      #25                 // Field columns:[[I
      45: invokespecial #29                 // Method longestSubArray:([[I)I
      48: putfield      #36                 // Field rowOffset:I
      51: aload_0
      52: iconst_0
      53: istore_3
      54: aload_0
      55: invokespecial #40                 // Method numberOfRows:()I
      58: istore        4
      60: iload         4
      62: anewarray     #42                 // class "[Ljava/lang/Object;"
      65: astore        5
      67: astore        11
      69: iload_3
      70: iload         4
      72: if_icmpge     164
      75: iload_3
      76: istore        6
      78: aload         5
      80: iload         6
      82: iconst_0
      83: istore        7
      85: aload_0
      86: invokespecial #45                 // Method numberOfColumns:()I
      89: istore        8
      91: iload         8
      93: anewarray     #4                  // class java/lang/Object
      96: astore        9
      98: istore        13
     100: astore        12
     102: iload         7
     104: iload         8
     106: if_icmpge     151
     109: iload         7
     111: istore        10
     113: aload         9
     115: iload         10
     117: iload         6
     119: aload_0
     120: getfield      #33                 // Field columnOffset:I
     123: if_icmple     141
     126: iload         10
     128: aload_0
     129: getfield      #36                 // Field rowOffset:I
     132: if_icmple     141
     135: getstatic     #51                 // Field de/soniro/nonogramsolver/Cell.UNKNOWN:Lde/soniro/nonogramsolver/Cell;
     138: goto          144
     141: getstatic     #54                 // Field de/soniro/nonogramsolver/Cell.EMPTY:Lde/soniro/nonogramsolver/Cell;
     144: aastore
     145: iinc          7, 1
     148: goto          102
     151: aload         12
     153: iload         13
     155: aload         9
     157: aastore
     158: iinc          3, 1
     161: goto          69
     164: aload         11
     166: aload         5
     168: putfield      #58                 // Field grid:[[Ljava/lang/Object;
     171: aload_0
     172: invokespecial #61                 // Method writeColumns:()V
     175: aload_0
     176: invokespecial #64                 // Method writeRows:()V
     179: nop
     180: return

  public final int[][] getRows();
    Code:
       0: aload_0
       1: getfield      #23                 // Field rows:[[I
       4: areturn

  public final int[][] getColumns();
    Code:
       0: aload_0
       1: getfield      #25                 // Field columns:[[I
       4: areturn

  public final java.lang.Object[][] getGrid();
    Code:
       0: aload_0
       1: getfield      #58                 // Field grid:[[Ljava/lang/Object;
       4: areturn

  private final void writeColumns();
    Code:
       0: aload_0
       1: getfield      #36                 // Field rowOffset:I
       4: iconst_1
       5: invokestatic  #79                 // Method kotlin/ranges/RangesKt.downTo:(II)Lkotlin/ranges/IntProgression;
       8: checkcast     #81                 // class java/lang/Iterable
      11: astore_1
      12: iconst_0
      13: istore_2
      14: aload_1
      15: invokeinterface #85,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      20: astore_3
      21: aload_3
      22: invokeinterface #91,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      27: ifeq          174
      30: aload_3
      31: checkcast     #93                 // class kotlin/collections/IntIterator
      34: invokevirtual #96                 // Method kotlin/collections/IntIterator.nextInt:()I
      37: istore        4
      39: iload         4
      41: istore        5
      43: iconst_0
      44: istore        6
      46: new           #98                 // class kotlin/ranges/IntRange
      49: dup
      50: iconst_0
      51: aload_0
      52: getfield      #25                 // Field columns:[[I
      55: checkcast     #42                 // class "[Ljava/lang/Object;"
      58: arraylength
      59: iconst_1
      60: isub
      61: invokespecial #101                // Method kotlin/ranges/IntRange."<init>":(II)V
      64: checkcast     #81                 // class java/lang/Iterable
      67: astore        7
      69: iconst_0
      70: istore        8
      72: aload         7
      74: invokeinterface #85,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      79: astore        9
      81: aload         9
      83: invokeinterface #91,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      88: ifeq          168
      91: aload         9
      93: checkcast     #93                 // class kotlin/collections/IntIterator
      96: invokevirtual #96                 // Method kotlin/collections/IntIterator.nextInt:()I
      99: istore        10
     101: iload         10
     103: istore        11
     105: iconst_0
     106: istore        12
     108: aload_0
     109: getfield      #25                 // Field columns:[[I
     112: iload         11
     114: aaload
     115: arraylength
     116: iload         5
     118: if_icmplt     163
     121: aload_0
     122: getfield      #58                 // Field grid:[[Ljava/lang/Object;
     125: aload_0
     126: getfield      #36                 // Field rowOffset:I
     129: iload         5
     131: isub
     132: aaload
     133: aload_0
     134: getfield      #33                 // Field columnOffset:I
     137: iload         11
     139: iadd
     140: aload_0
     141: getfield      #25                 // Field columns:[[I
     144: iload         11
     146: aaload
     147: aload_0
     148: getfield      #25                 // Field columns:[[I
     151: iload         11
     153: aaload
     154: arraylength
     155: iload         5
     157: isub
     158: iaload
     159: invokestatic  #107                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     162: aastore
     163: nop
     164: nop
     165: goto          81
     168: nop
     169: nop
     170: nop
     171: goto          21
     174: nop
     175: return

  private final void writeRows();
    Code:
       0: aload_0
       1: getfield      #33                 // Field columnOffset:I
       4: iconst_1
       5: invokestatic  #79                 // Method kotlin/ranges/RangesKt.downTo:(II)Lkotlin/ranges/IntProgression;
       8: checkcast     #81                 // class java/lang/Iterable
      11: astore_1
      12: iconst_0
      13: istore_2
      14: aload_1
      15: invokeinterface #85,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      20: astore_3
      21: aload_3
      22: invokeinterface #91,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      27: ifeq          174
      30: aload_3
      31: checkcast     #93                 // class kotlin/collections/IntIterator
      34: invokevirtual #96                 // Method kotlin/collections/IntIterator.nextInt:()I
      37: istore        4
      39: iload         4
      41: istore        5
      43: iconst_0
      44: istore        6
      46: new           #98                 // class kotlin/ranges/IntRange
      49: dup
      50: iconst_0
      51: aload_0
      52: getfield      #23                 // Field rows:[[I
      55: checkcast     #42                 // class "[Ljava/lang/Object;"
      58: arraylength
      59: iconst_1
      60: isub
      61: invokespecial #101                // Method kotlin/ranges/IntRange."<init>":(II)V
      64: checkcast     #81                 // class java/lang/Iterable
      67: astore        7
      69: iconst_0
      70: istore        8
      72: aload         7
      74: invokeinterface #85,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      79: astore        9
      81: aload         9
      83: invokeinterface #91,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      88: ifeq          168
      91: aload         9
      93: checkcast     #93                 // class kotlin/collections/IntIterator
      96: invokevirtual #96                 // Method kotlin/collections/IntIterator.nextInt:()I
      99: istore        10
     101: iload         10
     103: istore        11
     105: iconst_0
     106: istore        12
     108: aload_0
     109: getfield      #23                 // Field rows:[[I
     112: iload         11
     114: aaload
     115: arraylength
     116: iload         5
     118: if_icmplt     163
     121: aload_0
     122: getfield      #58                 // Field grid:[[Ljava/lang/Object;
     125: aload_0
     126: getfield      #36                 // Field rowOffset:I
     129: iload         11
     131: iadd
     132: aaload
     133: aload_0
     134: getfield      #33                 // Field columnOffset:I
     137: iload         5
     139: isub
     140: aload_0
     141: getfield      #23                 // Field rows:[[I
     144: iload         11
     146: aaload
     147: aload_0
     148: getfield      #23                 // Field rows:[[I
     151: iload         11
     153: aaload
     154: arraylength
     155: iload         5
     157: isub
     158: iaload
     159: invokestatic  #107                // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     162: aastore
     163: nop
     164: nop
     165: goto          81
     168: nop
     169: nop
     170: nop
     171: goto          21
     174: nop
     175: return

  private final int numberOfColumns();
    Code:
       0: aload_0
       1: getfield      #33                 // Field columnOffset:I
       4: aload_0
       5: getfield      #25                 // Field columns:[[I
       8: checkcast     #42                 // class "[Ljava/lang/Object;"
      11: arraylength
      12: iadd
      13: ireturn

  private final int numberOfRows();
    Code:
       0: aload_0
       1: getfield      #36                 // Field rowOffset:I
       4: aload_0
       5: getfield      #23                 // Field rows:[[I
       8: checkcast     #42                 // class "[Ljava/lang/Object;"
      11: arraylength
      12: iadd
      13: ireturn

  private final int longestSubArray(int[][]);
    Code:
       0: aload_1
       1: checkcast     #42                 // class "[Ljava/lang/Object;"
       4: astore_2
       5: iconst_0
       6: istore_3
       7: aload_2
       8: arraylength
       9: ifne          16
      12: iconst_1
      13: goto          17
      16: iconst_0
      17: ifeq          28
      20: new           #119                // class java/util/NoSuchElementException
      23: dup
      24: invokespecial #120                // Method java/util/NoSuchElementException."<init>":()V
      27: athrow
      28: aload_2
      29: iconst_0
      30: aaload
      31: astore        4
      33: aload_2
      34: invokestatic  #126                // Method kotlin/collections/ArraysKt.getLastIndex:([Ljava/lang/Object;)I
      37: istore        5
      39: iload         5
      41: ifne          49
      44: aload         4
      46: goto          125
      49: aload         4
      51: checkcast     #128                // class "[I"
      54: astore        6
      56: iconst_0
      57: istore        7
      59: aload         6
      61: arraylength
      62: istore        6
      64: iconst_1
      65: istore        7
      67: iload         7
      69: iload         5
      71: if_icmpgt     123
      74: aload_2
      75: iload         7
      77: aaload
      78: astore        8
      80: aload         8
      82: checkcast     #128                // class "[I"
      85: astore        9
      87: iconst_0
      88: istore        10
      90: aload         9
      92: arraylength
      93: istore        9
      95: iload         6
      97: iload         9
      99: if_icmpge     110
     102: aload         8
     104: astore        4
     106: iload         9
     108: istore        6
     110: iload         7
     112: iload         5
     114: if_icmpeq     123
     117: iinc          7, 1
     120: goto          74
     123: aload         4
     125: dup
     126: invokestatic  #132                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     129: checkcast     #128                // class "[I"
     132: arraylength
     133: ireturn

  public final void print();
    Code:
       0: aload_0
       1: getfield      #58                 // Field grid:[[Ljava/lang/Object;
       4: checkcast     #42                 // class "[Ljava/lang/Object;"
       7: astore_1
       8: iconst_0
       9: istore_2
      10: iconst_0
      11: istore_3
      12: aload_1
      13: arraylength
      14: istore        4
      16: iload_3
      17: iload         4
      19: if_icmpge     123
      22: aload_1
      23: iload_3
      24: aaload
      25: astore        5
      27: aload         5
      29: checkcast     #42                 // class "[Ljava/lang/Object;"
      32: astore        6
      34: iconst_0
      35: istore        7
      37: aload         6
      39: astore        8
      41: iconst_0
      42: istore        9
      44: iconst_0
      45: istore        10
      47: aload         8
      49: arraylength
      50: istore        11
      52: iload         10
      54: iload         11
      56: if_icmpge     108
      59: aload         8
      61: iload         10
      63: aaload
      64: astore        12
      66: aload         12
      68: astore        13
      70: iconst_0
      71: istore        14
      73: new           #147                // class java/lang/StringBuilder
      76: dup
      77: invokespecial #148                // Method java/lang/StringBuilder."<init>":()V
      80: aload         13
      82: invokevirtual #152                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      85: bipush        32
      87: invokevirtual #155                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
      90: invokevirtual #159                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      93: getstatic     #165                // Field java/lang/System.out:Ljava/io/PrintStream;
      96: swap
      97: invokevirtual #169                // Method java/io/PrintStream.print:(Ljava/lang/Object;)V
     100: nop
     101: nop
     102: iinc          10, 1
     105: goto          52
     108: nop
     109: getstatic     #165                // Field java/lang/System.out:Ljava/io/PrintStream;
     112: invokevirtual #172                // Method java/io/PrintStream.println:()V
     115: nop
     116: nop
     117: iinc          3, 1
     120: goto          16
     123: nop
     124: return

  public final void fillTrivialRows();
    Code:
       0: aload_0
       1: getfield      #23                 // Field rows:[[I
       4: checkcast     #42                 // class "[Ljava/lang/Object;"
       7: astore_1
       8: iconst_0
       9: istore_2
      10: iconst_0
      11: istore_3
      12: iconst_0
      13: istore        4
      15: aload_1
      16: arraylength
      17: istore        5
      19: iload         4
      21: iload         5
      23: if_icmpge     63
      26: aload_1
      27: iload         4
      29: aaload
      30: astore        6
      32: iload_3
      33: iinc          3, 1
      36: aload         6
      38: checkcast     #128                // class "[I"
      41: astore        7
      43: istore        8
      45: iconst_0
      46: istore        9
      48: aload_0
      49: iload         8
      51: aload         7
      53: invokevirtual #181                // Method fillRowIfTrivial:(I[I)V
      56: nop
      57: iinc          4, 1
      60: goto          19
      63: nop
      64: return

  public final void fillRowIfTrivial(int, int[]);
    Code:
       0: aload_2
       1: ldc           #188                // String row
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: invokestatic  #192                // Method kotlin/collections/ArraysKt.sum:([I)I
      10: aload_2
      11: arraylength
      12: iadd
      13: iconst_1
      14: isub
      15: aload_0
      16: getfield      #25                 // Field columns:[[I
      19: checkcast     #42                 // class "[Ljava/lang/Object;"
      22: arraylength
      23: if_icmpne     151
      26: iconst_0
      27: istore_3
      28: aload_0
      29: getfield      #33                 // Field columnOffset:I
      32: istore_3
      33: aload_0
      34: getfield      #36                 // Field rowOffset:I
      37: iload_1
      38: iadd
      39: istore        4
      41: aload_2
      42: astore        5
      44: iconst_0
      45: istore        6
      47: iconst_0
      48: istore        7
      50: aload         5
      52: arraylength
      53: istore        8
      55: iload         7
      57: iload         8
      59: if_icmpge     150
      62: aload         5
      64: iload         7
      66: iaload
      67: istore        9
      69: iload         9
      71: istore        10
      73: iconst_0
      74: istore        11
      76: iconst_0
      77: istore        12
      79: iload         12
      81: iload         10
      83: if_icmpge     116
      86: iload         12
      88: istore        13
      90: iconst_0
      91: istore        14
      93: aload_0
      94: getfield      #58                 // Field grid:[[Ljava/lang/Object;
      97: iload         4
      99: aaload
     100: iload_3
     101: getstatic     #195                // Field de/soniro/nonogramsolver/Cell.FILL:Lde/soniro/nonogramsolver/Cell;
     104: aastore
     105: iload_3
     106: iconst_1
     107: iadd
     108: istore_3
     109: nop
     110: iinc          12, 1
     113: goto          79
     116: iload_3
     117: aload_0
     118: invokespecial #45                 // Method numberOfColumns:()I
     121: iconst_1
     122: isub
     123: if_icmpge     142
     126: aload_0
     127: getfield      #58                 // Field grid:[[Ljava/lang/Object;
     130: iload         4
     132: aaload
     133: iload_3
     134: getstatic     #198                // Field de/soniro/nonogramsolver/Cell.NOT_FILLED:Lde/soniro/nonogramsolver/Cell;
     137: aastore
     138: iload_3
     139: iconst_1
     140: iadd
     141: istore_3
     142: nop
     143: nop
     144: iinc          7, 1
     147: goto          55
     150: nop
     151: return

  public final void fillTrivialColumns();
    Code:
       0: aload_0
       1: getfield      #25                 // Field columns:[[I
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: checkcast     #42                 // class "[Ljava/lang/Object;"
      11: arraylength
      12: istore_3
      13: iload_2
      14: iload_3
      15: if_icmpge     177
      18: iload_2
      19: istore        4
      21: aload_1
      22: iload_2
      23: aaload
      24: astore        5
      26: aload         5
      28: invokestatic  #192                // Method kotlin/collections/ArraysKt.sum:([I)I
      31: aload         5
      33: arraylength
      34: iadd
      35: iconst_1
      36: isub
      37: aload_0
      38: getfield      #23                 // Field rows:[[I
      41: checkcast     #42                 // class "[Ljava/lang/Object;"
      44: arraylength
      45: if_icmpne     171
      48: iconst_0
      49: istore        6
      51: aload_0
      52: getfield      #36                 // Field rowOffset:I
      55: istore        6
      57: aload_0
      58: getfield      #33                 // Field columnOffset:I
      61: iload         4
      63: iadd
      64: istore        7
      66: iconst_0
      67: istore        8
      69: aload         5
      71: arraylength
      72: istore        9
      74: iload         8
      76: iload         9
      78: if_icmpge     171
      81: aload         5
      83: iload         8
      85: iaload
      86: istore        10
      88: iconst_0
      89: istore        11
      91: iload         11
      93: iload         10
      95: if_icmpge     131
      98: iload         11
     100: istore        12
     102: iconst_0
     103: istore        13
     105: aload_0
     106: getfield      #58                 // Field grid:[[Ljava/lang/Object;
     109: iload         6
     111: aaload
     112: iload         7
     114: getstatic     #195                // Field de/soniro/nonogramsolver/Cell.FILL:Lde/soniro/nonogramsolver/Cell;
     117: aastore
     118: iload         6
     120: iconst_1
     121: iadd
     122: istore        6
     124: nop
     125: iinc          11, 1
     128: goto          91
     131: iload         6
     133: aload_0
     134: invokespecial #40                 // Method numberOfRows:()I
     137: iconst_1
     138: isub
     139: if_icmpge     165
     142: aload_0
     143: getfield      #58                 // Field grid:[[Ljava/lang/Object;
     146: iload         6
     148: aaload
     149: iload         7
     151: getstatic     #198                // Field de/soniro/nonogramsolver/Cell.NOT_FILLED:Lde/soniro/nonogramsolver/Cell;
     154: aastore
     155: iload         6
     157: istore        11
     159: iload         11
     161: iconst_1
     162: iadd
     163: istore        6
     165: iinc          8, 1
     168: goto          74
     171: iinc          2, 1
     174: goto          13
     177: return

  public final void writeColumn(de.soniro.nonogramsolver.Cell[], int);
    Code:
       0: aload_1
       1: ldc           #212                // String columnWithContent
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: astore_3
       8: iconst_0
       9: istore        4
      11: iconst_0
      12: istore        5
      14: iconst_0
      15: istore        6
      17: aload_3
      18: arraylength
      19: istore        7
      21: iload         6
      23: iload         7
      25: if_icmpge     72
      28: aload_3
      29: iload         6
      31: aaload
      32: astore        8
      34: iload         5
      36: iinc          5, 1
      39: aload         8
      41: astore        9
      43: istore        10
      45: iconst_0
      46: istore        11
      48: aload_0
      49: getfield      #58                 // Field grid:[[Ljava/lang/Object;
      52: iload         10
      54: aload_0
      55: getfield      #36                 // Field rowOffset:I
      58: iadd
      59: aaload
      60: iload_2
      61: aload         9
      63: aastore
      64: nop
      65: nop
      66: iinc          6, 1
      69: goto          21
      72: nop
      73: return
}


package neat.novelty

import kotlin.math.min

fun levenshtein(lhs: CharSequence, rhs: CharSequence): Int {
    if (lhs == rhs) {
        return 0
    }
    if (lhs.isEmpty()) {
        return rhs.length
    }
    if (rhs.isEmpty()) {
        return lhs.length
    }

    val lhsLength = lhs.length + 1
    val rhsLength = rhs.length + 1

    var cost = Array(lhsLength) { it }
    var newCost = Array(lhsLength) { 0 }

    for (i in 1 until rhsLength) {
        newCost[0] = i

        for (j in 1 until lhsLength) {
            val match = if (lhs[j - 1] == rhs[i - 1]) 0 else 1

            val costReplace = cost[j - 1] + match
            val costInsert = cost[j] + 1
            val costDelete = newCost[j - 1] + 1

            newCost[j] = min(min(costInsert, costDelete), costReplace)
        }

        val swap = cost
        cost = newCost
        newCost = swap
    }

    return cost[lhsLength - 1]
}

fun levenshtein(lhs: List<Int>, rhs: List<Int>): Int {
    if (lhs == rhs) {
        return 0
    }

    if (lhs.isEmpty()) {
        return rhs.size
    }
    if (rhs.isEmpty()) {
        return lhs.size
    }

    val lhsLength = lhs.size + 1
    val rhsLength = rhs.size + 1

    var cost = Array(lhsLength) { it }
    var newCost = Array(lhsLength) { 0 }

    for (i in 1 until rhsLength) {
        newCost[0] = i

        for (j in 1 until lhsLength) {
            val match = if (lhs[j - 1] == rhs[i - 1]) 0 else 1

            val costReplace = cost[j - 1] + match
            val costInsert = cost[j] + 1
            val costDelete = newCost[j - 1] + 1

            newCost[j] = min(min(costInsert, costDelete), costReplace)
        }

        val swap = cost
        cost = newCost
        newCost = swap
    }

    return cost[lhsLength - 1]
}

Compiled from "Levenshtein.kt"
public final class neat.novelty.LevenshteinKt {
  public static final int levenshtein(java.lang.CharSequence, java.lang.CharSequence);
    Code:
       0: aload_0
       1: ldc           #9                  // String lhs
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #17                 // String rhs
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: aload_1
      14: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      17: ifeq          22
      20: iconst_0
      21: ireturn
      22: aload_0
      23: invokeinterface #27,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      28: ifne          35
      31: iconst_1
      32: goto          36
      35: iconst_0
      36: ifeq          46
      39: aload_1
      40: invokeinterface #27,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      45: ireturn
      46: aload_1
      47: invokeinterface #27,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      52: ifne          59
      55: iconst_1
      56: goto          60
      59: iconst_0
      60: ifeq          70
      63: aload_0
      64: invokeinterface #27,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      69: ireturn
      70: aload_0
      71: invokeinterface #27,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      76: iconst_1
      77: iadd
      78: istore_2
      79: aload_1
      80: invokeinterface #27,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      85: iconst_1
      86: iadd
      87: istore_3
      88: iconst_0
      89: istore        5
      91: iload_2
      92: anewarray     #29                 // class java/lang/Integer
      95: astore        6
      97: iload         5
      99: iload_2
     100: if_icmpge     123
     103: iload         5
     105: istore        7
     107: aload         6
     109: iload         7
     111: iload         7
     113: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     116: aastore
     117: iinc          5, 1
     120: goto          97
     123: aload         6
     125: astore        4
     127: iconst_0
     128: istore        6
     130: iload_2
     131: anewarray     #29                 // class java/lang/Integer
     134: astore        7
     136: iload         6
     138: iload_2
     139: if_icmpge     161
     142: iload         6
     144: istore        8
     146: aload         7
     148: iload         8
     150: iconst_0
     151: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     154: aastore
     155: iinc          6, 1
     158: goto          136
     161: aload         7
     163: astore        5
     165: iconst_1
     166: istore        6
     168: iload         6
     170: iload_3
     171: if_icmpge     307
     174: aload         5
     176: iconst_0
     177: iload         6
     179: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     182: aastore
     183: iconst_1
     184: istore        7
     186: iload         7
     188: iload_2
     189: if_icmpge     289
     192: aload_0
     193: iload         7
     195: iconst_1
     196: isub
     197: invokeinterface #37,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     202: aload_1
     203: iload         6
     205: iconst_1
     206: isub
     207: invokeinterface #37,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
     212: if_icmpne     219
     215: iconst_0
     216: goto          220
     219: iconst_1
     220: istore        8
     222: aload         4
     224: iload         7
     226: iconst_1
     227: isub
     228: aaload
     229: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     232: iload         8
     234: iadd
     235: istore        9
     237: aload         4
     239: iload         7
     241: aaload
     242: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     245: iconst_1
     246: iadd
     247: istore        10
     249: aload         5
     251: iload         7
     253: iconst_1
     254: isub
     255: aaload
     256: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     259: iconst_1
     260: iadd
     261: istore        11
     263: aload         5
     265: iload         7
     267: iload         10
     269: iload         11
     271: invokestatic  #46                 // Method java/lang/Math.min:(II)I
     274: iload         9
     276: invokestatic  #46                 // Method java/lang/Math.min:(II)I
     279: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     282: aastore
     283: iinc          7, 1
     286: goto          186
     289: aload         4
     291: astore        7
     293: aload         5
     295: astore        4
     297: aload         7
     299: astore        5
     301: iinc          6, 1
     304: goto          168
     307: aload         4
     309: iload_2
     310: iconst_1
     311: isub
     312: aaload
     313: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     316: ireturn

  public static final int levenshtein(java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>);
    Code:
       0: aload_0
       1: ldc           #9                  // String lhs
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #17                 // String rhs
       9: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: aload_1
      14: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      17: ifeq          22
      20: iconst_0
      21: ireturn
      22: aload_0
      23: invokeinterface #69,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      28: ifeq          38
      31: aload_1
      32: invokeinterface #72,  1           // InterfaceMethod java/util/List.size:()I
      37: ireturn
      38: aload_1
      39: invokeinterface #69,  1           // InterfaceMethod java/util/List.isEmpty:()Z
      44: ifeq          54
      47: aload_0
      48: invokeinterface #72,  1           // InterfaceMethod java/util/List.size:()I
      53: ireturn
      54: aload_0
      55: invokeinterface #72,  1           // InterfaceMethod java/util/List.size:()I
      60: iconst_1
      61: iadd
      62: istore_2
      63: aload_1
      64: invokeinterface #72,  1           // InterfaceMethod java/util/List.size:()I
      69: iconst_1
      70: iadd
      71: istore_3
      72: iconst_0
      73: istore        5
      75: iload_2
      76: anewarray     #29                 // class java/lang/Integer
      79: astore        6
      81: iload         5
      83: iload_2
      84: if_icmpge     107
      87: iload         5
      89: istore        7
      91: aload         6
      93: iload         7
      95: iload         7
      97: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     100: aastore
     101: iinc          5, 1
     104: goto          81
     107: aload         6
     109: astore        4
     111: iconst_0
     112: istore        6
     114: iload_2
     115: anewarray     #29                 // class java/lang/Integer
     118: astore        7
     120: iload         6
     122: iload_2
     123: if_icmpge     145
     126: iload         6
     128: istore        8
     130: aload         7
     132: iload         8
     134: iconst_0
     135: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     138: aastore
     139: iinc          6, 1
     142: goto          120
     145: aload         7
     147: astore        5
     149: iconst_1
     150: istore        6
     152: iload         6
     154: iload_3
     155: if_icmpge     303
     158: aload         5
     160: iconst_0
     161: iload         6
     163: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     166: aastore
     167: iconst_1
     168: istore        7
     170: iload         7
     172: iload_2
     173: if_icmpge     285
     176: aload_0
     177: iload         7
     179: iconst_1
     180: isub
     181: invokeinterface #76,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     186: checkcast     #78                 // class java/lang/Number
     189: invokevirtual #79                 // Method java/lang/Number.intValue:()I
     192: aload_1
     193: iload         6
     195: iconst_1
     196: isub
     197: invokeinterface #76,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     202: checkcast     #78                 // class java/lang/Number
     205: invokevirtual #79                 // Method java/lang/Number.intValue:()I
     208: if_icmpne     215
     211: iconst_0
     212: goto          216
     215: iconst_1
     216: istore        8
     218: aload         4
     220: iload         7
     222: iconst_1
     223: isub
     224: aaload
     225: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     228: iload         8
     230: iadd
     231: istore        9
     233: aload         4
     235: iload         7
     237: aaload
     238: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     241: iconst_1
     242: iadd
     243: istore        10
     245: aload         5
     247: iload         7
     249: iconst_1
     250: isub
     251: aaload
     252: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     255: iconst_1
     256: iadd
     257: istore        11
     259: aload         5
     261: iload         7
     263: iload         10
     265: iload         11
     267: invokestatic  #46                 // Method java/lang/Math.min:(II)I
     270: iload         9
     272: invokestatic  #46                 // Method java/lang/Math.min:(II)I
     275: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     278: aastore
     279: iinc          7, 1
     282: goto          170
     285: aload         4
     287: astore        7
     289: aload         5
     291: astore        4
     293: aload         7
     295: astore        5
     297: iinc          6, 1
     300: goto          152
     303: aload         4
     305: iload_2
     306: iconst_1
     307: isub
     308: aaload
     309: invokevirtual #40                 // Method java/lang/Integer.intValue:()I
     312: ireturn
}


package roundC2021

import kotlin.math.max
import kotlin.math.min

fun main() {
    val cases = readLine()!!.toInt()
    (1..cases).forEach { caseIndex ->
        val (N, K) = readLine()!!.split(" ").map { it.toLong() }
        val S = readLine()!!

        if (N == 1L) {
            val y = max(min((S[0].letterNr).code.toLong(), K), 0)
            println("Case #$caseIndex: $y")
        } else {
            val maxi = (N.toInt() - 1) / 2
            val result = algorithm(S, K, 0, maxi)
            println("Case #$caseIndex: $result")
        }
    }
}

private fun Long.modPow(power: Long, mod: Long): Long {
    if (power == 0L) {
        return 1L
    }
    if (power == 1L) {
        return this % mod
    }
    val halfPower = this.modPow(power / 2L, mod)
    return if (power % 2 == 0L) {
        (halfPower * halfPower) % mod
    } else {
        val halfPlusOnePower = (halfPower * this) % mod
        (halfPower * halfPlusOnePower) % mod
    }
}

private fun algorithm(S: String, K: Long, index: Int, maxi: Int): Long {
    if (index > maxi) {
        return 0
    }
    val possibleSmallerLetters = max(min((S[index].letterNr).code.toLong(), K), 0)
    var result = (possibleSmallerLetters * K.modPow((maxi - index).toLong(), 1000000007)).appropriateMod()
    if (K >= S[index].letterNr.code.toLong()) {
        if (index == maxi) {
            if (S.length % 2 == 0) {
                val half = S.substring(0..index)
                if (half + half.reversed() < S) {
                    result += 1
                }
            } else {
                val half = S.substring(0 until index)
                if (half + S[index] + half.reversed() < S) {
                    result += 1
                }
            }
        } else {
            result = (result + algorithm(S, K, index + 1, maxi)).appropriateMod()
        }
    }
    return result.appropriateMod()
}

private val Char.letterNr: Char
    get() = this - 97

private fun Long.appropriateMod() =
    ((this % 1000000007) + 1000000007) % 1000000007

Compiled from "smallerstrings.kt"
public final class roundC2021.SmallerstringsKt {
  public static final void main();
    Code:
       0: invokestatic  #12                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
       3: dup
       4: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
       7: invokestatic  #24                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
      10: istore_0
      11: new           #26                 // class kotlin/ranges/IntRange
      14: dup
      15: iconst_1
      16: iload_0
      17: invokespecial #30                 // Method kotlin/ranges/IntRange."<init>":(II)V
      20: checkcast     #32                 // class java/lang/Iterable
      23: astore_1
      24: iconst_0
      25: istore_2
      26: aload_1
      27: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      32: astore_3
      33: aload_3
      34: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          367
      42: aload_3
      43: checkcast     #44                 // class kotlin/collections/IntIterator
      46: invokevirtual #48                 // Method kotlin/collections/IntIterator.nextInt:()I
      49: istore        4
      51: iload         4
      53: istore        5
      55: iconst_0
      56: istore        6
      58: invokestatic  #12                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
      61: dup
      62: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
      65: checkcast     #50                 // class java/lang/CharSequence
      68: iconst_1
      69: anewarray     #52                 // class java/lang/String
      72: astore        7
      74: aload         7
      76: iconst_0
      77: ldc           #54                 // String
      79: aastore
      80: aload         7
      82: iconst_0
      83: iconst_0
      84: bipush        6
      86: aconst_null
      87: invokestatic  #60                 // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      90: checkcast     #32                 // class java/lang/Iterable
      93: astore        7
      95: iconst_0
      96: istore        8
      98: aload         7
     100: astore        9
     102: new           #62                 // class java/util/ArrayList
     105: dup
     106: aload         7
     108: bipush        10
     110: invokestatic  #68                 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     113: invokespecial #71                 // Method java/util/ArrayList."<init>":(I)V
     116: checkcast     #73                 // class java/util/Collection
     119: astore        10
     121: iconst_0
     122: istore        11
     124: aload         9
     126: invokeinterface #36,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     131: astore        12
     133: aload         12
     135: invokeinterface #42,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     140: ifeq          187
     143: aload         12
     145: invokeinterface #77,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     150: astore        13
     152: aload         10
     154: aload         13
     156: checkcast     #52                 // class java/lang/String
     159: astore        14
     161: astore        15
     163: iconst_0
     164: istore        16
     166: aload         14
     168: invokestatic  #83                 // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     171: nop
     172: invokestatic  #87                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     175: aload         15
     177: swap
     178: invokeinterface #91,  2           // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     183: pop
     184: goto          133
     187: aload         10
     189: checkcast     #93                 // class java/util/List
     192: nop
     193: astore        17
     195: aload         17
     197: iconst_0
     198: invokeinterface #97,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     203: checkcast     #99                 // class java/lang/Number
     206: invokevirtual #103                // Method java/lang/Number.longValue:()J
     209: lstore        18
     211: aload         17
     213: iconst_1
     214: invokeinterface #97,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     219: checkcast     #99                 // class java/lang/Number
     222: invokevirtual #103                // Method java/lang/Number.longValue:()J
     225: lstore        20
     227: invokestatic  #12                 // Method kotlin/io/ConsoleKt.readLine:()Ljava/lang/String;
     230: dup
     231: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
     234: astore        11
     236: lload         18
     238: lconst_1
     239: lcmp
     240: ifne          304
     243: aload         11
     245: iconst_0
     246: invokevirtual #107                // Method java/lang/String.charAt:(I)C
     249: invokestatic  #111                // Method getLetterNr:(C)C
     252: i2l
     253: lload         20
     255: invokestatic  #117                // Method java/lang/Math.min:(JJ)J
     258: lconst_0
     259: invokestatic  #120                // Method java/lang/Math.max:(JJ)J
     262: lstore        22
     264: new           #122                // class java/lang/StringBuilder
     267: dup
     268: invokespecial #124                // Method java/lang/StringBuilder."<init>":()V
     271: ldc           #126                // String Case #
     273: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     276: iload         5
     278: invokevirtual #133                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     281: ldc           #135                // String :
     283: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     286: lload         22
     288: invokevirtual #138                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     291: invokevirtual #141                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     294: getstatic     #147                // Field java/lang/System.out:Ljava/io/PrintStream;
     297: swap
     298: invokevirtual #152                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     301: goto          362
     304: lload         18
     306: l2i
     307: iconst_1
     308: isub
     309: iconst_2
     310: idiv
     311: istore        12
     313: aload         11
     315: lload         20
     317: iconst_0
     318: iload         12
     320: invokestatic  #156                // Method algorithm:(Ljava/lang/String;JII)J
     323: lstore        24
     325: new           #122                // class java/lang/StringBuilder
     328: dup
     329: invokespecial #124                // Method java/lang/StringBuilder."<init>":()V
     332: ldc           #126                // String Case #
     334: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     337: iload         5
     339: invokevirtual #133                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     342: ldc           #135                // String :
     344: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     347: lload         24
     349: invokevirtual #138                // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
     352: invokevirtual #141                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     355: getstatic     #147                // Field java/lang/System.out:Ljava/io/PrintStream;
     358: swap
     359: invokevirtual #152                // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     362: nop
     363: nop
     364: goto          33
     367: nop
     368: return

  private static final long modPow(long, long, long);
    Code:
       0: lload_2
       1: lconst_0
       2: lcmp
       3: ifne          8
       6: lconst_1
       7: lreturn
       8: lload_2
       9: lconst_1
      10: lcmp
      11: ifne          19
      14: lload_0
      15: lload         4
      17: lrem
      18: lreturn
      19: lload_0
      20: lload_2
      21: ldc2_w        #185                // long 2l
      24: ldiv
      25: lload         4
      27: invokestatic  #188                // Method modPow:(JJJ)J
      30: lstore        6
      32: lload_2
      33: iconst_2
      34: i2l
      35: lrem
      36: lconst_0
      37: lcmp
      38: ifne          52
      41: lload         6
      43: lload         6
      45: lmul
      46: lload         4
      48: lrem
      49: goto          69
      52: lload         6
      54: lload_0
      55: lmul
      56: lload         4
      58: lrem
      59: lstore        8
      61: lload         6
      63: lload         8
      65: lmul
      66: lload         4
      68: lrem
      69: lreturn

  private static final long algorithm(java.lang.String, long, int, int);
    Code:
       0: iload_3
       1: iload         4
       3: if_icmple     8
       6: lconst_0
       7: lreturn
       8: aload_0
       9: iload_3
      10: invokevirtual #107                // Method java/lang/String.charAt:(I)C
      13: invokestatic  #111                // Method getLetterNr:(C)C
      16: i2l
      17: lload_1
      18: invokestatic  #117                // Method java/lang/Math.min:(JJ)J
      21: lconst_0
      22: invokestatic  #120                // Method java/lang/Math.max:(JJ)J
      25: lstore        5
      27: lload         5
      29: lload_1
      30: iload         4
      32: iload_3
      33: isub
      34: i2l
      35: ldc2_w        #194                // long 1000000007l
      38: invokestatic  #188                // Method modPow:(JJJ)J
      41: lmul
      42: invokestatic  #199                // Method appropriateMod:(J)J
      45: lstore        7
      47: lload_1
      48: aload_0
      49: iload_3
      50: invokevirtual #107                // Method java/lang/String.charAt:(I)C
      53: invokestatic  #111                // Method getLetterNr:(C)C
      56: i2l
      57: lcmp
      58: iflt          218
      61: iload_3
      62: iload         4
      64: if_icmpne     200
      67: aload_0
      68: invokevirtual #202                // Method java/lang/String.length:()I
      71: iconst_2
      72: irem
      73: ifne          136
      76: aload_0
      77: new           #26                 // class kotlin/ranges/IntRange
      80: dup
      81: iconst_0
      82: iload_3
      83: invokespecial #30                 // Method kotlin/ranges/IntRange."<init>":(II)V
      86: invokestatic  #206                // Method kotlin/text/StringsKt.substring:(Ljava/lang/String;Lkotlin/ranges/IntRange;)Ljava/lang/String;
      89: astore        9
      91: new           #122                // class java/lang/StringBuilder
      94: dup
      95: invokespecial #124                // Method java/lang/StringBuilder."<init>":()V
      98: aload         9
     100: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     103: aload         9
     105: checkcast     #50                 // class java/lang/CharSequence
     108: invokestatic  #210                // Method kotlin/text/StringsKt.reversed:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     111: invokevirtual #211                // Method java/lang/Object.toString:()Ljava/lang/String;
     114: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     117: invokevirtual #141                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     120: aload_0
     121: invokevirtual #214                // Method java/lang/String.compareTo:(Ljava/lang/String;)I
     124: ifge          218
     127: lload         7
     129: lconst_1
     130: ladd
     131: lstore        7
     133: goto          218
     136: aload_0
     137: iconst_0
     138: iload_3
     139: invokestatic  #220                // Method kotlin/ranges/RangesKt.until:(II)Lkotlin/ranges/IntRange;
     142: invokestatic  #206                // Method kotlin/text/StringsKt.substring:(Ljava/lang/String;Lkotlin/ranges/IntRange;)Ljava/lang/String;
     145: astore        9
     147: new           #122                // class java/lang/StringBuilder
     150: dup
     151: invokespecial #124                // Method java/lang/StringBuilder."<init>":()V
     154: aload         9
     156: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     159: aload_0
     160: iload_3
     161: invokevirtual #107                // Method java/lang/String.charAt:(I)C
     164: invokevirtual #223                // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
     167: aload         9
     169: checkcast     #50                 // class java/lang/CharSequence
     172: invokestatic  #210                // Method kotlin/text/StringsKt.reversed:(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
     175: invokevirtual #211                // Method java/lang/Object.toString:()Ljava/lang/String;
     178: invokevirtual #130                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     181: invokevirtual #141                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     184: aload_0
     185: invokevirtual #214                // Method java/lang/String.compareTo:(Ljava/lang/String;)I
     188: ifge          218
     191: lload         7
     193: lconst_1
     194: ladd
     195: lstore        7
     197: goto          218
     200: lload         7
     202: aload_0
     203: lload_1
     204: iload_3
     205: iconst_1
     206: iadd
     207: iload         4
     209: invokestatic  #156                // Method algorithm:(Ljava/lang/String;JII)J
     212: ladd
     213: invokestatic  #199                // Method appropriateMod:(J)J
     216: lstore        7
     218: lload         7
     220: invokestatic  #199                // Method appropriateMod:(J)J
     223: lreturn

  private static final char getLetterNr(char);
    Code:
       0: iload_0
       1: bipush        97
       3: isub
       4: i2c
       5: ireturn

  private static final long appropriateMod(long);
    Code:
       0: lload_0
       1: ldc           #229                // int 1000000007
       3: i2l
       4: lrem
       5: ldc           #229                // int 1000000007
       7: i2l
       8: ladd
       9: ldc           #229                // int 1000000007
      11: i2l
      12: lrem
      13: lreturn

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #233                // Method main:()V
       3: return
}