package de.startat.aoc2023

data class Number(val value: Int, val lineNumber : Int, val indices : IntRange)
data class Symbol(val value: String,val lineNumber: Int, val index : Int)
data class Schematic(val numbers : List<Number>, val symbols: List<Symbol>)

fun Symbol.isAdjacentTo(number: Number) : Boolean{
    val lineRange = number.lineNumber-1 .. number.lineNumber+1
    val indexRange = number.indices.first-1 .. number.indices.last+1
    return this.lineNumber in lineRange && this.index in indexRange
}

fun Schematic.sumOfNumbers() : Int {
    return numbers.fold(0){acc, number -> acc + number.value }
}

fun Schematic.gears() : List<Pair<Number,Number>> {
    return symbols.filter { s -> s.value == "*" }.mapNotNull { possibleGear ->
        val adjacentNumbers = numbers.filter { n -> possibleGear.isAdjacentTo(n) }.toList()
        return@mapNotNull if (adjacentNumbers.size == 2) {
            Pair(adjacentNumbers[0], adjacentNumbers[1])
        } else
            null
    }.toList()
}


class Day3 {
    private val numberRegex = Regex("\\d+")
    private val symbolRegex = Regex("[^\\d.\\n]")

    fun star1() {
        val schematic: Schematic = readSchematic(day3Input)
        println("Sum of schematic numbers = ${schematic.sumOfNumbers()}")
    }

    fun star2() {
        val schematic: Schematic = readSchematic(day3Input)
        val gearRatio = schematic.gears().fold(0) { acc, (first, second) -> acc + first.value * second.value }
        println("Gear ratio = $gearRatio")
    }

    private fun readSchematic(schematicString : String) : Schematic {
        val allNumbers: MutableList<Number> = mutableListOf()
        val allSymbols: MutableList<Symbol> = mutableListOf()

        for ((idx, line) in schematicString.lines().withIndex()) {
            println(line)
            val numbersInLine =
                numberRegex.findAll(line).map { match -> Number(match.value.toInt(), idx, match.range) }.toList()
            println("\t$numbersInLine")
            allNumbers += numbersInLine

            val symbolsInLine =
                symbolRegex.findAll(line).map { match -> Symbol(match.value, idx, match.range.first) }.toList()
            println("\t$symbolsInLine")
            allSymbols += symbolsInLine
        }

        val validNumbers = allNumbers.filter { n -> allSymbols.any{s -> s.isAdjacentTo(n)}}.toList()
        return Schematic(validNumbers, allSymbols)
    }
}


val day3testInput = """467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598.."""

