<commit_before>package io.github.ajoz.workshop.day2.solution

/**
 * We can see the solution to this puzzle in terms of a deterministic FSM (finite state machine). An input alphabet of
 * a FSM consists of a set of symbols, states change to next states due to a transition function.
 */

data class State<T>(val value: T) {
    override fun toString() = "State($value)"

    infix fun or(other: State<T>) = States(setOf(this, other))

    infix fun <V> after(symbol: Symbol<V>) = Match(this, symbol)

    infix fun <V> after(symbols: Set<Symbol<V>>) = symbols.map { Match(this, it) }.toSet()
}

data class States<T>(val values: Set<State<T>>) {
    infix fun or(state: State<T>) = States(values + state)

    infix fun <V> cyclesAfter(symbol: Symbol<V>): Transitions<T, V> {
        val transitions = values
                .map { state -> Match(state, symbol) }
                .map { match -> Pair(match, match.state) }
                .toMap()
        return Transitions(transitions)
    }

    infix fun <V> cyclesAfter(symbols: Set<Symbol<V>>): Transitions<T, V> {
        val transitions = symbols
                .map { symbol -> this.cyclesAfter(symbol) }
                .flatMap { it.values.toList() }
                .toMap()

        return Transitions(transitions)
    }
}

data class Symbol<T>(val value: T) {
    override fun toString() = "Symbol($value)"

    infix fun or(other: Symbol<T>) = Symbols(setOf(this, other))
}

data class Symbols<T>(val values: Set<Symbol<T>>) {
    infix fun or(symbol: Symbol<T>) = Symbols(values + symbol)
}

data class Match<T, V>(val state: State<T>, val symbol: Symbol<V>) {
    override fun toString() = "Match(state=${state.value}, symbol=${symbol.value})"

    infix fun transitionsTo(state: State<T>) = Transitions(mapOf(this to state))
}

data class Transitions<T, V>(val values: Map<Match<T, V>, State<T>>)

fun <T, V> transitions(vararg transitions: Transitions<T, V>): (State<T>, Symbol<V>) -> State<T> {
//    val t = transitions.map { it.values. }
    return fun (st: State<T>, sy: Symbol<V>): State<T> {
        return st
    }
}<commit_msg>[day2] Adding companion object for Match<T, V> class to shorten the code necessary to create a single Match.<commit_after>package io.github.ajoz.workshop.day2.solution

/**
 * We can see the solution to this puzzle in terms of a deterministic FSM (finite state machine). An input alphabet of
 * a FSM consists of a set of symbols, states change to next states due to a transition function.
 */

data class State<T>(val value: T) {
    override fun toString() = "State($value)"

    infix fun or(other: State<T>) = States(setOf(this, other))

    infix fun <V> after(symbol: Symbol<V>) = Match(this, symbol)

    infix fun <V> after(symbols: Set<Symbol<V>>) = symbols.map { Match(this, it) }.toSet()
}

data class States<T>(val values: Set<State<T>>) {
    infix fun or(state: State<T>) = States(values + state)

    infix fun <V> cyclesAfter(symbol: Symbol<V>): Transitions<T, V> {
        val transitions = values
                .map { state -> Match(state, symbol) }
                .map { match -> Pair(match, match.state) }
                .toMap()
        return Transitions(transitions)
    }

    infix fun <V> cyclesAfter(symbols: Set<Symbol<V>>): Transitions<T, V> {
        val transitions = symbols
                .map { symbol -> this.cyclesAfter(symbol) }
                .flatMap { it.values.toList() }
                .toMap()

        return Transitions(transitions)
    }
}

data class Symbol<T>(val value: T) {
    override fun toString() = "Symbol($value)"

    infix fun or(other: Symbol<T>) = Symbols(setOf(this, other))
}

data class Symbols<T>(val values: Set<Symbol<T>>) {
    infix fun or(symbol: Symbol<T>) = Symbols(values + symbol)
}

data class Match<T, V>(val state: State<T>, val symbol: Symbol<V>) {
    override fun toString() = "Match(state=${state.value}, symbol=${symbol.value})"

    infix fun transitionsTo(state: State<T>) = Transitions(mapOf(this to state))

    companion object {
        fun <T, V> matchOf(state: T, symbol: V) = Match(State(state), Symbol(symbol))
    }
}

data class Transitions<T, V>(val values: Map<Match<T, V>, State<T>>)

fun <T, V> transitions(vararg transitions: Transitions<T, V>): (State<T>, Symbol<V>) -> State<T> {
//    val t = transitions.map { it.values. }
    return fun(st: State<T>, sy: Symbol<V>): State<T> {
        return st
    }
}
{'fraction_non_alphanumeric': 0.1480307831598008, 'fraction_numerical': 0.000679040289723857, 'mean_word_length': 3.164938737040528, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2563774', 'n_tokens_mistral': 1446, 'n_tokens_neox': 1409, 'n_words': 427}