La sequenza di Kimberling


18

introduzione

Certo, abbiamo molte sfide in , quindi eccone un'altra.

La sequenza di Kimberling ( A007063 ) è la seguente:

1, 3, 5, 4, 10, 7, 15, 8, 20, 9, 18, 24, 31, 14, 28, 22, ...

Questo è prodotto mescolando la normale iterazione:

[1] 2  3  4  5  6  7  8

Il primo termine della sequenza è 1. Dopodiché, rimescoliamo la sequenza fino a quando non vengono utilizzati tutti i termini a sinistra. Il mescolamento ha il modello right - left - right - left - .... Dal momento che non ci sono termini alla sinistra del 1, non c'è mescolamento. Otteniamo quanto segue:

 2 [3] 4  5  6  7  8  9

Sulla i esima iterazione, si scartano l'i esimo elemento e mettere che nella nostra sequenza. Questa è la seconda iterazione, quindi scartiamo la seconda voce. La sequenza diventa: 1, 3. Per la nostra prossima iterazione, mescoleremo l'attuale iterazione con il modello sopra. Prendiamo il primo elemento non utilizzato a destra dell'i esimo elemento. Questo sembra essere 4. Lo aggiungeremo alla nostra nuova iterazione:

 4

Ora stiamo andando a prendere il primo elemento non utilizzato a sinistra della i esima voce. Questo è 2. Lo aggiungeremo alla nostra nuova iterazione:

 4  2

Poiché non ci sono elementi a sinistra dell'i ° elemento, aggiungeremo semplicemente il resto della sequenza alla nuova iterazione:

 4  2 [5] 6  7  8  9  10  11  ...

Questa è la nostra terza iterazione, quindi elimineremo la terza voce, ovvero 5. Questo è il terzo elemento della nostra sequenza:

 1, 3, 5

Per ottenere la prossima iterazione, basta ripetere il processo. Ho fatto una gif se non è chiaro:

inserisci qui la descrizione dell'immagine

La gif mi ha richiesto più tempo rispetto alla scrittura del post vero e proprio

Compito

  • Dato un numero intero non negativo n , genera il primo n termini della sequenza
  • È possibile fornire una funzione o un programma
  • Questo è , quindi vince l'invio con il minor numero di byte!

Casi test:

Input: 4
Output: 1, 3, 5, 4

Input: 8
Output: 1, 3, 5, 4, 10, 7, 15, 8

Input: 15
Output: 1, 3, 5, 4, 10, 7, 15, 8, 20, 9, 18, 24, 31, 14, 28

Nota: le virgole nell'output non sono necessarie. Ad esempio, è possibile utilizzare newline o creare un elenco, ecc.


Sto lavorando a un metodo usando la rotazione dello stack
Cyoce

@Cyoce Buona fortuna :)
Adnan,

sembra che ne avrò bisogno
Cyoce,

Risposte:


3

Pyth, 22 byte

JS*3QVQ@JN=J.i>JhN_<JN

Provalo online: dimostrazione

Esegue semplicemente la tecnica di mescolamento descritta nell'OP.

Spiegazione:

JS*3QVQ@JN=J.i>JhN_<JN
JS*3Q                    assign the list [1, 2, ..., 3*input-1] to J
     VQ                  for N in range(Q):
       @JN                  print J[N]
            .i              interleave 
              >JhN             J[N+1:] with
                  _<JN         reverse J[:N]
          =J                assign the resulting list to J

6

Julia, 78 71 byte

