package day05

import java.io.File
import kotlin.math.max
import kotlin.math.min

fun main() {
    run(::part1)
    run(::part2)
}

data class Map(val range: LongRange, val inc: Long)
data class Model(val seeds: List<LongRange>, val allMaps: List<List<Map>>)

fun run(part: (String) -> List<LongRange>) {
    val model = parseInput(part)
    var mapped = model.seeds
    for (maps in model.allMaps) {
        mapped = mapLongRanges(mapped, maps)
    }
    println(mapped.minOfOrNull { it.first })
}

fun mapLongRanges(ranges: List<LongRange>, maps: List<Map>): List<LongRange> {
    val result = mutableListOf<LongRange>()
    var unprocessed = mutableListOf<LongRange>()
    var toProcess = MutableList(ranges.size) { ranges[it] }
    for (map in maps) {
        for (range in toProcess) {
            if (range.first >= map.range.last || range.last <= map.range.first) {
                unprocessed += range
            } else {
                val start = max(range.first, map.range.first)
                val end = min(range.last, map.range.last)
                result += start + map.inc..<end + map.inc
                if (range.first < start) {
                    unprocessed += range.first..<start
                }
                if (range.last > end) {
                    unprocessed += end..<range.last
                }
            }
        }

        toProcess = unprocessed
        unprocessed = mutableListOf()
    }

    result += toProcess
    return result
}

fun parseInput(seeds: (String) -> List<LongRange>): Model {
    val lines = File("input.data").readLines()
    val ranges = seeds(lines[0])

    val allMaps = mutableListOf<List<Map>>()
    var curMaps = mutableListOf<Map>()

    for (line in lines.drop(3)) {
        when {
            line == "" -> continue
            line.endsWith(" map:") -> {
                allMaps += curMaps
                curMaps = mutableListOf()
            }

            else -> {
                val numbers = line.split(" ").map { it.toLong() }
                curMaps += Map(range = numbers[1]..< numbers[1] + numbers[2], inc = numbers[0] - numbers[1])
            }
        }
    }
    allMaps += curMaps
    return Model(seeds = ranges, allMaps = allMaps)
}

fun part1(line: String): List<LongRange> =
    line.split(" ").drop(1).map {
        val start = it.toLong()
        start..<start+1
    }

fun part2(line: String): List<LongRange> {
    val seedNumbers = line.split(" ").drop(1).map { it.toLong() }
    return seedNumbers.chunked(2).map { (start, len) -> start..<start + len }
}

// 993500720
//   4917124

Compiled from "day05.kt"
public final class day05.Day05Kt {
  public static final void main();
    Code:
       0: getstatic     #12                 // Field day05/Day05Kt$main$1.INSTANCE:Lday05/Day05Kt$main$1;
       3: checkcast     #14                 // class kotlin/jvm/functions/Function1
       6: invokestatic  #18                 // Method run:(Lkotlin/jvm/functions/Function1;)V
       9: getstatic     #23                 // Field day05/Day05Kt$main$2.INSTANCE:Lday05/Day05Kt$main$2;
      12: checkcast     #14                 // class kotlin/jvm/functions/Function1
      15: invokestatic  #18                 // Method run:(Lkotlin/jvm/functions/Function1;)V
      18: return

  public static final void run(kotlin.jvm.functions.Function1<? super java.lang.String, ? extends java.util.List<kotlin.ranges.LongRange>>);
    Code:
       0: aload_0
       1: ldc           #27                 // String part
       3: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #37                 // Method parseInput:(Lkotlin/jvm/functions/Function1;)Lday05/Model;
      10: astore_1
      11: aload_1
      12: invokevirtual #43                 // Method day05/Model.getSeeds:()Ljava/util/List;
      15: astore_2
      16: aload_1
      17: invokevirtual #46                 // Method day05/Model.getAllMaps:()Ljava/util/List;
      20: invokeinterface #52,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      25: astore_3
      26: aload_3
      27: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      32: ifeq          56
      35: aload_3
      36: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      41: checkcast     #48                 // class java/util/List
      44: astore        4
      46: aload_2
      47: aload         4
      49: invokestatic  #66                 // Method mapLongRanges:(Ljava/util/List;Ljava/util/List;)Ljava/util/List;
      52: astore_2
      53: goto          26
      56: aload_2
      57: checkcast     #68                 // class java/lang/Iterable
      60: invokeinterface #69,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      65: astore        4
      67: aload         4
      69: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      74: ifne          81
      77: aconst_null
      78: goto          168
      81: aload         4
      83: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      88: checkcast     #71                 // class kotlin/ranges/LongRange
      91: astore        5
      93: iconst_0
      94: istore        6
      96: aload         5
      98: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     101: invokestatic  #81                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     104: checkcast     #83                 // class java/lang/Comparable
     107: astore        5
     109: aload         4
     111: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     116: ifeq          166
     119: aload         4
     121: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     126: checkcast     #71                 // class kotlin/ranges/LongRange
     129: astore        6
     131: iconst_0
     132: istore        7
     134: aload         6
     136: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     139: invokestatic  #81                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     142: checkcast     #83                 // class java/lang/Comparable
     145: astore        6
     147: aload         5
     149: aload         6
     151: invokeinterface #87,  2           // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
     156: ifle          109
     159: aload         6
     161: astore        5
     163: goto          109
     166: aload         5
     168: astore_3
     169: getstatic     #93                 // Field java/lang/System.out:Ljava/io/PrintStream;
     172: aload_3
     173: invokevirtual #99                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     176: return

