La sequenza traballante di Golomb


21

OEIS ha una variazione (A111439) sulla sequenza di Golomb . Come nella sequenza di Golomb, A(n)descrive la frequenza con cui nappare nella sequenza. Inoltre, due numeri consecutivi non possono essere identici. Durante la creazione della sequenza, A(n)viene sempre scelto come numero intero positivo più piccolo che non viola queste due proprietà. A causa di numeri identici consecutivi non consentiti, la serie oscilla leggermente su e giù man mano che cresce. Ecco i primi 100 termini:

1, 2, 3, 2, 3, 4, 3, 4, 5, 6, 5, 6, 5, 6, 7, 6, 7, 8, 7, 8, 9, 8, 9, 8, 9, 
10, 9, 10, 9, 10, 11, 10, 11, 10, 11, 10, 11, 12, 11, 12, 13, 12, 13, 12, 
13, 12, 13, 12, 13, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 16, 15, 
16, 17, 16, 17, 16, 17, 16, 17, 16, 17, 18, 17, 18, 17, 18, 19, 18, 19, 18, 
19, 18, 19, 18, 19, 18, 19, 20, 19, 20, 21, 20, 21, 20, 21, 20, 21, 20

L'elenco completo dei primi 10.000 numeri è disponibile su OEIS .

La sfida è scrivere un programma o una funzione che calcoli A(n), dato n. nè 1basato per garantire che la proprietà auto-descrittiva funzioni.

Regole

È possibile scrivere un programma o una funzione e utilizzare uno qualsiasi dei nostri metodi standard per ricevere input e fornire output.

È possibile utilizzare qualsiasi linguaggio di programmazione , ma si noti che queste scappatoie sono vietate per impostazione predefinita.

Questo è , quindi la risposta valida più breve - misurata in byte - vince.

Casi test

n     A(n)
1     1
4     2
10    6
26    10
100   20
1000  86
1257  100
10000 358


3
Ero curioso, quindi l'ho rappresentato graficamente . Neato.
Ingegnere Toast,

