import java.io.File
import kotlin.text.Regex

fun main() {
    val input = File("input")
    val cards = input.useLines { it.map { Card.fromLine(it) }.toList() }

    println(part1(cards))
    println(part2(cards))
}

fun part1(cards: List<Card>): UInt {
    return cards
            .map { card -> card.getWins() }
            .map { num: Int ->
                when (num) {
                    0 -> 0u
                    else -> 1u shl (num - 1)
                }
            }
            .sum()
}

fun part2(cards: List<Card>): Int {
    var processingCards = ArrayDeque(cards)
    var winnings = cards.size

    while (processingCards.size > 0) {
        val card = processingCards.removeFirst()

        val cardWins = card.getWins()
        winnings += cardWins

        for (newCard in card.id..card.id + cardWins - 1) {
            processingCards.add(cards[newCard])
        }
    }

    return winnings
}

class Card(val id: Int, val winning: List<UInt>, val numbers: List<UInt>) {
    fun getWins(): Int {
        return this.numbers.filter { it in this.winning }.count()
    }

    companion object {
        fun fromLine(line: String): Card {
            val (name, card) = line.split(Regex(":\\s+"))
            val id = name.split(Regex("\\s+"))[1].toInt()

            val (winningString, numberString) = card.split(Regex("\\s+\\|\\s+"))
            val winning = winningString.split(Regex("\\s+")).map { it.toUInt() }
            val numbers = numberString.split(Regex("\\s+")).map { it.toUInt() }

            return Card(id, winning, numbers)
        }
    }
}