package exercise.collection

fun main() {
    val employees = listOf(
        Employee(
            employeeId = 124,
            name = "Kayla",
            department = "HR",
            salary = 2000.00
        ),
        Employee(
            employeeId = 125,
            name = "Lulu",
            department = "IT",
            salary = 5600.00
        ),
        Employee(
            employeeId = 126,
            name = "Amy",
            department = "Customer support",
            salary = 1500.00
        )
    )

    println(filterByLetter(employees, 'U'))
}

data class Employee(
    val employeeId: Int,
    val name: String,
    val department: String,
    val salary: Double
)

fun findEmployeeById(employees: List<Employee>, id: Int): Employee? {
    return employees.find { it.employeeId == id }
}

// sorts the list of employees alphabetically by their names
fun sortEmployeesByName(employees: List<Employee>): List<Employee> {
    return employees.sortedBy { it.name }
}

fun filterEmployeesByDepartment(employees: List<Employee>): Map<String, List<Employee>> {
    return employees.groupBy { it.department }
}

fun filterEmployeesByGivenDepartment(employees: List<Employee>, department: String): List<Employee> {
    return employees.filter { it.department == department }
}

sealed interface TopNSalariesResult {
    data class Error(val message: String) : TopNSalariesResult
    data class Success(val list: List<Employee>) : TopNSalariesResult
}

fun findTopNSalaries(employees: List<Employee>, topN: Int): TopNSalariesResult {
    if (topN <= 0 || topN > employees.size) return TopNSalariesResult.Error("Invalid criteria")

    val res = employees.sortedByDescending { it.salary }.take(topN)

    return TopNSalariesResult.Success(res)
}

// Pair(IT, 5600), Pair(HR, 2000)
fun calculateAverageSalaryByDepartment(employees: List<Employee>): Map<String, Double> {
    val filtered = filterEmployeesByDepartment(employees)

    return filtered.mapValues { (_, filtered) ->
        filtered.map { it.salary }.average()
    }
}

// Filter employees by a specific letter in their name
fun filterByLetter(employees: List<Employee>, letter: Char): List<Employee> {
    return employees.filter { !it.name.uppercase().contains(letter.uppercase()) }
}

Compiled from "Comparisons.kt"
public final class exercise.collection.CollectionOperators3Kt$findTopNSalaries$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public exercise.collection.CollectionOperators3Kt$findTopNSalaries$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class exercise/collection/Employee
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method exercise/collection/Employee.getSalary:()D
      12: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_1
      19: checkcast     #23                 // class exercise/collection/Employee
      22: astore_3
      23: astore        5
      25: iconst_0
      26: istore        4
      28: aload_3
      29: invokevirtual #27                 // Method exercise/collection/Employee.getSalary:()D
      32: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      35: aload         5
      37: swap
      38: checkcast     #35                 // class java/lang/Comparable
      41: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      44: ireturn
}

Compiled from "Comparisons.kt"
public final class exercise.collection.CollectionOperators3Kt$sortEmployeesByName$$inlined$sortedBy$1<T> implements java.util.Comparator {
  public exercise.collection.CollectionOperators3Kt$sortEmployeesByName$$inlined$sortedBy$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_1
       1: checkcast     #23                 // class exercise/collection/Employee
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method exercise/collection/Employee.getName:()Ljava/lang/String;
      12: checkcast     #29                 // class java/lang/Comparable
      15: aload_2
      16: checkcast     #23                 // class exercise/collection/Employee
      19: astore_3
      20: astore        5
      22: iconst_0
      23: istore        4
      25: aload_3
      26: invokevirtual #27                 // Method exercise/collection/Employee.getName:()Ljava/lang/String;
      29: aload         5
      31: swap
      32: checkcast     #29                 // class java/lang/Comparable
      35: invokestatic  #35                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      38: ireturn
}

Compiled from "CollectionOperators3.kt"
public final class exercise.collection.CollectionOperators3Kt {
  public static final void main();
    Code:
       0: iconst_3
       1: anewarray     #8                  // class exercise/collection/Employee
       4: astore_1
       5: aload_1
       6: iconst_0
       7: new           #8                  // class exercise/collection/Employee
      10: dup
      11: bipush        124
      13: ldc           #10                 // String Kayla
      15: ldc           #12                 // String HR
      17: ldc2_w        #13                 // double 2000.0d
      20: invokespecial #18                 // Method exercise/collection/Employee."<init>":(ILjava/lang/String;Ljava/lang/String;D)V
      23: aastore
      24: aload_1
      25: iconst_1
      26: new           #8                  // class exercise/collection/Employee
      29: dup
      30: bipush        125
      32: ldc           #20                 // String Lulu
      34: ldc           #22                 // String IT
      36: ldc2_w        #23                 // double 5600.0d
      39: invokespecial #18                 // Method exercise/collection/Employee."<init>":(ILjava/lang/String;Ljava/lang/String;D)V
      42: aastore
      43: aload_1
      44: iconst_2
      45: new           #8                  // class exercise/collection/Employee
      48: dup
      49: bipush        126
      51: ldc           #26                 // String Amy
      53: ldc           #28                 // String Customer support
      55: ldc2_w        #29                 // double 1500.0d
      58: invokespecial #18                 // Method exercise/collection/Employee."<init>":(ILjava/lang/String;Ljava/lang/String;D)V
      61: aastore
      62: aload_1
      63: invokestatic  #36                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      66: astore_0
      67: aload_0
      68: bipush        85
      70: invokestatic  #40                 // Method filterByLetter:(Ljava/util/List;C)Ljava/util/List;
      73: getstatic     #46                 // Field java/lang/System.out:Ljava/io/PrintStream;
      76: swap
      77: invokevirtual #52                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      80: return

  public static final exercise.collection.Employee findEmployeeById(java.util.List<exercise.collection.Employee>, int);
    Code:
       0: aload_0
       1: ldc           #60                 // String employees
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_2
      11: aload_2
      12: invokeinterface #72,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      17: astore_3
      18: aload_3
      19: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      24: ifeq          67
      27: aload_3
      28: invokeinterface #82,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      33: astore        4
      35: aload         4
      37: checkcast     #8                  // class exercise/collection/Employee
      40: astore        5
      42: iconst_0
      43: istore        6
      45: aload         5
      47: invokevirtual #86                 // Method exercise/collection/Employee.getEmployeeId:()I
      50: iload_1
      51: if_icmpne     58
      54: iconst_1
      55: goto          59
      58: iconst_0
      59: ifeq          18
      62: aload         4
      64: goto          68
      67: aconst_null
      68: checkcast     #8                  // class exercise/collection/Employee
      71: areturn

  public static final java.util.List<exercise.collection.Employee> sortEmployeesByName(java.util.List<exercise.collection.Employee>);
    Code:
       0: aload_0
       1: ldc           #60                 // String employees
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: new           #96                 // class exercise/collection/CollectionOperators3Kt$sortEmployeesByName$$inlined$sortedBy$1
      17: dup
      18: invokespecial #98                 // Method exercise/collection/CollectionOperators3Kt$sortEmployeesByName$$inlined$sortedBy$1."<init>":()V
      21: checkcast     #100                // class java/util/Comparator
      24: invokestatic  #104                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      27: areturn

