2019-12-06 09:56:14 +01:00
fun main ( ) {
2019-12-06 11:06:35 +01:00
val input = generateSequence ( :: readLine ) . map { it . split ( " ) " ) } . toList ( )
val parentToChildren = input . groupBy { it [ 0 ] } . mapValues { it . value . map { it [ 1 ] } }
val rootNode = ( parentToChildren . keys - parentToChildren . values . flatten ( ) . toSet ( ) ) . first ( )
println ( " Part 1: ${countOrbiters(parentToChildren, rootNode, 0)} " )
2019-12-06 11:44:33 +01:00
val childToParent = input . associateBy { it [ 1 ] } . mapValues { it . value [ 0 ] }
2019-12-06 11:06:35 +01:00
val santaParents = getParents ( childToParent , " SAN " )
val myParents = getParents ( childToParent , " YOU " )
2019-12-06 11:48:19 +01:00
val commonParent = myParents . toSet ( ) . let { s -> santaParents . first { it in s } }
2019-12-06 11:06:35 +01:00
println ( " Part 2: ${santaParents.indexOf(commonParent) + myParents.indexOf(commonParent)} " )
2019-12-06 09:56:14 +01:00
}
2019-12-06 11:06:35 +01:00
fun < T > countOrbiters ( graph : Map < T , List < T > > , key : T , acc : Int ) : Int =
2019-12-06 10:16:50 +01:00
acc + ( graph [ key ] ?. map { countOrbiters ( graph , it , acc + 1 ) } ?. sum ( ) ?: 0 )
2019-12-06 11:06:35 +01:00
fun < T > getParents ( graph : Map < T , T > , key : T ) : List < T > =
graph [ key ] ?. let { curr -> listOf ( curr ) + getParents ( graph , curr ) } ?: emptyList ( )