Find the largest number of distinct integers that sum to n

18

1

The Task

Given an input positive integer n (from 1 to your language's limit, inclusively), return or output the maximum number of distinct positive integers that sum to n.

Test Cases

Let f define a valid function according to the task:

The sequence for f, starting at 1:

1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, ...

As a larger test case:

>>> f(1000000000) // Might not be feasible with brute-forcers
44720

Test Code

For any test cases not explicitly given, the output of your code should match the result of the following:

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        System.out.println((int) Math.floor(Math.sqrt(2*x + 1./4) - 1./2));
    }
}

Try it online!

Addison Crump

Posted 2018-01-04T23:24:39.640

Reputation: 10 763

Can it be 0-indexed? – totallyhuman – 2018-01-05T00:05:00.240

1@totallyhuman "it" being the answers? Because this isn't about a list... – Addison Crump – 2018-01-05T00:12:26.530

Yes. Can the output for 1 be 2? – totallyhuman – 2018-01-05T00:13:52.047

3@totallyhuman No. This is about the distinct partitions of specific numbers. – Addison Crump – 2018-01-05T00:14:39.247

5

This is OEIS A003056.

– Jeppe Stig Nielsen – 2018-01-05T10:33:05.957

If it helps anyone, this is equivalent to finding the last triangle number, and returning its index in the sequence of triangle numbers. – FlipTack – 2018-01-05T17:33:00.283

4I feel insignificant most every time I stumble into the codegolf stack. The answers and the comments are much more than humbling. The questions are usually interesting too but with his comment @JeppeStigNielsen just throws in the completed blueprints when we are still contemplating the floor area. – KalleMP – 2018-01-06T21:25:10.483

Answers

9

05AB1E, 4 bytes

ÅTg<

Try it online!

Perfect tool for the job.

ÅT yields the list of Åll Triangular numbers up to and including N (unfortunately includes 0 too, otherwise it would be 3 bytes), g< gets the length and decrements it.

Mr. Xcoder

Posted 2018-01-04T23:24:39.640

Reputation: 39 774

8

Jelly, 6 5 bytes

R+\»ċ

Try it online!

Somewhat efficient. This sequence increments at triangular numbers, so this just counts how many triangular numbers are smaller than n.

Explanation:

        # Main link
R       # Range, generate [1..n]
 +\     # Cumulative sum (returns the first n triangular numbers)
   »    # For each element, return the maximum of that element and 'n'
    ċ   # How many elements are 'n'? (implicit right argument is n)

James

Posted 2018-01-04T23:24:39.640

Reputation: 54 537

In the explanation, you surely mean "how many numbers are smaller than or equal to n" – Luis Mendo – 2018-01-05T00:10:04.950

@LuisMendo See the new explanation. – James – 2018-01-05T00:12:35.380

6

Haskell, 26 bytes

-2 bytes thanks to H.PWiz.

(!!)$do x<-[0..];x<$[0..x]

Try it online!

This returns the nth element of the whole numbers where each i is replicated i + 1 times.

totallyhuman

Posted 2018-01-04T23:24:39.640

Reputation: 15 378

3I can't help but ask what "succ" is – Addison Crump – 2018-01-05T00:13:13.550

Yeah, I know lol. succ stands for successor. – totallyhuman – 2018-01-05T00:14:27.903

5

Brain-Flak, 36 bytes

<>(())({()<(({}())){<>({}[()])}>{}})

Try it online!

This uses the same structure as the standard division algorithm, except that the "divisor" is incremented every time it is read.

Nitrodon

Posted 2018-01-04T23:24:39.640

Reputation: 9 181

4

Pari/GP, 19 bytes

n->((8*n+1)^.5-1)\2

Try it online!

alephalpha

Posted 2018-01-04T23:24:39.640

Reputation: 23 988

3

Jelly, 7 bytes

×8‘½’:2

Try it online!

Jelly, 9 bytes

Ḥ+4ݤ½_.Ḟ

Try it online!

This is longer than Dennis’ and DJ’s, but this time on purpose. Very, very efficient.

Mr. Xcoder

Posted 2018-01-04T23:24:39.640

Reputation: 39 774

1lol I love precision – totallyhuman – 2018-01-05T03:43:37.277

@totallyhuman Use M. – user202729 – 2018-01-05T10:36:07.647

3

Brain-Flak, 82 bytes

Whitespace added for "Readability"

(())