  public static final java.util.Map<java.lang.String, java.util.List<exercise.collection.Employee>> filterEmployeesByDepartment(java.util.List<exercise.collection.Employee>);
    Code:
       0: aload_0
       1: ldc           #60                 // String employees
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #112                // class java/util/LinkedHashMap
      18: dup
      19: invokespecial #113                // Method java/util/LinkedHashMap."<init>":()V
      22: checkcast     #115                // class java/util/Map
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #72,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          150
      48: aload         6
      50: invokeinterface #82,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         7
      59: checkcast     #8                  // class exercise/collection/Employee
      62: astore        8
      64: iconst_0
      65: istore        9
      67: aload         8
      69: invokevirtual #119                // Method exercise/collection/Employee.getDepartment:()Ljava/lang/String;
      72: astore        10
      74: aload         4
      76: astore        11
      78: iconst_0
      79: istore        12
      81: aload         11
      83: aload         10
      85: invokeinterface #123,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      90: astore        13
      92: aload         13
      94: ifnonnull     129
      97: iconst_0
      98: istore        14
     100: new           #125                // class java/util/ArrayList
     103: dup
     104: invokespecial #126                // Method java/util/ArrayList."<init>":()V
     107: checkcast     #128                // class java/util/List
     110: astore        14
     112: aload         11
     114: aload         10
     116: aload         14
     118: invokeinterface #132,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     123: pop
     124: aload         14
     126: goto          131
     129: aload         13
     131: nop
     132: checkcast     #128                // class java/util/List
     135: astore        8
     137: aload         8
     139: aload         7
     141: invokeinterface #136,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     146: pop
     147: goto          38
     150: aload         4
     152: nop
     153: areturn

  public static final java.util.List<exercise.collection.Employee> filterEmployeesByGivenDepartment(java.util.List<exercise.collection.Employee>, java.lang.String);
    Code:
       0: aload_0
       1: ldc           #60                 // String employees
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_1
       7: ldc           #159                // String department
       9: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: checkcast     #68                 // class java/lang/Iterable
      16: astore_2
      17: iconst_0
      18: istore_3
      19: aload_2
      20: astore        4
      22: new           #125                // class java/util/ArrayList
      25: dup
      26: invokespecial #126                // Method java/util/ArrayList."<init>":()V
      29: checkcast     #161                // class java/util/Collection
      32: astore        5
      34: iconst_0
      35: istore        6
      37: aload         4
      39: invokeinterface #72,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      44: astore        7
      46: aload         7
      48: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      53: ifeq          100
      56: aload         7
      58: invokeinterface #82,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      63: astore        8
      65: aload         8
      67: checkcast     #8                  // class exercise/collection/Employee
      70: astore        9
      72: iconst_0
      73: istore        10
      75: aload         9
      77: invokevirtual #119                // Method exercise/collection/Employee.getDepartment:()Ljava/lang/String;
      80: aload_1
      81: invokestatic  #165                // Method kotlin/jvm/internal/Intrinsics.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
      84: ifeq          46
      87: aload         5
      89: aload         8
      91: invokeinterface #166,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      96: pop
      97: goto          46
     100: aload         5
     102: checkcast     #128                // class java/util/List
     105: nop
     106: areturn

  public static final exercise.collection.TopNSalariesResult findTopNSalaries(java.util.List<exercise.collection.Employee>, int);
    Code:
       0: aload_0
       1: ldc           #60                 // String employees
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iload_1
       7: ifle          20
      10: iload_1
      11: aload_0
      12: invokeinterface #179,  1          // InterfaceMethod java/util/List.size:()I
      17: if_icmple     33
      20: new           #181                // class exercise/collection/TopNSalariesResult$Error
      23: dup
      24: ldc           #183                // String Invalid criteria
      26: invokespecial #186                // Method exercise/collection/TopNSalariesResult$Error."<init>":(Ljava/lang/String;)V
      29: checkcast     #188                // class exercise/collection/TopNSalariesResult
      32: areturn
      33: aload_0
      34: checkcast     #68                 // class java/lang/Iterable
      37: astore_3
      38: iconst_0
      39: istore        4
      41: aload_3
      42: new           #190                // class exercise/collection/CollectionOperators3Kt$findTopNSalaries$$inlined$sortedByDescending$1
      45: dup
      46: invokespecial #191                // Method exercise/collection/CollectionOperators3Kt$findTopNSalaries$$inlined$sortedByDescending$1."<init>":()V
      49: checkcast     #100                // class java/util/Comparator
      52: invokestatic  #104                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      55: checkcast     #68                 // class java/lang/Iterable
      58: iload_1
      59: invokestatic  #195                // Method kotlin/collections/CollectionsKt.take:(Ljava/lang/Iterable;I)Ljava/util/List;
      62: astore_2
      63: new           #197                // class exercise/collection/TopNSalariesResult$Success
      66: dup
      67: aload_2
      68: invokespecial #200                // Method exercise/collection/TopNSalariesResult$Success."<init>":(Ljava/util/List;)V
      71: checkcast     #188                // class exercise/collection/TopNSalariesResult
      74: areturn

  public static final java.util.Map<java.lang.String, java.lang.Double> calculateAverageSalaryByDepartment(java.util.List<exercise.collection.Employee>);
    Code:
       0: aload_0
       1: ldc           #60                 // String employees
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #208                // Method filterEmployeesByDepartment:(Ljava/util/List;)Ljava/util/Map;
      10: astore_1
      11: aload_1
      12: astore_2
      13: iconst_0
      14: istore_3
      15: aload_2
      16: astore        4
      18: new           #112                // class java/util/LinkedHashMap
      21: dup
      22: aload_2
      23: invokeinterface #209,  1          // InterfaceMethod java/util/Map.size:()I
      28: invokestatic  #215                // Method kotlin/collections/MapsKt.mapCapacity:(I)I
      31: invokespecial #218                // Method java/util/LinkedHashMap."<init>":(I)V
      34: checkcast     #115                // class java/util/Map
      37: astore        5
      39: iconst_0
      40: istore        6
      42: aload         4
      44: invokeinterface #222,  1          // InterfaceMethod java/util/Map.entrySet:()Ljava/util/Set;
      49: checkcast     #68                 // class java/lang/Iterable
      52: astore        7
      54: iconst_0
      55: istore        8
      57: aload         7
      59: invokeinterface #72,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      64: astore        9
      66: aload         9
      68: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      73: ifeq          265
      76: aload         9
      78: invokeinterface #82,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      83: astore        10
      85: aload         5
      87: aload         10
      89: checkcast     #224                // class java/util/Map$Entry
      92: astore        11
      94: astore        12
      96: iconst_0
      97: istore        13
      99: aload         11
     101: invokeinterface #227,  1          // InterfaceMethod java/util/Map$Entry.getKey:()Ljava/lang/Object;
     106: aload         12
     108: swap
     109: aload         10
     111: checkcast     #224                // class java/util/Map$Entry
     114: astore        14
     116: astore        28
     118: astore        27
     120: iconst_0
     121: istore        15
     123: aload         14
     125: invokeinterface #230,  1          // InterfaceMethod java/util/Map$Entry.getValue:()Ljava/lang/Object;
     130: checkcast     #128                // class java/util/List
     133: astore        16
     135: aload         16
     137: checkcast     #68                 // class java/lang/Iterable
     140: astore        17
     142: iconst_0
     143: istore        18
     145: aload         17
     147: astore        19
     149: new           #125                // class java/util/ArrayList
     152: dup
     153: aload         17
     155: bipush        10
     157: invokestatic  #234                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     160: invokespecial #235                // Method java/util/ArrayList."<init>":(I)V
     163: checkcast     #161                // class java/util/Collection
     166: astore        20
     168: iconst_0
     169: istore        21
     171: aload         19
     173: invokeinterface #72,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     178: astore        22
     180: aload         22
     182: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     187: ifeq          233
     190: aload         22
     192: invokeinterface #82,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     197: astore        23
     199: aload         20
     201: aload         23
     203: checkcast     #8                  // class exercise/collection/Employee
     206: astore        24
     208: astore        25
     210: iconst_0
     211: istore        26
     213: aload         24
     215: invokevirtual #239                // Method exercise/collection/Employee.getSalary:()D
     218: invokestatic  #245                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     221: aload         25
     223: swap
     224: invokeinterface #166,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     229: pop
     230: goto          180
     233: aload         20
     235: checkcast     #128                // class java/util/List
     238: nop
     239: checkcast     #68                 // class java/lang/Iterable
     242: invokestatic  #249                // Method kotlin/collections/CollectionsKt.averageOfDouble:(Ljava/lang/Iterable;)D
     245: invokestatic  #245                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
     248: astore        29
     250: aload         27
     252: aload         28
     254: aload         29
     256: invokeinterface #132,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     261: pop
     262: goto          66
     265: aload         5
     267: nop
     268: nop
     269: areturn

