Skip to content

Commit

Permalink
Sync luhn (#780)
Browse files Browse the repository at this point in the history
  • Loading branch information
fejan-malek authored Aug 24, 2024
1 parent ee323bc commit 5b24db2
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 96 deletions.
31 changes: 15 additions & 16 deletions exercises/practice/luhn/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,31 @@

Given a number determine whether or not it is valid per the Luhn formula.

The [Luhn algorithm](https://en.wikipedia.org/wiki/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 [Luhn algorithm][luhn] 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
------
## 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.
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
### Example 1: valid credit card number

```text
4539 3195 0343 6467
```

The first step of the Luhn algorithm is to double every second digit,
starting from the right. We will be doubling
The first step of the Luhn algorithm is to double every second digit, starting from the right.
We will be doubling

```text
4_3_ 3_9_ 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:
If doubling the number results in a number greater than 9 then subtract 9 from the product.
The results of our doubling:

```text
8569 6195 0383 3437
Expand All @@ -42,9 +38,10 @@ Then sum all of the digits:
8+5+6+9+6+1+9+5+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!
If the sum is evenly divisible by 10, then the number is valid.
This number is valid!

## Example 2: invalid credit card number
### Example 2: invalid credit card number

```text
8273 1232 7352 0569
Expand All @@ -63,3 +60,5 @@ Sum the digits
```

57 is not evenly divisible by 10, so this number is not valid.

[luhn]: https://en.wikipedia.org/wiki/Luhn_algorithm
50 changes: 16 additions & 34 deletions exercises/practice/luhn/.meta/example.php
Original file line number Diff line number Diff line change
@@ -1,50 +1,32 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

function isValid($candidate)
function isValid(string $candidate): bool
{
$sanitizedCandidate = str_replace(" ", "", $candidate) ;
$sanitizedCandidate = str_replace(" ", "", $candidate);

if (strlen($sanitizedCandidate) <= 1 || !ctype_digit($sanitizedCandidate)) {
return false ;
return false;
}

$reversseCandidate = strrev($sanitizedCandidate) ;
$sum = 0 ;
$reverseCandidate = strrev($sanitizedCandidate);
$sum = 0;

for ($i = 0; $i < strlen($reverseCandidate); $i++) {
$digit = intval($reverseCandidate[$i]);

for ($i = 1; $i < strlen($reversseCandidate); $i += 2) {
$digit = 2 * intval($reversseCandidate[$i]) ;
// Double every second digit starting from the second position
if ($i % 2 != 0) {
$digit *= 2;

if ($digit > 9) {
$digit -= 9 ;
if ($digit > 9) {
$digit -= 9;
}
}

$sum += $digit ;
$sum += intval($reversseCandidate[$i - 1]) ;
$sum += $digit;
}

return $sum % 10 == 0 ;
return $sum % 10 === 0;
}
25 changes: 22 additions & 3 deletions exercises/practice/luhn/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[792a7082-feb7-48c7-b88b-bbfec160865e]
description = "single digit strings can not be valid"
Expand All @@ -26,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 @@ -50,8 +60,17 @@ 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"

[f94cf191-a62f-4868-bc72-7253114aa157]
description = "using ascii value for doubled non-digit isn't allowed"

[8b72ad26-c8be-49a2-b99c-bcc3bf631b33]
description = "non-numeric, non-space char in the middle with a sum that's divisible by 10 isn't allowed"
Loading

0 comments on commit 5b24db2

Please sign in to comment.