Last active
November 26, 2021 00:44
-
-
Save sheodox/c652a6d68d9c41bcb6f569ad25e1c576 to your computer and use it in GitHub Desktop.
An incrementable integer with infinite digits stored as an array of single digit integers because why not
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import assert from 'assert'; | |
class Digit { | |
// a number 0-9 | |
value: number; | |
constructor(value: number) { | |
if (value > 9 || value < 0) { | |
throw new Error(`Digit value must be between 0 and 9, got ${value}`); | |
} | |
if (Math.round(value) !== value) { | |
throw new Error(`Digits must be integers, got ${value}`); | |
} | |
this.value = value; | |
} | |
inc() { | |
if (this.value === 9) { | |
this.value = 0; | |
return true; | |
} | |
this.value++; | |
return false; | |
} | |
toString() { | |
return '' + this.value; | |
} | |
} | |
class InfiniteNumber { | |
digits: Digit[] = []; | |
constructor(number: string = '0') { | |
this.set(number); | |
} | |
set(number: string){ | |
if (typeof number !== 'string' || !/^\d+$/.test(number)) { | |
throw new Error(`InfiniteNumber must be initialized with an integer as a string, got ${number}`); | |
} | |
const initialDigits = number.split(''); | |
this.digits = initialDigits.map(digit => { | |
return new Digit(+digit); | |
}); | |
} | |
inc(by = 1) { | |
for (let i = 0; i < by; i++) { | |
let carryTheDigit = true, | |
processingDigitIndex = this.digits.length - 1; | |
while (carryTheDigit) { | |
if (processingDigitIndex < 0) { | |
this.digits.unshift(new Digit(1)); | |
break; | |
} | |
carryTheDigit = this.digits[processingDigitIndex].inc(); | |
processingDigitIndex--; | |
} | |
} | |
} | |
toString() { | |
return this.digits.map(digit => digit.toString()).join(''); | |
} | |
} | |
const test = new InfiniteNumber(); | |
test.inc(35); | |
assert.equal(test.toString(), '35', 'numbers must increment by a specific amount correctly'); | |
test.set('4'); | |
assert.equal(test.toString(), '4', 'numbers can be set arbitrarily'); | |
test.set('3839'); | |
assert.equal(test.toString(), '3839', 'numbers can be set arbitrarily'); | |
test.set('9999'); | |
test.inc() | |
assert.equal(test.toString(), '10000', 'multiple digits can be carried at once'); | |
const test2 = new InfiniteNumber('523'); | |
assert.equal(test2.toString(), '523', 'numbers should be initialized correctly'); | |
const test3 = new InfiniteNumber(); | |
for (let i = 0; i < 24; i++) { | |
test3.inc(); | |
} | |
assert.equal(test3.toString(), '24', 'individual increments should work'); | |
assert.throws( | |
() => { new Digit(-1) }, | |
{ message: /Digit value must be between 0 and 9/ }); | |
assert.throws( | |
() => { new Digit(10) }, | |
{ message: /Digit value must be between 0 and 9/ } | |
); | |
assert.throws( | |
() => { new InfiniteNumber('test') }, | |
{ message: /InfiniteNumber must be initialized with an integer as a string/ } | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment