DEV Community

Discussion on: Advent of Code 2019 Solution Megathread - Day 7: Amplification Circuit

Collapse
 
jbristow profile image
Jon Bristow • Edited

Here's my solution to part 1 minus the obscene overhaul to Day05. I spent too long futzing because my refactor wasn't as friendly as I had hoped, and there was a terrible bug in my permutation generator.


    fun permute(input: Option<List<Int>>): Sequence<List<Int>> {
        return generateSequence(input) { currOpt ->
            currOpt.flatMap { curr ->
                val optK = curr.windowed(2)
                    .mapIndexed { i, it -> i to it }
                    .findLast { (i, ak) -> ak[0] < ak[1] }
                    .toOption()
                    .map { it.first }

                optK.map { k ->
                    val l = curr.indices
                        .findLast { l -> curr[k] < curr[l] }!!
                    val newList = curr.toMutableList()
                    newList[k] = curr[l]
                    newList[l] = curr[k]
                    newList.take(k+1) + newList.drop(k+1).reversed()
                }
            }
        }.takeWhile { it !is None }
            .map { it.getOrElse { throw Error("Bad permutation.") } }
    }

    val permutations = Day07.permute((0 until 5).toList().some())

    private fun List<Int>.runPermutation(code: Array<Int>): Int {
        return fold(Option.empty<Int>()) { result, phase ->
            Day05.step(
                code,
                CurrentState(inputs = result.fold({ listOf(phase, 0) }, { listOf(phase, it) })).right()
            )
                .toIntOrNull()
                .toOption()
        }.getOrElse { -1000000 }
    }

    fun part1(): Option<Int> {
        val best = permutations.maxBy { p ->
            p.runPermutation(data.toTypedArray())
        }.toOption()

        println("best: $best")
        return best.map {
            it.runPermutation(data.toTypedArray())
        }
    }

I'm now mulling whether I want to go full Coroutines for part 2...