val day3Input = """.......358..........31.....339.....669.............598......328.....575......................447..650..............964...........692........
...............415..*.........@......*...627*...................945*.............144/.506............................*......514...*...150...
.........182..+.....873.756.......737........784..568....667..............258........./.........741...........707*....84........520.........
..579...@.........$........*..........258.................*.........274..*.....739.......157./.....*580...........893.....696*........889...
.....*.........875.........173.........*..................109...896*......959...*........=...677...........&636.........................$...
......961..$............-...............907...569....#...........................756.....................................681................
...........478...616.....30.....221*...............552.../33...258*343.....488........*682...526..*.........422...........&..........764....
................+..........................................................*................*.....7...550..........=.........878............
...171..275............#.....................401....50.$.................43...............123.............../949..135..331.....@.495........
........*...48@.662.100...............590...*........#.566.....................15..../426.............774...............+...........*.......
...944.28.........*.....................*....307...........410.361....55..................24.447.*......*....787*...266....361.......161....
....*...........405.&...=785...146......654.......281.............*.....+...................*....760..80..17.....84....*..+.................
.....830...140......745.........%..$..........972.......406*864..762..............695.327.................*...........512...................
............*...............#......414...........*..960...............1..............*.................374.....264.............833....336...
.......-.252.......10....518..................777...=...811..103.454..*....................774*433.........951*....826........@....=...*....
.....44..............*................-....................@..$......957...............216..........=..................614........521..232..
.........=232......802...+779.....759..307....................................%941.......*........512.............865.....*.................
...................................*.......162...662....816.681.....21*................290.........................*......364..........=....
.................258....195.........1..535......*.......*.....*........261............................650.......152.................514.....
..425...411@...../.........@...........*.....788.........186...91.279............-.....................*............268.......639.......864.
....................................=.933........../.................%...%........73........%203....187..362...861.....*389.....*.......*...
...254....847............@........135......6.......529..........202......96...........840.........@........*...*.../.........998.......989..
.........*.....288......650............349*.......................%.609...................526.....655.....854....425..............531*......
..../....848....&..............505...........................594..........434.................@.......$68............767..............732...
.410...............585...............185........................*...91........773..579........454............757.....*....568..+742.........
..............................*70.......*......478............769....&.182.......%.*..................568......-.570.861....*...............
..............*993.48......893........835....*..*......*.................*..........798..473.........../....................965...691.......
...........306.......*............531.......938.200.335.432...343.....360......836......-...........*..........951.691..............*.......
...341*360............958............*.........................#.........../.....*.../........728..585.........*.............902=..696......
.............190...................808..451........+..................272...59.641...822.........*..........289...36...................509..
..464*10.604.+....241.102%..............*...633.450......................+........................797............*.......575..........*.....
...........-............................488..........402.....936.847................+.......434.......................&.....&....844...478..
......147..............826...297................257...*...........*.....$.....932...492..81...%....829..........560...661.........*.........
.........*....379.......*....*...884..700.......*.....646..........914..659...............*....................=..........513/..621..790....
.369....472..*.......843....734....#.+....%...738........................................989............501.......817.375...............@...
..............727.........................131.....767..........=......665...685..............747..727.......868..*.............478#.........
........247.............-...........649.............*..*82..507...............*..................................504........................
.........*...........909...............*.....707..922..............701...213.833.866$.630...&..606+....................102.183@..*281.225...
...465.108...............772.....915.109..96.%...................../.....*.............*..685........155....811*...220.*...............*....
.................106.....=.................&........*........*488.........233.......590........$551.....*..........+...287.#874..%....956...
....................*513.........&...............829.487................................350..-........338.......55................464.......
....&............@............695......227................$.793.............802.....294...*...822..........960....*....295..946.............
....587...........859...204.......246*....*644.........925.........167.210..../..........129.............%....*...102.....*..*..........832.
.......................*..............558.......404.......................%..........................817..870.791......120..483..406...$....
....797%..68....929-.87....411............*........*.............458*143....721.-....706.......694....*.........................+...........
...........*..................*........369..........899..79................*....417.....*930..*........78.....@174.........276..............
.313........394...750..........773.........................................916......37+.......384...........-......355.203....*.....180.....
....@...902...........829.......................................*823........................*.............408.......*......960......*.......
........*......%........#...........@871..........756.........22.........956..............56.622.=461.823..........749...........297..557...
......877.......863..............................*.........................=.968..............................12.......946%..........%......
..............................123.39.551...12...700..507*....................*........320.........*...54....................................
.............583........424..................$...........571......#.......499.......-.............803......92.&......942..........782.......
....726.....$...............=....688.580...*...........#..........905............446....397...................629...*............*..........
.....*..758.......831........760..-....*.427......473...729............298...618........-.........562*865.........553....267...12...........
.................$.....971...........472.....61....#..................*.........@..714.......712............173.............*......-780.....
.....*948..........&.....*..750.311..................*425.193....@336..882........*..........*....913.........*...........369...............
..942..............209.791....-....%.626.787..812.954......................725/.806.%...............#.......447....679..........706...11....
...............922......................*................217@......962..............9.104...806...................%.....278*.....*..........
.........382......*........./.......346.......346....448............*....................$...................*................820..454%.....
.315......./....418.........748................%...............577..655.......*254..266.....383*...$......316.243.........*.................
.....................363................709.....................=..........714..........224......479...................817.428....../.......
......................*................*........318................237....................*...................497.152............457........
...........911........756..589..........562......=..253........8*................498...392.......394.768...@................................
...............$..751..........856...................*...56......202...201.........+................*.......525.......430...................
.193........953...*.....456..@................310*........*............../.58@.........*..............863..........$....%..675..+117...447..
.......940.................*.905.889......542.....723......591....*956.........743.$..156.........791*......923..84......../..........$.....
.........&.....538&......643......*..=......*..................659............@....66.....681...............................................
.................................127.585.238.......-866....654......................................393................80..19..979..........
.........................300.................102........................465*..............705.332......................%.........*.....*142.
......+....#.....*...500..%..336.419........*....+116.719...........237.....81...461*931.....*.........613.#426...................434.......
......489.420.459......*......*....*.....277.............%.........=...............................*..............746....512............%848
.......................804....445.197.........658.*342....................+461.630......%...930@....804.504........*.............+..299.....
...........270.....257........................./.........283....................*.......357.......................702.....644.587......*....
...460%...=...........*.......406.........162..............*...259.......*.......121.............360$.#...76..228.....847..*............666.
.....................612..178*.............*...527*872.762.267........307.606.........#........$......224....&....13*....-.455.......&......
..........152.......................919..485............/.........70.................623....968......................810............281.230.
......693.*...520............$......*...........*909.....................586.........................794......229.........88...385..........
..363*....636..*......619.....238....45..............982...........*145.....*803......-.......426.......#.....+.......213*...#....*.........
...............536.....+........................&.......*.......708.....170......360..220......*../.......16................796....283..564.
.652....&...........$.....*....................89...944.894................*....-............975.27...409*...978......./445.................
...*.538...........822.274.491.....-..........................572.........329.........*468......................&.......................213.
.47......568.......................706.....232....74..490............&965..........685................125...........................824*....
........*....725...........#548............=......*.........................................77*391...*........253...............767.........
.......769...&......................183........687..921......913$...@.....162...724.................220.........*...880.834.........404.....
...+.................466...%411...../...............*...............894....*.......*.............*............196.....*................*....
.90.......423..../......*.......1.........-.......360.....233...............2........=......@....422.....334.........878......322......573..
....649..........475....450....%......-....249.................905.............760..879......829..........-....................*............
......*......290.....................680............/............/.244&.........................................9.596.326.........359.......
...............*........200.....723................826....773...........576..790..=..............642.................*....617....*.....649..
.....#979....776..562.......@.....*........................#........363.....&....915..704....401....*...32*681.%261.......&.......351.......
896*.................*896...493.88....*.........622.............925*.................*....17*.......265..............893....................
....778.%222.......................873.872..........635@...852..........559........456..%......*128........179.......*............336*......
.................985.......................77...482.........-.......502*......404......206...41......631..*.........761...............782...
.....194...........&...............514*130..=..*.............................*...........................168.............../..46+...........
.............207...............................195.....619..$..........544..191.......419*842....64......................206..........816...
..............................670..84*78.................*.966......%.....*.....................*........=............................*.....
.564.........185-........250....*........464...762.....412.......302.....27..764.653/.738*596..........563....741.........13.148.......928..
....*.............%..565....%.60....+158..*...$............*503...................................824.................284.......*.931-......
....710...763...272..*...................851..../....................456.......121....603................3..445...............382.......837.
....................956..970........-..........377......381.......56.......926........../......135......*....../.........315........172.&...
........201.............+...........261.517..................606........../.....347......................655.......717........468..*........
...746...&...332...............681...............703...........*.....=............*...........................................*....824......
......-.........*478.............*.....595.245....*...918.....875...875.........965...........676...745*...858...479.......132..............
..354........*.................776.-...*...*...820...../..%..............291........../........*........59.*........*....................485
...&......668.956......738.........921.312.803.....770...613....78*522..&...........665......692............253......863............537.....
...................498......258...................................................................426.........................#.............
.....108..........&.....357.-......794..594#............#............255........$.........664.525./....885...$..............353..823........
........+...590..........*........*...........111.......420..374..............144...........*...*...80*.....164...928...427......&..........
...+...........*..289.185......$...659.772/....*.............*........361..........504.........436...................*......@...............
...14....*...296...*........453..............753.368.733...167..675....*....................................22........502..443..............
.......413........................200=..616.......+...*...........#.....143..768..........404.............@...=...102..............378......
...538..........579.......................=...........311.267...................*.....445...*.....%138..158............#...........*....323.
......$............/.................586%.........825.....*....................318......@...260.................618..229...865....353...*...
.............834.......68*981................606..*.....432............870...............................749....*...........#.........215...
......886....*...325...................18.25*.....977...................../.......385.........$.......95*......182./........................
............773........................*................165...+....+816........*...*...........391..................439............@........
........................682..........249...................*.435............400...261..119.....................................921..630.....
.......-.......92*744....*....................115.......780........205....................*...347.152......950..592&.152....@.....*.........
.....789.949..............530.248.149.............................*....*957............957.....&..*.......#..........#.....572..............
...........*.601.766..112.......*......113..@.....529...736.+...656.837........320...............518.120.........125..............900.......
83......434.....*.....*.../...224.....*....235..............498............175...*.930.......................+......*................*880...
...*296...............118.328........405.............../801................*...804....*.......................590...770.........276.........
297..............726.............................966............*997......165..........25.983............669.............&..992*.......966..
...........92....*........%.........108.............@.475....769..................897......@.........792................123.......122.......
...........*...&..579......811..708...&.................*........................*....767.......386...........558............708.....=......
........230..161...............*................#....177.........940...903./...706.......*785..=.....93..381..%.................*...........
...621.............652..886...157........$....204............418....*....%..62......422.............*.....=........555.537.............+479.
.....%............*.....*.............499............96.........*....656..............*...751..293...759.....174..........%..265..32%.......
...............610....105.416.........................%........242.........*.......746.......*....=...........*..259@.......................
............#................*591........./.-.......................653.103..62=.............585.............567...........586...+....216...
..840/....612.......588.................676..202...................&................@..............................301............632..*....
......................*.........=392.............667..%..........-...............457...134*....................165*.....................728.
.339&.*74.........402.581............518&.......*....823.....874..102..678.74..............219....114..................836..915..245.-......
..........38.....*........612...628..............90......513...*............*...........59......+..../....799..268....*.....*.........370...
..........$........./........*.....*.......$...................8.......684=.577..209.........550.............#.....#...529.240..............
.236..............153......163........*.414...........................................549........432............919............81.....-337..
....*.................604......-...631..........879........240.......97...............*.....315....&...720..........610...530...............
.....856...214..236....*.....159.%......738.....-......826....&.272.*.......36.....465.........../.....*...587.......*....*......548..699...
.............*........36..........743.=.../...............*......*..424.................580.#...897.448....*.......833...633.....*...*......
.............963......................542........734.....901...914..........843.............523..........818..................691.....833..."""
package de.startat.aoc2023