  public static final java.util.List<exercise.collection.Employee> filterByLetter(java.util.List<exercise.collection.Employee>, char);
    Code:
       0: aload_0
       1: ldc           #60                 // String employees
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: astore        4
      16: new           #125                // class java/util/ArrayList
      19: dup
      20: invokespecial #126                // Method java/util/ArrayList."<init>":()V
      23: checkcast     #161                // class java/util/Collection
      26: astore        5
      28: iconst_0
      29: istore        6
      31: aload         4
      33: invokeinterface #72,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      38: astore        7
      40: aload         7
      42: invokeinterface #78,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      47: ifeq          147
      50: aload         7
      52: invokeinterface #82,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      57: astore        8
      59: aload         8
      61: checkcast     #8                  // class exercise/collection/Employee
      64: astore        9
      66: iconst_0
      67: istore        10
      69: aload         9
      71: invokevirtual #271                // Method exercise/collection/Employee.getName:()Ljava/lang/String;
      74: getstatic     #277                // Field java/util/Locale.ROOT:Ljava/util/Locale;
      77: invokevirtual #281                // Method java/lang/String.toUpperCase:(Ljava/util/Locale;)Ljava/lang/String;
      80: dup
      81: ldc_w         #283                // String toUpperCase(...)
      84: invokestatic  #286                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
      87: checkcast     #288                // class java/lang/CharSequence
      90: iload_1
      91: invokestatic  #291                // Method java/lang/String.valueOf:(C)Ljava/lang/String;
      94: dup
      95: ldc_w         #293                // String null cannot be cast to non-null type java.lang.String
      98: invokestatic  #296                // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
     101: getstatic     #277                // Field java/util/Locale.ROOT:Ljava/util/Locale;
     104: invokevirtual #281                // Method java/lang/String.toUpperCase:(Ljava/util/Locale;)Ljava/lang/String;
     107: dup
     108: ldc_w         #283                // String toUpperCase(...)
     111: invokestatic  #286                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     114: checkcast     #288                // class java/lang/CharSequence
     117: iconst_0
     118: iconst_2
     119: aconst_null
     120: invokestatic  #302                // Method kotlin/text/StringsKt.contains$default:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;ZILjava/lang/Object;)Z
     123: ifne          130
     126: iconst_1
     127: goto          131
     130: iconst_0
     131: ifeq          40
     134: aload         5
     136: aload         8
     138: invokeinterface #166,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     143: pop
     144: goto          40
     147: aload         5
     149: checkcast     #128                // class java/util/List
     152: nop
     153: areturn

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


package exercise.collection

fun main() {
    val students = listOf<Student>(
        Student("John", 20, 3.5),
        Student("Jane", 21, 3.8),
        Student("Jack", 22, 3.2),
        Student("J", 20, 6.0),
        Student("JC", 20, 4.5)
    )

    println(studentsInfo(students))
}

data class Student(
    val name: String,
    val age: Int,
    val grade: Double
)

fun sortStudentsByName(students: List<Student>): List<Student> {
    return students.sortedBy { it.name }
}

fun sortStudentsByGradeDescending(students: List<Student>): List<Student> {
    return students.sortedByDescending { it.grade }
}

fun filterStudentsByAgeRange(students: List<Student>, minAge: Int, maxAge: Int): List<Student> {
    return students.filter { it.age in minAge..maxAge }
}

fun findTopStudents(students: List<Student>, topN: Int): List<Student> {
    return students.sortedByDescending { it.grade }.take(topN)
}

fun groupByGradeRange(students: List<Student>): Map<GradeLetter, List<Student>> {
    return students.groupBy { gradeDoubleToLetter(it.grade) }
}

enum class GradeLetter {
    A,
    B,
    C,
    D,
    F
}

fun gradeDoubleToLetter(grade: Double): GradeLetter {
    return when (grade) {
        in 2.0..2.49 -> GradeLetter.F
        in 2.5..3.49 -> GradeLetter.D
        in 3.5..4.49 -> GradeLetter.C
        in 4.5..5.49 -> GradeLetter.B
        else -> {
            GradeLetter.A
        }
    }
}

fun calculateAverageGrade(students: List<Student>): Double {
    return students.map { it.grade }.average()
}

// students with grade >= 2.5 , sortedBy grade, uppercase name

fun passedStudents(students: List<Student>): List<Student> {
    return students.filter { it.grade >= 2.5 }.map { it ->
        Student(it.name.uppercase(), it.age, it.grade)
    }
}

/*
new data class StudentInfo (1 student, belowAvg: Boolean (true if grade < avg), gradeLetter: Char)
fun studentsInfo(students: List<Student>) : List<StudentInfo>
Use fun calculateAverageGrade
Use fun gradeDoubleToLetter
 */

data class StudentInfo(
    val student: Student,
    val belowAverage: Boolean,
    val gradeLetter: GradeLetter
)

fun studentsInfo(students: List<Student>): List<StudentInfo> {
    val averageGrade = calculateAverageGrade(students)

    return students.map { student ->
        StudentInfo(
            student = student,
            belowAverage = student.grade < averageGrade,
            gradeLetter = gradeDoubleToLetter(student.grade)
        )
    }
}

Compiled from "Comparisons.kt"
public final class exercise.collection.CollectionOperatorsKt$findTopStudents$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public exercise.collection.CollectionOperatorsKt$findTopStudents$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class exercise/collection/Student
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method exercise/collection/Student.getGrade:()D
      12: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_1
      19: checkcast     #23                 // class exercise/collection/Student
      22: astore_3
      23: astore        5
      25: iconst_0
      26: istore        4
      28: aload_3
      29: invokevirtual #27                 // Method exercise/collection/Student.getGrade:()D
      32: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      35: aload         5
      37: swap
      38: checkcast     #35                 // class java/lang/Comparable
      41: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      44: ireturn
}

Compiled from "Comparisons.kt"
public final class exercise.collection.CollectionOperatorsKt$sortStudentsByGradeDescending$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public exercise.collection.CollectionOperatorsKt$sortStudentsByGradeDescending$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class exercise/collection/Student
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method exercise/collection/Student.getGrade:()D
      12: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_1
      19: checkcast     #23                 // class exercise/collection/Student
      22: astore_3
      23: astore        5
      25: iconst_0
      26: istore        4
      28: aload_3
      29: invokevirtual #27                 // Method exercise/collection/Student.getGrade:()D
      32: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      35: aload         5
      37: swap
      38: checkcast     #35                 // class java/lang/Comparable
      41: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      44: ireturn
}

Compiled from "Comparisons.kt"
public final class exercise.collection.CollectionOperatorsKt$sortStudentsByName$$inlined$sortedBy$1<T> implements java.util.Comparator {
  public exercise.collection.CollectionOperatorsKt$sortStudentsByName$$inlined$sortedBy$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_1
       1: checkcast     #23                 // class exercise/collection/Student
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method exercise/collection/Student.getName:()Ljava/lang/String;
      12: checkcast     #29                 // class java/lang/Comparable
      15: aload_2
      16: checkcast     #23                 // class exercise/collection/Student
      19: astore_3
      20: astore        5
      22: iconst_0
      23: istore        4
      25: aload_3
      26: invokevirtual #27                 // Method exercise/collection/Student.getName:()Ljava/lang/String;
      29: aload         5
      31: swap
      32: checkcast     #29                 // class java/lang/Comparable
      35: invokestatic  #35                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      38: ireturn
}

