Created
January 18, 2015 15:47
-
-
Save FScoward/5248070dbdc391c8eb07 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by FScoward on 15/01/18. | |
*/ | |
object Luhn { | |
/** | |
* Luhn algorithm | |
* */ | |
def isValid(s: String): Boolean = { | |
val list = doubleOddValues(toReverseIntList(s)) | |
sum(list) % 10 == 0 | |
} | |
/** | |
* 偶数桁の値を倍にして返す | |
* */ | |
private def doubleOddValues(list: List[Int]): List[Int] = { | |
(0 until list.size).map(i => { | |
if (i % 2 == 0) { | |
list(i) | |
} else { | |
list(i) * 2 | |
} | |
}).toList | |
} | |
/** | |
* 文字列をInt型の逆リストに変換 | |
* */ | |
private def toReverseIntList(s: String): List[Int] = { | |
s.sliding(1).map(_.toInt).toList.reverse | |
} | |
/** | |
* リストの値を合計する | |
* 但し、2桁以上の数字は分割して加算する | |
* */ | |
private def sum(list: List[Int]) = { | |
list.map(i => { | |
i match { | |
case i if i > 9 => { | |
i.toString.sliding(1).map(_.toInt).sum | |
} | |
case i => { | |
i | |
} | |
} | |
}).toList.sum | |
} | |
} | |
/* test -> another file [LuhnSpec.scala] */ | |
import org.specs2.Specification | |
/** | |
* Created by FScoward on 15/01/18. | |
*/ | |
class LuhnSpec extends Specification { | |
def is = | |
s2""" | |
49927398716 and 1234567812345670 is valid $e1 | |
49927398717 and 1234567812345678 is invalid $e2 | |
""" | |
def e1 = { | |
/** | |
* 49927398716 | |
* 6 + (2) + 7 + (1+6) + 9 + (6) + 7 + (4) + 9 + (1+8) + 4 = 70 | |
* */ | |
Luhn.isValid("49927398716") === true | |
Luhn.isValid("1234567812345670") === true | |
} | |
def e2 = { | |
Luhn.isValid("49927398717") === false | |
Luhn.isValid("1234567812345678") === false | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment