Skip to main content
3 of 5
clarification
asgallant
  • 309
  • 1
  • 5

Javascript (ES6), 83 bytes

Takes an integer as an input, outputs an array [a, b, c] containing a sorted list of triangle numbers a + b + c = x, where a is the largest triangle number less than or equal to the input, and b is the largest triangle number less than or equal to the input minus a.

x=>(y=a=>a++*a/2,z=b=>y(~~(Math.sqrt(2*b+.25)-.5)),n=z(x),x-=n,m=z(x),x-=m,[n,m,x])

Explanation

x=>(                                   // use arrow function syntax
    y=a=>a++*a/2,                      // calculate the a'th triangle number
    z=b=>y(~~(Math.sqrt(2*b+.25)-.5)), // calculate the largest triangle number < b
    n=z(x),                            // get the largest triangle number < x
    x-=n,                              // decrement x by n
    m=z(x),                            // get the largest triangle number < x
    x-=m,                              // decrement x by m, whatever is left over in x is a triangle number
    [n,m,x]                            // return an array of the 3 triangle numbers [n, m, x - n - m], via the comma operator (evaluates LtR, returns the last value)
)

How the math works

The nth triangle number is given by the formula n*(n+1)/2 (calculated here in the function a=>a++*a/2). In order to find the largest triangle number less than x, solve the inequality n*(n+1)/2 < x for the largest n, given by the floor of the quadratic solution for the largest root:

⌊(-b + √(b^2 - 4*a*c))/(2*a)⌋

plugging in a, b, and c from n*(n+1)/2 < x gives

⌊-0.5 + √(0.25 + 2x)⌋

which is solved for by

b=>y(~~(Math.sqrt(2*b+.25)-.5))

b=>
    y(                                   // get the triangle number at the index given by the input
        ~~(                              // ~ is bitwise negate, which converts from float to int before negating (via something like Math.trunc)
                                         // ~~ double bitwise negate is equivalent to Math.floor for positive numbers
            Math.sqrt(2*b + 0.25) - 0.5  // get the positive solution to the quadratic
        )
    )

const F = x=>(y=a=>a++*a/2,z=b=>y(~~(Math.sqrt(2*b+.25)-.5)),n=z(x),x-=n,m=z(x),x-=m,[n,m,x]);

$('#output').hide();
$('#run').click(() => {
  const x = parseInt($('#input').val(), 10);
  if (x >= 0) {
    $('#input').val(x);
    const values = F(x);
    $('#values').text(values.join(', '));
    $('#output').show();
  }
  else {
    $('#output').hide();
    alert('You must enter a positive integer');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Enter a value: <input type="text" id="input" />
<br />
<button id="run">Get triangle numbers</button>
<br />
<span id="output">Triangle numbers are: <span id="values"></span></span>

asgallant
  • 309
  • 1
  • 5