Compiled from "CollectionOperators.kt"
public final class exercise.collection.CollectionOperatorsKt {
  public static final void main();
    Code:
       0: iconst_5
       1: anewarray     #8                  // class exercise/collection/Student
       4: astore_1
       5: aload_1
       6: iconst_0
       7: new           #8                  // class exercise/collection/Student
      10: dup
      11: ldc           #10                 // String John
      13: bipush        20
      15: ldc2_w        #11                 // double 3.5d
      18: invokespecial #16                 // Method exercise/collection/Student."<init>":(Ljava/lang/String;ID)V
      21: aastore
      22: aload_1
      23: iconst_1
      24: new           #8                  // class exercise/collection/Student
      27: dup
      28: ldc           #18                 // String Jane
      30: bipush        21
      32: ldc2_w        #19                 // double 3.8d
      35: invokespecial #16                 // Method exercise/collection/Student."<init>":(Ljava/lang/String;ID)V
      38: aastore
      39: aload_1
      40: iconst_2
      41: new           #8                  // class exercise/collection/Student
      44: dup
      45: ldc           #22                 // String Jack
      47: bipush        22
      49: ldc2_w        #23                 // double 3.2d
      52: invokespecial #16                 // Method exercise/collection/Student."<init>":(Ljava/lang/String;ID)V
      55: aastore
      56: aload_1
      57: iconst_3
      58: new           #8                  // class exercise/collection/Student
      61: dup
      62: ldc           #26                 // String J
      64: bipush        20
      66: ldc2_w        #27                 // double 6.0d
      69: invokespecial #16                 // Method exercise/collection/Student."<init>":(Ljava/lang/String;ID)V
      72: aastore
      73: aload_1
      74: iconst_4
      75: new           #8                  // class exercise/collection/Student
      78: dup
      79: ldc           #30                 // String JC
      81: bipush        20
      83: ldc2_w        #31                 // double 4.5d
      86: invokespecial #16                 // Method exercise/collection/Student."<init>":(Ljava/lang/String;ID)V
      89: aastore
      90: aload_1
      91: invokestatic  #38                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
      94: astore_0
      95: aload_0
      96: invokestatic  #42                 // Method studentsInfo:(Ljava/util/List;)Ljava/util/List;
      99: getstatic     #48                 // Field java/lang/System.out:Ljava/io/PrintStream;
     102: swap
     103: invokevirtual #54                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     106: return

  public static final java.util.List<exercise.collection.Student> sortStudentsByName(java.util.List<exercise.collection.Student>);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: new           #70                 // class exercise/collection/CollectionOperatorsKt$sortStudentsByName$$inlined$sortedBy$1
      17: dup
      18: invokespecial #72                 // Method exercise/collection/CollectionOperatorsKt$sortStudentsByName$$inlined$sortedBy$1."<init>":()V
      21: checkcast     #74                 // class java/util/Comparator
      24: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      27: areturn

  public static final java.util.List<exercise.collection.Student> sortStudentsByGradeDescending(java.util.List<exercise.collection.Student>);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: new           #85                 // class exercise/collection/CollectionOperatorsKt$sortStudentsByGradeDescending$$inlined$sortedByDescending$1
      17: dup
      18: invokespecial #86                 // Method exercise/collection/CollectionOperatorsKt$sortStudentsByGradeDescending$$inlined$sortedByDescending$1."<init>":()V
      21: checkcast     #74                 // class java/util/Comparator
      24: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      27: areturn

  public static final java.util.List<exercise.collection.Student> filterStudentsByAgeRange(java.util.List<exercise.collection.Student>, int, int);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_3
      11: iconst_0
      12: istore        4
      14: aload_3
      15: astore        5
      17: new           #93                 // class java/util/ArrayList
      20: dup
      21: invokespecial #94                 // Method java/util/ArrayList."<init>":()V
      24: checkcast     #96                 // class java/util/Collection
      27: astore        6
      29: iconst_0
      30: istore        7
      32: aload         5
      34: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      39: astore        8
      41: aload         8
      43: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      48: ifeq          114
      51: aload         8
      53: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      58: astore        9
      60: aload         9
      62: checkcast     #8                  // class exercise/collection/Student
      65: astore        10
      67: iconst_0
      68: istore        11
      70: aload         10
      72: invokevirtual #114                // Method exercise/collection/Student.getAge:()I
      75: istore        12
      77: iload_1
      78: iload         12
      80: if_icmpgt     97
      83: iload         12
      85: iload_2
      86: if_icmpgt     93
      89: iconst_1
      90: goto          98
      93: iconst_0
      94: goto          98
      97: iconst_0
      98: ifeq          41
     101: aload         6
     103: aload         9
     105: invokeinterface #118,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     110: pop
     111: goto          41
     114: aload         6
     116: checkcast     #120                // class java/util/List
     119: nop
     120: areturn

  public static final java.util.List<exercise.collection.Student> findTopStudents(java.util.List<exercise.collection.Student>, int);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: new           #138                // class exercise/collection/CollectionOperatorsKt$findTopStudents$$inlined$sortedByDescending$1
      17: dup
      18: invokespecial #139                // Method exercise/collection/CollectionOperatorsKt$findTopStudents$$inlined$sortedByDescending$1."<init>":()V
      21: checkcast     #74                 // class java/util/Comparator
      24: invokestatic  #78                 // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      27: checkcast     #68                 // class java/lang/Iterable
      30: iload_1
      31: invokestatic  #143                // Method kotlin/collections/CollectionsKt.take:(Ljava/lang/Iterable;I)Ljava/util/List;
      34: areturn

  public static final java.util.Map<exercise.collection.GradeLetter, java.util.List<exercise.collection.Student>> groupByGradeRange(java.util.List<exercise.collection.Student>);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #149                // class java/util/LinkedHashMap
      18: dup
      19: invokespecial #150                // Method java/util/LinkedHashMap."<init>":()V
      22: checkcast     #152                // class java/util/Map
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          153
      48: aload         6
      50: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         7
      59: checkcast     #8                  // class exercise/collection/Student
      62: astore        8
      64: iconst_0
      65: istore        9
      67: aload         8
      69: invokevirtual #156                // Method exercise/collection/Student.getGrade:()D
      72: invokestatic  #160                // Method gradeDoubleToLetter:(D)Lexercise/collection/GradeLetter;
      75: astore        10
      77: aload         4
      79: astore        11
      81: iconst_0
      82: istore        12
      84: aload         11
      86: aload         10
      88: invokeinterface #164,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      93: astore        13
      95: aload         13
      97: ifnonnull     132
     100: iconst_0
     101: istore        14
     103: new           #93                 // class java/util/ArrayList
     106: dup
     107: invokespecial #94                 // Method java/util/ArrayList."<init>":()V
     110: checkcast     #120                // class java/util/List
     113: astore        14
     115: aload         11
     117: aload         10
     119: aload         14
     121: invokeinterface #168,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     126: pop
     127: aload         14
     129: goto          134
     132: aload         13
     134: nop
     135: checkcast     #120                // class java/util/List
     138: astore        8
     140: aload         8
     142: aload         7
     144: invokeinterface #169,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     149: pop
     150: goto          38
     153: aload         4
     155: nop
     156: areturn