{
    {}

    ((({})[[]]))

    ([({}<(())>)](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}

}{}{}{}

([]<>)

Try it online!

James

Posted 2018-01-04T23:24:39.640

Reputation: 54 537

Competition as always – Post Rock Garf Hunter – 2018-01-05T18:40:21.203

1Who'd've thought that combining two unreadable languages, Whitespace and Brain-Flak, could be considered "readable"! – caird coinheringaahing – 2018-04-02T02:02:06.037

3

R, 28 bytes

function(n)rep(1:n,1:n+1)[n]

Try it online!

Creates the vector of 1 repeated 2 times, 2 repeated 3 times, ..., n repeated n+1 times and takes the nth element. This will memory error either because 1:n is too large or because the repeated list with n*(n+1)/2 - 1 elements is too large.

R, 29 bytes

function(n)((8*n+1)^.5-1)%/%2

Try it online!

Computes the value directly, using the formula found in alephalpha's answer. This should run with no issues, apart from possibly numerical precision.

R, 30 bytes

function(n)sum(cumsum(1:n)<=n)

Try it online!

Counts the triangular numbers less than or equal to n. This'll possibly memory error if 1:n is large enough -- for instance, at 1e9 it throws Error: cannot allocate vector of size 3.7 Gb.

Giuseppe

Posted 2018-01-04T23:24:39.640

Reputation: 21 077

2

Pyth, 7 bytes

lh{I#./

Try it online!

Filter-keep the integer partitions which are Invariant over deduplication, grab the head and obtain its length.

Validity proof

Not very rigorous nor well-worded.

Let A = a1 + a2 + ... + an and B = b1 + b2 + ... + bm be two distinct partitions of the same integer N. We will assume that A is the longest unique partition. After we deduplicate B, that is, replace multiple occurrences of the same integer with only one of them, we know that the sum of B is less than N. But we also know that the function result is increasing (non-strictly), so we can deduce that the longest unique partition A always has at least the same amount of elements as the count of unique items in other partitions.

Mr. Xcoder

Posted 2018-01-04T23:24:39.640

Reputation: 39 774

2

APL (Dyalog), 8 bytes

+/+\∘⍳<⊢

Try it online!

Uriel

Posted 2018-01-04T23:24:39.640

Reputation: 11 708

2

Japt, 8 bytes

Closed formula solution.

*8Ä ¬É z

Try it


Explanation

Multiply by 8, add 1 (Ä), get the square root (¬), subtract 1 (É) and floor divide the result by 2 (z).


Alternative, 8 bytes

Port of DJMcMayhem's Jelly solution.

õ å+ è§U

Try it

Generate an array of integers (õ) from 1 to input, cumulatively reduce (å) by addition (+) and count (è) the elements that are less than or equal to (§) the input (U).

Shaggy

Posted 2018-01-04T23:24:39.640

Reputation: 24 623

2

Befunge, 32 20 bytes

1+::1+*2/&#@0#.-`#1_

Try it online!

James Holderness

Posted 2018-01-04T23:24:39.640

Reputation: 8 298

2

TI-Basic, 12 bytes

int(√(2Ans+1/4)-.5

Timtech

Posted 2018-01-04T23:24:39.640

Reputation: 12 038

2

JavaScript (Node.js), 18 bytes

x=>(x-~x)**.5-.5|0

Try it online!

Unihedron

Posted 2018-01-04T23:24:39.640

Reputation: 1 115

Is this always correct? I'm not certain floor((sqrt(8x+4)-1)/2) (your formula) and floor((sqrt(8x+1)-1)/2) (correct formula) give the same result for every x. – ETHproductions – 2018-01-06T01:10:46.733

@ETHproductions I could bluff and say "yes", but I think the more honest answer is that you should try to develop your own hypothesis and figure out if / why it mirrors the same formula. I didn't come up with this approach by myself (I learned it from a different site) but I played around with it a bit. It's a very interesting approach and I don't want to dissect the frog so early. – Unihedron – 2018-01-06T13:32:01.780

Hmm. I'm not sure how to prove it directly, but I wrote a brute-forcer that does not find any failures under 100 million. – ETHproductions – 2018-01-07T02:24:26.703

2

Java (JDK), 28 bytes

n->~-(int)Math.sqrt(8*n+1)/2

Try it online!

Because the example was really not well golfed :p

Credits

Olivier Grégoire

Posted 2018-01-04T23:24:39.640

Reputation: 10 647

128 bytes "Because your code was really not well golfed" ;p – Kevin Cruijssen – 2019-05-24T06:50:41.483

@KevinCruijssen Well, now it is! :o – Olivier Grégoire – 2019-05-24T07:29:12.010

2

Brain-Flak, 70 56 48 bytes

{([(({}[({}())()])[()])]<>){<>({}())}{}<>{}}<>{}

Try it online!

Explanation

The main part of this is the following snippet that I've written:

([(({})[()])]<>){<>({}())}{}<>{}

This will do nothing if the TOS is positive and will switch stacks otherwise. It is super stack unclean but it works. Now the main part of the program subtracts increasingly large numbers from the input until the input is non-positive. We start the accumulator at 1 each time subtracting 1 more than the accumulator from the input.

({}[({}())()])

We can put that inside the snippet above

([(({}[({}())()])[()])]<>){<>({}())}{}<>{}

That is put in a loop so it executes until we switch stacks. Once the loop finishes we retrieve the accumulator by switching stacks and removing the junk.

Post Rock Garf Hunter

Posted 2018-01-04T23:24:39.640

Reputation: 55 382

1Some more competition – Nitrodon – 2018-01-06T00:57:53.123

2

Triangularity, 49 bytes

....)....
...2)2...
..)1/)8..
.)1/)IE/.
@^)1_+/i.