data class Number(val value: Int, val lineNumber : Int, val indices : IntRange)
data class Symbol(val value: String,val lineNumber: Int, val index : Int)
data class Schematic(val numbers : List<Number>, val symbols: List<Symbol>)

fun Symbol.isAdjacentTo(number: Number) : Boolean{
    val lineRange = number.lineNumber-1 .. number.lineNumber+1
    val indexRange = number.indices.first-1 .. number.indices.last+1
    return this.lineNumber in lineRange && this.index in indexRange
}

fun Schematic.sumOfNumbers() : Int {
    return numbers.fold(0){acc, number -> acc + number.value }
}

fun Schematic.gears() : List<Pair<Number,Number>> {
    return symbols.filter { s -> s.value == "*" }.mapNotNull { possibleGear ->
        val adjacentNumbers = numbers.filter { n -> possibleGear.isAdjacentTo(n) }.toList()
        return@mapNotNull if (adjacentNumbers.size == 2) {
            Pair(adjacentNumbers[0], adjacentNumbers[1])
        } else
            null
    }.toList()
}


class Day3 {
    private val numberRegex = Regex("\\d+")
    private val symbolRegex = Regex("[^\\d.\\n]")

    fun star1() {
        val schematic: Schematic = readSchematic(day3Input)
        println("Sum of schematic numbers = ${schematic.sumOfNumbers()}")
    }

