Cut the gold chain

05AB1E, 23 11 8 bytes

ΔÍN-;иg=

Try it online!

Uses 0-based indexing.

Explanation:

             # start from the implicit input
Δ            # loop forever
 Í           # subtract 2
  N-         # subtract the current iteration number
    ;        # divide by 2
     и       # create a list of length x
      g      # get the length of the list
       =     # print

иg looks like a noop, but it actually does two useful things: it truncates to an integer (; returns a float), and it crashes the interpreter if x is negative (this is the only exit condition).


The 23 byte solution used a very different approach, so here it is for posterity: ÅœʒR2äθP}ʒæOê¥P}θ2äθη€O (TIO, explanation).


Python 2, 75 bytes

f=lambda n,i=0:n>=i<<i and f(n,i+1)or[min(n,2**j*i-i+j)for j in range(1,i)]

Try it online!


Explanation:

Builds a sequence of 'binary' chunks, with a base number matching the number of cuts.

Eg:

63 can be done in 3 cuts, which means a partition in base-4 (as we have 3 single rings):

Cuts: 5, 14, 31, which gives chains of 4 1 8 1 16 1 32 (sorted: 1 1 1 4 8 16 32).

All numbers can be made:

1       1
2       1 1
3       1 1 1
4       4
...
42      1 1 8 32
...
62      1 1 4 8 16 32
63      1 1 1 4 8 16 32

Other examples:

18: 4,11        ->  3 1 6 1 7
27: 5,14,27     ->  4 1 8 1 13 1
36: 5,14,31     ->  4 1 8 1 16 1 5
86: 6,17,38,79  ->  5 1 10 1 20 1 40 1 7

R, 77 69 bytes

-8 bytes thanks to Aaron Hayman

pmin(n<-scan(),0:(k=sum((a=2:n)*2^a<=n))+cumsum((k+2)*2^(0:k))+1)[-n]

Try it online!

Let \$k\$ be the number of cuts needed; \$k\$ is the smallest integer such that \$(k+1)\cdot2^k\geq n\$. Indeed, a possible solution is then to have subchains of lengths \$1,1,\ldots,1\$ (\$k\$ times) and \$(k+1), 2(k+1), 4(k+1), 8(k+1), \ldots, (k+1)\cdot 2^{k-1}\$. It is easy to check that this is sufficient and optimal.

(The last subchain might need to be made shorter if we exceed the total length of the chain.)

Ungolfed (based on previous, similar version):

n = scan()                            # read input
if(n - 1){                            # If n==1, return NULL
  k = match(F, (a = 2:n) * 2 ^ a > n) # compute k
  b = (k + 1) * 2 ^ (1:k - 1)         # lengths of subchains
  c = 1:k + cumsum(b)                 # positions of cuts
  pmin(c, n )                         # if last value is >n, coerce it to n
}

(Proof that the value of \$k\$ is as I state: suppose we have \$k\$ cuts. We then have \$k\$ unit subchains, so we need the first subchain to be of length \$k+1\$. We can now handle all lengths up to \$2k+1\$, so we need the next one to be of length \$2k+2\$, then \$4k+4\$... Thus the maximum we can get out of \$k\$ cuts is obtained by summing all those lengths, which gives \$(k+1)\cdot 2^k-1\$.)

If \$a(k)\$ is the smallest integer \$n\$ requiring \$k\$ cuts, then \$a(k)\$ is OEIS A134401.