Numeri segmentati


15

La sequenza di numeri segmentati o numeri primi di misurazione ( OEIS A002048 ) è la sequenza di numeri in modo tale che ciascun membro sia il numero positivo più piccolo (maggiore di zero) che non può essere costituito da una somma di numeri consecutivi precedenti, con a(0) = 1.

Esempio

Per calcolare a(7)calcoliamo prima a(0->6) = [1, 2, 4, 5, 8, 10, 14]. iniziamo quindi da zero e passiamo attraverso i numeri fino a quando non troviamo uno che non è la somma di uno o più numeri consecutivi nella sequenza.

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 = ????

Dal momento che non è possibile effettuare quindici sommando una sottosequenza consecutiva e ogni numero più piccolo può essere quindici è il numero successivo nella sequenza. a(7) = 15

Compito

Il tuo compito è prendere un numero (tramite metodi standard) e produrre l'ennesimo termine in questa sequenza (tramite metodi di output standard). Questo è code-golf e verrai valutato come tale.

Casi test

0 -> 1
1 -> 2
2 -> 4
3 -> 5
4 -> 8
5 -> 10
6 -> 14
7 -> 15
8 -> 16
9 -> 21

Risposte:


12

Haskell, 62 58 byte

-4 byte grazie a @xnor!

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

La sequenza è indicizzata 0.


1
Penso che siano necessari altri due byte e che circonda l'ultima riga ()per renderla una funzione corretta. Il parziale applicato !!è una sezione operatore e deve essere racchiuso ()per renderlo una funzione. Senza è solo un frammento che diventa solo una funzione (o "valore" per usare termini Haskell rigorosi) con l'argomento mancante.
nimi,

1
Bellissimo metodo! L'importazione sembra però eccessiva; filter(`notElem`scanl(+)x z)ydovresti ... dovrebbe.
xnor

7

Perl, 50 49 byte

Include +1 per -p

Esegui con input su STDIN:

segmented.pl <<< 7

segmented.pl:

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

Spiegazione

@Fcontiene l'elenco di somme (negative) di numeri consecutivi che terminano con l'ultimo numero corrente. Quando viene scoperto un nuovo numero, l'elenco viene esteso con 0 e quindi tutti i valori vengono diminuiti dal nuovo numero mantenendo l'invariante.

Globale %::è usato come hash che mappa tutti i numeri (negativi) che sono stati visti (attraverso @F) su un valore diverso da zero.

$\è il numero corrente e viene aumentato fino a quando non raggiunge un valore non ancora inserito %::.

Stando un po 'attenti all'ordine in cui tutto accade, non è necessaria l'inizializzazione, 1diventerà automaticamente il primo numero.

Poiché la dimensione di @Fè quanti numeri sono stati generati, può essere utilizzato come condizione di arresto


4

05AB1E , 17 16 byte

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

Spiegazione

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

Provalo online!

Salvato 1 byte grazie ad Adnan


Fa $invece di Xslavoro?
Adnan,

@Adnan: Sì, certo. Sciocco da parte mia Grazie!
Emigna,

4

Gelatina , 14 13 11 byte

Ḷ߀Ẇ;ḅ1‘ḟ$Ṃ

Provalo online!

Come funziona

Ḷ߀Ẇ;ḅ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.

2

Pyth - 19 17 byte

Accidenti a uno che ha rovinato tutti i miei impliciti. (Contano Stesse byte, letteralmente incremento Q: =hQesmaYf!}TsM.:Y)

esmaYf!}TsM.:Y)1h

Test Suite .


L'uso di ridurre salva (solo) un byte. eu+Gf!}TsM.:G))hQY
Mi

1
La mappa di @Jakube è generalmente più breve per sequenze autoreferenziali come queste
Maltysen,

2

Javascript, 125 112 110 byte

Salvato 2 byte grazie 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)}

Risposte precedenti

112 byte grazie 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 byte:

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)}

1
Perché b.every(c=>c-i), proverei !b.includes(i)o forse !a.some(b=>b.includes(i))funzionerà, mentre [0,...a[k]||[]].map(v=>i+v)potrebbe sostituire [i].concat((a[k]||[]).map(v=>i+v)). Inoltre hai davvero bisogno k?
Neil,

1
Ora che la tua if(!...){...}è solo una frase, probabilmente potresti sostituirla con ...||(...)o ...?0:....
Neil,

1

Python, 113 105 92 80 byte

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

Gli ultimi byte che ho salvato sono stati ispirati dalla risposta Perl di Ton: my Ffa la stessa cosa della sua @F; il mio sfa essenzialmente la stessa cosa della sua %::.


1

JavaScript (ES6), 77 byte

(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

Fondamentalmente una porta ricorsiva dell'algoritmo della risposta Perl di @ TonHospel.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.