  public static final java.util.List<kotlin.ranges.LongRange> mapLongRanges(java.util.List<kotlin.ranges.LongRange>, java.util.List<day05.Map>);
    Code:
       0: aload_0
       1: ldc           #112                // String ranges
       3: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #113                // String maps
       9: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: new           #115                // class java/util/ArrayList
      15: dup
      16: invokespecial #118                // Method java/util/ArrayList."<init>":()V
      19: checkcast     #48                 // class java/util/List
      22: astore_2
      23: new           #115                // class java/util/ArrayList
      26: dup
      27: invokespecial #118                // Method java/util/ArrayList."<init>":()V
      30: checkcast     #48                 // class java/util/List
      33: astore_3
      34: aload_0
      35: invokeinterface #122,  1          // InterfaceMethod java/util/List.size:()I
      40: istore        5
      42: new           #115                // class java/util/ArrayList
      45: dup
      46: iload         5
      48: invokespecial #125                // Method java/util/ArrayList."<init>":(I)V
      51: astore        6
      53: iconst_0
      54: istore        7
      56: iload         7
      58: iload         5
      60: if_icmpge     102
      63: iload         7
      65: istore        8
      67: aload         6
      69: iload         8
      71: istore        9
      73: astore        13
      75: iconst_0
      76: istore        10
      78: aload_0
      79: iload         9
      81: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      86: checkcast     #71                 // class kotlin/ranges/LongRange
      89: aload         13
      91: swap
      92: invokevirtual #133                // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      95: pop
      96: iinc          7, 1
      99: goto          56
     102: aload         6
     104: checkcast     #48                 // class java/util/List
     107: astore        4
     109: aload_1
     110: invokeinterface #52,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     115: astore        5
     117: aload         5
     119: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     124: ifeq          366
     127: aload         5
     129: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     134: checkcast     #135                // class day05/Map
     137: astore        6
     139: aload         4
     141: invokeinterface #52,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     146: astore        7
     148: aload         7
     150: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     155: ifeq          349
     158: aload         7
     160: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     165: checkcast     #71                 // class kotlin/ranges/LongRange
     168: astore        8
     170: aload         8
     172: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     175: aload         6
     177: invokevirtual #139                // Method day05/Map.getRange:()Lkotlin/ranges/LongRange;
     180: invokevirtual #142                // Method kotlin/ranges/LongRange.getLast:()J
     183: lcmp
     184: ifge          204
     187: aload         8
     189: invokevirtual #142                // Method kotlin/ranges/LongRange.getLast:()J
     192: aload         6
     194: invokevirtual #139                // Method day05/Map.getRange:()Lkotlin/ranges/LongRange;
     197: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     200: lcmp
     201: ifgt          219
     204: aload_3
     205: checkcast     #144                // class java/util/Collection
     208: aload         8
     210: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     215: pop
     216: goto          148
     219: aload         8
     221: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     224: aload         6
     226: invokevirtual #139                // Method day05/Map.getRange:()Lkotlin/ranges/LongRange;
     229: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     232: invokestatic  #151                // Method java/lang/Math.max:(JJ)J
     235: lstore        9
     237: aload         8
     239: invokevirtual #142                // Method kotlin/ranges/LongRange.getLast:()J
     242: aload         6
     244: invokevirtual #139                // Method day05/Map.getRange:()Lkotlin/ranges/LongRange;
     247: invokevirtual #142                // Method kotlin/ranges/LongRange.getLast:()J
     250: invokestatic  #154                // Method java/lang/Math.min:(JJ)J
     253: lstore        11
     255: aload_2
     256: checkcast     #144                // class java/util/Collection
     259: lload         9
     261: aload         6
     263: invokevirtual #157                // Method day05/Map.getInc:()J
     266: ladd
     267: lload         11
     269: aload         6
     271: invokevirtual #157                // Method day05/Map.getInc:()J
     274: ladd
     275: invokestatic  #163                // Method kotlin/ranges/RangesKt.until:(JJ)Lkotlin/ranges/LongRange;
     278: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     283: pop
     284: aload         8
     286: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     289: lload         9
     291: lcmp
     292: ifge          315
     295: aload_3
     296: checkcast     #144                // class java/util/Collection
     299: aload         8
     301: invokevirtual #75                 // Method kotlin/ranges/LongRange.getFirst:()J
     304: lload         9
     306: invokestatic  #163                // Method kotlin/ranges/RangesKt.until:(JJ)Lkotlin/ranges/LongRange;
     309: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     314: pop
     315: aload         8
     317: invokevirtual #142                // Method kotlin/ranges/LongRange.getLast:()J
     320: lload         11
     322: lcmp
     323: ifle          148
     326: aload_3
     327: checkcast     #144                // class java/util/Collection
     330: lload         11
     332: aload         8
     334: invokevirtual #142                // Method kotlin/ranges/LongRange.getLast:()J
     337: invokestatic  #163                // Method kotlin/ranges/RangesKt.until:(JJ)Lkotlin/ranges/LongRange;
     340: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     345: pop
     346: goto          148
     349: aload_3
     350: astore        4
     352: new           #115                // class java/util/ArrayList
     355: dup
     356: invokespecial #118                // Method java/util/ArrayList."<init>":()V
     359: checkcast     #48                 // class java/util/List
     362: astore_3
     363: goto          117
     366: aload_2
     367: checkcast     #144                // class java/util/Collection
     370: aload         4
     372: checkcast     #68                 // class java/lang/Iterable
     375: invokestatic  #169                // Method kotlin/collections/CollectionsKt.addAll:(Ljava/util/Collection;Ljava/lang/Iterable;)Z
     378: pop
     379: aload_2
     380: areturn

