Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync Luhn with problem specifications #199

Merged
merged 1 commit into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion exercises/practice/luhn/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"contributors": [
"adolfopa",
"etrepum",
"yurrriq"
"yurrriq",
"kahgoh"
],
"files": {
"solution": [
Expand Down
48 changes: 25 additions & 23 deletions exercises/practice/luhn/.meta/example.lfe
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
(defmodule luhn
(export (valid? 1)
(create 1)
(checksum 1)))
(export (valid? 1))
)

(defun valid? (number) (== (rem (checksum number) 10) 0))
(defun valid? (number)
(case (checksum (lists:reverse number) 0 0)
((tuple 'ok count total) (when (> count 1)) (== (rem total 10) 0))
(_ 'false)
)
)

(defun create (number)
(lists:flatten `(,number ,(- #\: (rem (checksum (++ number "0")) 10)))))
(defun checksum
(('() count total) (tuple 'ok count total))
(((cons 32 reversed-number) count total) (checksum reversed-number count total))
(((cons h reversed-number) count total)
(when (=< #\0 h) (=< h #\9))
(checksum reversed-number
(+ count 1)
(+ total (number-to-add count (- h #\0)))
)
)
((_ count total) (tuple 'invalid count total))
)

(defun checksum (number)
(checksum
(lists:reverse
(lists:filter
(lambda (c)
(=< #\0 c #\9))
number))
'odd
0))
(defun number-to-add
((count digit) (when (== (rem count 2) 0)) digit)
((_ digit) (when (< digit 5)) (* digit 2))
((_ digit) (- (* digit 2) 9))
)

(defun checksum
([() _ total] total)
([(cons h reversed-number) 'odd total]
(checksum reversed-number 'even (- (+ total h) #\0)))
([(cons h reversed-number) 'even total] (when (< h #\5))
(checksum reversed-number 'odd (+ total (* (- h #\0) 2))))
([(cons h reversed-number) 'even total] (when (>= h #\5))
(checksum reversed-number 'odd (- (+ total (* (- h #\0) 2)) 9))))
9 changes: 9 additions & 0 deletions exercises/practice/luhn/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ description = "invalid credit card"
[20e67fad-2121-43ed-99a8-14b5b856adb9]
description = "invalid long number with an even remainder"

[7e7c9fc1-d994-457c-811e-d390d52fba5e]
description = "invalid long number with a remainder divisible by 5"

[ad2a0c5f-84ed-4e5b-95da-6011d6f4f0aa]
description = "valid number with an even number of digits"

Expand All @@ -57,6 +60,12 @@ description = "more than a single zero is valid"
[ab56fa80-5de8-4735-8a4a-14dae588663e]
description = "input digit 9 is correctly converted to output digit 9"

[b9887ee8-8337-46c5-bc45-3bcab51bc36f]
description = "very long input is valid"

[8a7c0e24-85ea-4154-9cf1-c2db90eabc08]
description = "valid luhn with an odd number of digits and non zero first digit"

[39a06a5a-5bad-4e0f-b215-b042d46209b1]
description = "using ascii value for non-doubled non-digit isn't allowed"

Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/luhn/src/luhn.app.src
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%% -*- erlang -*-
{application, 'luhn',
[{description, ""},
[{description, "Given a number determine whether or not it is valid per the Luhn formula."},
{vsn, "0.0.1"},
{modules,
['luhn']},
Expand Down
5 changes: 5 additions & 0 deletions exercises/practice/luhn/src/luhn.lfe
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(defmodule luhn
(export (valid? 1))
)

; Please implement the `valid?` function.
72 changes: 63 additions & 9 deletions exercises/practice/luhn/test/luhn-tests.lfe
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,68 @@

(include-lib "ltest/include/ltest-macros.lfe")

(deftest invalid
(is-not (luhn:valid? "1111"))
(is-not (luhn:valid? "738")))
(deftest single-digit-strings-can-not-be-valid
(is-not (luhn:valid? "1")))

(deftest valid
(is (luhn:valid? "8739567"))
(is (luhn:valid? "8763"))
(is (luhn:valid? "2323 2005 7766 3554")))
(deftest a-single-zero-is-invalid
(is-not (luhn:valid? "0")))

(deftest create
(is-equal "2323 2005 7766 3554" (luhn:create "2323 2005 7766 355")))
(deftest a-simple-valid-SIN-that-remains-valid-reversed
(is (luhn:valid? "059")))

(deftest a-simple-valid-SIN-that-becomes-invalid-if-reversed
(is (luhn:valid? "59")))

(deftest a-valid-Canadian-SIN
(is (luhn:valid? "055 444 285")))

(deftest invalid-Canadian-SIN
(is-not (luhn:valid? "055 444 286")))

(deftest invalid-credit-card
(is-not (luhn:valid? "8273 1232 7352 0569")))

(deftest invalid-long-number-with-an-even-remainder
(is-not (luhn:valid? "1 2345 6789 1234 5678 9012")))

(deftest invalid-long-with-a-remainder-divisible-by-5
(is-not (luhn:valid? "1 2345 6789 1234 5678 9013")))

(deftest valid-number-with-an-even-number-of-digits
(is (luhn:valid? "095 245 88")))

(deftest valid-number-with-an-odd-number-of-spaces
(is (luhn:valid? "234 567 891 234")))

(deftest valid-strings-with-a-non-digit-added-at-the-end-become-invalid
(is-not (luhn:valid? "059a")))

(deftest valid-strings-with-punctuation-included-become-invalid
(is-not (luhn:valid? "055-444-285")))

(deftest valid-strings-with-symbols-included-become-invalid
(is-not (luhn:valid? "055# 444$ 285")))

(deftest single-zero-with-space-is-invalid
(is-not (luhn:valid? " 0")))

(deftest more-than-a-single-zero-is-valid
(is (luhn:valid? "0000 0")))

(deftest input-digit-9-is-correctly-converted-to-output-digit-9
(is (luhn:valid? "091")))

(deftest very-long-input-is-valid
(is (luhn:valid? "9999999999 9999999999 9999999999 9999999999")))

(deftest valid-luhn-with-an-odd-number-of-digits-and-non-zero-first-digit
(is (luhn:valid? "109")))

(deftest using-ascii-value-for-non-doubled-non-digit-isnt-allowed
(is-not (luhn:valid? "055b 444 285")))

(deftest using-ascii-value-for-doubled-non-digit-isnt-allowed
(is-not (luhn:valid? ":9")))

(deftest non-numeric-non-space-char-in-the-middle-with-a-sum-thats-divisible-by-10-isnt-allowed
(is-not (luhn:valid? "59%59")))
Loading