  public static final exercise.collection.GradeLetter gradeDoubleToLetter(double);
    Code:
       0: dload_0
       1: dstore_2
       2: ldc2_w        #185                // double 2.0d
       5: dload_2
       6: dcmpg
       7: ifgt          26
      10: dload_2
      11: ldc2_w        #187                // double 2.49d
      14: dcmpg
      15: ifgt          22
      18: iconst_1
      19: goto          27
      22: iconst_0
      23: goto          27
      26: iconst_0
      27: ifeq          36
      30: getstatic     #192                // Field exercise/collection/GradeLetter.F:Lexercise/collection/GradeLetter;
      33: goto          141
      36: ldc2_w        #193                // double 2.5d
      39: dload_2
      40: dcmpg
      41: ifgt          60
      44: dload_2
      45: ldc2_w        #195                // double 3.49d
      48: dcmpg
      49: ifgt          56
      52: iconst_1
      53: goto          61
      56: iconst_0
      57: goto          61
      60: iconst_0
      61: ifeq          70
      64: getstatic     #199                // Field exercise/collection/GradeLetter.D:Lexercise/collection/GradeLetter;
      67: goto          141
      70: ldc2_w        #11                 // double 3.5d
      73: dload_2
      74: dcmpg
      75: ifgt          94
      78: dload_2
      79: ldc2_w        #200                // double 4.49d
      82: dcmpg
      83: ifgt          90
      86: iconst_1
      87: goto          95
      90: iconst_0
      91: goto          95
      94: iconst_0
      95: ifeq          104
      98: getstatic     #204                // Field exercise/collection/GradeLetter.C:Lexercise/collection/GradeLetter;
     101: goto          141
     104: ldc2_w        #31                 // double 4.5d
     107: dload_2
     108: dcmpg
     109: ifgt          128
     112: dload_2
     113: ldc2_w        #205                // double 5.49d
     116: dcmpg
     117: ifgt          124
     120: iconst_1
     121: goto          129
     124: iconst_0
     125: goto          129
     128: iconst_0
     129: ifeq          138
     132: getstatic     #209                // Field exercise/collection/GradeLetter.B:Lexercise/collection/GradeLetter;
     135: goto          141
     138: getstatic     #212                // Field exercise/collection/GradeLetter.A:Lexercise/collection/GradeLetter;
     141: areturn

  public static final double calculateAverageGrade(java.util.List<exercise.collection.Student>);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #93                 // class java/util/ArrayList
      18: dup
      19: aload_1
      20: bipush        10
      22: invokestatic  #220                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      25: invokespecial #223                // Method java/util/ArrayList."<init>":(I)V
      28: checkcast     #96                 // class java/util/Collection
      31: astore        4
      33: iconst_0
      34: istore        5
      36: aload_3
      37: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      42: astore        6
      44: aload         6
      46: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      51: ifeq          97
      54: aload         6
      56: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      61: astore        7
      63: aload         4
      65: aload         7
      67: checkcast     #8                  // class exercise/collection/Student
      70: astore        8
      72: astore        10
      74: iconst_0
      75: istore        9
      77: aload         8
      79: invokevirtual #156                // Method exercise/collection/Student.getGrade:()D
      82: invokestatic  #229                // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      85: aload         10
      87: swap
      88: invokeinterface #118,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      93: pop
      94: goto          44
      97: aload         4
      99: checkcast     #120                // class java/util/List
     102: nop
     103: checkcast     #68                 // class java/lang/Iterable
     106: invokestatic  #233                // Method kotlin/collections/CollectionsKt.averageOfDouble:(Ljava/lang/Iterable;)D
     109: dreturn

  public static final java.util.List<exercise.collection.Student> passedStudents(java.util.List<exercise.collection.Student>);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #68                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #93                 // class java/util/ArrayList
      18: dup
      19: invokespecial #94                 // Method java/util/ArrayList."<init>":()V
      22: checkcast     #96                 // class java/util/Collection
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          100
      48: aload         6
      50: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         7
      59: checkcast     #8                  // class exercise/collection/Student
      62: astore        8
      64: iconst_0
      65: istore        9
      67: aload         8
      69: invokevirtual #156                // Method exercise/collection/Student.getGrade:()D
      72: ldc2_w        #193                // double 2.5d
      75: dcmpl
      76: iflt          83
      79: iconst_1
      80: goto          84
      83: iconst_0
      84: ifeq          38
      87: aload         4
      89: aload         7
      91: invokeinterface #118,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
      96: pop
      97: goto          38
     100: aload         4
     102: checkcast     #120                // class java/util/List
     105: nop
     106: checkcast     #68                 // class java/lang/Iterable
     109: astore_1
     110: nop
     111: iconst_0
     112: istore_2
     113: aload_1
     114: astore_3
     115: new           #93                 // class java/util/ArrayList
     118: dup
     119: aload_1
     120: bipush        10
     122: invokestatic  #220                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     125: invokespecial #223                // Method java/util/ArrayList."<init>":(I)V
     128: checkcast     #96                 // class java/util/Collection
     131: astore        4
     133: iconst_0
     134: istore        5
     136: aload_3
     137: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     142: astore        6
     144: aload         6
     146: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
     151: ifeq          224
     154: aload         6
     156: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     161: astore        7
     163: aload         4
     165: aload         7
     167: checkcast     #8                  // class exercise/collection/Student
     170: astore        8
     172: astore        10
     174: iconst_0
     175: istore        9
     177: new           #8                  // class exercise/collection/Student
     180: dup
     181: aload         8
     183: invokevirtual #244                // Method exercise/collection/Student.getName:()Ljava/lang/String;
     186: getstatic     #250                // Field java/util/Locale.ROOT:Ljava/util/Locale;
     189: invokevirtual #256                // Method java/lang/String.toUpperCase:(Ljava/util/Locale;)Ljava/lang/String;
     192: dup
     193: ldc_w         #258                // String toUpperCase(...)
     196: invokestatic  #261                // Method kotlin/jvm/internal/Intrinsics.checkNotNullExpressionValue:(Ljava/lang/Object;Ljava/lang/String;)V
     199: aload         8
     201: invokevirtual #114                // Method exercise/collection/Student.getAge:()I
     204: aload         8
     206: invokevirtual #156                // Method exercise/collection/Student.getGrade:()D
     209: invokespecial #16                 // Method exercise/collection/Student."<init>":(Ljava/lang/String;ID)V
     212: aload         10
     214: swap
     215: invokeinterface #118,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     220: pop
     221: goto          144
     224: aload         4
     226: checkcast     #120                // class java/util/List
     229: nop
     230: areturn

