Skip to content

Instantly share code, notes, and snippets.

@aloisdg
Last active March 20, 2019 14:43
Show Gist options
  • Select an option

  • Save aloisdg/44119ed6ce8232616a85684c157acbba to your computer and use it in GitHub Desktop.

Select an option

Save aloisdg/44119ed6ce8232616a85684c157acbba to your computer and use it in GitHub Desktop.
A F# implementation of Luhn's algorithm
// https://en.wikipedia.org/wiki/Luhn_algorithm
let inline charToInt (c:char) = int c - int '0'
let rec check (ccNumber:string) index sum alternate =
if index < 0 then
sum % 10 = 0
else
let n = ccNumber.[index] |> charToInt
let neoN =
if alternate then
let n2 = n * 2
if n2 > 9 then
n2 % 10 + 1
else
n2
else
n
check ccNumber (index - 1) (sum + neoN) (not alternate)
let clean input =
input
|> Seq.filter(System.Char.IsDigit)
|> System.String.Concat
let checkWithLuhn (ccNumber:string) :bool =
let cleandNumber = clean ccNumber
check cleandNumber (cleandNumber.Length - 1) 0 false
let visa = "4916 9027 3333 3548"
let mastercard = "5243 6733 9610 6502"
let amex = "3497 771847 23503"
checkWithLuhn visa |> printfn "%b"
checkWithLuhn mastercard |> printfn "%b"
checkWithLuhn amex |> printfn "%b"
@thinkbeforecoding

Copy link
Copy Markdown

Ca marche
Par contre tu vas faire beaucoup d'allocations de chaines... 1 par caractère
Garde la chaine sans la modifier, et fait passer un index dans ta récursion...

@thinkbeforecoding

Copy link
Copy Markdown

Tu peux aussi créer un function pour le (*2 -9?) des alternates.

@aloisdg

aloisdg commented Mar 20, 2019

Copy link
Copy Markdown
Author

Garde la chaine sans la modifier, et fait passer un index dans ta récursion...

Effectivement c'est bien mieux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment