82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Kotlin
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Kotlin
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env kotlin
 | 
						|
import java.util.Scanner
 | 
						|
 | 
						|
 | 
						|
class TrailHead(private val x: Int, private val y: Int, private val map: Map) {
 | 
						|
    private val peaks = mutableMapOf<Pair<Int, Int>, Int>()
 | 
						|
    fun getScore(): Int {
 | 
						|
        if (this.peaks.isEmpty()) {
 | 
						|
            for (peak in this.walkToPeak(this.x, this.y)) {
 | 
						|
                this.peaks[peak] = (this.peaks[peak] ?: 0) + 1
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return this.peaks.keys.size
 | 
						|
    }
 | 
						|
    fun getGetRating(): Int {
 | 
						|
        this.getScore()
 | 
						|
        return this.peaks.values.sum()
 | 
						|
    }
 | 
						|
 | 
						|
    private fun walkToPeak(x: Int, y: Int, previous: Int = -1): List<Pair<Int, Int>> {
 | 
						|
        if (x < 0 || x >= map.getLength() || y < 0 || y >= map.getHeight() || map.get(x, y) != (previous + 1)) {
 | 
						|
            return listOf()
 | 
						|
        } else if (map.get(x, y) == 9) {
 | 
						|
            return listOf(Pair(x, y))
 | 
						|
        } else {
 | 
						|
            val current = map.get(x, y)
 | 
						|
            return walkToPeak(x + 1, y, current) + walkToPeak(x - 1, y, current) + walkToPeak(x, y + 1, current) + walkToPeak(x, y - 1, current)
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
class Map(private val grid: List<List<Int>>) {
 | 
						|
    private val trailHeads = mutableListOf<TrailHead>()
 | 
						|
 | 
						|
    init {
 | 
						|
        grid.forEachIndexed { y, row ->
 | 
						|
            row.forEachIndexed { x, height ->
 | 
						|
                if (height == 0) {
 | 
						|
                    trailHeads.add(TrailHead(x, y, this))
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    fun addTrailHead(trailHead: TrailHead) {
 | 
						|
        trailHeads.add(trailHead)
 | 
						|
    }
 | 
						|
 | 
						|
    fun get(x: Int, y: Int): Int {
 | 
						|
        return grid[y][x]
 | 
						|
    }
 | 
						|
 | 
						|
    fun getHeight(): Int {
 | 
						|
        return grid.size
 | 
						|
    }
 | 
						|
 | 
						|
    fun getLength(): Int {
 | 
						|
        return if (grid.isNotEmpty()) grid[0].size else 0
 | 
						|
    }
 | 
						|
 | 
						|
    fun getScore(): Int {
 | 
						|
        return trailHeads.fold(0) { acc, trailHead -> acc + trailHead.getScore() }
 | 
						|
    }
 | 
						|
 | 
						|
    fun getGetRating(): Int {
 | 
						|
        return trailHeads.fold(0) { acc, trailHead -> acc + trailHead.getGetRating() }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
val scanner = Scanner(System.`in`)
 | 
						|
val mapInput = mutableListOf<List<Int>>()
 | 
						|
while (scanner.hasNext()) {
 | 
						|
    val line = scanner.nextLine()
 | 
						|
    val numbers = line.split("").filter { it.isNotEmpty() }.map { it.toInt() }
 | 
						|
    mapInput.add(numbers)
 | 
						|
}
 | 
						|
val map = Map(mapInput.reversed())
 | 
						|
 | 
						|
println("Score: ${map.getScore()}")
 | 
						|
println("Rating: ${map.getGetRating()}") |