diff --git a/src/main/kotlin/CustomAdt.kt b/src/main/kotlin/CustomAdt.kt index c30e0c4..c94a08a 100644 --- a/src/main/kotlin/CustomAdt.kt +++ b/src/main/kotlin/CustomAdt.kt @@ -6,10 +6,48 @@ sealed interface ParseResult { data class Failure(val pos: Int, val char: Char) : ParseResult } +fun String.firstNonDigitCharOrNull(): IndexedValue? = + this + .asSequence() + .withIndex() + .filterNot { isCorrectIntStringChar(it.index, it.value, this.first()) } + .firstOrNull() + +fun isCorrectIntStringChar(pos: Int, char: Char, firstChar: Char): Boolean { + val maxLengthOfPositiveIntString = Int.MAX_VALUE.toString().length + return when { + pos == 0 && char == '-' -> true + pos == 1 && char == '0' && firstChar == '-' -> false + pos == 1 && char == '0' && firstChar == '0' -> false + pos < maxLengthOfPositiveIntString && char.isDigit() -> true + pos == maxLengthOfPositiveIntString && char.isDigit() && firstChar == '-' -> true + else -> false + } +} + +fun parseCorrectInt(str: String): Int = + when (str.first()) { + '-' -> parseNegativeInt(str) + else -> parsePositiveInt(str) + } + +fun parseNegativeInt(str: String): Int = + -1 * parsePositiveInt(str.drop(1)) + +fun parsePositiveInt(str: String): Int = + str + .map { it - '0' } + .fold(0) { accumulator, digit -> accumulator * 10 + digit } + object CustomAdt { fun parseInt(str: String): ParseResult { - TODO() + return when { + str.isEmpty() -> ParseResult.Failure(-1, '\u0000') + else -> str.firstNonDigitCharOrNull() + ?.let { ParseResult.Failure(it.index, it.value) } + ?: ParseResult.Success(parseCorrectInt(str)) + } } } \ No newline at end of file