Try it online!

How it works

Triangularity requires the code to have a triangular distribution of the dots. That is, the length of each row must be equal the number of rows multiplied by 2 and decremented, and each row must have (on each side) a number of dots equal to its position in the program (the bottom row is row 0, the one above it is row 1 and so forth). There are only a couple of commands, and any character other than those listed on the 'Wiki / Commands' page is treated as a no-op (extraneous dots don't make affect the program in any way, as long as the overall shape of the program stays rectangular).

Note that for two-argument commands, I've used a and b throughout the explanation. Keeping that in mind, let's see what the actual program does, after removing all the extraneous characters that make up for the padding:

)2)2)1/)8)1/)IE/@^)1_+/i | Input from STDIN and output to STDOUT.

)                        | Push a 0 onto the stack. Must precede integer literals.
 2                       | Push ToS * 10 + 2 (the literal 2, basically).
  )2                     | Again, push a 2 onto the stack. This can be replaced by D
                         | (duplicate), but then the padding would discard the saving.
    )1                   | Literal 1.
      /                  | Division. Push b / a (1 / 2).
       )8)1              | The literal 8 and the literal 1 (lots of these!).
           /             | Division. Push b / a (1 / 8).
            )IE          | Get the 0th input from STDIN and evaluate it.
               /         | Divide it by 1 / 8 (multiply by 8, but there isn't any
                         | operand for multiplication, and I'm not willing to add one).
                @        | Add 1 to the result.
                 ^       | Exponentiation. Here, it serves as a square too.
                  )1_+   | Decrement (add literal -1).
                      /  | Divide (by 2).
                       i | Cast to an integer.

An alternate solution, and shorter if padding would not be necessary:

....)....
...2)1...
../DD)I..
.E/)4)1/.
+^s_+i...

Try it online!

Mr. Xcoder

Posted 2018-01-04T23:24:39.640

Reputation: 39 774

2

PowerShell 3.0, 45 bytes

[math]::Sqrt(2*$args[0]+.25)-.5-replace'\..*'

The math call hurt and PS's banker's rounding is the actual devil (hence needing regex to truncate to save a byte) but this seems pretty alright.

Veskah

Posted 2018-01-04T23:24:39.640

Reputation: 3 580

1

Jelly, 7 bytes

ŒPfŒṗṪL

Runs roughly in O(2n) time.

Try it online!

How it works

ŒPfŒṗṪL  Main link. Argument: n

ŒP       Powerset; yield all subarrays of [1, ..., n], sorted by length.
   Œṗ    Yield all integer partitions of n.
  f      Filter; keep subarrays that are partitions.
     Ṫ   Tail; extract the last result.
      L  Compute its length.

Dennis

Posted 2018-01-04T23:24:39.640

Reputation: 196 637

1

JavaScript (ES7), 22 19 bytes

n=>(8*n+1)**.5-1>>1

-3 bytes thank to ETHproductions.


Try it

o.innerText=(f=
n=>(8*n+1)**.5-1>>1
)(i.value=1000000000);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


Explanation

Multiply the input by 8 and add 1, raise that to the power of .5, giving us the square root, subtract 1 and bitshift the result right by 1.

Shaggy

Posted 2018-01-04T23:24:39.640

Reputation: 24 623

Can you include an explanation? I haven't done Javascript in a while – FantaC – 2018-01-05T01:45:20.797