    fun star2() {
        val schematic: Schematic = readSchematic(day3Input)
        val gearRatio = schematic.gears().fold(0) { acc, (first, second) -> acc + first.value * second.value }
        println("Gear ratio = $gearRatio")
    }

    private fun readSchematic(schematicString : String) : Schematic {
        val allNumbers: MutableList<Number> = mutableListOf()
        val allSymbols: MutableList<Symbol> = mutableListOf()

        for ((idx, line) in schematicString.lines().withIndex()) {
            println(line)
            val numbersInLine =
                numberRegex.findAll(line).map { match -> Number(match.value.toInt(), idx, match.range) }.toList()
            println("\t$numbersInLine")
            allNumbers += numbersInLine

            val symbolsInLine =
                symbolRegex.findAll(line).map { match -> Symbol(match.value, idx, match.range.first) }.toList()
            println("\t$symbolsInLine")
            allSymbols += symbolsInLine
        }

        val validNumbers = allNumbers.filter { n -> allSymbols.any{s -> s.isAdjacentTo(n)}}.toList()
        return Schematic(validNumbers, allSymbols)
    }
}


val day3testInput = """467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598.."""

val day3Input = """.......358..........31.....339.....669.............598......328.....575......................447..650..............964...........692........
...............415..*.........@......*...627*...................945*.............144/.506............................*......514...*...150...
.........182..+.....873.756.......737........784..568....667..............258........./.........741...........707*....84........520.........
..579...@.........$........*..........258.................*.........274..*.....739.......157./.....*580...........893.....696*........889...
.....*.........875.........173.........*..................109...896*......959...*........=...677...........&636.........................$...
......961..$............-...............907...569....#...........................756.....................................681................
...........478...616.....30.....221*...............552.../33...258*343.....488........*682...526..*.........422...........&..........764....
................+..........................................................*................*.....7...550..........=.........878............
...171..275............#.....................401....50.$.................43...............123.............../949..135..331.....@.495........
........*...48@.662.100...............590...*........#.566.....................15..../426.............774...............+...........*.......
...944.28.........*.....................*....307...........410.361....55..................24.447.*......*....787*...266....361.......161....
....*...........405.&...=785...146......654.......281.............*.....+...................*....760..80..17.....84....*..+.................
.....830...140......745.........%..$..........972.......406*864..762..............695.327.................*...........512...................
............*...............#......414...........*..960...............1..............*.................374.....264.............833....336...
.......-.252.......10....518..................777...=...811..103.454..*....................774*433.........951*....826........@....=...*....
.....44..............*................-....................@..$......957...............216..........=..................614........521..232..
.........=232......802...+779.....759..307....................................%941.......*........512.............865.....*.................
...................................*.......162...662....816.681.....21*................290.........................*......364..........=....
.................258....195.........1..535......*.......*.....*........261............................650.......152.................514.....
..425...411@...../.........@...........*.....788.........186...91.279............-.....................*............268.......639.......864.
....................................=.933........../.................%...%........73........%203....187..362...861.....*389.....*.......*...
...254....847............@........135......6.......529..........202......96...........840.........@........*...*.../.........998.......989..
.........*.....288......650............349*.......................%.609...................526.....655.....854....425..............531*......
..../....848....&..............505...........................594..........434.................@.......$68............767..............732...
.410...............585...............185........................*...91........773..579........454............757.....*....568..+742.........
..............................*70.......*......478............769....&.182.......%.*..................568......-.570.861....*...............
..............*993.48......893........835....*..*......*.................*..........798..473.........../....................965...691.......
...........306.......*............531.......938.200.335.432...343.....360......836......-...........*..........951.691..............*.......
...341*360............958............*.........................#.........../.....*.../........728..585.........*.............902=..696......
.............190...................808..451........+..................272...59.641...822.........*..........289...36...................509..
..464*10.604.+....241.102%..............*...633.450......................+........................797............*.......575..........*.....
...........-............................488..........402.....936.847................+.......434.......................&.....&....844...478..
......147..............826...297................257...*...........*.....$.....932...492..81...%....829..........560...661.........*.........
.........*....379.......*....*...884..700.......*.....646..........914..659...............*....................=..........513/..621..790....
.369....472..*.......843....734....#.+....%...738........................................989............501.......817.375...............@...
..............727.........................131.....767..........=......665...685..............747..727.......868..*.............478#.........
........247.............-...........649.............*..*82..507...............*..................................504........................
.........*...........909...............*.....707..922..............701...213.833.866$.630...&..606+....................102.183@..*281.225...
...465.108...............772.....915.109..96.%...................../.....*.............*..685........155....811*...220.*...............*....
.................106.....=.................&........*........*488.........233.......590........$551.....*..........+...287.#874..%....956...
....................*513.........&...............829.487................................350..-........338.......55................464.......
....&............@............695......227................$.793.............802.....294...*...822..........960....*....295..946.............
....587...........859...204.......246*....*644.........925.........167.210..../..........129.............%....*...102.....*..*..........832.
.......................*..............558.......404.......................%..........................817..870.791......120..483..406...$....
....797%..68....929-.87....411............*........*.............458*143....721.-....706.......694....*.........................+...........
...........*..................*........369..........899..79................*....417.....*930..*........78.....@174.........276..............
.313........394...750..........773.........................................916......37+.......384...........-......355.203....*.....180.....
....@...902...........829.......................................*823........................*.............408.......*......960......*.......
........*......%........#...........@871..........756.........22.........956..............56.622.=461.823..........749...........297..557...
......877.......863..............................*.........................=.968..............................12.......946%..........%......
..............................123.39.551...12...700..507*....................*........320.........*...54....................................
.............583........424..................$...........571......#.......499.......-.............803......92.&......942..........782.......
....726.....$...............=....688.580...*...........#..........905............446....397...................629...*............*..........
.....*..758.......831........760..-....*.427......473...729............298...618........-.........562*865.........553....267...12...........
.................$.....971...........472.....61....#..................*.........@..714.......712............173.............*......-780.....
.....*948..........&.....*..750.311..................*425.193....@336..882........*..........*....913.........*...........369...............
..942..............209.791....-....%.626.787..812.954......................725/.806.%...............#.......447....679..........706...11....
...............922......................*................217@......962..............9.104...806...................%.....278*.....*..........
.........382......*........./.......346.......346....448............*....................$...................*................820..454%.....
.315......./....418.........748................%...............577..655.......*254..266.....383*...$......316.243.........*.................
.....................363................709.....................=..........714..........224......479...................817.428....../.......
......................*................*........318................237....................*...................497.152............457........
...........911........756..589..........562......=..253........8*................498...392.......394.768...@................................
...............$..751..........856...................*...56......202...201.........+................*.......525.......430...................
.193........953...*.....456..@................310*........*............../.58@.........*..............863..........$....%..675..+117...447..
.......940.................*.905.889......542.....723......591....*956.........743.$..156.........791*......923..84......../..........$.....
.........&.....538&......643......*..=......*..................659............@....66.....681...............................................
.................................127.585.238.......-866....654......................................393................80..19..979..........
.........................300.................102........................465*..............705.332......................%.........*.....*142.
......+....#.....*...500..%..336.419........*....+116.719...........237.....81...461*931.....*.........613.#426...................434.......
......489.420.459......*......*....*.....277.............%.........=...............................*..............746....512............%848
.......................804....445.197.........658.*342....................+461.630......%...930@....804.504........*.............+..299.....
...........270.....257........................./.........283....................*.......357.......................702.....644.587......*....
...460%...=...........*.......406.........162..............*...259.......*.......121.............360$.#...76..228.....847..*............666.
.....................612..178*.............*...527*872.762.267........307.606.........#........$......224....&....13*....-.455.......&......
..........152.......................919..485............/.........70.................623....968......................810............281.230.
......693.*...520............$......*...........*909.....................586.........................794......229.........88...385..........
..363*....636..*......619.....238....45..............982...........*145.....*803......-.......426.......#.....+.......213*...#....*.........
...............536.....+........................&.......*.......708.....170......360..220......*../.......16................796....283..564.
.652....&...........$.....*....................89...944.894................*....-............975.27...409*...978......./445.................
...*.538...........822.274.491.....-..........................572.........329.........*468......................&.......................213.
.47......568.......................706.....232....74..490............&965..........685................125...........................824*....
........*....725...........#548............=......*.........................................77*391...*........253...............767.........
.......769...&......................183........687..921......913$...@.....162...724.................220.........*...880.834.........404.....
...+.................466...%411...../...............*...............894....*.......*.............*............196.....*................*....
.90.......423..../......*.......1.........-.......360.....233...............2........=......@....422.....334.........878......322......573..
....649..........475....450....%......-....249.................905.............760..879......829..........-....................*............
......*......290.....................680............/............/.244&.........................................9.596.326.........359.......
...............*........200.....723................826....773...........576..790..=..............642.................*....617....*.....649..
.....#979....776..562.......@.....*........................#........363.....&....915..704....401....*...32*681.%261.......&.......351.......
896*.................*896...493.88....*.........622.............925*.................*....17*.......265..............893....................
....778.%222.......................873.872..........635@...852..........559........456..%......*128........179.......*............336*......
.................985.......................77...482.........-.......502*......404......206...41......631..*.........761...............782...
.....194...........&...............514*130..=..*.............................*...........................168.............../..46+...........
.............207...............................195.....619..$..........544..191.......419*842....64......................206..........816...
..............................670..84*78.................*.966......%.....*.....................*........=............................*.....
.564.........185-........250....*........464...762.....412.......302.....27..764.653/.738*596..........563....741.........13.148.......928..
....*.............%..565....%.60....+158..*...$............*503...................................824.................284.......*.931-......
....710...763...272..*...................851..../....................456.......121....603................3..445...............382.......837.
....................956..970........-..........377......381.......56.......926........../......135......*....../.........315........172.&...
........201.............+...........261.517..................606........../.....347......................655.......717........468..*........
...746...&...332...............681...............703...........*.....=............*...........................................*....824......
......-.........*478.............*.....595.245....*...918.....875...875.........965...........676...745*...858...479.......132..............
..354........*.................776.-...*...*...820...../..%..............291........../........*........59.*........*....................485
...&......668.956......738.........921.312.803.....770...613....78*522..&...........665......692............253......863............537.....
...................498......258...................................................................426.........................#.............
.....108..........&.....357.-......794..594#............#............255........$.........664.525./....885...$..............353..823........
........+...590..........*........*...........111.......420..374..............144...........*...*...80*.....164...928...427......&..........
...+...........*..289.185......$...659.772/....*.............*........361..........504.........436...................*......@...............
...14....*...296...*........453..............753.368.733...167..675....*....................................22........502..443..............
.......413........................200=..616.......+...*...........#.....143..768..........404.............@...=...102..............378......
...538..........579.......................=...........311.267...................*.....445...*.....%138..158............#...........*....323.
......$............/.................586%.........825.....*....................318......@...260.................618..229...865....353...*...
.............834.......68*981................606..*.....432............870...............................749....*...........#.........215...
......886....*...325...................18.25*.....977...................../.......385.........$.......95*......182./........................
............773........................*................165...+....+816........*...*...........391..................439............@........
........................682..........249...................*.435............400...261..119.....................................921..630.....
.......-.......92*744....*....................115.......780........205....................*...347.152......950..592&.152....@.....*.........
.....789.949..............530.248.149.............................*....*957............957.....&..*.......#..........#.....572..............
...........*.601.766..112.......*......113..@.....529...736.+...656.837........320...............518.120.........125..............900.......
83......434.....*.....*.../...224.....*....235..............498............175...*.930.......................+......*................*880...
...*296...............118.328........405.............../801................*...804....*.......................590...770.........276.........
297..............726.............................966............*997......165..........25.983............669.............&..992*.......966..
...........92....*........%.........108.............@.475....769..................897......@.........792................123.......122.......
...........*...&..579......811..708...&.................*........................*....767.......386...........558............708.....=......
........230..161...............*................#....177.........940...903./...706.......*785..=.....93..381..%.................*...........
...621.............652..886...157........$....204............418....*....%..62......422.............*.....=........555.537.............+479.
.....%............*.....*.............499............96.........*....656..............*...751..293...759.....174..........%..265..32%.......
...............610....105.416.........................%........242.........*.......746.......*....=...........*..259@.......................
............#................*591........./.-.......................653.103..62=.............585.............567...........586...+....216...
..840/....612.......588.................676..202...................&................@..............................301............632..*....
......................*.........=392.............667..%..........-...............457...134*....................165*.....................728.
.339&.*74.........402.581............518&.......*....823.....874..102..678.74..............219....114..................836..915..245.-......
..........38.....*........612...628..............90......513...*............*...........59......+..../....799..268....*.....*.........370...
..........$........./........*.....*.......$...................8.......684=.577..209.........550.............#.....#...529.240..............
.236..............153......163........*.414...........................................549........432............919............81.....-337..
....*.................604......-...631..........879........240.......97...............*.....315....&...720..........610...530...............
.....856...214..236....*.....159.%......738.....-......826....&.272.*.......36.....465.........../.....*...587.......*....*......548..699...
.............*........36..........743.=.../...............*......*..424.................580.#...897.448....*.......833...633.....*...*......
.............963......................542........734.....901...914..........843.............523..........818..................691.....833..."""