Skip Navigation

InitialsDiceBearhttps://github.com/dicebear/dicebearhttps://creativecommons.org/publicdomain/zero/1.0/„Initials” (https://github.com/dicebear/dicebear) by „DiceBear”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/)TB
Posts
9
Comments
240
Joined
2 yr. ago

  • Kotlin

    A bit late to the party, but here's my solution. I don't know, if you even need to search for the smallest integer vector in the same direction in part 2, but I did it anyway.

  • Kotlin

    I finally got around to doing day 7. I try the brute force method (takes several seconds), but I'm particularly proud of my sequence generator for operation permutations.

    The Collection#rotate method is in the file Utils.kt, which can be found in my repo.

  • I'm not proud of it.

    I have a conjecture though, that any looping solution, obtained by adding one obstacle, would eventually lead to a rectangular loop. That may lead to a non brute-force solution. It's quite hard to prove rigorously though. (Maybe proving, that the loop has to be convex, which is an equivalent statement here, is easier? You can also find matrix representations of the guard's state changes, if that helps.)

    Maybe some of the more mathematically inclined people here can try proving or disproving that.

    I also have a repo.

  • Kotlin

    That was an easy one, once you define a comparator function. (At least when you have a sorting function in your standard-library.) The biggest part was the parsing. lol

     
        
    import kotlin.text.Regex
    
    fun main() {
        fun part1(input: List<String>): Int = parseInput(input).sumOf { if (it.isCorrectlyOrdered()) it[it.size / 2].pageNumber else 0 }
    
        fun part2(input: List<String>): Int = parseInput(input).sumOf { if (!it.isCorrectlyOrdered()) it.sorted()[it.size / 2].pageNumber else 0 }
    
        val testInput = readInput("Day05_test")
        check(part1(testInput) == 143)
        check(part2(testInput) == 123)
    
        val input = readInput("Day05")
        part1(input).println()
        part2(input).println()
    }
    
    fun parseInput(input: List<String>): List<List<Page>> {
        val (orderRulesStrings, pageSequencesStrings) = input.filter { it.isNotEmpty() }.partition { Regex("""\d+\|\d+""").matches(it) }
    
        val orderRules = orderRulesStrings.map { with(it.split('|')) { this[0].toInt() to this[1].toInt() } }
        val orderRulesX = orderRules.map { it.first }.toSet()
        val pages = orderRulesX.map { pageNumber ->
            val orderClasses = orderRules.filter { it.first == pageNumber }.map { it.second }
            Page(pageNumber, orderClasses)
        }.associateBy { it.pageNumber }
    
        val pageSequences = pageSequencesStrings.map { sequenceString ->
            sequenceString.split(',').map { pages[it.toInt()] ?: Page(it.toInt(), emptyList()) }
        }
    
        return pageSequences
    }
    
    /*
     * An order class is an equivalence class for every page with the same page to be printed before.
     */
    data class Page(val pageNumber: Int, val orderClasses: List<Int>): Comparable<Page> {
        override fun compareTo(other: Page): Int =
            if (other.pageNumber in orderClasses) -1
            else if (pageNumber in other.orderClasses) 1
            else 0
    }
    
    fun List<Page>.isCorrectlyOrdered(): Boolean = this == this.sorted()
    
     
      
  • Kotlin

    Just the standard Regex stuff. I found this website to be very helpful to write the patterns. (Very useful in general)

     
        
    fun main() {
        fun part1(input: List<String>): Int =
            Regex("""mul\(\d+,\d+\)""").findAll(input.joinToString()).sumOf {
                with(Regex("""\d+""").findAll(it.value)) { this.first().value.toInt() * this.last().value.toInt() }
            }
    
        fun part2(input: List<String>): Int {
            var isMultiplyInstructionEnabled = true  // by default
            return Regex("""mul\(\d+,\d+\)|do\(\)|don't\(\)""").findAll(input.joinToString()).fold(0) { acc, instruction ->
                when (instruction.value) {
                    "do()" -> acc.also { isMultiplyInstructionEnabled = true }
                    "don't()" -> acc.also { isMultiplyInstructionEnabled = false }
                    else -> {
                        if (isMultiplyInstructionEnabled) {
                            acc + with(Regex("""\d+""").findAll(instruction.value)) { this.first().value.toInt() * this.last().value.toInt() }
                        } else acc
                    }
                }
            }
        }
    
        val testInputPart1 = readInput("Day03_test_part1")
        val testInputPart2 = readInput("Day03_test_part2")
        check(part1(testInputPart1) == 161)
        check(part2(testInputPart2) == 48)
    
        val input = readInput("Day03")
        part1(input).println()
        part2(input).println()
    }
    
    ´´´