Day 2: Gift Shop

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • chunkystyles@sopuli.xyz
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    3 days ago

    My part 2 Kotlin solution:

    val factors = intArrayOf(2, 3, 5, 7)
    
    fun main() {
        var total = 0L
        val input = getInput(2)
        val ranges = parseInput1(input)
        ranges.forEach {
            val start = it.first.toLong()
            val end = it.second.toLong()
            for (id in start..end) {
                val idString = id.toString()
                if (isIdInvalid2(idString)) {
                    total += id
                }
            }
        }
        println(total)
    }
    
    fun parseInput1(input: String): List<Pair<String, String>> {
        return input.split(",")
            .filter { it.isNotBlank() }
            .map {
                val secondSplit = it.split("-")
                secondSplit.first().trim() to secondSplit.last().trim()
            }
    }
    
    fun isIdInvalid2(id: String): Boolean {
        for (factor in factors) {
            if (id.length % factor == 0) {
                val gap = id.length / factor
                var areAllMatching = true
                for (i in 0..<gap) {
                    val end = (factor - 1) * gap + i
                    if (!areCharactersTheSame(id, gap, i, end)) {
                        areAllMatching = false
                        break
                    }
                }
                if (areAllMatching) {
                    return true
                }
            }
        }
        return false
    }
    
    fun areCharactersTheSame(string: String, gap: Int, start: Int, end: Int): Boolean {
        val character = string[start]
        for (i in start + gap..end step gap) {
            if (character != string[i]) {
                return false
            }
        }
        return true
    }
    

    I didn’t look closely enough at the input to know how big an entire list of IDs would be huge or not. But I assumed it was. So instead I just did ranges as Pairs.

    I also only considered the prime factors up to 7, because there weren’t any IDs that needed any higher.

    Edit: I also worried that a brute force solution might be slow, but being day 2, I might have been a little too worried about that. The main algorithm ran in 68ms.