From 38abf1f4b4ec640f7699ed5ea5c0c0d594e0c92d Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 07:19:03 +0000 Subject: [PATCH 01/11] first try only works for very small input --- day15/kotlin/RJPlog/day2115_1_2.kts | 151 +++++++++++++++++++ day15/kotlin/RJPlog/day2115_puzzle_input.txt | 5 + 2 files changed, 156 insertions(+) create mode 100644 day15/kotlin/RJPlog/day2115_1_2.kts create mode 100644 day15/kotlin/RJPlog/day2115_puzzle_input.txt diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts new file mode 100644 index 00000000..543336ae --- /dev/null +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -0,0 +1,151 @@ +import java.io.File + + + // tag::followPath_15[] +fun followPath_15(): Int { + var segments = mutableListOf>() + var searchPath = mutableListOf() + var searchPathNew = mutableListOf() + var validPath = mutableListOf() + var searchEnd: Boolean = false + var currentPath: String + var newCurrentPath: String + var ruleCheckPassed: Boolean = false + var width: Int = 0 + var height: Int = 0 + var riskLevel = mutableListOf() + + // generate segments Pair(,) as in day12 + // generate searchpath start value (0,0-0,1 , 0,0-1,0) + // new: generate list with risk level: ((x,y-x,y), value) + // rule: single position is only allowed once + + File("day2115_puzzle_input.txt").forEachLine { + width = it.length + it.forEach{ + riskLevel.add(it.toString().toInt()) + } + height += 1 + } + + println("width $width, height $height") + println("risklevel: $riskLevel") + + for (y in 0..height - 1) { + for (x in 0..width-1) { + if (x+1 < width) { + segments.add(Pair(x.toString()+","+y.toString(),(x+1).toString()+","+y.toString())) + } + if (y+1 < height) { + segments.add(Pair(x.toString()+","+y.toString(),x.toString()+","+(y+1).toString())) + } + } + } + searchPath.add("0,0-0,1") + searchPath.add("0,0-1,0") + + println("segments: $segments") + println("searchPath: $searchPath") + + + +// var ii : Int = 0 + while (!searchEnd) { +//ii += 1 + searchEnd = true + + searchPath.forEach { + currentPath = it + //println("$ii: currentPath: $currentPath") + var instruction = it.split("-") + var lastSegment = instruction[instruction.size - 1] + + segments.forEach { + if (lastSegment == it.first) { + newCurrentPath = currentPath + "-" + it.second + if (it.second == (width-1).toString()+","+(height-1).toString()) { + //if (!validPath.contains(newCurrentPath)) { + validPath.add(newCurrentPath) + //} + } else { + + ruleCheckPassed = !(currentPath.contains(it.second)) // change!! + + if (ruleCheckPassed) { + searchPathNew.add(newCurrentPath) + searchEnd = false + } + } + } else if (lastSegment == it.second) { + newCurrentPath = currentPath + "-" + it.first + if (it.first == (width-1).toString()+","+(height-1).toString()) { + //if (!validPath.contains(newCurrentPath)) { + validPath.add(newCurrentPath) + //} + } else { + // check rule + ruleCheckPassed = !(currentPath.contains(it.first)) // change!! + if (ruleCheckPassed) { + searchPathNew.add(newCurrentPath) + searchEnd = false + } + } + } + } + } + searchPath.clear() + searchPath.addAll(searchPathNew) + searchPathNew.clear() + } + + println("-- path search ended, now calculation risk level") +// return validPath.size + + println() + var firstTotalRisk: Boolean = true + var totalRiskMin: Int = 0 + validPath.forEach{ + var totalRisk: Int = 0 + // println(it) + var steps = it.split("-") + for(i in 1..steps.size-1) { + var positions = steps[i].split(",") + // println(" ${steps[i]}, ${riskLevel[positions[0].toInt()+positions[1].toInt()*width]}") + totalRisk = totalRisk + riskLevel[positions[0].toInt()+positions[1].toInt()*width] + } + if (firstTotalRisk) { + totalRiskMin = totalRisk + firstTotalRisk = false + } else if (totalRisk < totalRiskMin) { + totalRiskMin = totalRisk + } + // println("totalRisk: $totalRisk") + // println("totalRiskMin: $totalRiskMin") + } + + return totalRiskMin +} +// end::followPath_15[] + + +fun main(args: Array) { + + var solution2: Int = 0 + + var solution1 = followPath_15() + + // tag::output[] +// print solution for part 1 + println("***********************") + println("--- Day 15: Chiton ---") + println("***********************") + println("Solution for part1") + println(" $solution1 ") + println() +// print solution for part 2 + println("*******************************") + println("Solution for part2") + println(" $solution2 ") + println() +// end::output[] +} \ No newline at end of file diff --git a/day15/kotlin/RJPlog/day2115_puzzle_input.txt b/day15/kotlin/RJPlog/day2115_puzzle_input.txt new file mode 100644 index 00000000..3482e0db --- /dev/null +++ b/day15/kotlin/RJPlog/day2115_puzzle_input.txt @@ -0,0 +1,5 @@ +11637 +13813 +21365 +36949 +74634 From 0174dc3172b417128294c9eecb18cdef648f9aa0 Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 07:27:51 +0000 Subject: [PATCH 02/11] thoughts for first approach and next steps --- day15/kotlin/RJPlog/README.adoc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 day15/kotlin/RJPlog/README.adoc diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc new file mode 100644 index 00000000..3a090d83 --- /dev/null +++ b/day15/kotlin/RJPlog/README.adoc @@ -0,0 +1,14 @@ +== Day 15: Chiton == + +This solution is written in Kotlin. + +The original puzzle can be found at https://adventofcode.com/2021/day/15 + +For execution enter _kotlin day2115_1_2.kts_ in the command line. + +=== Today I learned + +Today I started very fast with adapting solution of day12, creating a list of possible segment changes and creating all possible pathes through the grid only visiting every place once. For very small solutions it worked well, but already the given example with 10x10 was not able to calculate in proper time. + +So I have to rethink my approach. First, I still believe in the general approach and add some modifications to improve timing, change all string based operations to int based operations, let's see how far it will get me. + From 7cd62c12665650aa22a347122e266dd016e9251e Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 10:41:26 +0000 Subject: [PATCH 03/11] first rework, still not capable of large grids --- day15/kotlin/RJPlog/README.adoc | 2 + day15/kotlin/RJPlog/day2115_1_2.kts | 146 +++++++++++++++------------- 2 files changed, 82 insertions(+), 66 deletions(-) diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc index 3a090d83..6d813b21 100644 --- a/day15/kotlin/RJPlog/README.adoc +++ b/day15/kotlin/RJPlog/README.adoc @@ -12,3 +12,5 @@ Today I started very fast with adapting solution of day12, creating a list of po So I have to rethink my approach. First, I still believe in the general approach and add some modifications to improve timing, change all string based operations to int based operations, let's see how far it will get me. +Second try with rework all the string operations to lists, but still it does not work. Next part would be to calculate totalRisklevel while generating new pathes and add a rule to not add the path when exceeding already reached totalRisks with other pathes. Initvalue could be puzzle input straight from left to right and down. + diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts index 543336ae..1f520d59 100644 --- a/day15/kotlin/RJPlog/day2115_1_2.kts +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -1,90 +1,97 @@ import java.io.File - // tag::followPath_15[] +// tag::followPath_15[] fun followPath_15(): Int { - var segments = mutableListOf>() - var searchPath = mutableListOf() - var searchPathNew = mutableListOf() - var validPath = mutableListOf() + var segments = mutableListOf>() // changed from String, String to Int, Int + var currentPath = mutableListOf() + var newCurrentPath = mutableListOf() + var searchPath = MutableList(0) { mutableListOf() } + var searchPathNew = MutableList(0) { mutableListOf() } + var validPath = MutableList(0) { mutableListOf() } var searchEnd: Boolean = false - var currentPath: String - var newCurrentPath: String + + var ruleCheckPassed: Boolean = false var width: Int = 0 - var height: Int = 0 + var height: Int = 0 var riskLevel = mutableListOf() // generate segments Pair(,) as in day12 // generate searchpath start value (0,0-0,1 , 0,0-1,0) // new: generate list with risk level: ((x,y-x,y), value) // rule: single position is only allowed once - + File("day2115_puzzle_input.txt").forEachLine { width = it.length - it.forEach{ - riskLevel.add(it.toString().toInt()) + it.forEach { + riskLevel.add(it.toString().toInt()) } height += 1 } - - println("width $width, height $height") - println("risklevel: $riskLevel") - + + println("width $width, height $height") + println("risklevel: $riskLevel") + for (y in 0..height - 1) { - for (x in 0..width-1) { - if (x+1 < width) { - segments.add(Pair(x.toString()+","+y.toString(),(x+1).toString()+","+y.toString())) + for (x in 0..width - 1) { + if (x + 1 < width) { + segments.add(Pair(x + y * width, (x + 1) + y * width)) } - if (y+1 < height) { - segments.add(Pair(x.toString()+","+y.toString(),x.toString()+","+(y+1).toString())) + if (y + 1 < height) { + segments.add(Pair(x + y * width, x + (y + 1) * width)) } } } - searchPath.add("0,0-0,1") - searchPath.add("0,0-1,0") - - println("segments: $segments") - println("searchPath: $searchPath") - - - -// var ii : Int = 0 + currentPath.add(0) + currentPath.add(1) + searchPath.add(currentPath.toMutableList()) + currentPath.clear() + currentPath.add(0) + currentPath.add(width) + searchPath.add(currentPath.toMutableList()) + + println("segments: $segments") + println("searchPath: $searchPath") + + + var ii: Int = 0 while (!searchEnd) { -//ii += 1 + ii += 1 searchEnd = true - + searchPath.forEach { currentPath = it //println("$ii: currentPath: $currentPath") - var instruction = it.split("-") - var lastSegment = instruction[instruction.size - 1] + + var lastSegment = currentPath.last() segments.forEach { + // println("${it.first}, ${it.second}") if (lastSegment == it.first) { - newCurrentPath = currentPath + "-" + it.second - if (it.second == (width-1).toString()+","+(height-1).toString()) { - //if (!validPath.contains(newCurrentPath)) { - validPath.add(newCurrentPath) - //} + newCurrentPath = currentPath.toMutableList() + newCurrentPath.add(it.second) + // println("newCurrentPath $newCurrentPath") + if (it.second == width * height - 1) { + validPath.add(newCurrentPath) } else { - - ruleCheckPassed = !(currentPath.contains(it.second)) // change!! - + ruleCheckPassed = !(currentPath.contains(it.second)) if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) searchEnd = false } } } else if (lastSegment == it.second) { - newCurrentPath = currentPath + "-" + it.first - if (it.first == (width-1).toString()+","+(height-1).toString()) { - //if (!validPath.contains(newCurrentPath)) { - validPath.add(newCurrentPath) - //} + newCurrentPath = currentPath.toMutableList() + newCurrentPath.add(it.first) + // println("newCurrentPath $newCurrentPath") + if (it.first == width * height - 1) { + validPath.add(newCurrentPath) } else { - // check rule - ruleCheckPassed = !(currentPath.contains(it.first)) // change!! + // extend rulecheck by already checking totalRisk. + // in a 3x3 grid, direct way is max 5*9, you can take also already the input data, every new path with higher totalRisk dont have to be added. + // or you check, if there is already a path reaching same spot with less totalRisk + ruleCheckPassed = !(currentPath.contains(it.first)) if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) searchEnd = false @@ -97,33 +104,40 @@ fun followPath_15(): Int { searchPath.addAll(searchPathNew) searchPathNew.clear() } - - println("-- path search ended, now calculation risk level") + + println() + println("-- path search ended, now calculation risk level") + println() + + validPath.forEach { + println(it) + } // return validPath.size - - println() - var firstTotalRisk: Boolean = true - var totalRiskMin: Int = 0 + + println("validPath:") + println() + var firstTotalRisk: Boolean = true + var totalRiskMin: Int = 0 validPath.forEach{ var totalRisk: Int = 0 - // println(it) - var steps = it.split("-") - for(i in 1..steps.size-1) { - var positions = steps[i].split(",") - // println(" ${steps[i]}, ${riskLevel[positions[0].toInt()+positions[1].toInt()*width]}") - totalRisk = totalRisk + riskLevel[positions[0].toInt()+positions[1].toInt()*width] + + + for(i in 1..it.size-1) { + totalRisk = totalRisk + riskLevel[it[i]] } if (firstTotalRisk) { totalRiskMin = totalRisk firstTotalRisk = false } else if (totalRisk < totalRiskMin) { totalRiskMin = totalRisk - } - // println("totalRisk: $totalRisk") - // println("totalRiskMin: $totalRiskMin") + } + //println("$it /totalRisk: $totalRisk") + } + println() + println("totalRiskMin: $totalRiskMin") - return totalRiskMin + return totalRiskMin } // end::followPath_15[] @@ -131,9 +145,9 @@ fun followPath_15(): Int { fun main(args: Array) { var solution2: Int = 0 - + var solution1 = followPath_15() - + // tag::output[] // print solution for part 1 println("***********************") From ef2b79fef2f8be5a619c3e129a3c7224e0e31b2c Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 10:58:19 +0000 Subject: [PATCH 04/11] 10x10 example is running, but still not enough --- day15/kotlin/RJPlog/README.adoc | 2 + day15/kotlin/RJPlog/day2115_1_2.kts | 58 +++++++++++--------- day15/kotlin/RJPlog/day2115_puzzle_input.txt | 15 +++-- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc index 6d813b21..9f6c44ca 100644 --- a/day15/kotlin/RJPlog/README.adoc +++ b/day15/kotlin/RJPlog/README.adoc @@ -14,3 +14,5 @@ So I have to rethink my approach. First, I still believe in the general approach Second try with rework all the string operations to lists, but still it does not work. Next part would be to calculate totalRisklevel while generating new pathes and add a rule to not add the path when exceeding already reached totalRisks with other pathes. Initvalue could be puzzle input straight from left to right and down. +Third try with additional rule if path has a total risk level of (width*height-1)*9 now worked for the 10x10 example. But the puzzle input is oviosely to big. Next improvement would be to set the init value not on (width*height-1)*9 but as above described based on puzzle input from left to rigth and then down, second improvement will be to just dynamically adapt the totalRiskMin to already reached min pathes. + diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts index 1f520d59..b0a10634 100644 --- a/day15/kotlin/RJPlog/day2115_1_2.kts +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -1,6 +1,5 @@ import java.io.File - // tag::followPath_15[] fun followPath_15(): Int { var segments = mutableListOf>() // changed from String, String to Int, Int @@ -17,6 +16,10 @@ fun followPath_15(): Int { var height: Int = 0 var riskLevel = mutableListOf() + var firstTotalRisk: Boolean = true + var totalRiskMin: Int = 0 + var totalRisk: Int = 0 + // generate segments Pair(,) as in day12 // generate searchpath start value (0,0-0,1 , 0,0-1,0) // new: generate list with risk level: ((x,y-x,y), value) @@ -30,6 +33,8 @@ fun followPath_15(): Int { height += 1 } + totalRiskMin = ((width * height) - 1) * 9 + println("width $width, height $height") println("risklevel: $riskLevel") @@ -67,15 +72,19 @@ fun followPath_15(): Int { var lastSegment = currentPath.last() segments.forEach { - // println("${it.first}, ${it.second}") + // println("${it.first}, ${it.second}") if (lastSegment == it.first) { newCurrentPath = currentPath.toMutableList() newCurrentPath.add(it.second) - // println("newCurrentPath $newCurrentPath") + // println("newCurrentPath $newCurrentPath") if (it.second == width * height - 1) { validPath.add(newCurrentPath) } else { - ruleCheckPassed = !(currentPath.contains(it.second)) + for (i in 1..newCurrentPath.size - 1) { + totalRisk = totalRisk + riskLevel[newCurrentPath[i]] + } + ruleCheckPassed = !(currentPath.contains(it.second)) && totalRisk < totalRiskMin + totalRisk = 0 if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) searchEnd = false @@ -84,14 +93,14 @@ fun followPath_15(): Int { } else if (lastSegment == it.second) { newCurrentPath = currentPath.toMutableList() newCurrentPath.add(it.first) - // println("newCurrentPath $newCurrentPath") + // println("newCurrentPath $newCurrentPath") if (it.first == width * height - 1) { validPath.add(newCurrentPath) - } else { - // extend rulecheck by already checking totalRisk. - // in a 3x3 grid, direct way is max 5*9, you can take also already the input data, every new path with higher totalRisk dont have to be added. - // or you check, if there is already a path reaching same spot with less totalRisk - ruleCheckPassed = !(currentPath.contains(it.first)) + for (i in 1..newCurrentPath.size - 1) { + totalRisk = totalRisk + riskLevel[newCurrentPath[i]] + } + ruleCheckPassed = !(currentPath.contains(it.first)) && totalRisk < totalRiskMin + totalRisk = 0 if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) searchEnd = false @@ -116,26 +125,25 @@ fun followPath_15(): Int { println("validPath:") println() - var firstTotalRisk: Boolean = true - var totalRiskMin: Int = 0 - validPath.forEach{ - var totalRisk: Int = 0 + validPath.forEach { + totalRisk = 0 - for(i in 1..it.size-1) { - totalRisk = totalRisk + riskLevel[it[i]] - } - if (firstTotalRisk) { - totalRiskMin = totalRisk - firstTotalRisk = false - } else if (totalRisk < totalRiskMin) { - totalRiskMin = totalRisk - } - //println("$it /totalRisk: $totalRisk") + for (i in 1..it.size - 1) { + totalRisk = totalRisk + riskLevel[it[i]] } + if (firstTotalRisk) { + totalRiskMin = totalRisk + firstTotalRisk = false + } else if (totalRisk < totalRiskMin) { + totalRiskMin = totalRisk + } + //println("$it /totalRisk: $totalRisk") + + } println() - println("totalRiskMin: $totalRiskMin") + println("totalRiskMin: $totalRiskMin") return totalRiskMin } diff --git a/day15/kotlin/RJPlog/day2115_puzzle_input.txt b/day15/kotlin/RJPlog/day2115_puzzle_input.txt index 3482e0db..ab80887e 100644 --- a/day15/kotlin/RJPlog/day2115_puzzle_input.txt +++ b/day15/kotlin/RJPlog/day2115_puzzle_input.txt @@ -1,5 +1,10 @@ -11637 -13813 -21365 -36949 -74634 +1163751742 +1381373672 +2136511328 +3694931569 +7463417111 +1319128137 +1359912421 +3125421639 +1293138521 +2311944581 From 7ca37036ccc23627a6a9bffda10a2355b81bea82 Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 12:10:52 +0000 Subject: [PATCH 05/11] saving current status. works 10x19 --- day15/kotlin/RJPlog/README.adoc | 2 + day15/kotlin/RJPlog/day2115_1_2.kts | 62 +++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc index 9f6c44ca..f1355592 100644 --- a/day15/kotlin/RJPlog/README.adoc +++ b/day15/kotlin/RJPlog/README.adoc @@ -16,3 +16,5 @@ Second try with rework all the string operations to lists, but still it does not Third try with additional rule if path has a total risk level of (width*height-1)*9 now worked for the 10x10 example. But the puzzle input is oviosely to big. Next improvement would be to set the init value not on (width*height-1)*9 but as above described based on puzzle input from left to rigth and then down, second improvement will be to just dynamically adapt the totalRiskMin to already reached min pathes. +Several optimizations later, I don't know how to proceed. Taking break. Current status: Works for 10x10. + diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts index b0a10634..cd49f265 100644 --- a/day15/kotlin/RJPlog/day2115_1_2.kts +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -25,18 +25,28 @@ fun followPath_15(): Int { // new: generate list with risk level: ((x,y-x,y), value) // rule: single position is only allowed once + File("day2115_puzzle_input.txt").forEachLine { width = it.length it.forEach { riskLevel.add(it.toString().toInt()) } + if (firstTotalRisk) { + for (i in 1..it.length - 1) { + totalRiskMin = totalRiskMin + it[i].toString().toInt() + } + firstTotalRisk = false + } else { + totalRiskMin = totalRiskMin + it.takeLast(1).toString().toInt() + } height += 1 } - totalRiskMin = ((width * height) - 1) * 9 + //totalRiskMin = ((width + height) - 1) * 9 println("width $width, height $height") println("risklevel: $riskLevel") + println("totalRiskMin: $totalRiskMin") for (y in 0..height - 1) { for (x in 0..width - 1) { @@ -78,55 +88,83 @@ fun followPath_15(): Int { newCurrentPath.add(it.second) // println("newCurrentPath $newCurrentPath") if (it.second == width * height - 1) { - validPath.add(newCurrentPath) + //validPath.add(newCurrentPath) + for (i in 1..newCurrentPath.size - 1) { + totalRisk = totalRisk + riskLevel[newCurrentPath[i]] + } + if (totalRisk < totalRiskMin) { + totalRiskMin = totalRisk + validPath.add(newCurrentPath) + println("validPath: $newCurrentPath found, , totalRisk $totalRisk, totalRiskMin: $totalRiskMin") + } + + + totalRisk = 0 + } else { for (i in 1..newCurrentPath.size - 1) { totalRisk = totalRisk + riskLevel[newCurrentPath[i]] } ruleCheckPassed = !(currentPath.contains(it.second)) && totalRisk < totalRiskMin - totalRisk = 0 + if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) + //println(" path added at totalRisk $totalRisk, totalRiskMin $totalRiskMin") searchEnd = false } + totalRisk = 0 } } else if (lastSegment == it.second) { newCurrentPath = currentPath.toMutableList() newCurrentPath.add(it.first) // println("newCurrentPath $newCurrentPath") if (it.first == width * height - 1) { - validPath.add(newCurrentPath) + //validPath.add(newCurrentPath) for (i in 1..newCurrentPath.size - 1) { totalRisk = totalRisk + riskLevel[newCurrentPath[i]] } - ruleCheckPassed = !(currentPath.contains(it.first)) && totalRisk < totalRiskMin + if (totalRisk < totalRiskMin) { + totalRiskMin = totalRisk + validPath.add(newCurrentPath) + println("validPath: $newCurrentPath found, totalRisk $totalRisk, totalRiskMin: $totalRiskMin") + } + + totalRisk = 0 + } else { + for (i in 1..newCurrentPath.size - 1) { + totalRisk = totalRisk + riskLevel[newCurrentPath[i]] + } + ruleCheckPassed = !(currentPath.contains(it.first)) && totalRisk < totalRiskMin + if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) + //println(" path added at totalRisk $totalRisk, totalRiskMin $totalRiskMin") searchEnd = false } + totalRisk = 0 } - } + } } } searchPath.clear() +// println("serachPath $searchPath") searchPath.addAll(searchPathNew) +// println("serachPath $searchPath") searchPathNew.clear() +// println("serachPathNew $searchPathNew") } println() println("-- path search ended, now calculation risk level") println() - validPath.forEach { - println(it) - } // return validPath.size println("validPath:") println() - validPath.forEach { +/* validPath.forEach { totalRisk = 0 @@ -139,12 +177,12 @@ fun followPath_15(): Int { } else if (totalRisk < totalRiskMin) { totalRiskMin = totalRisk } - //println("$it /totalRisk: $totalRisk") + println("$it /totalRisk: $totalRisk") } println() println("totalRiskMin: $totalRiskMin") - +*/ return totalRiskMin } // end::followPath_15[] From e198be60c32b335879b595ab7a557cfe29459158 Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 16:22:15 +0000 Subject: [PATCH 06/11] finally part1 is running --- day15/kotlin/RJPlog/README.adoc | 2 + day15/kotlin/RJPlog/day2115_1_2.kts | 49 ++++++--- day15/kotlin/RJPlog/day2115_puzzle_input.txt | 110 +++++++++++++++++-- 3 files changed, 136 insertions(+), 25 deletions(-) diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc index f1355592..f92b09bd 100644 --- a/day15/kotlin/RJPlog/README.adoc +++ b/day15/kotlin/RJPlog/README.adoc @@ -18,3 +18,5 @@ Third try with additional rule if path has a total risk level of (width*height-1 Several optimizations later, I don't know how to proceed. Taking break. Current status: Works for 10x10. +Finally first part is solved. Takes 5min to run through, but it works. Definitely no good idea for second part, so at the end I again have to rethink my strategy. Obivous is, that example and puzzle input take no left or up steps, so I will try to use this in the next approach. + diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts index cd49f265..432b0fef 100644 --- a/day15/kotlin/RJPlog/day2115_1_2.kts +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -9,6 +9,7 @@ fun followPath_15(): Int { var searchPathNew = MutableList(0) { mutableListOf() } var validPath = MutableList(0) { mutableListOf() } var searchEnd: Boolean = false + var totalRiskPerTile = mutableMapOf() var ruleCheckPassed: Boolean = false @@ -19,6 +20,7 @@ fun followPath_15(): Int { var firstTotalRisk: Boolean = true var totalRiskMin: Int = 0 var totalRisk: Int = 0 + var tileRisk: Int = 0 // generate segments Pair(,) as in day12 // generate searchpath start value (0,0-0,1 , 0,0-1,0) @@ -45,7 +47,7 @@ fun followPath_15(): Int { //totalRiskMin = ((width + height) - 1) * 9 println("width $width, height $height") - println("risklevel: $riskLevel") +// println("risklevel: $riskLevel") println("totalRiskMin: $totalRiskMin") for (y in 0..height - 1) { @@ -61,13 +63,17 @@ fun followPath_15(): Int { currentPath.add(0) currentPath.add(1) searchPath.add(currentPath.toMutableList()) + totalRiskPerTile.put(1, 0) currentPath.clear() currentPath.add(0) currentPath.add(width) searchPath.add(currentPath.toMutableList()) + totalRiskPerTile.put(width, 0) - println("segments: $segments") +// println("segments: $segments") println("searchPath: $searchPath") + println("totalRiskPerTile: $totalRiskPerTile") + println() var ii: Int = 0 @@ -95,7 +101,7 @@ fun followPath_15(): Int { if (totalRisk < totalRiskMin) { totalRiskMin = totalRisk validPath.add(newCurrentPath) - println("validPath: $newCurrentPath found, , totalRisk $totalRisk, totalRiskMin: $totalRiskMin") + // println("validPath: $newCurrentPath found, , totalRisk $totalRisk, totalRiskMin: $totalRiskMin") } @@ -105,11 +111,17 @@ fun followPath_15(): Int { for (i in 1..newCurrentPath.size - 1) { totalRisk = totalRisk + riskLevel[newCurrentPath[i]] } - ruleCheckPassed = !(currentPath.contains(it.second)) && totalRisk < totalRiskMin + if (totalRiskPerTile.contains(it.second)) { + ruleCheckPassed = + !(currentPath.contains(it.second)) && totalRisk < totalRiskPerTile.getValue(it.second) + } else { + ruleCheckPassed = !(currentPath.contains(it.second)) && totalRisk < totalRiskMin + } if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) - //println(" path added at totalRisk $totalRisk, totalRiskMin $totalRiskMin") + totalRiskPerTile.put(it.second, totalRisk) + // println(" path added at totalRisk $totalRisk, totalRiskMin $totalRiskMin, ${it.second}") searchEnd = false } totalRisk = 0 @@ -126,7 +138,7 @@ fun followPath_15(): Int { if (totalRisk < totalRiskMin) { totalRiskMin = totalRisk validPath.add(newCurrentPath) - println("validPath: $newCurrentPath found, totalRisk $totalRisk, totalRiskMin: $totalRiskMin") + // println("validPath: $newCurrentPath found, totalRisk $totalRisk, totalRiskMin: $totalRiskMin") } @@ -135,22 +147,30 @@ fun followPath_15(): Int { for (i in 1..newCurrentPath.size - 1) { totalRisk = totalRisk + riskLevel[newCurrentPath[i]] } - ruleCheckPassed = !(currentPath.contains(it.first)) && totalRisk < totalRiskMin + if (totalRiskPerTile.contains(it.first)) { + ruleCheckPassed = + !(currentPath.contains(it.first)) && totalRisk < totalRiskPerTile.getValue(it.first) + + } else { + ruleCheckPassed = !(currentPath.contains(it.first)) && totalRisk < totalRiskMin + } if (ruleCheckPassed) { searchPathNew.add(newCurrentPath) - //println(" path added at totalRisk $totalRisk, totalRiskMin $totalRiskMin") + totalRiskPerTile.put(it.first, totalRisk) + // println(" path $newCurrentPath added at totalRisk $totalRisk, totalRiskMin $totalRiskMin, $it.first}") searchEnd = false } totalRisk = 0 } - } + } } } searchPath.clear() // println("serachPath $searchPath") searchPath.addAll(searchPathNew) -// println("serachPath $searchPath") + println("$ii searchPath.size ${searchPath.size}") + // println("totalRiskPerTile $totalRiskPerTile") searchPathNew.clear() // println("serachPathNew $searchPathNew") } @@ -161,13 +181,11 @@ fun followPath_15(): Int { // return validPath.size - println("validPath:") +// println("validPath:") println() /* validPath.forEach { totalRisk = 0 - - for (i in 1..it.size - 1) { totalRisk = totalRisk + riskLevel[it[i]] } @@ -178,7 +196,6 @@ fun followPath_15(): Int { totalRiskMin = totalRisk } println("$it /totalRisk: $totalRisk") - } println() println("totalRiskMin: $totalRiskMin") @@ -189,7 +206,7 @@ fun followPath_15(): Int { fun main(args: Array) { - + var t1 = System.currentTimeMillis() var solution2: Int = 0 var solution1 = followPath_15() @@ -207,5 +224,7 @@ fun main(args: Array) { println("Solution for part2") println(" $solution2 ") println() + t1 = System.currentTimeMillis() - t1 + println("puzzle solved in ${t1} ms") // end::output[] } \ No newline at end of file diff --git a/day15/kotlin/RJPlog/day2115_puzzle_input.txt b/day15/kotlin/RJPlog/day2115_puzzle_input.txt index ab80887e..f2433a6d 100644 --- a/day15/kotlin/RJPlog/day2115_puzzle_input.txt +++ b/day15/kotlin/RJPlog/day2115_puzzle_input.txt @@ -1,10 +1,100 @@ -1163751742 -1381373672 -2136511328 -3694931569 -7463417111 -1319128137 -1359912421 -3125421639 -1293138521 -2311944581 +9899623167955799382567812944379969888862225189992795696599917679656768699999959517619965244969693964 +9299799754769995528964879691987994394279962991817261288292875969792662487997119818181869584684876846 +7797846998192515817979298977311989795237984959677986552466183891499117966741289581161899999893535995 +2746871998587973835699889998392494767471869998599394899949381694296896989189962932964957933899542279 +9758993391987992656989818498486988599883838318197866615597799585988981991747229849497999993243298395 +9399859277754624991914794999879918389948983892536995414838519589749997992375963822994963898129816891 +4988761796994698798992294593199869969449299299888928699598878616594466846698991331991384879288286649 +6681812758921325927688654155918195422521578475935721834774323989692982969497917655999285958895411188 +9294959984991949829739979782757486496875798879567285829265899568198989661156887948394893429849894344 +1989218789489289118884889794782687999839837887113234849779927951925453711933428829589699775283299939 +7113936997884496159763714189899331495417669273479968229199411999655789958743868829834719469784979991 +9937892998524945938896699224293782778973971162817489767755178489985773997289738882981958789689969738 +9893667719871253431939794519776593881899999984999962999886168599984689197789256958928814719171836987 +7696995999998819843579887897889999959818767599838619996753857949223958869799888996941198418198283783 +1289497758397697991165997178769891934583779487914994292296484372375549278795469999576912852999577146 +2145499618574685969944916191819694176889517862891987992286738596322515719885117867136329394989169918 +7838949788839218366923347957991884889313781679758899928466899961477194699875195737897469919119172964 +8969814999876973195999999664518987675889217897686288588198473581989799964747919586577197883617842912 +3646447111298979939618644396846388979979632986751561976254775749577761761684199897989861979978818249 +3693987887785199696529192391881158366749834784416121923891965298714355149487439797789695651691994849 +4399691971845787891217793292838938799899841989958969696922899969166555789939469791978193767969589599 +1597452938979863187994895272216937677557565817137799589361998819892494688832787778742593847599654928 +4998869993788952899573655981676899457612878235987545139618869168599744167461768978559866999931887219 +9918547918588952892628699998876576788789978665681743292193488577137979718219286915399767218557788869 +9998367769929846173918588599919843778167888739193129964797338846491478969759283689171367669868696599 +9829571337865973928146726168773595121993396595989823959918677438974595858859326775998195658642797956 +5793777994687577296639276199298961337939999276974564922373996999998896861236943745399984915955692759 +8789948788688489312693916698488579198763994399199437915419489358888884961886351789858973958786889999 +5879997993698997672824288898985156878882726578969987158868171318286218527399415884599865885525859388 +8379442598616924549819587897983867986988889799152599316616759976993492798923293246979593289985791628 +3968859989982898979586988795551294599557648419698923978899722987994894199989792982774967868858646279 +9829239289228887898997945462929342499998978292194388196249998889225899862864989191819638899998777615 +9967999499299697596478854784557388578189997996598585389567638994254119539615798295959637616748119532 +7847779999158579987835924358969787977597752337899972679968795498957999379878979811614915695186989695 +8787986185978797993569967519247299584691389899837387899257389889997699847936381982679869948118949973 +8892258536995523797193975239126969921916799491982514589138849539992988167819349194725937978282692648 +1878811997841889827197299198979379979548789491823826898798938518762468896781974994769838768796981188 +6687799987379984289919668178999996996259698999986889991848599999617587193985177478619758877988414119 +9796589979989554195357786964468849181957799166899932768913891979449599511641935582792967896999669568 +9997594681917699997971899851259914198996778488197217597149189838338395538993679994299957334548182789 +9796766148448919429994826289895989965276959822999699996172999933998459348899957977144691995889895635 +9933948715818236524533482296321646865771299998466692471768748749714113978548698174997268924649799377 +1115792324352764449879949619583961556985945166299981779898828999849818899727394899987459918996791614 +9999526461777598464699652921794786889797998584659354994685156891439971996969999759889814757629997878 +6911834446491822919437989977369664983425959695491256751688945588669787213118199192181885639885788986 +7193244156988889749827796999989172687638671791497992997829991156878759879964242959949842255399978886 +8298127588799726879818241977767996679143687999194453896536629967662999355465118498999587781693887799 +6159947745481178284839686663914258897928952293468359997988879622844586789396881149175166787919571489 +7991294191117923999487293655288588353955581996927271977626982898577919799999782836662238781847999946 +9999599756999399989749995889585696786827989887519995188912372378767849516399824963999418698929977812 +5486736694189936967838185919999718893983154998987189478918393217519949289989328318899858999328984293 +8949995919564717698297691783566233929798588899688918378766963916729833899587746499989898586989499812 +3524193826987847299996184999799677595943978496911914269385247587789997827759828889367399941458756212 +9696539817993691789966498932397742679824297799995798526139889399952988489928897934487195818678859583 +2599943991191886966399997328964855991777927342867919884377589116899789189839698983799277993881888486 +2817973579994999182718675472898896996529319459887399672919562861299341996661878975837749458982915958 +3656841349489982595888934776772918197948998751789698339968959593759899927872797969479296179583462987 +9157743798478765988169591329911428979929841499826518846685978789116659589136914999191949998749889195 +5891119177956587927342315968196825692999686655731452887488589969889877497991875774999261196439919378 +8971296237126599216899243157987983864699752899669959868888389188533951967961279963997198991967893968 +9331713863971946599958118713939498189384492897577739798867798995264539518793295279888619399895643957 +7299934981419753716499426161576357197977647997936887657763137838872996757748991898428989999246799711 +2927598992939912676749895911999919121999689897797689859793677699896948178757849758699468979256775936 +4996298679798776526899726187198594777667938181452251897585766569856979161831949999359379795567464978 +6749697994899278119299119998411491197271389997591477879181293778862959568794255919916431991587389199 +7917599295856995448398478815799177895955994437998988469939759999482637996873958891797158899568959974 +3971493629788179694678156991899297599876983796147322799885496923998788465997492876993998775555847491 +7589697756587167589199199931779484295478977888887947996911879683944986888123519869913756279999718376 +9681891297599815159559839675522495189461498893954599819393873379999979518672477477171896578897588233 +7218994464751199958895319996657748594987395382849437679243645291991819981869236327979599689979494557 +3669579587841491999981887963937888932999949969968697361799957867798969849977367993858899197339573594 +9938999157929999391948399198949897746612998265971677274753997966219884369519491683899788999296718841 +2792979659919192951318997999298763787689864349785448519148893482199639421688567998269185598719848999 +2956993919948418575296753192419975619989681488774889855393285898997153735745938167798389785972737993 +8277731747919861157877398119967988787181989184148964479699868665199169958899862971952346887939119495 +7957189873684459991539999918145326838946811314819664298566584999664824932481229968691232955488996359 +5689899439928318983291862946713578981598998372769991897899964571991679961789499851669889897998923876 +3992921155599616339882973837995998618999992927962947899864889685918698869875995491967919874765214249 +5928994589588896418678769788982982467546658264292739286852797455119997956825919952139759634939363929 +6466919491711156749275961775919918642899696899138799477759812969836989931761564516794132259978999975 +6818715183889871995339229997318691989488799797672239864373984231579812138977183167796579991289844199 +8299834651294894848996986998229879799792129998996896572993779468116894286897914723111995996593932918 +9898961999279872995195669299467897939166178995288998948411783889832837489765636216821255797239972994 +9294128842689878939853174458439783985991881697485769291768896997918381963397479848198981137733977259 +9938693875599496191998786643916999989789656293298174199414987899951694925461891182769753418339819588 +9299771958199974769247739386371956958922337417899967982645986299869439179889938853297748885816258959 +5789218997367742787939849896229539979929943216698841986289892459919159297757929647191726176799837458 +9997998899972949122469892269164697788597419659972681773616787817194787989924999971988949166393587685 +8697819586862976298894966154799259953999979498492485569382199995858671376959237316117353968898987789 +5833788449272889999938592989788917857997366887287599569391116987816957492646638194951369148466995865 +8797392875679992576397998611946721199191997929616189898185668118656285951889998279779591569993782497 +1243998587194789478969895899976929999998981784112911287566869897178888467393969798949922993999722783 +6898491932163517498563145499993597998279478596617759269779837313979394939989887994797759687495749698 +5918852999916934988579946896318848447798929874928938578765844728128792997498716499896334799391962229 +1445281593898246791614118399847688799965474888492979999898593475998999989517878579949888291967993779 +8819479319669561859977789779885299979994739846376789967696231939168985397398886199361944119969942269 +8384597187994673998976978685877959945984938992895779118788869382587282961593144198939311957191999898 +6891958879895544489956999491779892727268265764998397998885889467849955382531433982795569362982971997 +4719927539178224292254897986253889381997819878927876771217358792678752779988195867984854987879869761 +5496179226499867986599862998778132568199955188683452991319684698887391958959379992599899599281999798 From 566c47b94dc9525a9b40b62601150cb269fc8cef Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 18:55:11 +0000 Subject: [PATCH 07/11] new concept working with part 1 --- day15/kotlin/RJPlog/README.adoc | 2 + day15/kotlin/RJPlog/day2115_1_2.kts | 206 ++++------------------------ 2 files changed, 28 insertions(+), 180 deletions(-) diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc index f92b09bd..26eadd50 100644 --- a/day15/kotlin/RJPlog/README.adoc +++ b/day15/kotlin/RJPlog/README.adoc @@ -20,3 +20,5 @@ Several optimizations later, I don't know how to proceed. Taking break. Current Finally first part is solved. Takes 5min to run through, but it works. Definitely no good idea for second part, so at the end I again have to rethink my strategy. Obivous is, that example and puzzle input take no left or up steps, so I will try to use this in the next approach. +New approach, much faster and way more efficent, now I have to add part 2 + diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts index 432b0fef..32c422d4 100644 --- a/day15/kotlin/RJPlog/day2115_1_2.kts +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -1,215 +1,61 @@ import java.io.File // tag::followPath_15[] -fun followPath_15(): Int { - var segments = mutableListOf>() // changed from String, String to Int, Int - var currentPath = mutableListOf() - var newCurrentPath = mutableListOf() - var searchPath = MutableList(0) { mutableListOf() } - var searchPathNew = MutableList(0) { mutableListOf() } - var validPath = MutableList(0) { mutableListOf() } - var searchEnd: Boolean = false - var totalRiskPerTile = mutableMapOf() +fun followPath_15_test(input1: Int): Int { - - var ruleCheckPassed: Boolean = false +// var ruleCheckPassed: Boolean = false var width: Int = 0 var height: Int = 0 var riskLevel = mutableListOf() - - var firstTotalRisk: Boolean = true - var totalRiskMin: Int = 0 - var totalRisk: Int = 0 - var tileRisk: Int = 0 - - // generate segments Pair(,) as in day12 - // generate searchpath start value (0,0-0,1 , 0,0-1,0) - // new: generate list with risk level: ((x,y-x,y), value) - // rule: single position is only allowed once - + var riskLevelSum = mutableListOf() File("day2115_puzzle_input.txt").forEachLine { width = it.length it.forEach { riskLevel.add(it.toString().toInt()) - } - if (firstTotalRisk) { - for (i in 1..it.length - 1) { - totalRiskMin = totalRiskMin + it[i].toString().toInt() - } - firstTotalRisk = false - } else { - totalRiskMin = totalRiskMin + it.takeLast(1).toString().toInt() + riskLevelSum.add(it.toString().toInt()) } height += 1 } - - //totalRiskMin = ((width + height) - 1) * 9 - - println("width $width, height $height") +// println("width $width, height $height") // println("risklevel: $riskLevel") - println("totalRiskMin: $totalRiskMin") - - for (y in 0..height - 1) { - for (x in 0..width - 1) { - if (x + 1 < width) { - segments.add(Pair(x + y * width, (x + 1) + y * width)) - } - if (y + 1 < height) { - segments.add(Pair(x + y * width, x + (y + 1) * width)) - } - } - } - currentPath.add(0) - currentPath.add(1) - searchPath.add(currentPath.toMutableList()) - totalRiskPerTile.put(1, 0) - currentPath.clear() - currentPath.add(0) - currentPath.add(width) - searchPath.add(currentPath.toMutableList()) - totalRiskPerTile.put(width, 0) - -// println("segments: $segments") - println("searchPath: $searchPath") - println("totalRiskPerTile: $totalRiskPerTile") - println() - - - var ii: Int = 0 - while (!searchEnd) { - ii += 1 - searchEnd = true - - searchPath.forEach { - currentPath = it - //println("$ii: currentPath: $currentPath") - - var lastSegment = currentPath.last() - - segments.forEach { - // println("${it.first}, ${it.second}") - if (lastSegment == it.first) { - newCurrentPath = currentPath.toMutableList() - newCurrentPath.add(it.second) - // println("newCurrentPath $newCurrentPath") - if (it.second == width * height - 1) { - //validPath.add(newCurrentPath) - for (i in 1..newCurrentPath.size - 1) { - totalRisk = totalRisk + riskLevel[newCurrentPath[i]] - } - if (totalRisk < totalRiskMin) { - totalRiskMin = totalRisk - validPath.add(newCurrentPath) - // println("validPath: $newCurrentPath found, , totalRisk $totalRisk, totalRiskMin: $totalRiskMin") - } +// println("risklevelSum: $riskLevelSum") - totalRisk = 0 + // create riskLevelSum + for (y in 0..(height*input1 - 1)) { + for (x in 0..(width*input1 - 1)) { + if (!(x == 0 && y == 0)) { + if (x == 0) { + riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(y - 1) * width] + } else if (y == 0) { + riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(x - 1)] } else { - for (i in 1..newCurrentPath.size - 1) { - totalRisk = totalRisk + riskLevel[newCurrentPath[i]] - } - if (totalRiskPerTile.contains(it.second)) { - ruleCheckPassed = - !(currentPath.contains(it.second)) && totalRisk < totalRiskPerTile.getValue(it.second) - } else { - ruleCheckPassed = !(currentPath.contains(it.second)) && totalRisk < totalRiskMin - } - - if (ruleCheckPassed) { - searchPathNew.add(newCurrentPath) - totalRiskPerTile.put(it.second, totalRisk) - // println(" path added at totalRisk $totalRisk, totalRiskMin $totalRiskMin, ${it.second}") - searchEnd = false - } - totalRisk = 0 - } - } else if (lastSegment == it.second) { - newCurrentPath = currentPath.toMutableList() - newCurrentPath.add(it.first) - // println("newCurrentPath $newCurrentPath") - if (it.first == width * height - 1) { - //validPath.add(newCurrentPath) - for (i in 1..newCurrentPath.size - 1) { - totalRisk = totalRisk + riskLevel[newCurrentPath[i]] - } - if (totalRisk < totalRiskMin) { - totalRiskMin = totalRisk - validPath.add(newCurrentPath) - // println("validPath: $newCurrentPath found, totalRisk $totalRisk, totalRiskMin: $totalRiskMin") - } - - - totalRisk = 0 - } else { - for (i in 1..newCurrentPath.size - 1) { - totalRisk = totalRisk + riskLevel[newCurrentPath[i]] - } - if (totalRiskPerTile.contains(it.first)) { - ruleCheckPassed = - !(currentPath.contains(it.first)) && totalRisk < totalRiskPerTile.getValue(it.first) - - } else { - ruleCheckPassed = !(currentPath.contains(it.first)) && totalRisk < totalRiskMin - - } - if (ruleCheckPassed) { - searchPathNew.add(newCurrentPath) - totalRiskPerTile.put(it.first, totalRisk) - // println(" path $newCurrentPath added at totalRisk $totalRisk, totalRiskMin $totalRiskMin, $it.first}") - searchEnd = false - } - totalRisk = 0 + riskLevelSum[x + y * width] = riskLevel[x + y * width] + minOf( + riskLevelSum[(x - 1) + y * width], + riskLevelSum[x + (y - 1) * width] + ) } + // println(riskLevelSum[x+y*width]) } } - } - searchPath.clear() -// println("serachPath $searchPath") - searchPath.addAll(searchPathNew) - println("$ii searchPath.size ${searchPath.size}") - // println("totalRiskPerTile $totalRiskPerTile") - searchPathNew.clear() -// println("serachPathNew $searchPathNew") + } +// println("riskLevelSum: $riskLevelSum") - println() - println("-- path search ended, now calculation risk level") - println() - -// return validPath.size - -// println("validPath:") - println() - -/* validPath.forEach { - totalRisk = 0 - for (i in 1..it.size - 1) { - totalRisk = totalRisk + riskLevel[it[i]] - } - if (firstTotalRisk) { - totalRiskMin = totalRisk - firstTotalRisk = false - } else if (totalRisk < totalRiskMin) { - totalRiskMin = totalRisk - } - println("$it /totalRisk: $totalRisk") - } - println() - println("totalRiskMin: $totalRiskMin") -*/ - return totalRiskMin + return (riskLevelSum.last() - riskLevelSum.first()) } // end::followPath_15[] fun main(args: Array) { var t1 = System.currentTimeMillis() - var solution2: Int = 0 - var solution1 = followPath_15() + + var solution1 = followPath_15_test(1) + + var solution2 = followPath_15_test(1) // tag::output[] // print solution for part 1 From 47f5cb7c0d90ff263e12abd528ea8def0806d74e Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 20:36:30 +0000 Subject: [PATCH 08/11] algorithm for part 2 added, but does not work --- day15/kotlin/RJPlog/README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc index 26eadd50..57346903 100644 --- a/day15/kotlin/RJPlog/README.adoc +++ b/day15/kotlin/RJPlog/README.adoc @@ -20,5 +20,5 @@ Several optimizations later, I don't know how to proceed. Taking break. Current Finally first part is solved. Takes 5min to run through, but it works. Definitely no good idea for second part, so at the end I again have to rethink my strategy. Obivous is, that example and puzzle input take no left or up steps, so I will try to use this in the next approach. -New approach, much faster and way more efficent, now I have to add part 2 +New approach, much faster and way more efficent, now I have to add part 2. Part 2 added, for the example it works well, but for the real input not. So I have to start debugging. From f2701a99ff911e06843f8904af46b3e189983c88 Mon Sep 17 00:00:00 2001 From: RJPlog Date: Wed, 15 Dec 2021 20:38:03 +0000 Subject: [PATCH 09/11] algorithm for part2 added, but does not work --- day15/kotlin/RJPlog/day2115_1_2.kts | 74 ++++++++++++++++++----------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts index 32c422d4..f0aedaf8 100644 --- a/day15/kotlin/RJPlog/day2115_1_2.kts +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -9,41 +9,60 @@ fun followPath_15_test(input1: Int): Int { var riskLevel = mutableListOf() var riskLevelSum = mutableListOf() - File("day2115_puzzle_input.txt").forEachLine { - width = it.length - it.forEach { - riskLevel.add(it.toString().toInt()) - riskLevelSum.add(it.toString().toInt()) + for (j in 0..input1 - 1) { + File("day2115_puzzle_input.txt").forEachLine { + width = it.length * input1 + for (i in 0..input1 - 1) { + it.forEach { + var risk = it.toString().toInt() + i + j + if (risk > 9) { + risk = risk % 9 + } + riskLevel.add(risk) + riskLevelSum.add(risk) + } + } + height += 1 } - height += 1 } -// println("width $width, height $height") -// println("risklevel: $riskLevel") -// println("risklevelSum: $riskLevelSum") + println("width $width, height $height") +/* println("risklevel: $riskLevel") + println("risklevelSum: $riskLevelSum") + for (y in 0..height - 1) { + for (x in 0..width - 1) { + print(riskLevel[x + y * width]) + } + println() + } */ + println("next") // create riskLevelSum - for (y in 0..(height*input1 - 1)) { - for (x in 0..(width*input1 - 1)) { - if (!(x == 0 && y == 0)) { - if (x == 0) { - riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(y - 1) * width] - } else if (y == 0) { - riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(x - 1)] - } else { - riskLevelSum[x + y * width] = riskLevel[x + y * width] + minOf( - riskLevelSum[(x - 1) + y * width], - riskLevelSum[x + (y - 1) * width] - ) - } - // println(riskLevelSum[x+y*width]) + for (y in 0..height - 1) { + for (x in 0..width - 1) { + if (!(x == 0 && y == 0)) { + if (x == 0) { + riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(y - 1) * width] + } else if (y == 0) { + riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(x - 1)] + } else { + riskLevelSum[x + y * width] = riskLevel[x + y * width] + minOf( + riskLevelSum[(x - 1) + y * width], + riskLevelSum[x + (y - 1) * width] + ) } + // println(riskLevelSum[x+y*width]) } - + } + } // println("riskLevelSum: $riskLevelSum") + println("riskLevelSum.size ${riskLevelSum.size}") + println("${riskLevelSum.last()}, ${riskLevelSum.first()}") + + return (riskLevelSum.last() - riskLevelSum.first()) } // end::followPath_15[] @@ -54,8 +73,9 @@ fun main(args: Array) { var solution1 = followPath_15_test(1) - - var solution2 = followPath_15_test(1) + println() + + var solution2 = followPath_15_test(5) // tag::output[] // print solution for part 1 @@ -68,7 +88,7 @@ fun main(args: Array) { // print solution for part 2 println("*******************************") println("Solution for part2") - println(" $solution2 ") + println(" $solution2 ") //3001 is to high println() t1 = System.currentTimeMillis() - t1 println("puzzle solved in ${t1} ms") From 2b0507604fabccabb1c7e70880edde72b2c94a5c Mon Sep 17 00:00:00 2001 From: RJPlog Date: Sun, 17 Dec 2023 14:36:14 +0100 Subject: [PATCH 10/11] Update day2115_1_2.kts Algorithm of Dijkstra implemented. Part 2 now is also working --- day15/kotlin/RJPlog/day2115_1_2.kts | 127 ++++++++++++++-------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/day15/kotlin/RJPlog/day2115_1_2.kts b/day15/kotlin/RJPlog/day2115_1_2.kts index f0aedaf8..2781dba8 100644 --- a/day15/kotlin/RJPlog/day2115_1_2.kts +++ b/day15/kotlin/RJPlog/day2115_1_2.kts @@ -1,96 +1,99 @@ import java.io.File +import kotlin.math.* -// tag::followPath_15[] -fun followPath_15_test(input1: Int): Int { +// tag::HillClimbing[] +fun HillClimbing(in1: Int): Int { + + var landscape: String = "" + var xStart: Int = 0 + var yStart: Int = 0 -// var ruleCheckPassed: Boolean = false var width: Int = 0 var height: Int = 0 - var riskLevel = mutableListOf() - var riskLevelSum = mutableListOf() - - for (j in 0..input1 - 1) { + + var riskLevel = mutableListOf() + + for (j in 0..in1 - 1) { File("day2115_puzzle_input.txt").forEachLine { - width = it.length * input1 - for (i in 0..input1 - 1) { + width = it.length * in1 + for (i in 0..in1 - 1) { it.forEach { var risk = it.toString().toInt() + i + j if (risk > 9) { risk = risk % 9 } riskLevel.add(risk) - riskLevelSum.add(risk) + } } height += 1 } } - + println("width $width, height $height") -/* println("risklevel: $riskLevel") - println("risklevelSum: $riskLevelSum") - for (y in 0..height - 1) { - for (x in 0..width - 1) { - print(riskLevel[x + y * width]) - } - println() - } */ - - println("next") - // create riskLevelSum - - for (y in 0..height - 1) { - for (x in 0..width - 1) { - if (!(x == 0 && y == 0)) { - if (x == 0) { - riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(y - 1) * width] - } else if (y == 0) { - riskLevelSum[x + y * width] = riskLevel[x + y * width] + riskLevelSum[(x - 1)] - } else { - riskLevelSum[x + y * width] = riskLevel[x + y * width] + minOf( - riskLevelSum[(x - 1) + y * width], - riskLevelSum[x + (y - 1) * width] - ) + + var xEnd: Int = width-1 + var yEnd: Int = height-1 + + + var distList = MutableList(width * height) { width * height * 9} + distList[xStart * yStart * width] = 0 + + // iterate over all points + var gameEnd: Boolean = false + var distListSum = distList.sum() + + while (!gameEnd) { + for (y in 0..height - 1) { + for (x in 0..width - 1) { + // check successors of all known nodes + var dist = distList[x + y * width] + if (dist != width * height) { + // calculate all possible directions + if (x - 1 >= 0) { + distList[x - 1 + y * width] = min(distList[(x - 1) + y * width], dist + riskLevel[(x-1) + y * width]) + } + if (x + 1 < width) { + distList[(x + 1) + y * width] = min(distList[(x + 1) + y * width], dist + riskLevel[(x+1) + y * width]) + } + if (y - 1 >= 0) { + distList[x + (y - 1) * width] = min(distList[x + (y - 1) * width], dist + riskLevel[x + (y-1) * width]) + } + if (y + 1 < height) { + distList[x + (y + 1) * width] = min(distList[x + (y + 1) * width], dist + riskLevel[x + (y+1) * width]) + } } - // println(riskLevelSum[x+y*width]) } } - + if (distListSum == distList.sum()) { + gameEnd = true + } + distListSum = distList.sum() } -// println("riskLevelSum: $riskLevelSum") - - println("riskLevelSum.size ${riskLevelSum.size}") - println("${riskLevelSum.last()}, ${riskLevelSum.first()}") - - - return (riskLevelSum.last() - riskLevelSum.first()) + return distList[xEnd + yEnd * width] } -// end::followPath_15[] +// end::Hillclimbing[] - -fun main(args: Array) { +fun main() { var t1 = System.currentTimeMillis() + var solution1 = HillClimbing(1) + var solution2 = HillClimbing(5) - var solution1 = followPath_15_test(1) - println() - - var solution2 = followPath_15_test(5) - - // tag::output[] +// tag::output[] // print solution for part 1 - println("***********************") - println("--- Day 15: Chiton ---") - println("***********************") + println("***************************************") + println("--- Day 12: Hill Climbing Algorithm ---") + println("***************************************") println("Solution for part1") - println(" $solution1 ") + println(" $solution1 is the fewest steps.") println() // print solution for part 2 - println("*******************************") + println("***************************************") println("Solution for part2") - println(" $solution2 ") //3001 is to high - println() + println(" $solution2 is the fewest steps.") +// end::output[] + t1 = System.currentTimeMillis() - t1 println("puzzle solved in ${t1} ms") -// end::output[] -} \ No newline at end of file +} From 85145109e051693fd687d7003670bef11b1091dd Mon Sep 17 00:00:00 2001 From: RJPlog Date: Sun, 17 Dec 2023 14:38:01 +0100 Subject: [PATCH 11/11] Update README.adoc --- day15/kotlin/RJPlog/README.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/day15/kotlin/RJPlog/README.adoc b/day15/kotlin/RJPlog/README.adoc index 57346903..7fc810d8 100644 --- a/day15/kotlin/RJPlog/README.adoc +++ b/day15/kotlin/RJPlog/README.adoc @@ -22,3 +22,6 @@ Finally first part is solved. Takes 5min to run through, but it works. Definitel New approach, much faster and way more efficent, now I have to add part 2. Part 2 added, for the example it works well, but for the real input not. So I have to start debugging. + +Update after severall months: After studiing Dijkstra algorithm I completly reworked this solution. Now it works for both parts. +