  public static final java.util.List<exercise.collection.StudentInfo> studentsInfo(java.util.List<exercise.collection.Student>);
    Code:
       0: aload_0
       1: ldc           #60                 // String students
       3: invokestatic  #66                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokestatic  #266                // Method calculateAverageGrade:(Ljava/util/List;)D
      10: dstore_1
      11: aload_0
      12: checkcast     #68                 // class java/lang/Iterable
      15: astore_3
      16: iconst_0
      17: istore        4
      19: aload_3
      20: astore        5
      22: new           #93                 // class java/util/ArrayList
      25: dup
      26: aload_3
      27: bipush        10
      29: invokestatic  #220                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      32: invokespecial #223                // Method java/util/ArrayList."<init>":(I)V
      35: checkcast     #96                 // class java/util/Collection
      38: astore        6
      40: iconst_0
      41: istore        7
      43: aload         5
      45: invokeinterface #100,  1          // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      50: astore        8
      52: aload         8
      54: invokeinterface #106,  1          // InterfaceMethod java/util/Iterator.hasNext:()Z
      59: ifeq          130
      62: aload         8
      64: invokeinterface #110,  1          // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      69: astore        9
      71: aload         6
      73: aload         9
      75: checkcast     #8                  // class exercise/collection/Student
      78: astore        10
      80: astore        12
      82: iconst_0
      83: istore        11
      85: new           #268                // class exercise/collection/StudentInfo
      88: dup
      89: aload         10
      91: aload         10
      93: invokevirtual #156                // Method exercise/collection/Student.getGrade:()D
      96: dload_1
      97: dcmpg
      98: ifge          105
     101: iconst_1
     102: goto          106
     105: iconst_0
     106: aload         10
     108: invokevirtual #156                // Method exercise/collection/Student.getGrade:()D
     111: invokestatic  #160                // Method gradeDoubleToLetter:(D)Lexercise/collection/GradeLetter;
     114: invokespecial #271                // Method exercise/collection/StudentInfo."<init>":(Lexercise/collection/Student;ZLexercise/collection/GradeLetter;)V
     117: nop
     118: aload         12
     120: swap
     121: invokeinterface #118,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     126: pop
     127: goto          52
     130: aload         6
     132: checkcast     #120                // class java/util/List
     135: nop
     136: areturn

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


package exercise.collection

fun main() {
    val salesData = listOf<Sale>(
        Sale("Meat", 7.0, 10),
        Sale("Fish", 5.0, 5),
        Sale("Snack", 3.0, 2),
        Sale("Bread", 1.0, 5),
        Sale("Nuts", 2.0, 9),
        Sale("Chocolate", 3.0, 5)
    )

    println(calculateTotalProfit(salesData, 1.0))
}

/*
You are given a list of sales data represented as objects with the following
properties: productName (String), price (Double), and quantitySold (Int).
Your task is to create a Kotlin program that performs various operations on the list using collection operators.
 */

data class Sale(
    val productName: String,
    val price: Double,
    val quantitySold: Int
)

fun calculateTotalRevenue(salesData: List<Sale>): Double {
    return salesData.sumOf { it.price * it.quantitySold }
}

fun findMostSoldProduct(salesData: List<Sale>): String {
    return try {
        salesData.maxBy { it.quantitySold }.productName
    } catch (e: Exception) {
        "Invalid data"
    }
}

fun filterSalesByPriceRange(salesData: List<Sale>, minPrice: Double, maxPrice: Double): List<String> {
    return salesData.filter { it.price in minPrice..maxPrice }
        .sortedByDescending { it.price }
        .map { "${it.productName}: ${it.price}" }
}

fun findTopNSellingProducts(salesData: List<Sale>, topN: Int): List<String> {
    return salesData.sortedByDescending { it.quantitySold }
        .take(topN)
        .map { "${it.productName}: ${it.quantitySold} sold" }
}

enum class PriceCategory {
    Low,
    Medium,
    High
}

data class SaleWithProfit(
    val saleData: Sale,
    val profit: Double
)

fun calculatePriceCategory(price: Double): PriceCategory {
    return when (price) {
        in 0.0..2.0 -> PriceCategory.Low
        in 2.01..3.0 -> PriceCategory.Medium
        else -> PriceCategory.High
    }
}

fun groupByPriceCategory(salesData: List<Sale>): Map<PriceCategory, List<Sale>> {
    return salesData.groupBy { calculatePriceCategory(it.price) }
}

fun calculateTotalProfit(salesData: List<Sale>, fixedCostPerProduct: Double): List<String> {
    return salesData.map {
        SaleWithProfit(saleData = it, profit = (it.price * it.quantitySold) - (fixedCostPerProduct * it.quantitySold))
    }
        .map {
            "${it.saleData.productName} - ${it.profit} profit"
        }
}

Compiled from "CollectionOperators2.kt"
public final class exercise.collection.CollectionOperators2Kt {
  public static final void main();
    Code:
       0: bipush        6
       2: anewarray     #8                  // class exercise/collection/Sale
       5: astore_1
       6: aload_1
       7: iconst_0
       8: new           #8                  // class exercise/collection/Sale
      11: dup
      12: ldc           #10                 // String Meat
      14: ldc2_w        #11                 // double 7.0d
      17: bipush        10
      19: invokespecial #16                 // Method exercise/collection/Sale."<init>":(Ljava/lang/String;DI)V
      22: aastore
      23: aload_1
      24: iconst_1
      25: new           #8                  // class exercise/collection/Sale
      28: dup
      29: ldc           #18                 // String Fish
      31: ldc2_w        #19                 // double 5.0d
      34: iconst_5
      35: invokespecial #16                 // Method exercise/collection/Sale."<init>":(Ljava/lang/String;DI)V
      38: aastore
      39: aload_1
      40: iconst_2
      41: new           #8                  // class exercise/collection/Sale
      44: dup
      45: ldc           #22                 // String Snack
      47: ldc2_w        #23                 // double 3.0d
      50: iconst_2
      51: invokespecial #16                 // Method exercise/collection/Sale."<init>":(Ljava/lang/String;DI)V
      54: aastore
      55: aload_1
      56: iconst_3
      57: new           #8                  // class exercise/collection/Sale
      60: dup
      61: ldc           #26                 // String Bread
      63: dconst_1
      64: iconst_5
      65: invokespecial #16                 // Method exercise/collection/Sale."<init>":(Ljava/lang/String;DI)V
      68: aastore
      69: aload_1
      70: iconst_4
      71: new           #8                  // class exercise/collection/Sale
      74: dup
      75: ldc           #28                 // String Nuts
      77: ldc2_w        #29                 // double 2.0d
      80: bipush        9
      82: invokespecial #16                 // Method exercise/collection/Sale."<init>":(Ljava/lang/String;DI)V
      85: aastore
      86: aload_1
      87: iconst_5
      88: new           #8                  // class exercise/collection/Sale
      91: dup
      92: ldc           #32                 // String Chocolate
      94: ldc2_w        #23                 // double 3.0d
      97: iconst_5
      98: invokespecial #16                 // Method exercise/collection/Sale."<init>":(Ljava/lang/String;DI)V
     101: aastore
     102: aload_1
     103: invokestatic  #38                 // Method kotlin/collections/CollectionsKt.listOf:([Ljava/lang/Object;)Ljava/util/List;
     106: astore_0
     107: aload_0
     108: dconst_1
     109: invokestatic  #42                 // Method calculateTotalProfit:(Ljava/util/List;D)Ljava/util/List;
     112: getstatic     #48                 // Field java/lang/System.out:Ljava/io/PrintStream;
     115: swap
     116: invokevirtual #54                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     119: return

  public static final double calculateTotalRevenue(java.util.List<exercise.collection.Sale>);
    Code:
       0: aload_0
       1: ldc           #61                 // String salesData
       3: invokestatic  #67                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #69                 // class java/lang/Iterable
      10: astore_1
      11: dconst_0
      12: dstore_2
      13: aload_1
      14: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      19: astore        4
      21: aload         4
      23: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      28: ifeq          76
      31: aload         4
      33: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      38: astore        5
      40: dload_2
      41: aload         5
      43: checkcast     #8                  // class exercise/collection/Sale
      46: astore        6
      48: dstore        8
      50: iconst_0
      51: istore        7
      53: aload         6
      55: invokevirtual #87                 // Method exercise/collection/Sale.getPrice:()D
      58: aload         6
      60: invokevirtual #91                 // Method exercise/collection/Sale.getQuantitySold:()I
      63: i2d
      64: dmul
      65: dstore        10
      67: dload         8
      69: dload         10
      71: dadd
      72: dstore_2
      73: goto          21
      76: dload_2
      77: dreturn

  public static final java.lang.String findMostSoldProduct(java.util.List<exercise.collection.Sale>);
    Code:
       0: aload_0
       1: ldc           #61                 // String salesData
       3: invokestatic  #67                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: nop
       7: aload_0
       8: checkcast     #69                 // class java/lang/Iterable
      11: astore_1
      12: iconst_0
      13: istore_2
      14: aload_1
      15: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      20: astore_3
      21: aload_3
      22: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      27: ifne          38
      30: new           #102                // class java/util/NoSuchElementException
      33: dup
      34: invokespecial #104                // Method java/util/NoSuchElementException."<init>":()V
      37: athrow
      38: aload_3
      39: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      44: astore        4
      46: aload_3
      47: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      52: ifne          60
      55: aload         4
      57: goto          128
      60: aload         4
      62: checkcast     #8                  // class exercise/collection/Sale
      65: astore        5
      67: iconst_0
      68: istore        6
      70: aload         5
      72: invokevirtual #91                 // Method exercise/collection/Sale.getQuantitySold:()I
      75: istore        5
      77: aload_3
      78: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      83: astore        6
      85: aload         6
      87: checkcast     #8                  // class exercise/collection/Sale
      90: astore        7
      92: iconst_0
      93: istore        8
      95: aload         7
      97: invokevirtual #91                 // Method exercise/collection/Sale.getQuantitySold:()I
     100: istore        7
     102: iload         5
     104: iload         7
     106: if_icmpge     117
     109: aload         6
     111: astore        4
     113: iload         7
     115: istore        5
     117: aload_3
     118: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     123: ifne          77
     126: aload         4
     128: checkcast     #8                  // class exercise/collection/Sale
     131: invokevirtual #108                // Method exercise/collection/Sale.getProductName:()Ljava/lang/String;
     134: astore_1
     135: goto          142
     138: astore_2
     139: ldc           #110                // String Invalid data
     141: astore_1
     142: aload_1
     143: areturn
    Exception table:
       from    to  target type
           6   135   138   Class java/lang/Exception

