Smallest positive integer not yet appeared so that the sum of the first n elements is divisible by n

5

Task

Given positive integer n, output a(n) where a is the sequence defined below:

a(n) is the smallest positive integer not yet appeared so that the sum of the first n elements in the sequence is divisible by n.

Example

  • a(1) is 1 because it is the smallest positive integer that has not appeared in the sequence, and 1 is divisible by 1.
  • a(10) is 16 because look at the first nine elements: 1,3,2,6,8,4,11,5,14. They sum up to 54, so for the first ten elements to sum up to a multiple of 10, a(10) would need to have a remainder of 6 when divided by 10. 6 has already appeared, so a(10) is 16 instead.

Testcases

n     a(n)
1     1
2     3
3     2
4     6
5     8
6     4
7     11
8     5
9     14
10    16
11    7
12    19
13    21
14    9
15    24
16    10
17    27
18    29
19    12
20    32
100   62
1000  1618
10000 16180

References

Leaky Nun

Posted 2016-08-18T01:26:59.340

Reputation: 45 011

What values of n and a(n) must we support? – Rohan Jhunjhunwala – 2016-08-18T01:42:02.150

@RohanJhunjhunwala Theoretically every positive number. – Leaky Nun – 2016-08-18T01:44:31.887

so bignum mandatory? – Rohan Jhunjhunwala – 2016-08-18T01:47:20.170

@RohanJhunjhunwala I said theoretically, meaning it is not mandatory. – Leaky Nun – 2016-08-18T01:47:37.463

so less than 2^31 -1 is ok? – Rohan Jhunjhunwala – 2016-08-18T01:49:28.623

I only ask so I can use int in Java (and S.I.L.O.S) – Rohan Jhunjhunwala – 2016-08-18T01:49:46.800

@RohanJhunjhunwala Yes. – Leaky Nun – 2016-08-18T01:50:51.980

Strangely related. – xnor – 2016-08-18T04:07:34.383

Answers

12

Python 2, 43 bytes

r=.5+5**.5/2
lambda n:[n/r+1,n*r][n%r<1]//1

Outputs floats. Uses the relation

a(n) = A002251(n-1) + 1

to Wythoff pairs. Takes from the upper or lower Beatty sequence by multiplying or dividing by the golden ratio and converting to an integer.

xnor

Posted 2016-08-18T01:26:59.340

Reputation: 115 687

I think the precision is fine up to 2**32. – xnor – 2016-08-18T04:27:54.180

Then it does not work outside the boundary. – Leaky Nun – 2016-08-18T04:28:29.543

@LeakyNun I thought you said up to 2^31 -1 is ok? – xnor – 2016-08-18T04:30:36.803

What does it return for 2^31-1? – Leaky Nun – 2016-08-18T04:34:36.200

@LeakyNun It gives 6949403065.0. – xnor – 2016-08-18T13:35:36.980

My arbitrary precision version gives 3474701531. – Leaky Nun – 2016-08-18T16:09:43.810

Can you try 2^31-2? – Leaky Nun – 2016-08-18T16:09:48.663

@LeakyNun Oops, I ran the wrong value. 2^31-1 gives 3474701531.0 and 2**31-2 gives 3474701529.0. Here are 10 nearby values if you want to compare.

– xnor – 2016-08-19T02:03:28.517

3

Python 3, 102 bytes

Definitely not the shortest solution (not familiar with code golf) but I was bored so here it is in Python. I'm sure you could make it smaller with lambdas/filter.

def a(n,s=[]):
    for j in range(1,n+1):
        i=1
        while i in s or(sum(s)+i)%j:i+=1
        s+=[i]
    return s[-1]

gowrath

Posted 2016-08-18T01:26:59.340

Reputation: 885

Use a while loop for the second nested loop. Your solution currently does not theoretically support higher integers. – Leaky Nun – 2016-08-18T02:38:06.157

Rather than using 4 spaces, you can use a tab or one space. – Leaky Nun – 2016-08-18T02:48:29.563

You can also use space for the first level and then tab for the second level. – Leaky Nun – 2016-08-18T02:48:41.673

Make sure to include your byte count. – Leaky Nun – 2016-08-18T02:48:48.940

You ca put the opposite of the if condition as the while condition, and then append the item to the array outside the while loop. – Leaky Nun – 2016-08-18T03:01:29.590