  public static final day05.Model parseInput(kotlin.jvm.functions.Function1<? super java.lang.String, ? extends java.util.List<kotlin.ranges.LongRange>>);
    Code:
       0: aload_0
       1: ldc           #182                // String seeds
       3: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #184                // class java/io/File
       9: dup
      10: ldc           #186                // String input.data
      12: invokespecial #189                // Method java/io/File."<init>":(Ljava/lang/String;)V
      15: aconst_null
      16: iconst_1
      17: aconst_null
      18: invokestatic  #195                // Method kotlin/io/FilesKt.readLines$default:(Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Ljava/util/List;
      21: astore_1
      22: aload_0
      23: aload_1
      24: iconst_0
      25: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      30: invokeinterface #199,  2          // InterfaceMethod kotlin/jvm/functions/Function1.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
      35: checkcast     #48                 // class java/util/List
      38: astore_2
      39: new           #115                // class java/util/ArrayList
      42: dup
      43: invokespecial #118                // Method java/util/ArrayList."<init>":()V
      46: checkcast     #48                 // class java/util/List
      49: astore_3
      50: new           #115                // class java/util/ArrayList
      53: dup
      54: invokespecial #118                // Method java/util/ArrayList."<init>":()V
      57: checkcast     #48                 // class java/util/List
      60: astore        4
      62: aload_1
      63: checkcast     #68                 // class java/lang/Iterable
      66: iconst_3
      67: invokestatic  #203                // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      70: invokeinterface #52,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      75: astore        5
      77: aload         5
      79: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      84: ifeq          378
      87: aload         5
      89: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      94: checkcast     #205                // class java/lang/String
      97: astore        6
      99: nop
     100: aload         6
     102: ldc           #207                // String
     104: invokestatic  #211                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
     107: ifne          77
     110: aload         6
     112: ldc           #213                // String  map:
     114: iconst_0
     115: iconst_2
     116: aconst_null
     117: invokestatic  #219                // Method kotlin/text/StringsKt.endsWith$default:(Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Z
     120: ifeq          150
     123: aload_3
     124: checkcast     #144                // class java/util/Collection
     127: aload         4
     129: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     134: pop
     135: new           #115                // class java/util/ArrayList
     138: dup
     139: invokespecial #118                // Method java/util/ArrayList."<init>":()V
     142: checkcast     #48                 // class java/util/List
     145: astore        4
     147: goto          77
     150: aload         6
     152: checkcast     #221                // class java/lang/CharSequence
     155: iconst_1
     156: anewarray     #205                // class java/lang/String
     159: astore        8
     161: aload         8
     163: iconst_0
     164: ldc           #223                // String
     166: aastore
     167: aload         8
     169: iconst_0
     170: iconst_0
     171: bipush        6
     173: aconst_null
     174: invokestatic  #227                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
     177: checkcast     #68                 // class java/lang/Iterable
     180: astore        8
     182: iconst_0
     183: istore        9
     185: aload         8
     187: astore        10
     189: new           #115                // class java/util/ArrayList
     192: dup
     193: aload         8
     195: bipush        10
     197: invokestatic  #231                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     200: invokespecial #125                // Method java/util/ArrayList."<init>":(I)V
     203: checkcast     #144                // class java/util/Collection
     206: astore        11
     208: iconst_0
     209: istore        12
     211: aload         10
     213: invokeinterface #69,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     218: astore        13
     220: aload         13
     222: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     227: ifeq          274
     230: aload         13
     232: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     237: astore        14
     239: aload         11
     241: aload         14
     243: checkcast     #205                // class java/lang/String
     246: astore        15
     248: astore        17
     250: iconst_0
     251: istore        16
     253: aload         15
     255: invokestatic  #235                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     258: nop
     259: invokestatic  #81                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     262: aload         17
     264: swap
     265: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     270: pop
     271: goto          220
     274: aload         11
     276: checkcast     #48                 // class java/util/List
     279: nop
     280: astore        7
     282: aload         4
     284: checkcast     #144                // class java/util/Collection
     287: new           #135                // class day05/Map
     290: dup
     291: aload         7
     293: iconst_1
     294: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     299: checkcast     #237                // class java/lang/Number
     302: invokevirtual #240                // Method java/lang/Number.longValue:()J
     305: aload         7
     307: iconst_1
     308: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     313: checkcast     #237                // class java/lang/Number
     316: invokevirtual #240                // Method java/lang/Number.longValue:()J
     319: aload         7
     321: iconst_2
     322: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     327: checkcast     #237                // class java/lang/Number
     330: invokevirtual #240                // Method java/lang/Number.longValue:()J
     333: ladd
     334: invokestatic  #163                // Method kotlin/ranges/RangesKt.until:(JJ)Lkotlin/ranges/LongRange;
     337: aload         7
     339: iconst_0
     340: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     345: checkcast     #237                // class java/lang/Number
     348: invokevirtual #240                // Method java/lang/Number.longValue:()J
     351: aload         7
     353: iconst_1
     354: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     359: checkcast     #237                // class java/lang/Number
     362: invokevirtual #240                // Method java/lang/Number.longValue:()J
     365: lsub
     366: invokespecial #243                // Method day05/Map."<init>":(Lkotlin/ranges/LongRange;J)V
     369: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     374: pop
     375: goto          77
     378: aload_3
     379: checkcast     #144                // class java/util/Collection
     382: aload         4
     384: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     389: pop
     390: new           #39                 // class day05/Model
     393: dup
     394: aload_2
     395: aload_3
     396: invokespecial #246                // Method day05/Model."<init>":(Ljava/util/List;Ljava/util/List;)V
     399: areturn

  public static final java.util.List<kotlin.ranges.LongRange> part1(java.lang.String);
    Code:
       0: aload_0
       1: ldc_w         #266                // String line
       4: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: checkcast     #221                // class java/lang/CharSequence
      11: iconst_1
      12: anewarray     #205                // class java/lang/String
      15: astore_1
      16: aload_1
      17: iconst_0
      18: ldc           #223                // String
      20: aastore
      21: aload_1
      22: iconst_0
      23: iconst_0
      24: bipush        6
      26: aconst_null
      27: invokestatic  #227                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      30: checkcast     #68                 // class java/lang/Iterable
      33: iconst_1
      34: invokestatic  #203                // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      37: checkcast     #68                 // class java/lang/Iterable
      40: astore_1
      41: iconst_0
      42: istore_2
      43: aload_1
      44: astore_3
      45: new           #115                // class java/util/ArrayList
      48: dup
      49: aload_1
      50: bipush        10
      52: invokestatic  #231                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      55: invokespecial #125                // Method java/util/ArrayList."<init>":(I)V
      58: checkcast     #144                // class java/util/Collection
      61: astore        4
      63: iconst_0
      64: istore        5
      66: aload_3
      67: invokeinterface #69,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      72: astore        6
      74: aload         6
      76: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      81: ifeq          135
      84: aload         6
      86: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      91: astore        7
      93: aload         4
      95: aload         7
      97: checkcast     #205                // class java/lang/String
     100: astore        8
     102: astore        12
     104: iconst_0
     105: istore        9
     107: aload         8
     109: invokestatic  #235                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     112: lstore        10
     114: lload         10
     116: lload         10
     118: lconst_1
     119: ladd
     120: invokestatic  #163                // Method kotlin/ranges/RangesKt.until:(JJ)Lkotlin/ranges/LongRange;
     123: aload         12
     125: swap
     126: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     131: pop
     132: goto          74
     135: aload         4
     137: checkcast     #48                 // class java/util/List
     140: nop
     141: areturn

