Skip to content

Commit

Permalink
Prepare for day 4
Browse files Browse the repository at this point in the history
Signed-off-by: Robbe Pincket <7889478+Kroppeb@users.noreply.github.com>
  • Loading branch information
Kroppeb committed Dec 4, 2019
1 parent aa7db98 commit 74979ea
Show file tree
Hide file tree
Showing 12 changed files with 1,596 additions and 49 deletions.
1,171 changes: 1,171 additions & 0 deletions resources/2017/7

Large diffs are not rendered by default.

Empty file added resources/4
Empty file.
66 changes: 46 additions & 20 deletions src/Reflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
I decided to switch to Kotlin as I felt that Kotlin would be more powerful.
I went with making the solutions in Kotlin Worksheets mostly to get rid of the `fun main(){}` overhead and easy display of intermediate results

## Day 2 conversion
### Day 2 conversion
* Used input of day 1
* Make a file for the next day in advance with some imports and a start.
* Worksheet doesn't display exceptions
Expand All @@ -22,29 +22,55 @@ I went with making the solutions in Kotlin Worksheets mostly to get rid of the `

Also made a tentative `IntComputer`

## Day3
### Day3
* Input was csv style
* [ ] Make csv (comma (`,`) separated values), ssv (semicolon (`;`) separated values) and wsv (whitespace `/\s/` separated values)
* [x] Make csv (comma (`,`) separated values), ssv (semicolon (`;`) separated values) and wsv (whitespace `/\s/` separated values)
* An integer-string had a `\r` at the end
* [ ] Make `String.getInt()`, `String.getInts()` and similar extension functions
* [x] Make `String.getInt()`, `String.getInts()` and similar extension functions
* Worksheets failed to execute `map` and `sumBy` properly in some cases?
* [ ] Make all solutions in normal Kotlin code
* => Make all future solutions in normal Kotlin code
* Didn't read problem statement well enough
* [ ] Listen to my gut when it says "huh, that's weird" instead of of just assuming it's a design decision to keep the questions easy
* => Listen to my gut when it says "huh, that's weird" instead of of just assuming it's a design decision to keep the questions easy
* Struggled a bit too much with set (and map) operations
* [ ] Make helper functions
* [ ] Make operator overloading for sets and maps
* [x] Make helper functions
* [x] Make operator overloading for sets and maps
* Imports for `abs` don't list `abs(Int)`.
* => Pick `abs(Double)` in `kotlin.Math`. This will pick the right overload anyway
* [ ] Add `import kotlin.Math` to the template

Also add:
*[ ] 2D point operations (`Point<T> = Pair<T,T> where T:Number`)
*[ ] `RDLU` to point
*[ ] Distance calculators
*[ ] `Iterable<Point<T>>.getClosest()` and similar

Ideas:
*[ ] Make an RLE encoder and decode
*[ ] FoldMap: map but with previous value/folding value
* This would allow the input to be RLE decode and then foldmaped with the `+` operator to give all points
* [x] Add `import kotlin.Math` to the template

#### Also add:
*[x] 2D point operations (`Point = Pair<Int,Int>`)
*[x] `RDLU` to point
*[x] Distance calculators
*[x] `Iterable<Point<T>>.getClosest()` and similar

#### Ideas:
*[x] Make an RLE encoder and decode
*[x] FoldMap: map but with previous value/folding value
* This would allow the input to be RLE decode and then foldmaped with the `+` operator to give all points
* Realized this is `scan` so renamed

### Some training
#### 2017/4
No looking up, just gut timing but question is too easy to really get results.
#### 2017/7
Looked up some timings to verify it would be a bit of a harder problem.

Initially I felt like I was gonna need topoSort but wasn't needed
* Missed the `,`'s in the input
*[x] add a `getAlphaNum()` and similar
*[x] maybe add `getIntsLines() = getLines().map{it.getInts()}` and similar
* Forgot to call the recursive formula .. (OOF)


### Potential ToDo's
* [ ] Make Point an actual class
* [ ] Convolutions, forEach(unordered/Ordered)Pair/triplet
* [ ] Grids
* [ ] Path calculation
* [ ] BracketStack
* [ ] Bounds
* [ ] (stepped) Toposort
* [ ] eventqueue
* [ ] cyclic list
* [ ] ticking game system // for turnbased combat or similar
46 changes: 33 additions & 13 deletions src/helpers/Point.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,32 @@ import kotlin.math.sqrt
typealias Point = Pair<Int, Int>

fun Char.toPoint() = when (this) {
'E' -> 1 to 0
'R' -> 1 to 0

'S' -> 0 to 1
'D' -> 0 to 1

'W' -> -1 to 0
'L' -> -1 to 0

'N' -> 0 to -1
'U' -> 0 to -1
else -> error("")
}

fun Point.right() = first + 1 to second
fun Point.down() = first to second + 1
fun Point.left() = first + 1 to second
fun Point.up() = first to second - 1

fun Point.rotateClock() = -second to first
fun Point.rotateAntiClock() = second to -first

fun Point.getQuadNeighbours() = listOf(right(), down(), left(), up())
fun Point.getDiagonalNeighbours() = listOf(right().down(), down().left(), left().up(), up().right())
fun Point.getOctNeighbours() = listOf(right(), right().down(), down(), down().left(), left(), left().up(), up(), up().right())

operator fun Point.unaryMinus(): Point = -first to -second

operator fun Point.minus(other: Point): Point = first - other.first to second - other.second
Expand All @@ -30,7 +49,7 @@ operator fun Point.times(other: Int): Point = first * other to second * other
operator fun Point.div(other: Int): Point = first / other to second / other
operator fun Point.rem(other: Int): Point = first % other to second % other

fun abs(v:Point):Point = abs(v.first) to abs(v.second)
fun abs(v: Point): Point = abs(v.first) to abs(v.second)

fun Point.sqrDist(): Int = first * first + second * second
fun Point.dist(): Double = sqrt(sqrDist().toDouble())
Expand All @@ -43,27 +62,28 @@ fun Point.manDistTo(other: Point): Int = (this - other).manDist()
fun Iterable<Point>.getClosest(): Point? = this.minBy(Point::sqrDist)
fun Iterable<Point>.getClosestMan(): Point? = this.minBy(Point::manDist)

fun Iterable<Point>.getClosestTo(other: Point): Point? = this.minBy{it.sqrDistTo(other)}
fun Iterable<Point>.getClosestManTo(other: Point): Point? = this.minBy{it.manDistTo(other)}
fun Iterable<Point>.getClosestTo(other: Point): Point? = this.minBy { it.sqrDistTo(other) }
fun Iterable<Point>.getClosestManTo(other: Point): Point? = this.minBy { it.manDistTo(other) }

fun Iterable<Point>.getFurthest(): Point? = this.maxBy(Point::sqrDist)
fun Iterable<Point>.getFurthestMan(): Point? = this.maxBy(Point::manDist)

fun Iterable<Point>.getFurthestTo(other: Point): Point? = this.maxBy{it.sqrDistTo(other)}
fun Iterable<Point>.getFurthestManTo(other: Point): Point? = this.maxBy{it.manDistTo(other)}
fun Iterable<Point>.getFurthestTo(other: Point): Point? = this.maxBy { it.sqrDistTo(other) }
fun Iterable<Point>.getFurthestManTo(other: Point): Point? = this.maxBy { it.manDistTo(other) }

fun Iterable<Point>.getClosestSqrDist(): Int? = this.map(Point::sqrDist).min()
fun Iterable<Point>.getClosestDist(): Double? = getClosestSqrDist()?.let{sqrt(it.toDouble())}
fun Iterable<Point>.getClosestDist(): Double? = getClosestSqrDist()?.let { sqrt(it.toDouble()) }
fun Iterable<Point>.getClosestManDist(): Int? = this.map(Point::manDist).min()

fun Iterable<Point>.getClosestSqrDistTo(other: Point): Int? = this.map{it.sqrDistTo(other)}.min()
fun Iterable<Point>.getClosestDistTo(other: Point): Double? = getClosestSqrDistTo(other)?.let{sqrt(it.toDouble())}
fun Iterable<Point>.getClosestManDistTo(other: Point): Int? = this.map{it.manDistTo(other)}.min()
fun Iterable<Point>.getClosestSqrDistTo(other: Point): Int? = this.map { it.sqrDistTo(other) }.min()
fun Iterable<Point>.getClosestDistTo(other: Point): Double? = getClosestSqrDistTo(other)?.let { sqrt(it.toDouble()) }
fun Iterable<Point>.getClosestManDistTo(other: Point): Int? = this.map { it.manDistTo(other) }.min()

fun Iterable<Point>.getFurthestSqrDist(): Int? = this.map(Point::sqrDist).max()
fun Iterable<Point>.getFurthestDist(): Double? = getFurthestSqrDist()?.let{sqrt(it.toDouble())}
fun Iterable<Point>.getFurthestDist(): Double? = getFurthestSqrDist()?.let { sqrt(it.toDouble()) }
fun Iterable<Point>.getFurthestManDist(): Int? = this.map(Point::manDist).max()

fun Iterable<Point>.getFurthestSqrDistTo(other: Point): Int? = this.map{it.sqrDistTo(other)}.max()
fun Iterable<Point>.getFurthestDistTo(other: Point): Double? = getFurthestSqrDistTo(other)?.let{sqrt(it.toDouble())}
fun Iterable<Point>.getFurthestManDistTo(other: Point): Int? = this.map{it.manDistTo(other)}.max()
fun Iterable<Point>.getFurthestSqrDistTo(other: Point): Int? = this.map { it.sqrDistTo(other) }.max()
fun Iterable<Point>.getFurthestDistTo(other: Point): Double? = getFurthestSqrDistTo(other)?.let { sqrt(it.toDouble()) }
fun Iterable<Point>.getFurthestManDistTo(other: Point): Int? = this.map { it.manDistTo(other) }.max()

54 changes: 42 additions & 12 deletions src/helpers/input.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@ private val regexDigit = Regex("""\d""")
private val regexFloat = Regex("""-?\d+(?:\.\d+)?""")
private val regexPosFloat = Regex("""\d+(?:\.\d+)?""")
private val regexWord = Regex("""[a-zA-Z]+""")
private val regexAlphaNum = Regex("""[a-zA-Z0-9]+""")


fun getData(day: Int) =
(day::class.java.getResource("$day")
?: day::class.java.getResource("../$day")
)
.readText()
fun getData(day: Int): String =
if (day > 100) {
val y = day / 100
val d = day % 100
day::class.java.getResource("$y/$d")
.readText()
} else {
day::class.java.getResource("$day")
.readText()
}

fun getInts(day: Int): List<Int> {
return regexInt.findAll(getData(day)).map { it.value.toInt() }.toList()
Expand All @@ -40,20 +46,33 @@ fun getWords(day: Int): List<String> {
return regexWord.findAll(getData(day)).map { it.value }.toList()
}

fun getAlphaNums(day: Int): List<String> {
return regexAlphaNum.findAll(getData(day)).map { it.value }.toList()
}

fun getLines(day: Int): List<String> {
return getData(day).lines()
}

fun getCSV(day: Int): List<List<String>>{
return getLines(day).map{it.split(',')}
/**
* Read in Comma (',') Separated Values
*/
fun getCSV(day: Int): List<List<String>> {
return getLines(day).map { it.split(',') }
}

fun getSSV(day: Int): List<List<String>>{
return getLines(day).map{it.split(';')}
/**
* Read in Semicolon (';') Separated Values
*/
fun getSSV(day: Int): List<List<String>> {
return getLines(day).map { it.split(';') }
}

fun getWSV(day: Int): List<List<String>>{
return getLines(day).map{it.split(' ', '\t')}
/**
* Read in Whitespace (' ' or '\t') Separated Values
*/
fun getWSV(day: Int): List<List<String>> {
return getLines(day).map { it.split(' ', '\t') }
}

fun String.getInt() = regexInt.find(this)?.value?.toInt()
Expand All @@ -62,10 +81,21 @@ fun String.getDigit() = regexDigit.find(this)?.value?.toInt()
fun String.getFloat() = regexFloat.find(this)?.value?.toDouble()
fun String.getPosFloat() = regexPosFloat.find(this)?.value?.toDouble()
fun String.getWord() = regexWord.find(this)?.value
fun String.getAlphaNum() = regexAlphaNum.find(this)?.value

fun String.getInts() = regexInt.findAll(this).map { it.value.toInt() }.toList()
fun String.getPosInts() = regexPosInt.findAll(this).map { it.value.toInt() }.toList()
fun String.getDigits() = regexDigit.findAll(this).map { it.value.toInt() }.toList()
fun String.getFloats() = regexFloat.findAll(this).map { it.value.toDouble() }.toList()
fun String.getPosFloats() = regexPosFloat.findAll(this).map { it.value.toDouble() }.toList()
fun String.getWords() = regexWord.findAll(this).map { it.value }.toList()
fun String.getWords() = regexWord.findAll(this).map { it.value }.toList()
fun String.getAlphaNums() = regexAlphaNum.findAll(this).map { it.value }.toList()

fun getIntLines(day:Int) = getLines(day).map{it.getInts()}
fun getPosIntLines(day:Int) = getLines(day).map{it.getPosInts()}
fun getDigitLines(day:Int) = getLines(day).map{it.getDigits()}
fun getFloatLines(day:Int) = getLines(day).map{it.getFloats()}
fun getPosFloatLines(day:Int) = getLines(day).map{it.getPosFloats()}
fun getWordLines(day:Int) = getLines(day).map{it.getWords()}
fun getAlphaNumLines(day:Int) = getLines(day).map{it.getAlphaNums()}

19 changes: 18 additions & 1 deletion src/helpers/iterators.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fun <K:Comparable<K>,V>Map<K,V>.minByKey() = minBy { it.key }!!.value

operator fun <E> List<E>.times(count: Int) = repeat(count)

inline fun <T,R>Iterable<T>.foldMap(start:R, transform:(R, T)->R): List<R> {
inline fun <T,R>Iterable<T>.scan(start:R, transform:(R, T)->R): List<R> {
var acc = start
val ret = mutableListOf<R>()
for(i in this){
Expand All @@ -65,6 +65,23 @@ inline fun <T,R>Iterable<T>.foldMap(start:R, transform:(R, T)->R): List<R> {
return ret
}

inline fun <T>Iterable<T>.scan(transform:(T, T)->T): List<T> {
val iter = iterator()
if (!iter.hasNext())
return emptyList()
var acc = iter.next()
val ret = mutableListOf<T>(acc)
for(i in iter){
acc = transform(acc, i)
ret.add(acc)
}
return ret
}

fun Iterable<Int>.cumSum()=scan(Int::plus)



//region list components
operator fun <T> List<T>.get(indexes: IntRange) = subList(indexes.first, indexes.last + 1)

Expand Down
5 changes: 2 additions & 3 deletions src/solutions/day 3 converted2.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package solutions

import helpers.*
import kotlin.math.abs

private fun part1(data: List<List<Char>>) {
fun getPoints(wl: List<Char>): List<Point> = wl.foldMap(0 to 0) { p, c ->
fun getPoints(wl: List<Char>): List<Point> = wl.scan(0 to 0) { p, c ->
p+c.toPoint()
}

Expand All @@ -19,7 +18,7 @@ private fun part1(data: List<List<Char>>) {
}

private fun part2(data: List<List<Char>>) {
fun getPoints(wl: List<Char>): Map<Point, Int> = wl.foldMap(0 to 0 to 0) { (p,d), c ->
fun getPoints(wl: List<Char>): Map<Point, Int> = wl.scan(0 to 0 to 0) { (p,d), c ->
p+c.toPoint() to d+1
}.groupBy { it.first }.mapValues { (_,v)->v.first().second }

Expand Down
33 changes: 33 additions & 0 deletions src/solutions/day 4.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package solutions

import helpers.*
import kotlin.math.*

private fun part1(data: List<Int>){

}


fun main(){
val data = getInts(4)
part1(data)



















}
28 changes: 28 additions & 0 deletions src/solutions/template.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package solutions

import helpers.*
import kotlin.math.*

fun main(){
val data = getInts(TODO())




















}
Loading

0 comments on commit 74979ea

Please sign in to comment.