n->[(i=j=x;while j<2i-3 j=i-(j%2>0?1-j:j+22;i-=1end;i+j-1)for x=1:n]

Questa è una funzione senza nome che accetta un numero intero e restituisce un array di numeri interi. Per chiamarlo, assegnarlo a una variabile.

L'approccio qui è lo stesso di quello descritto su OEIS.

Ungolfed:

# This computes the element of the sequence
function K(x)
    i = j = x
    while j < 2i - 3
        j = i - (j % 2 > 0 ? 1 - j : j + 22
        i -= 1
    end
    return i + j - 1
end

# This gives the first n terms of the sequence
n -> [K(i) for i = 1:n]

Risparmiato 7 byte grazie a Mauris!


3

Mathematica 130 byte

(n=0;s={};Nest[(n++;AppendTo[s,z=#[[n]]];Flatten[TakeDrop[#,1+2(n-1)]/.{t___,z,r___}:> 
Riffle[{r},Reverse@{t}]])&,Range[3*#],#];s)&

Iniziamo con un elenco costituito dall'intervallo da 1a 3x, dovex è il numero desiderato di termini della sequenza di Kimberling.

Ad ogni passo, n, TakeDroprompe la lista corrente in un elenco fronte 2n+1termini (dove viene fatto il lavoro) e la lista posteriore (che verrà successivamente unito alla rielaborato elenco anteriore). La lista frontale è abbinata al seguente schema, {t___,z,r___}dove z è il termine Kimberling al centro della lista frontale. rè Rifflecon il contrario di te quindi viene aggiunto l'elenco posteriore. zviene rimosso e aggiunto a ( AppendTo) la sequenza crescente di Kimberling.

nviene incrementato di 1e l'elenco corrente viene elaborato dalla stessa funzione tramiteNest.


Esempio

(n=0;s={};Nest[(n++;AppendTo[s,z=#[[n]]];Flatten[TakeDrop[#,1+2(n-1)]/.{t___,z,r___}:> 
Riffle[{r},Reverse@{t}]])&,Range[3*#],#];s)&[100]

{1, 3, 5, 4, 10, 7, 15, 8, 20, 9, 18, 24, 31, 14, 28, 22, 42, 35, 33, 46, 53, 6, 36, 23, 2 , 55, 62, 59, 76, 65, 54, 11, 34, 48, 70, 79, 99, 95, 44, 97, 58, 84, 25, 13, 122, 83, 26, 115, 82, 91 , 52, 138, 67, 90, 71, 119, 64, 37, 81, 39, 169, 88, 108, 141, 38, 16, 146, 41, 21, 175, 158, 165, 86, 191, 45 , 198, 216, 166, 124, 128, 204, 160, 12, 232, 126, 208, 114, 161, 156, 151, 249, 236, 263, 243, 101, 121, 72, 120, 47, 229 }


2

Python 2, 76 byte

for a in range(input()):
 b=a+1
 while-~b<2*a:b=a-(b^b%-2)/2;a-=1
 print a+b

Spiegazione

Questa è la formula OEIS dopo molte trasformazioni golf-y! Ha funzionato magnificamente . Il codice originale era

i=b=a+1
while b<2*i-3:b=i-(b+2,1-b)[b%2]/2;i-=1
print i+b-1

Per prima cosa mi sono sbarazzato di i, sostituendolo con a+1ovunque ed espandendo le espressioni:

b=a+1
while b<2*a-1:b=a+1-(b+2,1-b)[b%2]/2;a-=1
print a+b

Quindi, riscrivi b<2*a-1come -~b<2*aper salvare un byte di spazio bianco e spostalo +1nella selezione, divisione per 2 e negazione:

while-~b<2*a:b=a-(b,-b-1)[b%2]/2;a-=1

Quindi, -b-1è giusto ~b, così possiamo scrivere (b,~b)[b%2]. Ciò equivale a b^0 if b%2 else b^-1utilizzare l'operatore XOR, o in alternativa, b^b%-2.

while-~b<2*a:b=a-(b^b%-2)/2;a-=1

2

Pyth, 29 25 byte

VQ+.W<hHyN-~tN/x%Z_2Z2hNN

Jakube ha salvato 4 byte, ma non ho più idea di come leggere il codice.

Ecco la vecchia soluzione:

VQKhNW<hKyN=K-~tN/x%K_2K2)+KN

Traduzione della mia risposta Python. Non sono molto bravo in Pyth, quindi forse ci sono ancora modi per accorciarlo.

VQ                              for N in range(input()):
  KhN                             K = N+1
     W<hKyN                       while 1+K < 2*N:
           =K-~tN/x%K_2K2)         K = (N--) - (K%-2 xor K) / 2
                          +KN     print K + N

È possibile utilizzare .Wper il golf fuori 4 byte: VQ+.W<hHyN-~tN/x%Z_2Z2hNN.
Jakube,

È fantastico - potresti spiegarci approssimativamente come funziona?
Lynn,

1
.Wha la forma: .W<condition><apply><start-value>. Ho usato il valore iniziale hN, come hai fatto tu KhN. .Wcambia questo valore finché <condition>è vero. Ho usato le tue stesse condizioni <hHyN. La condizione è una funzione lambda con il parametro H, quindi il valore corrente (nel tuo codice K) è H. E ho anche usato la tua stessa <apply>istruzione, l'ho sostituita solo Kcon Z, perché l' <apply>istruzione è una funzione lambda con parametro Z. Possiamo ignorare il =K, .Wgestisce questo. Sostituisce il vecchio valore con quello calcolato. Alla fine stampa+...N
Jakube,

2

APL, 56 44 byte

{⍵<⍺+⍺-3:(⍺-1)∇⍺-4÷⍨3+(1+2×⍵)ׯ1*⍵⋄⍺+⍵-1}⍨¨⍳

Questo è un treno monadico senza nome che accetta un numero intero sulla destra e restituisce un array. È più o meno lo stesso approccio della mia risposta Julia .

La funzione più interna è una funzione diadica ricorsivo che restituisce i n esimo termine della sequenza Kimberling, dato n identico sinistro e destro argomenti.

{⍵<⍺+⍺-3:                                    ⍝ If ⍵ < 2⍺ - 3
         (⍺-1)∇⍺-4÷⍨3+(1+2×⍵)ׯ1*⍵           ⍝ Recurse, incrementing a and setting
                                             ⍝ ⍵ = ⍺ - (3 + (-1)^⍵ * (1 + 2⍵))/4
                                   ⋄⍺+⍵-1}   ⍝ Otherwise return ⍺ + ⍵ - 1

Con quello in mano, siamo in grado di ottenere termini individuali della sequenza. Tuttavia, il problema diventa quindi che questa è una funzione diadica , nel senso che richiede argomenti su entrambi i lati. Inserisci l' operatore! Data una funzione fe un input x, f⍨xè uguale a x f x. Quindi, nel nostro caso, facendo riferimento alla funzione di cui sopra f, possiamo costruire il seguente treno monadico:

f⍨¨⍳

Applichiamo fa ciascun numero intero da 1 all'input, producendo un array.

Risparmiato 12 byte grazie a Dennis!

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.