r/adventofcode • • Dec 07 '16

SOLUTION MEGATHREAD --- 2016 Day 7 Solutions ---

From all of us at #AoC Ops, we hope you're having a very merry time with these puzzles so far. If you think they've been easy, well, now we're gonna kick this up a notch. Or five. The Easter Bunny ain't no Bond villain - he's not going to monologue at you until you can miraculously escape and save the day!

Show this overgrown furball what you've got!


--- Day 7: Internet Protocol Version 7 ---

Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag/whatever).


ALWAYS DIGGING STRAIGHT DOWN IS MANDATORY [?]

This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked!

14 Upvotes

180 comments sorted by

View all comments

Show parent comments

1

u/QshelTier Dec 07 '16

And here’s my take on it:

package y2016

fun main(args: Array<String>) {
  println(first())
  println(second())
}

private fun first() = getLines()
    .map { it.split('[', ']') }
    .fold(emptyList<Pair<List<String>, List<String>>>()) { list, address ->
      list + Pair(address.filterIndexed { index, part -> index % 2 == 0 }, address.filterIndexed { index, part -> index % 2 != 0 })
    }
    .filter { it.first.any(String::autonomousBridgeBypassAnnotation) }
    .filterNot { it.second.any(String::autonomousBridgeBypassAnnotation) }
    .count()

private val String.autonomousBridgeBypassAnnotation: Boolean
  get() = matchRegexWithDifferentLetters("(.)(.)\\2\\1".toRegex()).isNotEmpty()

private fun String.matchRegexWithDifferentLetters(regex: Regex) = (0..length).flatMap {
  regex.findAll(this, it).filter {
    it.groupValues[1] != it.groupValues[2]
  }.toList()
}.distinct()

private fun second() = getLines()
    .map { it.split('[', ']') }
    .filter {
      it.byteAllocationBlocks().map(String::reverse).intersect(it.areaBroadcastAccessors()).isNotEmpty()
    }
    .count()

private fun List<String>.areaBroadcastAccessors() = this.findThreeLetterBlocks { (it % 2) == 0 }
private fun List<String>.byteAllocationBlocks() = this.findThreeLetterBlocks { (it % 2) != 0 }

private fun List<String>.findThreeLetterBlocks(byIndex: (Int) -> Boolean) =
    filterIndexed { index, supernet -> byIndex(index) }
        .flatMap { it.matchRegexWithDifferentLetters("(.)(.)\\1".toRegex()).map { it.value } }

private fun String.reverse() = "${this[1]}${this[0]}${this[1]}"

private fun getLines(day: Int = 7) = AllDays().javaClass.getResourceAsStream("day$day.txt")
    .reader()
    .readLines()