diff --git a/exercises/luhn/example.js b/exercises/luhn/example.js index 5c95369521..472e63a3f1 100644 --- a/exercises/luhn/example.js +++ b/exercises/luhn/example.js @@ -1,57 +1,34 @@ -export default class Luhn { - - constructor(number) { - this.checkDigit = number % 10; - this.addends = Luhn.calculateAddends(number); - this.checksum = Luhn.calculateChecksum(this.addends); - this.valid = Luhn.determineIfValid(this.checksum); - } - - static calculateAddends(number) { - const numberAsString = '' + number + '', - numbers = [...numberAsString], - addends = []; - - for (let i = 0; i < numbers.length; i++) { - const index = numbers.length - 1 - i; - let currentAddend = parseInt(numbers[index], 10); - - if ((i + 1) % 2 === 0) { - currentAddend = currentAddend * 2; - if (currentAddend > 10) { - currentAddend = currentAddend - 9; - } +function isValid(number) { + number = number.replace(/\s/g, ''); + const digits = [...number]; + + const sum = digits + // convert to integers + .map(d => parseInt(d, 10)) + // double even positions (odd indexes) + .map((d, i) => { + if (i % 2 !== 0) { + return d * 2; } - addends.push(currentAddend); - } - return addends.reverse(); - } - - static calculateChecksum(numbers) { - let sum = 0; - for (let i = 0; i < numbers.length; i++) { - sum += numbers[i]; - } - return sum; - } + return d; + }) + // limit to digits less than 10 + .map(d => { + if (d > 9) { + return d - 9; + } + return d; + }) + // sum all digits + .reduce((d, acc) => d + acc, 0); - static determineIfValid(sum) { - return sum % 10 === 0; - } + return sum > 0 && sum % 10 === 0; +} - static create(number) { - let finalNumber = number * 10, - luhnNumber = new Luhn(finalNumber), - index = 0; +export default class Luhn { - while (!luhnNumber.valid) { - finalNumber = number * 10 + index; - luhnNumber = new Luhn(finalNumber); - if (luhnNumber.valid) { - break; - } - index += 1; - } - return finalNumber; + constructor(number) { + this.valid = isValid(number); } + } diff --git a/exercises/luhn/luhn.spec.js b/exercises/luhn/luhn.spec.js index 148dc2ae03..6e6bf6bc09 100644 --- a/exercises/luhn/luhn.spec.js +++ b/exercises/luhn/luhn.spec.js @@ -2,59 +2,34 @@ import Luhn from './luhn'; describe('Luhn',() => { - it('check digit',() => { - const luhn = new Luhn(34567); - expect(luhn.checkDigit).toEqual(7); - }); - - xit('check digit again',() => { - const luhn = new Luhn(91370); - expect(luhn.checkDigit).toEqual(0); - }); - - xit('addends',() => { - const luhn = new Luhn(12121); - expect(luhn.addends).toEqual([1, 4, 1, 4, 1]); - }); - - xit('too large added',() => { - const luhn = new Luhn(8631); - expect(luhn.addends).toEqual([7, 6, 6, 1]); - }); - - xit('checksum',() => { - const luhn = new Luhn(4913); - expect(luhn.checksum).toEqual(22); - }); - - xit('checksum again',() => { - const luhn = new Luhn(201773); - expect(luhn.checksum).toEqual(21); + it('single digit strings can not be valid', () => { + const luhn = new Luhn('1'); + expect(luhn.valid).toEqual(false); }); - xit('invalid number',() => { - const luhn = new Luhn(738); + xit('A single zero is invalid', () => { + const luhn = new Luhn('0'); expect(luhn.valid).toEqual(false); }); - xit('invalid number',() => { - const luhn = new Luhn(8739567); + xit('valid Canadian SIN', () => { + const luhn = new Luhn('046 454 286'); expect(luhn.valid).toEqual(true); }); - xit('create valid number',() => { - const number = Luhn.create(123); - expect(number).toEqual(1230); + xit('invalid Canadian SIN', () => { + const luhn = new Luhn('046 454 287'); + expect(luhn.valid).toEqual(false); }); - xit('create other valid number',() => { - const number = Luhn.create(873956); - expect(number).toEqual(8739567); + xit('invalid credit card', () => { + const luhn = new Luhn('8273 1232 7352 0569'); + expect(luhn.valid).toEqual(false); }); - xit('create yet another valid number',() => { - const number = Luhn.create(837263756); - expect(number).toEqual(8372637564); + xit('valid strings with a non-digit added become invalid', () => { + const luhn = new Luhn('046a 454 286'); + expect(luhn.valid).toEqual(false); }); });