diff --git a/spec/unit/utils.spec.ts b/spec/unit/utils.spec.ts index c03a29909..76123d1ca 100644 --- a/spec/unit/utils.spec.ts +++ b/spec/unit/utils.spec.ts @@ -325,9 +325,10 @@ describe("utils", function() { describe('averageBetweenStrings', () => { it('should average appropriately', () => { - logger.log(stringToBase(" ")); - logger.log(stringToBase("!!")); expect(averageBetweenStrings(" ", "!!")).toEqual(" P"); + expect(averageBetweenStrings(" ", "!")).toEqual(" "); + expect(averageBetweenStrings('A', 'B')).toEqual('A '); + expect(averageBetweenStrings('AA', 'BB')).toEqual('Aq'); expect(averageBetweenStrings('A', 'z')).toEqual(']'); expect(averageBetweenStrings('a', 'z', "abcdefghijklmnopqrstuvwxyz")).toEqual('m'); expect(averageBetweenStrings('AA', 'zz')).toEqual('^.'); diff --git a/src/utils.ts b/src/utils.ts index 60dec0999..d6b294719 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -568,8 +568,16 @@ export function stringToBase(s: string, alphabet = DEFAULT_ALPHABET): bigint { export function averageBetweenStrings(a: string, b: string, alphabet = DEFAULT_ALPHABET): string { const padN = Math.max(a.length, b.length); const baseA = stringToBase(alphabetPad(a, padN, alphabet), alphabet); - const baseB = stringToBase(alphabetPad(b, padN, alphabet), alphabet); - return baseToString((baseA + baseB) / BigInt(2), alphabet); + let baseB = stringToBase(alphabetPad(b, padN, alphabet), alphabet); + let avg = (baseA + baseB) / BigInt(2); + + // Detect integer division conflicts. This happens when two numbers are divided too close so + // we lose a .5 precision. We need to add a padding character in these cases. + if (avg === baseA || avg == baseB) { + return baseToString(avg, alphabet) + alphabet[0]; + } + + return baseToString(avg, alphabet); } /**