2018-3-20

Sum large numbers with Kotlin versus Javascript

Solution to the 13th Project Euler problem – Large sum - in both Kotlin and Javascript.

The 13th Project Euler problem - Large sum - is stated as follows. Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.

37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
[...]
53503534226472524250874054075591789781264330331690

This problem is trivial in Kotlin due to the built-in class BigInteger which lets you do arithmetic on arbitrary big integers.

import java.math.BigInteger

fun main(args: Array<String>) {

    var numbers = """
    37107287533902102798797998220837590246510135740250
    53503534226472524250874054075591789781264330331690
        """

    var numbersAsArray = numbers.split("\n")    
        .filter { !it.isBlank() }
        .map { it.trim() }
        .map { BigInteger(it) }
        .fold(BigInteger("0"), { sum, n -> sum.add(n) })


    println(numbersAsArray);

}

This problem is less trivial in languages where you don't have support for 1arge enough integers, e.g., Javascript. In those languages, you have to implement your own add-function.

const numbers = `
    37107287533902102798797998220837590246510135740250
    53503534226472524250874054075591789781264330331690`;


function addIntegerArrays(a = [], b = [], memo = '', carry = 0) {

    if (a.length + b.length + carry === 0) {
        return memo
    }

    // Get current number from the end of both
    const currentNumberA = a[a.length - 1] || 0;
    const currentNumberB = b[b.length - 1] || 0;

    // Sum the carry and the last digits or default to 0
    const sum = carry + currentNumberA + currentNumberB;

    const nextNumber = sum % 10;
    const nextCarry = sum > 9 ? 1 : 0;
    const nextA = a.slice(0, a.length - 1);
    const nextB = b.slice(0, b.length - 1);

    const result = `${nextNumber}${memo}`;

    return addIntegerArrays(nextA, nextB, result, nextCarry);

}

function addStrings(a, b) {
    // Convert strings to arrays.
    const preparedA = a.split('')
        .map(v => parseInt(v, 10));

    const preparedB = b.split('')
        .map(v => parseInt(v, 10));

    return addIntegerArrays(preparedA, preparedB);
}


const res = numbers.split('\n')
    .map(v => v.trim())
    .filter(v => /^[0-9]+/.test(v))
    .reduce((mem, n) => addStrings(mem, n), '0');
Jan Järfalk — User experienced esthete, technician, geek and web worker. Aspiring artist and recreational mathematician. I indulge and travel plenty. Constraints are good.