How bout n=>(8*n+1)**.5-1>>1 to save 3 bytes? (haven't tested) – ETHproductions – 2018-01-05T02:56:03.687

I outgolfed this in JS: https://codegolf.stackexchange.com/a/152558/21830

– Unihedron – 2018-01-05T05:28:04.340

@ETHproductions - looks like that works, thanks. – Shaggy – 2018-01-05T09:59:20.930

@tfbninja, I'd have thought t fairly self-explanatory but explanation added. – Shaggy – 2018-01-05T09:59:57.280

1

Haskell, 28 bytes

Kinda boring, but it's quite shorter than the other Haskell solution and has a really nice pointfree expression. Unfortunately I couldn't get it any shorter without the type system getting in the way:

g x=floor$sqrt(2*x+0.25)-0.5

Try it online!

Pointfree, 33 bytes

ceiling.(-0.5+).sqrt.(0.25+).(2*)

Alternatively, 33 bytes

Same length as the pointfree version, but much more interesting.

g n=sum[1|x<-scanl1(+)[1..n],n>x]

ბიმო

Posted 2018-01-04T23:24:39.640

Reputation: 15 345

I managed to tie the formula by fixing some dumb mistakes! – totallyhuman – 2018-01-05T03:08:44.513

@totallyhuman: Nice, now yours is much nicer too :) – ბიმო – 2018-01-05T15:34:13.147

1

Python 2/3, 32 bytes

Python implementation of the closed form formula