  public static final java.util.List<kotlin.ranges.LongRange> part2(java.lang.String);
    Code:
       0: aload_0
       1: ldc_w         #266                // String line
       4: invokestatic  #33                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: checkcast     #221                // class java/lang/CharSequence
      11: iconst_1
      12: anewarray     #205                // class java/lang/String
      15: astore_2
      16: aload_2
      17: iconst_0
      18: ldc           #223                // String
      20: aastore
      21: aload_2
      22: iconst_0
      23: iconst_0
      24: bipush        6
      26: aconst_null
      27: invokestatic  #227                // Method kotlin/text/StringsKt.split$default:(Ljava/lang/CharSequence;[Ljava/lang/String;ZIILjava/lang/Object;)Ljava/util/List;
      30: checkcast     #68                 // class java/lang/Iterable
      33: iconst_1
      34: invokestatic  #203                // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      37: checkcast     #68                 // class java/lang/Iterable
      40: astore_2
      41: iconst_0
      42: istore_3
      43: aload_2
      44: astore        4
      46: new           #115                // class java/util/ArrayList
      49: dup
      50: aload_2
      51: bipush        10
      53: invokestatic  #231                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      56: invokespecial #125                // Method java/util/ArrayList."<init>":(I)V
      59: checkcast     #144                // class java/util/Collection
      62: astore        5
      64: iconst_0
      65: istore        6
      67: aload         4
      69: invokeinterface #69,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      74: astore        7
      76: aload         7
      78: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      83: ifeq          130
      86: aload         7
      88: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      93: astore        8
      95: aload         5
      97: aload         8
      99: checkcast     #205                // class java/lang/String
     102: astore        9
     104: astore        15
     106: iconst_0
     107: istore        10
     109: aload         9
     111: invokestatic  #235                // Method java/lang/Long.parseLong:(Ljava/lang/String;)J
     114: nop
     115: invokestatic  #81                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
     118: aload         15
     120: swap
     121: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     126: pop
     127: goto          76
     130: aload         5
     132: checkcast     #48                 // class java/util/List
     135: nop
     136: astore_1
     137: aload_1
     138: checkcast     #68                 // class java/lang/Iterable
     141: iconst_2
     142: invokestatic  #271                // Method kotlin/collections/CollectionsKt.chunked:(Ljava/lang/Iterable;I)Ljava/util/List;
     145: checkcast     #68                 // class java/lang/Iterable
     148: astore_2
     149: iconst_0
     150: istore_3
     151: aload_2
     152: astore        4
     154: new           #115                // class java/util/ArrayList
     157: dup
     158: aload_2
     159: bipush        10
     161: invokestatic  #231                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     164: invokespecial #125                // Method java/util/ArrayList."<init>":(I)V
     167: checkcast     #144                // class java/util/Collection
     170: astore        5
     172: iconst_0
     173: istore        6
     175: aload         4
     177: invokeinterface #69,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     182: astore        7
     184: aload         7
     186: invokeinterface #58,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     191: ifeq          271
     194: aload         7
     196: invokeinterface #62,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     201: astore        8
     203: aload         5
     205: aload         8
     207: checkcast     #48                 // class java/util/List
     210: astore        9
     212: astore        15
     214: iconst_0
     215: istore        10
     217: aload         9
     219: iconst_0
     220: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     225: checkcast     #237                // class java/lang/Number
     228: invokevirtual #240                // Method java/lang/Number.longValue:()J
     231: lstore        11
     233: aload         9
     235: iconst_1
     236: invokeinterface #129,  2          // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     241: checkcast     #237                // class java/lang/Number
     244: invokevirtual #240                // Method java/lang/Number.longValue:()J
     247: lstore        13
     249: lload         11
     251: lload         11
     253: lload         13
     255: ladd
     256: invokestatic  #163                // Method kotlin/ranges/RangesKt.until:(JJ)Lkotlin/ranges/LongRange;
     259: aload         15
     261: swap
     262: invokeinterface #145,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     267: pop
     268: goto          184
     271: aload         5
     273: checkcast     #48                 // class java/util/List
     276: nop
     277: areturn

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

Compiled from "day05.kt"
final class day05.Day05Kt$main$2 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function1<java.lang.String, java.util.List<? extends kotlin.ranges.LongRange>> {
  public static final day05.Day05Kt$main$2 INSTANCE;

  day05.Day05Kt$main$2();
    Code:
       0: aload_0
       1: iconst_1
       2: ldc           #11                 // class day05/Day05Kt
       4: ldc           #13                 // String part2
       6: ldc           #15                 // String part2(Ljava/lang/String;)Ljava/util/List;
       8: iconst_1
       9: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      12: return

  public final java.util.List<kotlin.ranges.LongRange> invoke(java.lang.String);
    Code:
       0: aload_1
       1: ldc           #25                 // String p0
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokestatic  #33                 // Method day05/Day05Kt.part2:(Ljava/lang/String;)Ljava/util/List;
      10: areturn

  public java.lang.Object invoke(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #37                 // class java/lang/String
       5: invokevirtual #39                 // Method invoke:(Ljava/lang/String;)Ljava/util/List;
       8: areturn

  static {};
    Code:
       0: new           #2                  // class day05/Day05Kt$main$2
       3: dup
       4: invokespecial #44                 // Method "<init>":()V
       7: putstatic     #47                 // Field INSTANCE:Lday05/Day05Kt$main$2;
      10: return
}

Compiled from "day05.kt"
final class day05.Day05Kt$main$1 extends kotlin.jvm.internal.FunctionReferenceImpl implements kotlin.jvm.functions.Function1<java.lang.String, java.util.List<? extends kotlin.ranges.LongRange>> {
  public static final day05.Day05Kt$main$1 INSTANCE;

  day05.Day05Kt$main$1();
    Code:
       0: aload_0
       1: iconst_1
       2: ldc           #11                 // class day05/Day05Kt
       4: ldc           #13                 // String part1
       6: ldc           #15                 // String part1(Ljava/lang/String;)Ljava/util/List;
       8: iconst_1
       9: invokespecial #18                 // Method kotlin/jvm/internal/FunctionReferenceImpl."<init>":(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
      12: return

  public final java.util.List<kotlin.ranges.LongRange> invoke(java.lang.String);
    Code:
       0: aload_1
       1: ldc           #25                 // String p0
       3: invokestatic  #31                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: invokestatic  #33                 // Method day05/Day05Kt.part1:(Ljava/lang/String;)Ljava/util/List;
      10: areturn