  public static final java.util.List<java.lang.String> filterSalesByPriceRange(java.util.List<exercise.collection.Sale>, double, double);
    Code:
       0: aload_0
       1: ldc           #61                 // String salesData
       3: invokestatic  #67                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #69                 // class java/lang/Iterable
      10: astore        5
      12: iconst_0
      13: istore        6
      15: aload         5
      17: astore        7
      19: new           #132                // class java/util/ArrayList
      22: dup
      23: invokespecial #133                // Method java/util/ArrayList."<init>":()V
      26: checkcast     #135                // class java/util/Collection
      29: astore        8
      31: iconst_0
      32: istore        9
      34: aload         7
      36: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      41: astore        10
      43: aload         10
      45: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      50: ifeq          118
      53: aload         10
      55: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      60: astore        11
      62: aload         11
      64: checkcast     #8                  // class exercise/collection/Sale
      67: astore        12
      69: iconst_0
      70: istore        13
      72: aload         12
      74: invokevirtual #87                 // Method exercise/collection/Sale.getPrice:()D
      77: dstore        14
      79: dload_1
      80: dload         14
      82: dcmpg
      83: ifgt          101
      86: dload         14
      88: dload_3
      89: dcmpg
      90: ifgt          97
      93: iconst_1
      94: goto          102
      97: iconst_0
      98: goto          102
     101: iconst_0
     102: ifeq          43
     105: aload         8
     107: aload         11
     109: invokeinterface #139,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     114: pop
     115: goto          43
     118: aload         8
     120: checkcast     #125                // class java/util/List
     123: nop
     124: checkcast     #69                 // class java/lang/Iterable
     127: astore        5
     129: nop
     130: iconst_0
     131: istore        6
     133: aload         5
     135: new           #141                // class exercise/collection/CollectionOperators2Kt$filterSalesByPriceRange$$inlined$sortedByDescending$1
     138: dup
     139: invokespecial #142                // Method exercise/collection/CollectionOperators2Kt$filterSalesByPriceRange$$inlined$sortedByDescending$1."<init>":()V
     142: checkcast     #144                // class java/util/Comparator
     145: invokestatic  #148                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
     148: checkcast     #69                 // class java/lang/Iterable
     151: astore        5
     153: nop
     154: iconst_0
     155: istore        6
     157: aload         5
     159: astore        7
     161: new           #132                // class java/util/ArrayList
     164: dup
     165: aload         5
     167: bipush        10
     169: invokestatic  #152                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     172: invokespecial #155                // Method java/util/ArrayList."<init>":(I)V
     175: checkcast     #135                // class java/util/Collection
     178: astore        8
     180: iconst_0
     181: istore        9
     183: aload         7
     185: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     190: astore        10
     192: aload         10
     194: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     199: ifeq          268
     202: aload         10
     204: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     209: astore        11
     211: aload         8
     213: aload         11
     215: checkcast     #8                  // class exercise/collection/Sale
     218: astore        12
     220: astore        16
     222: iconst_0
     223: istore        13
     225: new           #157                // class java/lang/StringBuilder
     228: dup
     229: invokespecial #158                // Method java/lang/StringBuilder."<init>":()V
     232: aload         12
     234: invokevirtual #108                // Method exercise/collection/Sale.getProductName:()Ljava/lang/String;
     237: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     240: ldc           #164                // String :
     242: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     245: aload         12
     247: invokevirtual #87                 // Method exercise/collection/Sale.getPrice:()D
     250: invokevirtual #167                // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
     253: invokevirtual #170                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     256: aload         16
     258: swap
     259: invokeinterface #139,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     264: pop
     265: goto          192
     268: aload         8
     270: checkcast     #125                // class java/util/List
     273: nop
     274: areturn

  public static final java.util.List<java.lang.String> findTopNSellingProducts(java.util.List<exercise.collection.Sale>, int);
    Code:
       0: aload_0
       1: ldc           #61                 // String salesData
       3: invokestatic  #67                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #69                 // class java/lang/Iterable
      10: astore_2
      11: iconst_0
      12: istore_3
      13: aload_2
      14: new           #194                // class exercise/collection/CollectionOperators2Kt$findTopNSellingProducts$$inlined$sortedByDescending$1
      17: dup
      18: invokespecial #195                // Method exercise/collection/CollectionOperators2Kt$findTopNSellingProducts$$inlined$sortedByDescending$1."<init>":()V
      21: checkcast     #144                // class java/util/Comparator
      24: invokestatic  #148                // Method kotlin/collections/CollectionsKt.sortedWith:(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
      27: checkcast     #69                 // class java/lang/Iterable
      30: iload_1
      31: invokestatic  #199                // Method kotlin/collections/CollectionsKt.take:(Ljava/lang/Iterable;I)Ljava/util/List;
      34: checkcast     #69                 // class java/lang/Iterable
      37: astore_2
      38: nop
      39: iconst_0
      40: istore_3
      41: aload_2
      42: astore        4
      44: new           #132                // class java/util/ArrayList
      47: dup
      48: aload_2
      49: bipush        10
      51: invokestatic  #152                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      54: invokespecial #155                // Method java/util/ArrayList."<init>":(I)V
      57: checkcast     #135                // class java/util/Collection
      60: astore        5
      62: iconst_0
      63: istore        6
      65: aload         4
      67: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      72: astore        7
      74: aload         7
      76: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      81: ifeq          155
      84: aload         7
      86: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      91: astore        8
      93: aload         5
      95: aload         8
      97: checkcast     #8                  // class exercise/collection/Sale
     100: astore        9
     102: astore        11
     104: iconst_0
     105: istore        10
     107: new           #157                // class java/lang/StringBuilder
     110: dup
     111: invokespecial #158                // Method java/lang/StringBuilder."<init>":()V
     114: aload         9
     116: invokevirtual #108                // Method exercise/collection/Sale.getProductName:()Ljava/lang/String;
     119: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     122: ldc           #164                // String :
     124: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     127: aload         9
     129: invokevirtual #91                 // Method exercise/collection/Sale.getQuantitySold:()I
     132: invokevirtual #202                // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
     135: ldc           #204                // String  sold
     137: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     140: invokevirtual #170                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     143: aload         11
     145: swap
     146: invokeinterface #139,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     151: pop
     152: goto          74
     155: aload         5
     157: checkcast     #125                // class java/util/List
     160: nop
     161: areturn

  public static final exercise.collection.PriceCategory calculatePriceCategory(double);
    Code:
       0: dload_0
       1: dstore_2
       2: dconst_0
       3: dload_2
       4: dcmpg
       5: ifgt          24
       8: dload_2
       9: ldc2_w        #29                 // double 2.0d
      12: dcmpg
      13: ifgt          20
      16: iconst_1
      17: goto          25
      20: iconst_0
      21: goto          25
      24: iconst_0
      25: ifeq          34
      28: getstatic     #214                // Field exercise/collection/PriceCategory.Low:Lexercise/collection/PriceCategory;
      31: goto          71
      34: ldc2_w        #215                // double 2.01d
      37: dload_2
      38: dcmpg
      39: ifgt          58
      42: dload_2
      43: ldc2_w        #23                 // double 3.0d
      46: dcmpg
      47: ifgt          54
      50: iconst_1
      51: goto          59
      54: iconst_0
      55: goto          59
      58: iconst_0
      59: ifeq          68
      62: getstatic     #219                // Field exercise/collection/PriceCategory.Medium:Lexercise/collection/PriceCategory;
      65: goto          71
      68: getstatic     #222                // Field exercise/collection/PriceCategory.High:Lexercise/collection/PriceCategory;
      71: areturn

