1 | package com.adventofcode.day16 | |
2 | ||
3 | class TicketScanning(private val validRanges: Collection<ValidRanges>, val ticket: Ticket, private val nearbyTickets: Collection<Ticket>) { | |
4 | ||
5 | fun errorsInNearByTickets(): Collection<Int> { | |
6 |
1
1. errorsInNearByTickets : replaced return value with Collections.emptyList for com/adventofcode/day16/TicketScanning::errorsInNearByTickets → KILLED |
return nearbyTickets.map { it.findErrorsAccordingTo(validRanges) }.flatten() |
7 | } | |
8 | ||
9 | fun findPossibleFields(): Map<Int, Collection<Collection<String>>> { | |
10 | return nearbyTickets.mapIndexed { index, it -> | |
11 | val data = it.findValidAccordingTo(validRanges) | |
12 | data.map { it.key to it.value } | |
13 | }.flatten() | |
14 | .groupBy { it.first } | |
15 | .map { it.key to it.value.map { it.second } } | |
16 | .map { it.first to it.second }.toMap() | |
17 | ||
18 | } | |
19 | ||
20 | fun findWhichFieldIsWhich(): Map<Int, String> { | |
21 | ||
22 | val namedFields = (0 until ticket.fields.size).map { it to "" }.toMap().toMutableMap() | |
23 | ||
24 | var possibles= findPossibleFields() | |
25 |
1
1. findWhichFieldIsWhich : negated conditional → KILLED |
.map { it.key to it.value.filterNot { possibleFields -> possibleFields.isEmpty() } |
26 | .reduce { acc, collection -> acc.intersect(collection) } } | |
27 | .toMap() | |
28 | ||
29 |
2
1. findWhichFieldIsWhich : negated conditional → KILLED 2. findWhichFieldIsWhich : negated conditional → KILLED |
while (possibles.isNotEmpty() ) { |
30 |
1
1. findWhichFieldIsWhich : removed call to com/adventofcode/day16/TicketScanning::memorizeFoundFields → TIMED_OUT |
memorizeFoundFields(possibles, namedFields) |
31 | possibles = removeFoundFields(possibles) | |
32 | possibles = reducePossibilitiesAccordingToFoundFields(possibles, namedFields) | |
33 | } | |
34 | return namedFields | |
35 | } | |
36 | ||
37 | private fun reducePossibilitiesAccordingToFoundFields(possibles: Map<Int, Collection<String>>, namedFields: MutableMap<Int, String>) = | |
38 |
2
1. reducePossibilitiesAccordingToFoundFields : negated conditional → KILLED 2. reducePossibilitiesAccordingToFoundFields : replaced return value with null for com/adventofcode/day16/TicketScanning::reducePossibilitiesAccordingToFoundFields → KILLED |
possibles.map { it.key to it.value.filterNot { namedFields.values.contains(it) } }.toMap() |
39 | ||
40 | private fun removeFoundFields(possibles: Map<Int, Collection<String>>) = | |
41 |
4
1. removeFoundFields : changed conditional boundary → SURVIVED 2. removeFoundFields : negated conditional → TIMED_OUT 3. removeFoundFields : negated conditional → TIMED_OUT 4. removeFoundFields : replaced return value with null for com/adventofcode/day16/TicketScanning::removeFoundFields → KILLED |
possibles.filter { it.value.size > 1 } |
42 | ||
43 | private fun memorizeFoundFields(possibles: Map<Int, Collection<String>>, namedFields: MutableMap<Int, String>) { | |
44 |
2
1. memorizeFoundFields : negated conditional → KILLED 2. memorizeFoundFields : negated conditional → KILLED |
possibles.filter { it.value.size == 1 }.forEach { namedFields[it.key] = it.value.first() } |
45 | } | |
46 | ||
47 | fun multiplyDepartureFieldsTogether(): Long { | |
48 | return findWhichFieldIsWhich() | |
49 |
1
1. multiplyDepartureFieldsTogether : negated conditional → KILLED |
.filter { it.value.startsWith("departure") } |
50 | .map { ticket.fields[it.key].toLong() } | |
51 |
1
1. multiplyDepartureFieldsTogether : Replaced long multiplication with division → KILLED |
.reduce{a, b -> a*b} |
52 | ||
53 | } | |
54 | ||
55 | companion object { | |
56 | fun fromInput(input: List<String>): TicketScanning { | |
57 | ||
58 | ||
59 | val validRanges = mutableListOf<ValidRanges>() | |
60 | var ticket: Ticket? = null | |
61 | val nearbyTickets = mutableListOf<Ticket>() | |
62 | ||
63 | var typeOfLine = "validRanges" | |
64 |
2
1. fromInput : negated conditional → KILLED 2. fromInput : negated conditional → KILLED |
input.filterNot { it.isEmpty() }.forEachIndexed { index, data -> |
65 | if (data == "your ticket:") { | |
66 | typeOfLine = "ticket"; return@forEachIndexed | |
67 | } | |
68 | if (data == "nearby tickets:") { | |
69 | typeOfLine = "nearbyticket"; return@forEachIndexed | |
70 | } | |
71 | ||
72 | when (typeOfLine) { | |
73 | "validRanges" -> validRanges += extractValidRanges(data) | |
74 | "ticket" -> ticket = extractTicket(data) | |
75 | "nearbyticket" -> nearbyTickets.add(extractTicket(data)) | |
76 | } | |
77 | ||
78 | } | |
79 | ||
80 | return TicketScanning(validRanges, ticket!!, nearbyTickets) | |
81 | } | |
82 | ||
83 | private fun extractValidRanges(data: String): ValidRanges { | |
84 | val splitData = data.split(": ") | |
85 | val name = splitData[0] | |
86 | val bounds = splitData[1].split(" or ") | |
87 | val firstRAnge = bounds[0].split("-").map { it.toInt() } | |
88 | val secondRange = bounds[1].split("-").map { it.toInt() } | |
89 |
1
1. extractValidRanges : replaced return value with null for com/adventofcode/day16/TicketScanning$Companion::extractValidRanges → KILLED |
return ValidRanges(name = name, firstLowerBound = firstRAnge[0], firstHigherBound = firstRAnge[1], secondLowerBound = secondRange[0], secondHigherBound = secondRange[1]) as ValidRanges |
90 | } | |
91 | ||
92 |
1
1. extractTicket : replaced return value with null for com/adventofcode/day16/TicketScanning$Companion::extractTicket → KILLED |
private fun extractTicket(data: String): Ticket = Ticket(*data.split(",").map { it.toInt() }.toIntArray()) |
93 | } | |
94 | } | |
95 | ||
Mutations | ||
6 |
1.1 |
|
25 |
1.1 |
|
29 |
1.1 2.2 |
|
30 |
1.1 |
|
38 |
1.1 2.2 |
|
41 |
1.1 2.2 3.3 4.4 |
|
44 |
1.1 2.2 |
|
49 |
1.1 |
|
51 |
1.1 |
|
64 |
1.1 2.2 |
|
89 |
1.1 |
|
92 |
1.1 |
|
101 |
1.1 2.2 3.3 4.4 |
|
104 |
1.1 2.2 3.3 4.4 |
|
115 |
1.1 |
|
149 |
1.1 |
|
191 |
1.1 |
|
194 |
1.1 |