  public java.lang.Object invoke(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #37                 // class java/lang/String
       5: invokevirtual #39                 // Method invoke:(Ljava/lang/String;)Ljava/util/List;
       8: areturn

  static {};
    Code:
       0: new           #2                  // class day05/Day05Kt$main$1
       3: dup
       4: invokespecial #44                 // Method "<init>":()V
       7: putstatic     #47                 // Field INSTANCE:Lday05/Day05Kt$main$1;
      10: return
}


package com.ztoais.dailycoding.algoexpert.easy
/*
Two Number Sum
Write a function that takes in a non-empty array of distinct integers and an integer representing a target sum. If any
two numbers in the input array sum up to the target sum, the function  should return then in an array. in any order. if
no two numbers sum up the target sum, the function should return an empty array.

Note that the target sum has to be obtained by summing two different integers in the array: you can't add a single integer
to itself in order to obtain the target sum.

You can assume that there will be at most one pair of numbers summing up to the target sum.
 */

//Sample input
/*
{
  "array": [3, 5, -4, 8, 11, 1, -1, 6],
  "targetSum": 10
}
//Sample output
 [-1,11]
 */
fun twoNumberSum(array: MutableList<Int>,targetSum:Int):List<Int>{
    val initialValue = array[0]

    val newArray = mutableListOf<Int>()

    array.drop(1).forEach{nextValue ->
        if(initialValue+nextValue == targetSum){
            return listOf(initialValue,nextValue)
        }else{
            newArray.add(nextValue)
        }
    }

    if(newArray.size >1){
        return twoNumberSum(newArray,targetSum)
    }

    return listOf()
}

/*
 //Test cases

 Test Case 1
{
  "array": [3, 5, -4, 8, 11, 1, -1, 6],
  "targetSum": 10
}
Test Case 2
{
  "array": [4, 6],
  "targetSum": 10
}
Test Case 3
{
  "array": [4, 6, 1],
  "targetSum": 5
}
Test Case 4
{
  "array": [4, 6, 1, -3],
  "targetSum": 3
}
Test Case 5
{
  "array": [1, 2, 3, 4, 5, 6, 7, 8, 9],
  "targetSum": 17
}
Test Case 6
{
  "array": [1, 2, 3, 4, 5, 6, 7, 8, 9, 15],
  "targetSum": 18
}
Test Case 7
{
  "array": [-7, -5, -3, -1, 0, 1, 3, 5, 7],
  "targetSum": -5
}
Test Case 8
{
  "array": [-21, 301, 12, 4, 65, 56, 210, 356, 9, -47],
  "targetSum": 163
}
Test Case 9
{
  "array": [-21, 301, 12, 4, 65, 56, 210, 356, 9, -47],
  "targetSum": 164
}
Test Case 10
{
  "array": [3, 5, -4, 8, 11, 1, -1, 6],
  "targetSum": 15
}
Test Case 11
{
  "array": [14],
  "targetSum": 15
}
Test Case 12
{
  "array": [15],
  "targetSum": 15
}
 */

Compiled from "TwoNumberSum.kt"
public final class com.ztoais.dailycoding.algoexpert.easy.TwoNumberSumKt {
  public static final java.util.List<java.lang.Integer> twoNumberSum(java.util.List<java.lang.Integer>, int);
    Code:
       0: aload_0
       1: ldc           #10                 // String array
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: iconst_0
       8: invokeinterface #22,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      13: checkcast     #24                 // class java/lang/Number
      16: invokevirtual #28                 // Method java/lang/Number.intValue:()I
      19: istore_2
      20: new           #30                 // class java/util/ArrayList
      23: dup
      24: invokespecial #34                 // Method java/util/ArrayList."<init>":()V
      27: checkcast     #18                 // class java/util/List
      30: astore_3
      31: aload_0
      32: checkcast     #36                 // class java/lang/Iterable
      35: iconst_1
      36: invokestatic  #42                 // Method kotlin/collections/CollectionsKt.drop:(Ljava/lang/Iterable;I)Ljava/util/List;
      39: checkcast     #36                 // class java/lang/Iterable
      42: astore        4
      44: iconst_0
      45: istore        5
      47: aload         4
      49: invokeinterface #46,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      54: astore        6
      56: aload         6
      58: invokeinterface #52,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      63: ifeq          142
      66: aload         6
      68: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      73: astore        7
      75: aload         7
      77: checkcast     #24                 // class java/lang/Number
      80: invokevirtual #28                 // Method java/lang/Number.intValue:()I
      83: istore        8
      85: iconst_0
      86: istore        9
      88: iload_2
      89: iload         8
      91: iadd
      92: iload_1
      93: if_icmpne     125
      96: iconst_2
      97: anewarray     #58                 // class java/lang/Integer
     100: astore        10
     102: aload         10
     104: iconst_0
     105: iload_2
     106: invokestatic  #62                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     109: aastore
     110: aload         10
     112: iconst_1
     113: iload         8
     115: invokestatic  #62                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     118: aastore
     119: aload         10
     121: invokestatic  #66                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     124: areturn
     125: aload_3
     126: iload         8
     128: invokestatic  #62                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     131: invokeinterface #70,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     136: pop
     137: nop
     138: nop
     139: goto          56
     142: nop
     143: aload_3
     144: invokeinterface #73,  1           // InterfaceMethod java/util/List.size:()I
     149: iconst_1
     150: if_icmple     159
     153: aload_3
     154: iload_1
     155: invokestatic  #75                 // Method twoNumberSum:(Ljava/util/List;I)Ljava/util/List;
     158: areturn
     159: invokestatic  #79                 // Method kotlin/collections/CollectionsKt.emptyList:()Ljava/util/List;
     162: areturn
}


package com.ztoais.dailycoding.algoexpert.hard

/*
 Write a function that takes in a non-empty array of distinct integers and an integer representing a target sum. The
 function should find all quadruplets in the array that sum up to the target sum and return a tow-dimensional array of
 all these quadruplets in no particular order.

 If no four numbers sum up to the target sum, the function should return an empty array

 Sample input
 array = [7,6,4,-1,1,2]
 targetSum = 16

 Sample output
 [[7,6,4,-1],[7,6,1,2]]
 */

/*

 */

fun fourNumberSum(array: MutableList<Int>, targetSum:Int):List<List<Int>>{
    val result = mutableListOf<List<Int>>()
    val appPairSums = mutableMapOf<Int,List<Pair<Int,Int>>>()
    for (i in 1 until array.size-1) {
        for(j in i+1 until array.size){
            val currentSum:Int = array[i]+array[j]
            val difference = targetSum - currentSum
            if(appPairSums.containsKey(difference)){
                val pairValues = appPairSums[difference]
                pairValues?.let {
                    for(pair in it){
                        val quadruplets = listOf(pair.first,pair.second, array[i], array[j])
                        result.add(quadruplets)
                    }

                }

            }
        }
        for(k in 0 until i){
            val currentSum = array[i]+array[k]
            if(!appPairSums.containsKey(currentSum)){
                appPairSums[currentSum] = listOf(Pair(array[k],array[i]))
            }else{
                val pairList = appPairSums[currentSum]?.toMutableList()
                pairList?.add(Pair(array[k],array[i]))
                if (pairList != null) {
                    appPairSums[currentSum] = pairList.toList()
                }
            }
        }
    }

    return result
}

/*

Tests

Quick Test

Sandbox

Test Case 1
{
  "array": [7, 6, 4, -1, 1, 2],
  "targetSum": 16
}
Test Case 2
{
  "array": [1, 2, 3, 4, 5, 6, 7],
  "targetSum": 10
}
Test Case 3
{
  "array": [5, -5, -2, 2, 3, -3],
  "targetSum": 0
}
Test Case 4
{
  "array": [-2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9],
  "targetSum": 4
}
Test Case 5
{
  "array": [-1, 22, 18, 4, 7, 11, 2, -5, -3],
  "targetSum": 30
}
Test Case 6
{
  "array": [-10, -3, -5, 2, 15, -7, 28, -6, 12, 8, 11, 5],
  "targetSum": 20
}
Test Case 7
{
  "array": [1, 2, 3, 4, 5],
  "targetSum": 100
}
Test Case 8
{
  "array": [1, 2, 3, 4, 5, -5, 6, -6],
  "targetSum": 5
}
 */

Compiled from "FourNumberSum.kt"
public final class com.ztoais.dailycoding.algoexpert.hard.FourNumberSumKt {
  public static final java.util.List<java.util.List<java.lang.Integer>> fourNumberSum(java.util.List<java.lang.Integer>, int);
    Code:
       0: aload_0
       1: ldc           #10                 // String array
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #18                 // class java/util/ArrayList
       9: dup
      10: invokespecial #22                 // Method java/util/ArrayList."<init>":()V
      13: checkcast     #24                 // class java/util/List
      16: astore_2
      17: new           #26                 // class java/util/LinkedHashMap
      20: dup
      21: invokespecial #27                 // Method java/util/LinkedHashMap."<init>":()V
      24: checkcast     #29                 // class java/util/Map
      27: astore_3
      28: iconst_1
      29: istore        4
      31: aload_0
      32: invokeinterface #33,  1           // InterfaceMethod java/util/List.size:()I
      37: iconst_1
      38: isub
      39: istore        5
      41: iload         4
      43: iload         5
      45: if_icmpge     468
      48: iload         4
      50: iconst_1
      51: iadd
      52: istore        6
      54: aload_0
      55: invokeinterface #33,  1           // InterfaceMethod java/util/List.size:()I
      60: istore        7
      62: iload         6
      64: iload         7
      66: if_icmpge     257
      69: aload_0
      70: iload         4
      72: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      77: checkcast     #39                 // class java/lang/Number
      80: invokevirtual #42                 // Method java/lang/Number.intValue:()I
      83: aload_0
      84: iload         6
      86: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      91: checkcast     #39                 // class java/lang/Number
      94: invokevirtual #42                 // Method java/lang/Number.intValue:()I
      97: iadd
      98: istore        8
     100: iload_1
     101: iload         8
     103: isub
     104: istore        9
     106: aload_3
     107: iload         9
     109: invokestatic  #48                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     112: invokeinterface #52,  2           // InterfaceMethod java/util/Map.containsKey:(Ljava/lang/Object;)Z
     117: ifeq          251
     120: aload_3
     121: iload         9
     123: invokestatic  #48                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     126: invokeinterface #55,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     131: checkcast     #24                 // class java/util/List
     134: astore        10
     136: aload         10
     138: dup
     139: ifnull        249
     142: astore        11
     144: iconst_0
     145: istore        12
     147: aload         11
     149: invokeinterface #59,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     154: astore        13
     156: aload         13
     158: invokeinterface #65,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     163: ifeq          245
     166: aload         13
     168: invokeinterface #69,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     173: checkcast     #71                 // class kotlin/Pair
     176: astore        14
     178: iconst_4
     179: anewarray     #44                 // class java/lang/Integer
     182: astore        15
     184: aload         15
     186: iconst_0
     187: aload         14
     189: invokevirtual #74                 // Method kotlin/Pair.getFirst:()Ljava/lang/Object;
     192: aastore
     193: aload         15
     195: iconst_1
     196: aload         14
     198: invokevirtual #77                 // Method kotlin/Pair.getSecond:()Ljava/lang/Object;
     201: aastore
     202: aload         15
     204: iconst_2
     205: aload_0
     206: iload         4
     208: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     213: aastore
     214: aload         15
     216: iconst_3
     217: aload_0
     218: iload         6
     220: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     225: aastore
     226: aload         15
     228: invokestatic  #83                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     231: astore        16
     233: aload_2
     234: aload         16
     236: invokeinterface #86,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     241: pop
     242: goto          156
     245: nop
     246: goto          251
     249: pop
     250: nop
     251: iinc          6, 1
     254: goto          62
     257: iconst_0
     258: istore        6
     260: iload         6
     262: iload         4
     264: if_icmpge     462
     267: aload_0
     268: iload         4
     270: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     275: checkcast     #39                 // class java/lang/Number
     278: invokevirtual #42                 // Method java/lang/Number.intValue:()I
     281: aload_0
     282: iload         6
     284: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     289: checkcast     #39                 // class java/lang/Number
     292: invokevirtual #42                 // Method java/lang/Number.intValue:()I
     295: iadd
     296: istore        7
     298: aload_3
     299: iload         7
     301: invokestatic  #48                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     304: invokeinterface #52,  2           // InterfaceMethod java/util/Map.containsKey:(Ljava/lang/Object;)Z
     309: ifne          357
     312: iload         7
     314: invokestatic  #48                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     317: astore        9
     319: aload_3
     320: aload         9
     322: new           #71                 // class kotlin/Pair
     325: dup
     326: aload_0
     327: iload         6
     329: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     334: aload_0
     335: iload         4
     337: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     342: invokespecial #89                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     345: invokestatic  #92                 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
     348: invokeinterface #96,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     353: pop
     354: goto          456
     357: aload_3
     358: iload         7
     360: invokestatic  #48                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     363: invokeinterface #55,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
     368: checkcast     #24                 // class java/util/List
     371: dup
     372: ifnull        384
     375: checkcast     #98                 // class java/util/Collection
     378: invokestatic  #102                // Method kotlin/collections/CollectionsKt.toMutableList:(Ljava/util/Collection;)Ljava/util/List;
     381: goto          386
     384: pop
     385: aconst_null
     386: astore        8
     388: aload         8
     390: dup
     391: ifnull        426
     394: new           #71                 // class kotlin/Pair
     397: dup
     398: aload_0
     399: iload         6
     401: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     406: aload_0
     407: iload         4
     409: invokeinterface #37,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     414: invokespecial #89                 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
     417: invokeinterface #86,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     422: pop
     423: goto          427
     426: pop
     427: aload         8
     429: ifnull        456
     432: iload         7
     434: invokestatic  #48                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     437: astore        10
     439: aload_3
     440: aload         10
     442: aload         8
     444: checkcast     #104                // class java/lang/Iterable
     447: invokestatic  #108                // Method kotlin/collections/CollectionsKt.toList:(Ljava/lang/Iterable;)Ljava/util/List;
     450: invokeinterface #96,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     455: pop
     456: iinc          6, 1
     459: goto          260
     462: iinc          4, 1
     465: goto          41
     468: aload_2
     469: areturn
}


package com.ztoais.dailycoding.algoexpert.medium

import kotlin.io.path.createTempDirectory

/*
 Three Number Sum

Write a function that takes in a non-empty array of distinct integers and an integer representing a target sum. The
function should find all triplets in the array that sum up to the target sum and return a two-dimensional array of all
these triplets. The numbers in each triplet should be ordered in ascending order, and the triplets themselves should be
ordered in ascending order with respect to the numbers they hold.

If no three numbers sum up to the target sum, the function should return an empty array.

Sample Input:
array = [12,3,1,2,-6,5,-8,6]
targetSum = 0

Sample Output:
[[-8,2,6],[-8,3,5],[-6,1,5]]
 */

fun threeNumberSum(array: MutableList<Int>, targetSum: Int):List<List<Int>>{
    //1. Sort the array
    //2. Current number firs
    //3. User Right and left pointer movement one at time.
    //4. Left pointer movement increase the current sum
    //5. Right pointer movement decrease the current sum
    //6. If the target sum equal then move the left and right same time
    //7. Time : O(N2) Space:  O(N)
    array.sort()
    val result = mutableListOf<List<Int>>()
    for(i in 0..array.size-2){
        var left = i+1
        var right = array.size-1
        while(left < right){
            val currentSum = array[i]+array[left]+array[right]
            if(currentSum == targetSum){
                result.add(listOf(array[i],array[left],array[right]))
                left+=1
                right-=1
            }else if(currentSum < targetSum){
                left+=1
            }else if(currentSum > targetSum){
                right-=1
            }
        }
    }

    return result
}

/*
Tests

Test Case 1
{
  "array": [12, 3, 1, 2, -6, 5, -8, 6],
  "targetSum": 0
}
Test Case 2
{
  "array": [1, 2, 3],
  "targetSum": 6
}
Test Case 3
{
  "array": [1, 2, 3],
  "targetSum": 7
}
Test Case 4
{
  "array": [8, 10, -2, 49, 14],
  "targetSum": 57
}
Test Case 5
{
  "array": [12, 3, 1, 2, -6, 5, 0, -8, -1],
  "targetSum": 0
}
Test Case 6
{
  "array": [12, 3, 1, 2, -6, 5, 0, -8, -1, 6],
  "targetSum": 0
}
Test Case 7
{
  "array": [12, 3, 1, 2, -6, 5, 0, -8, -1, 6, -5],
  "targetSum": 0
}
Test Case 8
{
  "array": [1, 2, 3, 4, 5, 6, 7, 8, 9, 15],
  "targetSum": 18
}
Test Case 9
{
  "array": [1, 2, 3, 4, 5, 6, 7, 8, 9, 15],
  "targetSum": 32
}
Test Case 10
{
  "array": [1, 2, 3, 4, 5, 6, 7, 8, 9, 15],
  "targetSum": 33
}
Test Case 11
{
  "array": [1, 2, 3, 4, 5, 6, 7, 8, 9, 15],
  "targetSum": 5
}
 */

Compiled from "ThreeNumberSum.kt"
public final class com.ztoais.dailycoding.algoexpert.medium.ThreeNumberSumKt {
  public static final java.util.List<java.util.List<java.lang.Integer>> threeNumberSum(java.util.List<java.lang.Integer>, int);
    Code:
       0: aload_0
       1: ldc           #10                 // String array
       3: invokestatic  #16                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #22                 // Method kotlin/collections/CollectionsKt.sort:(Ljava/util/List;)V
      10: new           #24                 // class java/util/ArrayList
      13: dup
      14: invokespecial #28                 // Method java/util/ArrayList."<init>":()V
      17: checkcast     #30                 // class java/util/List
      20: astore_2
      21: iconst_0
      22: istore_3
      23: aload_0
      24: invokeinterface #34,  1           // InterfaceMethod java/util/List.size:()I
      29: iconst_2
      30: isub
      31: istore        4
      33: iload_3
      34: iload         4
      36: if_icmpgt     210
      39: iload_3
      40: iconst_1
      41: iadd
      42: istore        5
      44: aload_0
      45: invokeinterface #34,  1           // InterfaceMethod java/util/List.size:()I
      50: iconst_1
      51: isub
      52: istore        6
      54: iload         5
      56: iload         6
      58: if_icmpge     198
      61: aload_0
      62: iload_3
      63: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      68: checkcast     #40                 // class java/lang/Number
      71: invokevirtual #43                 // Method java/lang/Number.intValue:()I
      74: aload_0
      75: iload         5
      77: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      82: checkcast     #40                 // class java/lang/Number
      85: invokevirtual #43                 // Method java/lang/Number.intValue:()I
      88: iadd
      89: aload_0
      90: iload         6
      92: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      97: checkcast     #40                 // class java/lang/Number
     100: invokevirtual #43                 // Method java/lang/Number.intValue:()I
     103: iadd
     104: istore        7
     106: iload         7
     108: iload_1
     109: if_icmpne     174
     112: aload_2
     113: iconst_3
     114: anewarray     #45                 // class java/lang/Integer
     117: astore        8
     119: aload         8
     121: iconst_0
     122: aload_0
     123: iload_3
     124: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     129: aastore
     130: aload         8
     132: iconst_1
     133: aload_0
     134: iload         5
     136: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     141: aastore
     142: aload         8
     144: iconst_2
     145: aload_0
     146: iload         6
     148: invokeinterface #38,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     153: aastore
     154: aload         8
     156: invokestatic  #49                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     159: invokeinterface #53,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     164: pop
     165: iinc          5, 1
     168: iinc          6, -1
     171: goto          54
     174: iload         7
     176: iload_1
     177: if_icmpge     186
     180: iinc          5, 1
     183: goto          54
     186: iload         7
     188: iload_1
     189: if_icmple     54
     192: iinc          6, -1
     195: goto          54
     198: iload_3
     199: iload         4
     201: if_icmpeq     210
     204: iinc          3, 1
     207: goto          39
     210: aload_2
     211: areturn
}


package solutions.CHK

//+------+-------+------------------------+
//| Item | Price | Special offers         |
//+------+-------+------------------------+
//| H    | 10    | 5H for 45, 10H for 80  |
//| K    | 80    | 2K for 150             |
//| N    | 40    | 3N get one M free      |
//| P    | 50    | 5P for 200             |
//| Q    | 30    | 3Q for 80              |
//| R    | 50    | 3R get one Q free      |
//| U    | 40    | 3U get one U free      |
//| V    | 50    | 2V for 90, 3V for 130  |
//+------+-------+------------------------+

object CheckoutSolution {