  public static final java.util.Map<exercise.collection.PriceCategory, java.util.List<exercise.collection.Sale>> groupByPriceCategory(java.util.List<exercise.collection.Sale>);
    Code:
       0: aload_0
       1: ldc           #61                 // String salesData
       3: invokestatic  #67                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #69                 // class java/lang/Iterable
      10: astore_1
      11: iconst_0
      12: istore_2
      13: aload_1
      14: astore_3
      15: new           #228                // class java/util/LinkedHashMap
      18: dup
      19: invokespecial #229                // Method java/util/LinkedHashMap."<init>":()V
      22: checkcast     #231                // class java/util/Map
      25: astore        4
      27: iconst_0
      28: istore        5
      30: aload_3
      31: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      36: astore        6
      38: aload         6
      40: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      45: ifeq          153
      48: aload         6
      50: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      55: astore        7
      57: aload         7
      59: checkcast     #8                  // class exercise/collection/Sale
      62: astore        8
      64: iconst_0
      65: istore        9
      67: aload         8
      69: invokevirtual #87                 // Method exercise/collection/Sale.getPrice:()D
      72: invokestatic  #233                // Method calculatePriceCategory:(D)Lexercise/collection/PriceCategory;
      75: astore        10
      77: aload         4
      79: astore        11
      81: iconst_0
      82: istore        12
      84: aload         11
      86: aload         10
      88: invokeinterface #237,  2          // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      93: astore        13
      95: aload         13
      97: ifnonnull     132
     100: iconst_0
     101: istore        14
     103: new           #132                // class java/util/ArrayList
     106: dup
     107: invokespecial #133                // Method java/util/ArrayList."<init>":()V
     110: checkcast     #125                // class java/util/List
     113: astore        14
     115: aload         11
     117: aload         10
     119: aload         14
     121: invokeinterface #241,  3          // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     126: pop
     127: aload         14
     129: goto          134
     132: aload         13
     134: nop
     135: checkcast     #125                // class java/util/List
     138: astore        8
     140: aload         8
     142: aload         7
     144: invokeinterface #242,  2          // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     149: pop
     150: goto          38
     153: aload         4
     155: nop
     156: areturn

  public static final java.util.List<java.lang.String> calculateTotalProfit(java.util.List<exercise.collection.Sale>, double);
    Code:
       0: aload_0
       1: ldc           #61                 // String salesData
       3: invokestatic  #67                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: checkcast     #69                 // class java/lang/Iterable
      10: astore_3
      11: iconst_0
      12: istore        4
      14: aload_3
      15: astore        5
      17: new           #132                // class java/util/ArrayList
      20: dup
      21: aload_3
      22: bipush        10
      24: invokestatic  #152                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
      27: invokespecial #155                // Method java/util/ArrayList."<init>":(I)V
      30: checkcast     #135                // class java/util/Collection
      33: astore        6
      35: iconst_0
      36: istore        7
      38: aload         5
      40: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
      45: astore        8
      47: aload         8
      49: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
      54: ifeq          122
      57: aload         8
      59: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      64: astore        9
      66: aload         6
      68: aload         9
      70: checkcast     #8                  // class exercise/collection/Sale
      73: astore        10
      75: astore        12
      77: iconst_0
      78: istore        11
      80: new           #258                // class exercise/collection/SaleWithProfit
      83: dup
      84: aload         10
      86: aload         10
      88: invokevirtual #87                 // Method exercise/collection/Sale.getPrice:()D
      91: aload         10
      93: invokevirtual #91                 // Method exercise/collection/Sale.getQuantitySold:()I
      96: i2d
      97: dmul
      98: dload_1
      99: aload         10
     101: invokevirtual #91                 // Method exercise/collection/Sale.getQuantitySold:()I
     104: i2d
     105: dmul
     106: dsub
     107: invokespecial #261                // Method exercise/collection/SaleWithProfit."<init>":(Lexercise/collection/Sale;D)V
     110: aload         12
     112: swap
     113: invokeinterface #139,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     118: pop
     119: goto          47
     122: aload         6
     124: checkcast     #125                // class java/util/List
     127: nop
     128: checkcast     #69                 // class java/lang/Iterable
     131: astore_3
     132: nop
     133: iconst_0
     134: istore        4
     136: aload_3
     137: astore        5
     139: new           #132                // class java/util/ArrayList
     142: dup
     143: aload_3
     144: bipush        10
     146: invokestatic  #152                // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
     149: invokespecial #155                // Method java/util/ArrayList."<init>":(I)V
     152: checkcast     #135                // class java/util/Collection
     155: astore        6
     157: iconst_0
     158: istore        7
     160: aload         5
     162: invokeinterface #73,  1           // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
     167: astore        8
     169: aload         8
     171: invokeinterface #79,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
     176: ifeq          255
     179: aload         8
     181: invokeinterface #83,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
     186: astore        9
     188: aload         6
     190: aload         9
     192: checkcast     #258                // class exercise/collection/SaleWithProfit
     195: astore        10
     197: astore        12
     199: iconst_0
     200: istore        11
     202: new           #157                // class java/lang/StringBuilder
     205: dup
     206: invokespecial #158                // Method java/lang/StringBuilder."<init>":()V
     209: aload         10
     211: invokevirtual #265                // Method exercise/collection/SaleWithProfit.getSaleData:()Lexercise/collection/Sale;
     214: invokevirtual #108                // Method exercise/collection/Sale.getProductName:()Ljava/lang/String;
     217: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     220: ldc_w         #267                // String  -
     223: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     226: aload         10
     228: invokevirtual #270                // Method exercise/collection/SaleWithProfit.getProfit:()D
     231: invokevirtual #167                // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
     234: ldc_w         #272                // String  profit
     237: invokevirtual #162                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     240: invokevirtual #170                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     243: aload         12
     245: swap
     246: invokeinterface #139,  2          // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
     251: pop
     252: goto          169
     255: aload         6
     257: checkcast     #125                // class java/util/List
     260: nop
     261: areturn

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

Compiled from "Comparisons.kt"
public final class exercise.collection.CollectionOperators2Kt$findTopNSellingProducts$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public exercise.collection.CollectionOperators2Kt$findTopNSellingProducts$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class exercise/collection/Sale
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method exercise/collection/Sale.getQuantitySold:()I
      12: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_1
      19: checkcast     #23                 // class exercise/collection/Sale
      22: astore_3
      23: astore        5
      25: iconst_0
      26: istore        4
      28: aload_3
      29: invokevirtual #27                 // Method exercise/collection/Sale.getQuantitySold:()I
      32: invokestatic  #33                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      35: aload         5
      37: swap
      38: checkcast     #35                 // class java/lang/Comparable
      41: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      44: ireturn
}

Compiled from "Comparisons.kt"
public final class exercise.collection.CollectionOperators2Kt$filterSalesByPriceRange$$inlined$sortedByDescending$1<T> implements java.util.Comparator {
  public exercise.collection.CollectionOperators2Kt$filterSalesByPriceRange$$inlined$sortedByDescending$1();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  public final int compare(T, T);
    Code:
       0: aload_2
       1: checkcast     #23                 // class exercise/collection/Sale
       4: astore_3
       5: iconst_0
       6: istore        4
       8: aload_3
       9: invokevirtual #27                 // Method exercise/collection/Sale.getPrice:()D
      12: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      15: checkcast     #35                 // class java/lang/Comparable
      18: aload_1
      19: checkcast     #23                 // class exercise/collection/Sale
      22: astore_3
      23: astore        5
      25: iconst_0
      26: istore        4
      28: aload_3
      29: invokevirtual #27                 // Method exercise/collection/Sale.getPrice:()D
      32: invokestatic  #33                 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
      35: aload         5
      37: swap
      38: checkcast     #35                 // class java/lang/Comparable
      41: invokestatic  #41                 // Method kotlin/comparisons/ComparisonsKt.compareValues:(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
      44: ireturn
}