Skip to content

Commit 9d4abb0

Browse files
committed
Synchronize Luhn exercise with canonical specs
Canonical specs for Luhn exercise were changed, and tracks implementing that exercise should synchronize wih them. Closes #316
1 parent 9f90d05 commit 9d4abb0

2 files changed

Lines changed: 44 additions & 98 deletions

File tree

exercises/luhn/example.js

Lines changed: 28 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,34 @@
11
'use strict';
22

3-
function Luhn(number) {
4-
this.checkDigit = number % 10;
5-
this.addends = this.calculateAddends(number);
6-
this.checksum = this.calculateChecksum(this.addends);
7-
this.valid = this.determineIfValid(this.checksum);
8-
}
9-
10-
Luhn.prototype = {
11-
calculateAddends: function(number) {
12-
13-
var numberAsString = '' + number + '';
14-
var numbers = numberAsString.split('');
15-
var addends = [];
16-
17-
for (var i = 0; i < numbers.length; i++) {
18-
var index = numbers.length - 1 - i;
19-
20-
var currentAddend = parseInt(numbers[index], 10);
21-
22-
if ((i + 1) % 2 === 0) {
23-
currentAddend = currentAddend * 2;
24-
if (currentAddend > 10) {
25-
currentAddend = currentAddend - 9;
26-
}
3+
function isValid(number) {
4+
number = number.replace(/\s/g, '');
5+
const digits = [...number];
6+
7+
const sum = digits
8+
// convert to integers
9+
.map(d => parseInt(d, 10))
10+
// double even positions (odd indexes)
11+
.map((d, i) => {
12+
if (i % 2 !== 0) {
13+
return d * 2;
2714
}
15+
return d;
16+
})
17+
// limit to digits less than 10
18+
.map(d => {
19+
if (d > 9) {
20+
return d - 9;
21+
}
22+
return d;
23+
})
24+
// sum all digits
25+
.reduce((d, acc) => d + acc, 0);
2826

29-
addends.push(currentAddend);
30-
}
31-
32-
return addends.reverse();
33-
34-
},
35-
calculateChecksum: function(numbers) {
36-
var sum = 0;
37-
for (var i = 0; i < numbers.length; i++) {
38-
sum += numbers[i];
39-
}
40-
41-
return sum;
42-
},
43-
determineIfValid: function(sum) {
44-
return (sum % 10 === 0);
45-
}
46-
};
47-
48-
Luhn.create = function(number) {
49-
var finalNumber = number * 10;
50-
var luhnNumber = new Luhn(finalNumber);
51-
var index = 0;
52-
53-
while(!luhnNumber.valid) {
54-
finalNumber = number * 10 + index;
55-
luhnNumber = new Luhn(finalNumber);
56-
if (luhnNumber.valid) { break; }
57-
index += 1;
58-
}
27+
return sum > 0 && sum % 10 === 0;
28+
}
5929

60-
return finalNumber;
61-
};
30+
function Luhn(number) {
31+
this.valid = isValid(number);
32+
}
6233

63-
module.exports = Luhn;
34+
module.exports = Luhn;

exercises/luhn/luhn.spec.js

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,34 @@ var Luhn = require('./luhn');
22

33
describe('Luhn',function() {
44

5-
it('check digit',function() {
6-
var luhn = new Luhn(34567);
7-
expect(luhn.checkDigit).toEqual(7);
8-
});
9-
10-
xit('check digit again',function() {
11-
var luhn = new Luhn(91370);
12-
expect(luhn.checkDigit).toEqual(0);
13-
});
14-
15-
xit('addends',function() {
16-
var luhn = new Luhn(12121);
17-
expect(luhn.addends).toEqual([1, 4, 1, 4, 1]);
18-
});
19-
20-
xit('too large addend',function() {
21-
var luhn = new Luhn(8631);
22-
expect(luhn.addends).toEqual([7, 6, 6, 1]);
23-
});
24-
25-
xit('checksum',function() {
26-
var luhn = new Luhn(4913);
27-
expect(luhn.checksum).toEqual(22);
28-
});
29-
30-
xit('checksum again',function() {
31-
var luhn = new Luhn(201773);
32-
expect(luhn.checksum).toEqual(21);
5+
it('single digit strings can not be valid', function () {
6+
const luhn = new Luhn('1');
7+
expect(luhn.valid).toEqual(false);
338
});
349

35-
xit('invalid number',function() {
36-
var luhn = new Luhn(738);
10+
xit('A single zero is invalid', function () {
11+
const luhn = new Luhn('0');
3712
expect(luhn.valid).toEqual(false);
3813
});
3914

40-
xit('invalid number',function() {
41-
var luhn = new Luhn(8739567);
15+
xit('valid Canadian SIN', function () {
16+
const luhn = new Luhn('046 454 286');
4217
expect(luhn.valid).toEqual(true);
4318
});
4419

45-
xit('create valid number',function() {
46-
var number = Luhn.create(123);
47-
expect(number).toEqual(1230);
20+
xit('invalid Canadian SIN', function () {
21+
const luhn = new Luhn('046 454 287');
22+
expect(luhn.valid).toEqual(false);
4823
});
4924

50-
xit('create other valid number',function() {
51-
var number = Luhn.create(873956);
52-
expect(number).toEqual(8739567);
25+
xit('invalid credit card', function () {
26+
const luhn = new Luhn('8273 1232 7352 0569');
27+
expect(luhn.valid).toEqual(false);
5328
});
5429

55-
xit('create yet another valid number',function() {
56-
var number = Luhn.create(837263756);
57-
expect(number).toEqual(8372637564);
30+
xit('valid strings with a non-digit added become invalid', function () {
31+
const luhn = new Luhn('046a 454 286');
32+
expect(luhn.valid).toEqual(false);
5833
});
5934

6035
});

0 commit comments

Comments
 (0)