    private val valid = listOf('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z')

    fun checkout(skus: String): Int {

        if (skus.count { it !in valid } != 0) return -1

        return Skus(totalSoFar = 0, skus = skus.toMutableList())
            // SKUs without a deal involved
            .consumeSimpleItems()
            .consumeE()
            .consumeA()
            .consumeB()
            .consumeF()
            .totalSoFar
    }

}

data class Skus(var totalSoFar: Int, val skus: MutableList<Char>) {

    val simpleSkusToPrice = mapOf(
        'C' to 20,
        'D' to 15,
        'G' to 20,
        'I' to 35,
        'J' to 60,
        'L' to 90,
        'M' to 15,
        'O' to 10,
        'S' to 30,
        'T' to 20,
        'W' to 20,
        'X' to 90,
        'Y' to 10,
        'Z' to 50
    )

    fun consumeA(): Skus {
        val aCount = countSku('A')
        val firstDealCount = aCount / 5
        val secondDealCount = (aCount - (firstDealCount * 5)) / 3
        val leftOver = (aCount - (firstDealCount * 5) - secondDealCount * 3)
        skus.removeIf { it == 'A' }
        totalSoFar += (firstDealCount * 200) + (secondDealCount * 130) + (leftOver * 50)
        return this
    }

    fun consumeB(): Skus {
        val value = specialDeal(2, 45, 30, countSku('B'))
        skus.removeIf { it == 'B' }
        totalSoFar += value
        return this
    }