4
@EngineerToast Il grafico è anche su OEIS. Stavo esaminando quanto a lungo le "piste" vedi nel tuo grafico e questo diventa davvero strano . (Questo grafico mostra quanto spesso Nappare dopo l'ultima occorrenza della N-1quale misura il numero di oscillazioni fino a N.)
Martin Ender

Risposte:


5

Haskell , 67 byte

f k|k<4=k|p<-k-1=[n|n<-[1..],n/=f p,sum[1|a<-[1..p],f a==n]<f n]!!0

Definisce una funzione f. Provalo online! È molto lento, il f 15timeout dell'elaborazione su TIO.

Spiegazione

Solo andando con la definizione: in ogni fase, scegliere il numero minimo positivo nche soddisfa i vincoli (non uguale alla voce precedente e non si è ancora verificato i f ntempi).

f k             -- Define f k:
 |k<4=k         -- If k < 4, it's k.
 |p<-k-1=       -- Otherwise, bind k-1 to p,
  [n|           -- compute the list of numbers n where
   n<-[1..],    -- n is drawn from [1,2,3,...],
   n/=f p,      -- n is not equal to f p, and
   sum[1|       -- the number of
    a<-[1..p],  -- those elements of [1,2,3,...,p]
    f a==n]     -- whose f-image equals n
   <f n]        -- is less than f n,
  !!0           -- and take the first element of that list.

5

Mathematica, 69 68 byte

Grazie a Martin Ender per aver trovato un ulteriore -1 byte per me!

Last@Nest[{##&@@#,1//.x_/;x==Last@#||#~Count~x==#[[x]]->x+1}&,{},#]&

Funzione senza nome che accetta un numero intero positivo ncome input e restituisce un numero intero positivo. Costruiamo l'intero elenco dei primi nelementi di questa sequenza, quindi prendiamo l' Lastelemento. L'elenco viene creato iniziando con l'elenco vuoto {}e operando su di esso con una funzione nvolte consecutive (via Nest).

La funzione in questione è {##&@@#,1//.x_/;x==Last@#||#~Count~x==#[[x]]->x+1}&, che accetta un elenco parziale di valori di sequenza (essenzialmente ##&@@#) e vi aggiunge il valore successivo. Il valore successivo viene calcolato partendo x=1, poi ripetutamente sostituendo xda x+1finché la condizione x==Last@#||#~Count~x==#[[x]]è soddisfatta, in altre parole, se uno xè l'elemento precedente, oppure xè già nell'elenco il numero corretto di volte. Questa funzione genera alcuni errori, poiché (ad esempio) non dovremmo chiamare l' xelemento th dell'elenco iniziale {}; tuttavia, i valori sono tutti corretti.


4

Python 2, 99 86 byte

Grazie a @Dennis per diversi miglioramenti per un totale di 13 byte!

s=0,1,2,3
exec't=1\nwhile t==s[-1]or s.count(t)/s[t]:t+=1\ns+=t,;'*input()
print s[-4]

Il programma procede in modo piuttosto ingenuo: tiene traccia dell'elenco di valori finora determinato e cerca di aggiungere il valore successivo. Cerca di aggiungere 1a alla fine dell'elenco se può; in caso contrario, prova a 2e così via fino a quando non è permesso qualcosa.

Ora, iniziamo seminando i risultati per 1,2,3essere 1,2,3. Questo viene fatto per evitare che i problemi con l'elenco dei valori già calcolati siano troppo brevi: suppongo che se nè almeno 4allora a(n)è strettamente inferiore a n. (In questo programma, s[n]è uguale a a(n). La nostra lista in realtà è inizializzata per essere [0,1,2,3]perché le liste sono 0-indicate in Python. Quindi, per esempio a(1)=s[1]=1, e a(2)=s[2]=2.)

Quindi, supponiamo che stiamo cercando di determinare s[m], nel senso che il nostro elenco include già s[0], s[1], ..., s[m-1]. Inizieremo a t=1e proveremo a impostare s[m]=1. Quando non funziona, andiamo a t=2e proviamo a impostare s[m]=2. Ogni volta che incrementiamo t, controlliamo se s.count(t)==s[t]... ma il lato destro non produrrà un errore fintanto che non dovremo mai andare più in alto t=m. La congettura afferma che non dobbiamo mai farlo, dal momento che il primo valore che calcoliamo è in realtà s[4].

Questa implementazione calcola 3 più valori della sequenza di quelli necessari. Ad esempio, se lo nè 8, eseguirà il calcolo s[11]prima di restituire il valore di s[8].

Sarei felice di vedere una prova della congettura. Credo che possa essere provato dall'induzione (forte?).

Modifica: ecco una prova della congettura . In realtà dimostriamo una forma leggermente più forte dell'affermazione, poiché non comporta alcun lavoro extra.

Teorema: per tutti nmaggiori o uguali a 4, il termine a(n)è minore o uguale a (n-2).

Proof (di Strong Induction): (Base n=4): l'affermazione è vera per n=4, da allora a(4) = 2 = 4-2.

Ora supponiamo che a(k)sia minore o uguale a k-2per tutto kda 4attraverso n, inclusivo (e supponiamo che nsia almeno 4). In particolare, ciò significa che tutti i termini precedenti della sequenza erano al massimo (n-2). Dobbiamo dimostrare che a(n+1)sarà al massimo (n-1). Ora, per definizione, a(n)è il numero intero positivo più piccolo che non viola nessuna delle condizioni, quindi dobbiamo solo mostrare che il valore (n-1)non violerà nessuna delle condizioni.

Il valore (n-1)non violerà la condizione "nessuna ripetizione consecutiva", poiché per l'ipotesi di induzione la voce precedente era al massimo (n-2). E non violerà la condizione " a(m)è il numero di volte che mappare", a meno che non (n-1)sia già stato raggiunto a(n-1)volte. Ma dal forte presupposto di induzione, (n-1)era stato precedentemente raggiunto 0tempi, e a(n-1)non è uguale a 0poiché a(m)è positivo per tutti m.

Pertanto a(n+1)è inferiore o uguale a n-1 = (n+1)-2, come desiderato. QED.


3

Gelatina , 17 byte

Ṭ€S<;1Tḟ®Ḣ©ṭ
⁸Ç¡Ṫ

Gli ultimi tre casi di test sono troppo per TIO. Ho verificato 1000 e 1257 localmente.

Provalo online! o verifica i primi 100 termini .

Come funziona

⁸Ç¡Ṫ          Main link. No arguments.

⁸             Yield [].
 Ç¡           Execute the helper link n times (where n is an integer read from
              STDIN), initially with argument [], then with the previous return
              value as argument. Yield the last return value.
              Tail; yield the last element of the result.


Ṭ€S<;1Tḟ®Ḣ©ṭ  Helper link. Argument: A (array)

Ṭ€            Untruth each convert each k into an array of k-1 zeroes and one 1.
  S           Sum; column-wise reduce by +, counting the occurrences of all
              between 1 and max(A).
   <          Compare the count of k with A[k] (1-indexed), yielding 1 for all
              integers that still have to appear once or more times.
    ;1        Append a 1 (needed in case the previous result is all zeroes).
      T       Truth; find all indices of ones.
       ḟ®     Filter-false register; remove the value of the register (initially 0)
              from the previous result.
         Ḣ©   Head copy; yield the first (smallest) value of the result and save
              it in the register.
           ṭ  Tack; append the result to A.

3

Python 2 , 77 74 byte

f=lambda n,k=1:n*(n<4)or map(f,range(n)+k*[n-1]).count(k)<f(k)or-~f(n,k+1)

Questa è un'implementazione ricorsiva dell'algoritmo di @ mathmandan .

L'implementazione è O (folle) : l'ingresso 9 richiede 2 secondi localmente, input 10 52 secondi e input 11 17 minuti e 28 secondi. Tuttavia, se dichiarato come funzione regolare anziché come lambda, la memoizzazione può essere utilizzata per verificare i casi di test.

Provalo online!

Nota che anche con Memoizzazione, TIO non può calcolare f (1257) o F (10000) (sia verificato a livello locale).


2

05AB1E , 32 31 byte

XˆXˆG[N¯2(è<›¯¤NÊsN¢¯Nè‹&&#]N.ˆ

Provalo online!

Spiegazione

XˆXˆ                             # initialize global list as [1,1]
    G                            # input-1 times do:
     [                    #]     # loop until expression is true     
      N¯2(è<›                    # n > list[-2]-1
             ¯¤NÊ                # list[-1] != N
                 sN¢¯Nè‹         # count(list, N) < list[N]
                        &&       # logical AND of the 3 expressions
                            N.ˆ  # add N to global list 
                                   and output last value in list and end of program

Siamo tecnicamente in loop Gquando aggiungiamo N all'elenco globale, ma tutti i loop in 05AB1E usano la stessa variabile N dell'indice, quindi il ciclo interno [...]ha sovrascritto la N del Gsignificato, che possiamo aggiungere al di fuori del ciclo.

Problemi con loop e condizionali nidificati ci impediscono di farlo all'interno del loop.


2

Befunge, 141 136 byte

<v9\0:p8\2:*2:-1<9
v>p1+:3\8p0\9p:#^_&
>1-:#v_1.@>$8g.@
*+2%\>1-:!|>$!:::9g!\!9g!*\:8g\!8g`
9\+1g9::< \|`g9\g8+2::p
g2+\8p2+^:<>:0\9p::8

Provalo online!

A causa delle limitazioni di memoria di Befunge, non è davvero pratico tenere traccia di tutte le voci delle voci precedenti nella sequenza, quindi questa soluzione utilizza un algoritmo con un footprint di memoria inferiore che calcola i valori più direttamente.

Detto questo, siamo ancora limitati dalla dimensione della cella, che nell'interprete di riferimento Befunge-93 è un valore con segno a 8 bit, quindi il numero pari supportato più alto nella sequenza è A(1876) = 126e il numero dispari supportato più alto è A(1915) = 127.

Se vuoi testare valori più grandi, dovrai usare un interprete con una cella più grande. Ciò dovrebbe includere la maggior parte delle implementazioni di Befunge-98 ( Provalo online! ).


0

Python 2, 117 byte

Meh. Non così corto. La semplice soluzione iterativa.

L=[1,2,3]
n=input()
while len(L)<n:
 for i in range(2,n):
    if L.count(i)<L[i-1]and L[-1]!=i:L+=[i];break
print L[n-1]

Provalo online

Ecco un brutto tentativo di soluzione ricorsiva (129 byte):

def f(n,L=[1,2,3]):
 if len(L)>=n:print L[n-1];exit(0)
 for i in range(2,n):
    if L.count(i)<L[i-1]and L[-1]!=i:f(n,L+[i])
 f(n,L)

Fisso. Pensavo di poter usare -1invece di n-1salvare un byte, credo di no.
mbomb007,
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.