Números segmentados

15

A sequência de números segmentados ou números primos de medição ( OEIS A002048 ) é a sequência de números, de modo que cada membro é o menor número positivo (maior que zero) que não pode ser feito da soma dos números consecutivos anteriores a(0) = 1.

Exemplo

Para calcular a(7), primeiro calculamos a(0->6) = [1, 2, 4, 5, 8, 10, 14]. começamos do zero e examinamos os números até encontrarmos um que não seja a soma de um ou mais números consecutivos na sequência.

1  = 1
2  = 2
3  = 1 + 2
4  = 4
5  = 5
6  = 2 + 4
7  = 1 + 2 + 4
8  = 8
9  = 4 + 5
10 = 10
11 = 2 + 4 + 5
12 = 1 + 2 + 4 + 5
13 = 5 + 8
14 = 14
15 = ????

Como quinze não podem ser feitos somando qualquer subsequência consecutiva e cada número menor pode ser quinze é o próximo número na sequência. a(7) = 15

Tarefa

Sua tarefa é pegar um número (por meio de métodos padrão) e gerar o enésimo termo nesta sequência (por meio de métodos de saída padrão). Isso é código-golfe e você será pontuado como tal.

Casos de teste

0 -> 1
1 -> 2
2 -> 4
3 -> 5
4 -> 8
5 -> 10
6 -> 14
7 -> 15
8 -> 16
9 -> 21
Post Rock Garf Hunter
fonte

Respostas:

12

Haskell, 62 58 bytes

-4 bytes graças a @xnor!

(x:y)#z=x:filter(`notElem`scanl(+)x z)y#(x:z)
([1..]#[]!!)

A sequência é indexada em 0.

ThreeFx
fonte
1
Eu acho que você precisa de mais dois bytes e rodeia a última linha ()para torná-la uma função adequada. A parcial aplicada !!é uma seção do operador e deve ser incluída ()para torná-la uma função. Sem ele, é apenas um trecho que só se torna uma função (ou "valor" para usar termos estritos de Haskell) com o argumento ausente.
nimi
1
Lindo método! A importação parece um exagero; filter(`notElem`scanl(+)x z)ydeveria fazer.
xnor
7

Perl, 50 49 bytes

Inclui +1 para -p

Execute com entrada no STDIN:

segmented.pl <<< 7

segmented.pl:

#!/usr/bin/perl -p
${$_-=$\}++for@F;1while${-++$\};++$#F<$_&&redo}{

Explicação

@Fcontém a lista de somas (negativas) de números consecutivos que terminam com o último número atual. Quando um novo número é descoberto, a lista é estendida com 0 e todos os valores são diminuídos pelo novo número, mantendo a invariante.

Global %::é usado como um hash mapeando todos os números (negativos) que foram vistos (através @F) para um valor diferente de zero.

$\é o número atual e é aumentado até atingir um valor ainda não inserido %::.

Por ter um pouco de cuidado com a ordem em que tudo acontece, nenhuma inicialização é necessária, 1automaticamente se tornará o primeiro número.

Como o tamanho de @Fé quantos números foram gerados, ele pode ser usado como uma condição de parada

Ton Hospel
fonte
4

05AB1E , 17 16 bytes

Xˆ$µ>D¯ŒOså_i¼Dˆ

Explicação

Xˆ                # initialize global array to [1]
  $               # push 1 and input to stack
   µ              # while counter != input
    >             # increase variable on stack
      ¯ŒO         # list of all sums of consecutive number in global array
     D   så_i     # if current stack value is not in the list
             ¼    # increase counter
              Dˆ  # add current stack value to global array

Experimente online!

Guardado 1 byte graças a Adnan

Emigna
fonte
Será que em $vez de Xstrabalhar?
Adnan
@ Adnan: Sim, é claro. Bobo da minha parte. Obrigado!
Emigna
4

Geléia , 14 13 11 bytes

Ḷ߀Ẇ;ḅ1‘ḟ$Ṃ

Experimente online!

Como funciona

Ḷ߀Ẇ;ḅ1‘ḟ$Ṃ  Main link. Argument: n

Ḷ            Unlength; yield [0, ..., n - 1].
 ߀          Recursively map the main link over the range.
   Ẇ         Window; yield all subarrays of consecutive elements of the result.
    ;        Append n to the array of subarrays.
     ḅ1      Convert all subarrays from base 1 to integer.
             This is equivalent to S€ (sum each), but it allows ; to hook.
         $   Combine the previous two links into a monadic chain.
       ‘       Increment all sums.
        ḟ      Filter; remove the original sums from the incremented ones.
          Ṃ  Compute the minimum.
Dennis
fonte
2

Pitão - 19 17 bytes

Maldito seja, alguém estragando todos os meus implícitos. (O mesmo bytes contar, literalmente incrementando Q: =hQesmaYf!}TsM.:Y)

esmaYf!}TsM.:Y)1h

Conjunto de Teste .

Maltysen
fonte
O uso de reduzir salva (apenas) um byte. Espera-se mais ...eu+Gf!}TsM.:G))hQY
Jakube
1
@Jakube mapa é geralmente mais curto para auto sequências referenciais como estes
Maltysen
2

Javascript, 125 112 110 bytes

Guardado 2 bytes graças a @Neil

f=n=>{a=[[]];for(i=1,z=0;z<=n;i++)a.some(b=>b.includes(i))||(a[z+1]=[0,...a[z++]||[]].map(v=>i+v));alert(i-1)}

Respostas anteriores

112 bytes graças a @Neil:

f=n=>{a=[[]];for(i=1,z=0;z<=n;i++)if(!a.some(b=>b.includes(i))){a[z+1]=[0,...a[z++]||[]].map(v=>i+v)}alert(i-1)}

125 bytes:

f=n=>{a=[[]];for(i=1,k=z=0;z<=n;i++)if(a.every(b=>b.every(c=>c-i))){a[i]=[i].concat((a[k]||[]).map(v=>i+v));k=i,z++}alert(k)}
Hedi
fonte
1
Para b.every(c=>c-i), eu tentaria !b.includes(i)ou possivelmente !a.some(b=>b.includes(i))funciona, enquanto [0,...a[k]||[]].map(v=>i+v)pode substituir [i].concat((a[k]||[]).map(v=>i+v)). Também precisa mesmo k?
Neil
1
Agora que sua if(!...){...}é apenas uma declaração, você provavelmente poderá substituí-la por ...||(...)ou ...?0:....
Neil
1

Python, 113 105 92 80 bytes

s=F={1}
x=1
exec"while{x}<=s:x+=1\nF={x+j for j in{0}|F};s|=F\n"*input()
print x

Os bytes finais que salvei foram inspirados na resposta de Ton Perl: o meu Ffaz a mesma coisa que o dele @F; o meu sfaz essencialmente a mesma coisa que o dele %::.

Lynn
fonte
1

JavaScript (ES6), 77 bytes

(n,a=[],s=a,i=1)=>s[i]?f(n,a,s,i+1):--n?f(n,[0,...a].map(j=>s[j+=i]=j),s,i):i

Basicamente, uma porta recursiva do algoritmo da resposta Perl do @ TonHospel.

Neil
fonte