    fun consumeE(): Skus {
        val eCost = countSku('E') * 40
        totalSoFar += eCost
        val freeBs = countSku('E') / 2
        skus.removeIf { it == 'E' }
        for (i in 0 until freeBs ) {
            skus.remove('B')
        }
        return this
    }

    fun consumeF(): Skus {
        totalSoFar += freeSelfDeal('F', 3, 10)
        skus.removeIf { it == 'F' }
        return this
    }

    fun consumeSimpleItems(): Skus {
        simpleSkusToPrice.forEach { (sku, price) ->
            val count = skus.count { it == sku }
            totalSoFar += count * price
            skus.removeIf { it == sku }
        }
        return this
    }

    private fun countSku(char: Char) = this.skus.count { it == char }

    private fun freeSelfDeal(sku: Char, countForFree: Int, usualPrice: Int): Int {
        val count = countSku(sku)
        val free = count / countForFree
        return (count - free) * usualPrice
    }

    private fun specialDeal(dealCount: Int, forMoney: Int, usualPrice: Int, itemCount: Int): Int {
        var total = 0
        var items = itemCount
        while (items >= dealCount) {
            total += forMoney
            items -= dealCount
        }
        total += items * usualPrice
        return total
    }

}

Compiled from "CheckoutSolution.kt"
public final class solutions.CHK.CheckoutSolution {
  public static final solutions.CHK.CheckoutSolution INSTANCE;