lambda n:int((sqrt(1+8*n)-1)//2)

The integer division //2 rounds towards zero, so no floor( ) required

Karl der Kaefer

Posted 2018-01-04T23:24:39.640

Reputation: 111

1

Welcome to PPCG! Does this need from math import sqrt to work? If so, it should be included in the bytecount. (In that case lambda n:int((math.sqrt(1+8*n)-1)//2) import math is a little shorter.)

– Steadybox – 2018-01-05T11:15:22.727

29 bytes – FlipTack – 2018-01-05T17:27:08.543

Yes, it needs the import to work, so that should be included in the byte count. – mbomb007 – 2018-01-05T19:30:03.073

1

Milky Way, 12 bytes

'8*1+g1-2/v!

Explanation

code         explanation       value

'            push input        n          
 8*          push 8, multiply  8n
   1+        add 1             8n+1
     g       square root       sqrt(8n+1)
      1-     subtract 1        sqrt(8n+1)-1
        2/   divide by 2       (sqrt(8n+1)-1)/2
          v  floor             floor((sqrt(8n+1)-1)/2)
           ! output

ovs

Posted 2018-01-04T23:24:39.640

Reputation: 21 408

1

Pyt, 7 5 bytes

Đř△>Ʃ

Explanation:

                      Implicit input
Đř△                   Gets a list of the first N triangle numbers
   >                  Is N greater than each element in the list? (returns an array of True/False)
    Ʃ                 Sums the list (autoconverts booleans to ints)



Faster, but longer way

Pyt, 11 9 bytes

Đ2*√⌈ř△>Ʃ

Explanation:

Đ2*√⌈ř△           Gets a list of triangle numbers up to the ceiling(sqrt(2*N))-th
       >          Is N greater than each element of the list? (returns an array of True/False)
        Ʃ         Sums the array



Alternative way - port of Shaggy's answer

Pyt, 8 7 bytes

8*⁺√⁻2÷

mudkip201

Posted 2018-01-04T23:24:39.640

Reputation: 833

1

J, 11 bytes

2&!inv<.@-*

Try it online!

2&!inv       solve [x choose 2 = input]
         -*  minus 1
      <.     and floor

FrownyFrog

Posted 2018-01-04T23:24:39.640

Reputation: 3 112

I like that trick with * to produce 1 – Jonah – 2019-06-02T00:51:39.943

1

Whitespace, 111 bytes

[S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   T   _Read_integer_from_STDIN][T T   T   _Retrieve_input][S S S T    S S S N
_Push_8][T  S S N
_Multiply][S S S T  N
_Push_1][T  S S S _Add][S S T   T   N
_Push_n=-1][N
S S N
_Create_Label_SQRT_LOOP][S S S T    N
_Push_1][T  S S S _Add][S N
S _Duplicate_n][S N
S _Duplicate_n][T   S S N
Multiply][S T   S S T   S N
_Copy_0-based_2nd_(the_input)][S S S T  N
_Push_1][T  S S S _Add][T   S S T   _Subtract][N
T   T   N
_If_negative_jump_to_Label_SQRT_LOOP][S S S T   S N
_Push_2][T  S S T   _Subtract][S S S T  S N
_Push_2][T  S T S _Integer_divide][T    N
S T _Print_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs, and new-lines only).

Explanation in pseudo-code:

Uses the formula:

$$f_n = \left\lfloor\frac{\sqrt{8n + 1} - 1}{2}\right\rfloor$$

NOTE: Whitespace doesn't have a square-root builtin, so we have to do this manually.

Integer i = read STDIN as integer
i = i * 8 + 1
Integer n = -1
Start SQRT_LOOP:
  n = n + 1
  If(n*n < i+1):
    Go to next iteration of SQRT_LOOP
n = (n - 2) integer-divided by 2
Print n as integer to STDOUT

Kevin Cruijssen

Posted 2018-01-04T23:24:39.640

Reputation: 67 575

0

Vitsy, 16 bytes

2*14/+12/^12/-_N

Try it online!

Might as well add my own contribution to the mix. This is shorter than the partition iterations solution in Vitsy.

Addison Crump

Posted 2018-01-04T23:24:39.640

Reputation: 10 763

0

Oasis, 14 bytes

n8*1+1tm1%_b+0

Try it online!

How?

n8*1+           8n + 1
     1tm        sqrt
        1%_     integer?
           b+   add f(n-1)

             0  f(0) is 0

This is a recursive solution that increments the result when it encounters a triangular index, starting with 0 for the input 0.

Uriel

Posted 2018-01-04T23:24:39.640

Reputation: 11 708

0

Perl 5 -p, 19(++) bytes

$_=0|-.5+sqrt$_*2+1

Try it online!

Unihedron

Posted 2018-01-04T23:24:39.640

Reputation: 1 115

0

Ruby, 27 bytes

Three for the price of one. I am disappointed that I can't go shorter.

->n{a=0;n-=a+=1while n>a;a}
->n{((8*n+1)**0.5-1).div 2}
->n{((n-~n)**0.5-0.5).to_i}

Try it online! (to select the function, add f= in front of it)

Unihedron

Posted 2018-01-04T23:24:39.640

Reputation: 1 115

0

Pyke, 6 bytes

8*h,te

Try it here!

8      - Push literal 8.
 *     - Multiply by the input.
  h    - Increment.
   ,   - Square root.
    t  - Decrement.
     e - Floor halve.

Mr. Xcoder

Posted 2018-01-04T23:24:39.640

Reputation: 39 774

0

Swift, 41 bytes

import Foundation
{Int(sqrt($0*8+1)-1)/2}

Try it online!

Herman L

Posted 2018-01-04T23:24:39.640

Reputation: 3 611

0

Pushy, 8 bytes

8*hrt2/#

Try it online!

Uses the closed formula (sqrt(8n + 1) - 1) / 2:

8*          \ Multiply by 8
  h         \ Increment
   r        \ Integer root
    t       \ Decrement
     2/     \ Floordiv by 2
       #    \ Output

I thought I recognised this formula - it's the reverse of the function for a triangle number:

f(x) = (x + 1)(x / 2)
f-1(x) = (sqrt(8x+ 1) - 1) / 2

...which makes sense as we're counting integer sums.

FlipTack

Posted 2018-01-04T23:24:39.640

Reputation: 13 242

0

Add++, 12 bytes

L,ßR¬+A€<€!s

Try it online!

Because closed form solutions are boring

caird coinheringaahing

Posted 2018-01-04T23:24:39.640

Reputation: 13 702

0

Wolfram Language (Mathematica), 22 bytes

⌊√(1+8*#)/2-.5⌋&

Try it online!

nixpower

Posted 2018-01-04T23:24:39.640

Reputation: 71

0

c++,61

int f(int n){for(int i=1;;i){if(n<i) return i-1; else n-=i}}

jahly

Posted 2018-01-04T23:24:39.640

Reputation: 31

2Consider adding a short explanation of your code (see the other answers for examples). Code-only answers like this tend to get flagged automatically as low quality. – mbomb007 – 2019-05-23T20:08:51.970

0

Cubix, 16 bytes

.(@sI1-?s.O@s)W\

Try it online!

    . (
    @ s
I 1 - ? s . O @
s ) W \ . . . .
    . .
    . .

Watch it run

  • I1 set up the stack with n and 1 (incrementer)
  • -? subtract the incrementer from n and test result
    • if result 0 sO@, swap result with incrementer, output and halt
    • if result negative s(O, swap result with incrementer, decrement, output and via a few commands, halt
    • if result positive \s)W, redirect, swap result with incrementer, increment and redirect back into the subtract/test

MickyT

Posted 2018-01-04T23:24:39.640

Reputation: 11 735