@LeakyNun Very true. Thanks for all the suggestions :) – gowrath – 2016-08-18T03:06:42.420

You can put i+=1 on the same line as the while condition – Leaky Nun – 2016-08-18T04:29:02.467

You can remove the whitespace after or – Leaky Nun – 2016-08-18T04:40:06.093

You can save a few bytes by defining s in your def; i.e. def a(n,s=[]): (saves 4 spaces and a newline, but adds one comma.) – Delioth – 2016-08-19T15:51:16.380

3

OCaml, 163 bytes

open List
let a x=let rec h m s=let rec n m s c=if fold_left(+)c(s)mod m<>0||mem c s then n m s(c+1)else c in if m=x then hd s else h(m+1)((n(m+1)s 2)::s) in h 1[1]

Online interpreter

Usage

>> open List
>> let a x=let rec h m s=let rec n m s c=if fold_left(+)c(s)mod m<>0||mem c s then n m s(c+1)else c in if m=x then hd s else h(m+1)((n(m+1)s 2)::s)in h 1[1];;
<< val a : int -> int = <fun>
>> a(100);;
<< int = 62

where >> is STDIN and << is STDOUT.

m-chrzan

Posted 2016-08-18T01:26:59.340

Reputation: 1 390

Can you remove the whitespace after the last in? – Leaky Nun – 2016-08-18T06:28:43.083

I'm guessing you meant before? Thanks for editing in the demo! – m-chrzan – 2016-08-18T06:38:28.723

Yes, I meant before – Leaky Nun – 2016-08-18T06:39:33.257

2

Pyth - 23 21 18 bytes

Can probably streamline the generation process with more lambdas or other tricks, but this is my first answer in more than a month.

eem=+Yf!|}TY%+TsYh

Try it online here.

Maltysen

Posted 2016-08-18T01:26:59.340

Reputation: 25 023

1

R, 99 bytes

f=function(n){a=n
b=c()
while(0<(a=a-1))b=c(f(a),b)
while(a<-a+1)if(!(sum(b)+a)%%n&!a%in%b)break
a}

Simple algorithm. Runs from n-1 to 1 and gathers all of those numbers in the sequence. Then it moves up from 1 -- checking membership and whether it divides appropriately.

user5957401

Posted 2016-08-18T01:26:59.340

Reputation: 699

1

Actually, 17 bytes

This uses xnor's algorithm. Golfing suggestions welcome. Try it online!

,;;φ(/u(φ*1φ(%<I≈

Here's a 31-byte version that uses the function definition, but with the oddity that, at first, the function returns the sequence a(n)-1, so the result needs to be incremented at the end. Try it online!

[]╗,`1";#╜+;l@Σ%@╜í+uY"£╓╖`n╜Nu

Ungolfing:

First algorithm

,;;                 Take the input, duplicate it twice
          1φ(%<I    If input mod phi less than 1
       (φ*          then input * phi
   φ(/u             else input / phi + 1
                ≈   int() the result

Second algorithm

[]╗    Push a list to register 0 (call this res from now on)
,      Take input
`1     Start function, push 1
  "      Start string
  ;      Duplicate i 
  #╜+;   res + list(i), duplicate
  l      len(new list)
  @Σ     sum(new list)
  %      sum % len
  @╜í    Rotate i to top, check if i in res
  +uY    (sum%len) + (i in res) + 1, negate (1 if i fits conditions, else 0)
  "£     End string, turn into a function
╓      Push first (1) values where f(x) is truthy, starting with f(0)
╖`     Append result to the list in register 0, end function
n      Run function (input) times
╜Nu    Return res[-1]+1

Sherlock9

Posted 2016-08-18T01:26:59.340

Reputation: 11 664

0

Python 3, 96 bytes

n=int(input())
a=[]
for L in range(1,n+1):
 t=L-sum(a)%L
 while t in a:t+=L
 a+=[t]
print(a[-1])

Ideone it!

Leaky Nun

Posted 2016-08-18T01:26:59.340

Reputation: 45 011

0

JavaScript (ES6), 69 bytes

n=>{for(a=[],s=i=0;i++<n;a[j]=1,s+=j)for(j=i-s%i;a[j];)j+=i;return j}

At each stage just checks all the numbers with the appropriate remainder until it finds one that it hasn't seen before, then marks it seen and updates the total.

Neil

Posted 2016-08-18T01:26:59.340

Reputation: 95 035