  private static final java.util.List<java.lang.Character> valid;

  private solutions.CHK.CheckoutSolution();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public final int checkout(java.lang.String);
    Code:
       0: aload_1
       1: ldc           #15                 // String skus
       3: invokestatic  #21                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: checkcast     #23                 // class java/lang/CharSequence
      10: astore_2
      11: iconst_0
      12: istore_3
      13: iconst_0
      14: istore        4
      16: iconst_0
      17: istore        5
      19: iload         5
      21: aload_2
      22: invokeinterface #27,  1           // InterfaceMethod java/lang/CharSequence.length:()I
      27: if_icmpge     80
      30: aload_2
      31: iload         5
      33: invokeinterface #31,  2           // InterfaceMethod java/lang/CharSequence.charAt:(I)C
      38: istore        6
      40: iload         6
      42: istore        7
      44: iconst_0
      45: istore        8
      47: getstatic     #35                 // Field valid:Ljava/util/List;
      50: iload         7
      52: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      55: invokeinterface #47,  2           // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
      60: ifne          67
      63: iconst_1
      64: goto          68
      67: iconst_0
      68: ifeq          74
      71: iinc          4, 1
      74: iinc          5, 1
      77: goto          19
      80: iload         4
      82: ifeq          87
      85: iconst_m1
      86: ireturn
      87: new           #49                 // class solutions/CHK/Skus
      90: dup
      91: iconst_0
      92: aload_1
      93: checkcast     #23                 // class java/lang/CharSequence
      96: invokestatic  #55                 // Method kotlin/text/StringsKt.toMutableList:(Ljava/lang/CharSequence;)Ljava/util/List;
      99: invokespecial #58                 // Method solutions/CHK/Skus."<init>":(ILjava/util/List;)V
     102: invokevirtual #62                 // Method solutions/CHK/Skus.consumeSimpleItems:()Lsolutions/CHK/Skus;
     105: invokevirtual #65                 // Method solutions/CHK/Skus.consumeE:()Lsolutions/CHK/Skus;
     108: invokevirtual #68                 // Method solutions/CHK/Skus.consumeA:()Lsolutions/CHK/Skus;
     111: invokevirtual #71                 // Method solutions/CHK/Skus.consumeB:()Lsolutions/CHK/Skus;
     114: invokevirtual #74                 // Method solutions/CHK/Skus.consumeF:()Lsolutions/CHK/Skus;
     117: invokevirtual #77                 // Method solutions/CHK/Skus.getTotalSoFar:()I
     120: ireturn

  static {};
    Code:
       0: new           #2                  // class solutions/CHK/CheckoutSolution
       3: dup
       4: invokespecial #91                 // Method "<init>":()V
       7: putstatic     #94                 // Field INSTANCE:Lsolutions/CHK/CheckoutSolution;
      10: bipush        26
      12: anewarray     #37                 // class java/lang/Character
      15: astore_0
      16: aload_0
      17: iconst_0
      18: bipush        65
      20: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      23: aastore
      24: aload_0
      25: iconst_1
      26: bipush        66
      28: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      31: aastore
      32: aload_0
      33: iconst_2
      34: bipush        67
      36: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      39: aastore
      40: aload_0
      41: iconst_3
      42: bipush        68
      44: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      47: aastore
      48: aload_0
      49: iconst_4
      50: bipush        69
      52: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      55: aastore
      56: aload_0
      57: iconst_5
      58: bipush        70
      60: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      63: aastore
      64: aload_0
      65: bipush        6
      67: bipush        71
      69: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      72: aastore
      73: aload_0
      74: bipush        7
      76: bipush        72
      78: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      81: aastore
      82: aload_0
      83: bipush        8
      85: bipush        73
      87: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      90: aastore
      91: aload_0
      92: bipush        9
      94: bipush        74
      96: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      99: aastore
     100: aload_0
     101: bipush        10
     103: bipush        75
     105: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     108: aastore
     109: aload_0
     110: bipush        11
     112: bipush        76
     114: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     117: aastore
     118: aload_0
     119: bipush        12
     121: bipush        77
     123: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     126: aastore
     127: aload_0
     128: bipush        13
     130: bipush        78
     132: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     135: aastore
     136: aload_0
     137: bipush        14
     139: bipush        79
     141: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     144: aastore
     145: aload_0
     146: bipush        15
     148: bipush        80
     150: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     153: aastore
     154: aload_0
     155: bipush        16
     157: bipush        81
     159: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     162: aastore
     163: aload_0
     164: bipush        17
     166: bipush        82
     168: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     171: aastore
     172: aload_0
     173: bipush        18
     175: bipush        83
     177: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     180: aastore
     181: aload_0
     182: bipush        19
     184: bipush        84
     186: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     189: aastore
     190: aload_0
     191: bipush        20
     193: bipush        85
     195: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     198: aastore
     199: aload_0
     200: bipush        21
     202: bipush        86
     204: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     207: aastore
     208: aload_0
     209: bipush        22
     211: bipush        87
     213: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     216: aastore
     217: aload_0
     218: bipush        23
     220: bipush        88
     222: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     225: aastore
     226: aload_0
     227: bipush        24
     229: bipush        89
     231: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     234: aastore
     235: aload_0
     236: bipush        25
     238: bipush        90
     240: invokestatic  #41                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     243: aastore
     244: aload_0
     245: invokestatic  #100                // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     248: putstatic     #35                 // Field valid:Ljava/util/List;
     251: return
}