-
Exercism - Luhn(with.Kotlin)문제풀이/Exercism 2019. 8. 19. 14:34반응형
[Instructions]
Given a number determine whether or not it is valid per the Luhn formula.
The Luhn algorithm is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers and Canadian Social Insurance Numbers.
The task is to check if a given string is valid.
Validating a Number
Strings of length 1 or less are not valid. Spaces are allowed in the input, but they should be stripped before checking. All other non-digit characters are disallowed.
Example 1: valid credit card number
4539 1488 0343 6467
The first step of the Luhn algorithm is to double every second digit, starting from the right. We will be doubling
4_3_ 1_8_ 0_4_ 6_6_
If doubling the number results in a number greater than 9 then subtract 9 from the product. The results of our doubling:
8569 2478 0383 3437
Then sum all of the digits:
8+5+6+9+2+4+7+8+0+3+8+3+3+4+3+7 = 80
If the sum is evenly divisible by 10, then the number is valid. This number is valid!
Example 2: invalid credit card number
8273 1232 7352 0569
Double the second digits, starting from the right
7253 2262 5312 0539
Sum the digits
7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57
57 is not evenly divisible by 10, so this number is not valid.
[Solution1]
object Luhn { fun isValid(s: String): Boolean { val strReplaceSpace = s.replace(" ", "") if(strReplaceSpace.length < 2) return false val sum = strReplaceSpace .mapIndexed { index, c -> if(!c.isDigit()) return false val num = c.toString().toInt() if(checkDouble(index, strReplaceSpace.length)) { val doubleNum = num * 2 if(doubleNum > 9){ return@mapIndexed doubleNum - 9 } return@mapIndexed doubleNum } return@mapIndexed num } .toIntArray() .sum() return sum % 10 == 0 } private fun checkDouble(index:Int, strLength: Int): Boolean = if(strLength.isOdd()) index.isOdd() else !index.isOdd() private fun Int.isOdd(): Boolean { return this % 2 != 0 } }
최초에 생각하는대로 규칙을 반견하여 작성함
[Solution2]
object Luhn { fun isValid(s: String): Boolean { val strReplaceSpace = s.replace(" ", "") if(strReplaceSpace.length < 2) return false val sum = strReplaceSpace .mapIndexed { index, c -> if(!c.isDigit()) return false if(checkDouble(index, strReplaceSpace.length)) c.toString().toInt() * 2 else c.toString().toInt() } .map { if(it > 9) it - 9 else it } .sum() return sum % 10 == 0 } private fun checkDouble(index:Int, strLength: Int): Boolean = if(strLength % 2 != 0) index % 2 != 0 else index % 2 == 0 }
홀수짝수 여부를 구분하는 함수를 줄이고 처리함
[Solution3]
object Luhn { fun isValid(s: String): Boolean { val strReplaceSpace = s.replace(" ", "") if(strReplaceSpace.length < 2) return false val sum = strReplaceSpace .reversed() .mapIndexed { index, c -> if(!c.isDigit()) return false if(index % 2 != 0) c.toString().toInt() * 2 else c.toString().toInt() } .map { if(it > 9) it - 9 else it } .sum() return sum % 10 == 0 } }
문자열 자체를 reversed() 하여 식을 간소화 시킴
[Solution4]
object Luhn { fun isValid(s: String): Boolean { val strReplaceSpace = s.replace(" ", "") if(strReplaceSpace.length < 2) return false if(strReplaceSpace.any { !it.isDigit() }) return false val sum = strReplaceSpace .reversed() .map { it.toString().toInt() } .mapIndexed { index, i -> if(index % 2 != 0) i * 2 else i } .sumBy { if(it > 9) it - 9 else it } return sum % 10 == 0 } }
isDigit 하는 부분을 map 외부로 빼냄
정수로 변경하는부분을 사전 처리하도록 변경
map 과 sum 을 합쳐서 sumby 로 처리함
반응형'문제풀이 > Exercism' 카테고리의 다른 글
Exercism - Diamond(with.Kotlin) (0) 2019.08.27 Exercism - Largest Series Product (With.Kotlin) (0) 2019.08.21 Exercism - Acronym(with.Kotlin) (0) 2019.08.19 Exercism - Perfect Numbers(with.Kotlin) (0) 2019.08.17 Exercism - Difference Of Squares(with.Kotlin) (0) 2019.08.06 Exercism - Scrabble Score (With.Kotlin) (0) 2019.07.30 Exercism - Space Age (With.Kotlin) (0) 2019.07.26 Exercism - Gigasecond(With.Kotlin) (0) 2019.07.23