2023-12-01 06:38:13 +01:00
package aoc2023
import println
import readInput
/ *
-- - Day 1 : Trebuchet ? ! -- -
Something is wrong with global snow production , and you ' ve been selected to take a look . The Elves have even given you a map ; on it , they ' ve used stars to mark the top fifty locations that are likely to be having problems .
You ' ve been doing this long enough to know that to restore snow operations , you need to check all fifty stars by December 25 th .
Collect stars by solving puzzles . Two puzzles will be made available on each day in the Advent calendar ; the second puzzle is unlocked when you complete the first . Each puzzle grants one star . Good luck !
You try to ask why they can ' t just use a weather machine ( " not powerful enough " ) and where they ' re even sending you ( " the sky " ) and why your map looks mostly blank ( " you sure ask a lot of questions " ) and hang on did you just say the sky ( " of course, where do you think snow comes from " ) when you realize that the Elves are already loading you into a trebuchet ( " please hold still, we need to strap you in " ) .
As they ' re making the final adjustments , they discover that their calibration document ( your puzzle input ) has been amended by a very young Elf who was apparently just excited to show off her art skills . Consequently , the Elves are having trouble reading the values on the document .
The newly - improved calibration document consists of lines of text ; each line originally contained a specific calibration value that the Elves now need to recover . On each line , the calibration value can be found by combining the first digit and the last digit ( in that order ) to form a single two - digit number .
For example :
1 abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
-- - Part Two -- -
In this example , the calibration values of these four lines are 12 , 38 , 15 , and 77. Adding these together produces 142.
Consider your entire calibration document . What is the sum of all of the calibration values ?
Your calculation isn ' t quite right . It looks like some of the digits are actually spelled out with letters : one , two , three , four , five , six , seven , eight , and nine also count as valid " digits " .
Equipped with this new information , you now need to find the real first and last digit on each line . For example :
two1nine
eightwothree
abcone2threexyz
xtwone3four
4 nineeightseven2
zoneight234
7 pqrstsixteen
In this example , the calibration values are 29 , 83 , 13 , 24 , 42 , 14 , and 76. Adding these together produces 281.
What is the sum of all of the calibration values ?
* /
fun main ( ) {
val inlineTestInput = """
1 abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
"""
val inlineTestInput2 = """
two1nine
eightwothree
abcone2threexyz
xtwone3four
4 nineeightseven2
zoneight234
7 pqrstsixteen
"""
fun part1 ( input : List < String > ) : Int {
2023-12-01 19:06:02 +01:00
return input . sumOf { ( it . first { it . isDigit ( ) } . toString ( ) + it . last { it . isDigit ( ) } . toString ( ) ) . toInt ( ) }
2023-12-01 06:38:13 +01:00
}
val digitStrings = arrayOf ( " --- " , " one " , " two " , " three " , " four " , " five " , " six " , " seven " , " eight " , " nine " )
2023-12-01 19:06:02 +01:00
val digitStringsRev = digitStrings . map { it . reversed ( ) } . toTypedArray ( )
fun findFirst ( s : String , digs : Array < String > ) : Int {
for ( p in s . indices ) {
if ( s [ p ] . isDigit ( ) ) return s [ p ] . digitToInt ( )
val m = s . subSequence ( p , s . length )
val match = digs . withIndex ( ) . firstOrNull { m . startsWith ( it . value ) }
if ( match != null ) return match . index
2023-12-01 06:38:13 +01:00
}
2023-12-01 19:06:02 +01:00
return - 1
2023-12-01 06:38:13 +01:00
}
fun part2 ( input : List < String > ) : Int {
2023-12-01 19:06:02 +01:00
return input . sumOf { findFirst ( it , digitStrings ) * 10 + findFirst ( it . reversed ( ) , digitStringsRev ) }
2023-12-01 06:38:13 +01:00
}
// test if implementation meets criteria from the description, like:
val testInput = inlineTestInput . trim ( ) . reader ( ) . readLines ( )
val testInput2 = inlineTestInput2 . trim ( ) . reader ( ) . readLines ( )
//val testInput = readInput("aoc2023/Day01_test")
println ( " Part 1 Test: " + part1 ( testInput ) )
println ( " Part 2 Test: " + part2 ( testInput2 ) )
check ( part1 ( testInput ) == 142 )
check ( part2 ( testInput2 ) == 281 )
val input = readInput ( " aoc2023/Day01 " )
part1 ( input ) . println ( )
part2 ( input ) . println ( )
}