Dai una permutazione senza due numeri interi consecutivi uno accanto all'altro


18

Sfida

Dato un numero intero n ≥ 4 , emette una permutazione degli interi [0, n-1] con la proprietà che non esistono due numeri interi consecutivi (numeri interi con differenza assoluta 1) uno accanto all'altro.

Esempi

  • 4 → [1, 3, 0, 2]
  • 5 → [0, 2, 4, 1, 3]
  • 6 → [0, 2, 4, 1, 3, 5]
  • 7 → [0, 2, 4, 1, 5, 3, 6]

È possibile utilizzare invece 1-indicizzazione (utilizzando numeri interi [1, n] anziché [0, n-1] ).

Il tuo codice deve essere eseguito in un tempo polinomiale in n , quindi non puoi provare tutte le permutazioni e testarne ognuna.


Quando dici "emetti una permutazione", intendi come un elenco? Oppure possiamo produrre una funzione che implementa la mappatura della permutazione stessa?
— xnor

@xnor Dovrebbe essere emesso in una forma leggibile dall'uomo. Non mi interessa esattamente come.
— Anush,

Sarebbe [[1,3],[0,2]]un formato di output accettabile?
— Shaggy,

@Shaggy Non è eccezionale. Significa 1,3,0,2?
— Anush,

Risposte:


31

Gelatina , 3 2 byte

ḂÞ

Ordina gli interi in [1, ..., n] in base al loro LSB.

Provalo online!


Wow! È fantastico.
— Anush,

2
"Ordina per LSB" significa che ogni altro si sposta all'inizio, ma la definizione di Jelly richiede che i numeri in ogni metà rimangano nel loro ordine originale? In caso contrario, 100 (4) potrebbe essere vicino a 101 (5) ed essere comunque "ordinato da LSB". Non criticare il codice, ma forse il commento descrittivo non è completo?
— Groleau

1
@WGroleau Sì, Þordinamento stabile, perché è implementato utilizzando la sortedfunzione Python , che è garantita per essere stabile .
— user202729

3
L'algoritmo è più impressionante per me delle dimensioni ridotte, nella sua intelligenza. Potresti anche, suppongo, invertire l'ordine dei bit, ordinare e invertirlo.
— Francia,

4
Ci possono essere solo 65536 diversi programmi Jelly a due byte. È sorprendente che così tante di queste siano le risposte alle sfide dei ppcg.
— Anush,




6

Haskell, 22 byte

f è una funzione di n che restituisce un elenco ordinato in modo appropriato. Sto usando l'opzione 1-indicizzazione.

f n=[2,4..n]++[1,3..n]

6

Ottava , 17 byte

@(x)[2:2:x,1:2:x]

Provalo online!

Questo utilizza lo stesso approccio di molti altri. Concatena due vettori, uno con tutti i numeri pari nell'intervallo compreso 2 ... x e tutti i numeri dispari nell'intervallo compreso 1 ... x . La sintassi dovrebbe essere abbastanza ovvia, quindi non lo spiegherò.


1
Non sono 3e 2uno accanto all'altro in f(4)?
— pajonk,

Oops ... risolto. Stesso numero di byte. :-)
— Stewie Griffin,

5

JavaScript (ES6), 40 byte

f=
n=>[...Array(i=n)].map(_=>(i+--i)%(n|1))
<input type=number min=4 oninput=o.textContent=f(+this.value).join`\n`><pre id=o>

Modifica: salvato 1 byte grazie a @Arnauld.


5

Gaia , 2 byte

r∫

Provalo online!

Questo semplicemente (stabile) ∫ sy gli interi nell'intervallo [1, ingresso] dal loro pa r ità.


Stesso commento di Jelly: l'algoritmo o la definizione della lingua garantiscono che le due metà rimangano ciascuna nel loro ordine originale?
— Galles,

@WGroleau Sì, in Gaia, il meta-operatore di ordinamento è stabile.
— Mr. Xcoder



4

Japt, 4 byte

È inoltre possibile sostituire ucon vper ottenere un ordine diverso.

õ ñu

Provalo

In alternativa, se riusciamo a produrre una matrice di 2 array:

õ ó

Provalo


Tecnicamente il secondo produce un elenco di numeri separati da virgole ;-) 4Purtroppo entrambi falliscono ; puoi correggere il primo cambiando uin vo oin õ.
— ETHproductions

3

Mathematica, 50 -> 47 -> 42 byte

p = Join[Range[2, #, 2], Range[1, #, 2]] &

Provalo online!

Grazie a user202729 per aver sottolineato il duplice potenziale di ottimizzazione Join [] installato di Flatten [] e utilizzando le funzioni pure.

Vorrei aggiungere due osservazioni.

1) È abbastanza semplice costruire una permutazione specifica senza successione decrescente o crescente per n> = 4 come richiesto n nel PO.

Si compone di due elenchi consecutivi.

Anche per questi sono:
list1 = (2,4, ..., n / 2)
list2 = (1,3, ..., n / 2-1)

Per dispari n abbiamo:
list1 = (2,4, ..., Piano [n / 2])
list2 = (1,3, ..., Piano [n / 2])

Per questo "algoritmo" deve essere presa solo una decisione (n pari o dispari), il resto è solo scrivere n numeri.

Una possibile soluzione Mathematica è fornita in alto.

2) Una domanda correlata è quante di queste permuazioni esistono in funzione di n.

Mathematica, 124 byte

a[0] = a[1] = 1; a[2] = a[3] = 0;
a[n_] := a[n] = (n + 1)*a[n - 1] - (n - 2)*a[n - 2] - (n - 5)*a[n - 3] + (n - 3)*a[n - 4]

Provalo online!

Esempio:

a[#] & /@ Range[4, 12]

{2, 14, 90, 646, 5242, 47622, ​​479306, 5296790, 63779034}

Contare il numero di tali permutazioni è un problema standard.

Per n = 4 ci sono 2: {{2,4,1,3}, {3,1,4,2}}

Per n = 5 ci sono 14: {{1,3,5,2,4}, {1,4,2,5,3}, {2,4,1,3,5}, {2,4, 1,5,3}, {2,5,3,1,4}, {3,1,4,2,5}, {3,1,5,2,4}, {3,5,1, 4,2}, {3,5,2,4,1}, {4,1,3,5,2}, {4,2,5,1,3}, {4,2,5,3, 1}, {5,2,4,1,3}, {5,3,1,4,2}}

Il numero a (n) di queste permutazioni aumenta rapidamente: 2, 14, 90, 646, 5242, 47622, ​​479306, 5296790, 63779034, ...

Per n grande il rapporto a (n) / n! sembra avvicinarsi al limite 1 / e ^ 2 = 0.135335 ... Non ho prove rigorose ma è solo una congettura di prove numeriche. Puoi verificarlo provando a eseguire il programma online.

Il programma sopra (basato sul riferimento riportato di seguito) calcola questi numeri.

Puoi trovare ulteriori informazioni nella sequenza pertinente su OEIS: A002464 . Il problema di Hertzsprung: modi per disporre n re non attaccanti su una tavola X n, con 1 in ogni riga e colonna. Anche numero di permutazioni di lunghezza n senza successioni in aumento o in diminuzione.


@ Stewie Griffin Dato che sono nuovo qui, ti preghiamo di spiegare più in dettaglio cosa intendi. Nella mia prima osservazione ho fornito un algoritmo e un codice che risolvono il problema in tempi polinomiali. Quindi dovrebbe essere considerata una soluzione alla sfida. La seconda parte estende l'interessante problema. Quindi dovrebbe essere considerato come un commento.
— Dr. Wolfgang Hintze,

Mi sono preso la libertà di modificare leggermente la tua richiesta in modo che il tuo codice Mathematica sia in cima. Con le sfide del code-golf è obbligatorio fornire il codice effettivo (il più breve possibile). Il modo in cui l'ho formattato diventa una risposta di Mathematica come probabilmente intendevi, e ha ancora la tua spiegazione originale sotto di essa. Se ritieni che manchi qualcosa o ho modificato in modo errato la tua risposta iniziale, sentiti libero di modificarlo di nuovo. Benvenuti in PPCG! :)
— Kevin Cruijssen,

@ Kevin Cruijssen Grazie mille per il caloroso benvenuto e la modifica della mia ingenua presentazione. Ho ora aggiunto un programma Mathematica per la seconda osservazione. Che probabilmente non è lege artis. Soprattutto non so come creare il bel link "provalo online".
— Dr. Wolfgang Hintze,

Qualsiasi collegamento può essere creato utilizzando [some text](the_link). Per quanto riguarda in particolare il link "Provalo online", il sito web https://tio.run/ che è ospitato dal nostro @Dennis contiene collegamenti a tutti i tipi di linguaggi di programmazione. Wolfram Language (Mathematica) è uno di questi. Nella parte superiore puoi quindi fare clic sul pulsante Riproduci per eseguire il codice o sul pulsante Collegamento ipertestuale per copiare "Provalo online". (markup-) collegamenti. E puoi dividere il tuo codice in un vero "Codice" (la tua presentazione), con un'intestazione / piè di pagina opzionale per (piuttosto) stampare una o più prove.
— Kevin Cruijssen,

Ci scusiamo per il mio commento piuttosto schietto, e la mancanza di risposta da allora in poi! La risposta è apparsa nella coda di revisione e non ho notato il codice a causa della formattazione. Non è raro che i nuovi utenti pubblichino "osservazioni interessanti" alle sfide, senza fornire una risposta effettiva ad esse. Mentre è fatto in buona fede, non è di questo che tratta il sito. Ho pensato che fosse una risposta del genere. Avrei dovuto rispondere al tuo commento, ma avevo fretta e non potevo scrivere un nuovo commento, quindi ho rimosso quello vecchio. Scuse! E benvenuti nel sito! Spero che resterai in giro! :)
— Stewie Griffin,



2

Spazio bianco , 161 byte

Ecco l'invio ufficiale, non commentato: provalo online!

push_0   
read_n	
		push_0   
retreive_n			push_1  		
subtract	   dup_and_out[ 
 	
 	]label_s'
   
'push_2  		 
subtract	   dup[ 
 ]jump_next_if_neg:
		  
:dup_and_out[ 
 	
 	]else_jump_back:
 
 
:label_ss'
    
'push_0   
retreive_n			push_2  		 
subtract	   dup_and_out[ 
 	
 	]dup[ 
 ]jump_next:
 
    
:label_ssss'
      
'push_2  		 
subtract	   dup[ 
 ]jump_end_if_neg:
		   
:dup_and_out[ 
 	
 	]else_jump_back:
 
    
:label_sss'
     
'end



Provalo online!

Ho sacrificato alcuni byte in modo che il programma si eseguisse senza errori, credo che potrei perdere circa 7-8 byte e continuerebbe a produrre correttamente, ma genererebbe anche messaggi di errore e nessuno lo vuole.

Spiegazione byte completa:

[Space][Space][Space][N]                   Push a 0 on the stack
[Tab][Tab][N][Tab][Tab][Tab][Tab]          Read input value and store in heap
[Space][Space][Space][N]                   Push a 0 on the stack again
[Tab][Tab][Tab]                            Retrieve the value from the heap
[Space][Space][Tab][Tab][N]                Push a -1 on the stack
[Tab][Space][Space][Space]                 Add -1 to value
[Space][N][Space]                          Duplicate 
[Tab][N][Space][Tab]                       Output
[N][Space][Space][Space][N]                Set First Label
[Space][Space][Tab][Tab][Space][N]         Push a -2 on the stack
[Tab][Space][Space][Space]                 Subtract 2 from value
[Space][N][Space]                          Duplicate
[N][Tab][Tab][Space][Space][N]             If negative, jump to second label
[Space][N][Space]                          Duplicate
[Tab][N][Space][Tab]                       Output
[N][Space][N][Space][N]                    Jump back to first label
[N][Space][Space][Space][Space][N]         Set Second Label
[Space][Space][Space][N]                   Push a 0 on the stack
[Tab][Tab][Tab]                            Retrieve input value from heap again
[Space][Space][Tab][Tab][Space][N]         Push a -2 on the stack
[Tab][Space][Space][Space]                 This time, Add a -2 to the value
[Space][N][Space]                          Duplicate
[Tab][N][Space][Tab]                       Output
[Space][N][Space]                          Duplicate
[N][Space][N][Space][Tab][N]               Jump to third label
[N][Space][Space][Space][Tab][N]           Set third label
[Space][Space][Tab][Tab][Space][N]         Push a -2 on the stack
[Tab][Space][Space][Space]                 Subtract 2 from value
[Space][N][Space]                          Duplicate
[N][Tab][Tab][Space][Space][Space][N]      Jump to end if negative
[Space][N][Space]                          Duplicate
[Tab][N][Space][Tab]                       Output
[N][Space][N][Space][Tab][N]               Jump back to third label
[N][Space][Space][Space][Space][Space][N]  Set fourth label/end
[N][N][N]                                  Terminate

Alcune cose da golf: push_0, read_STDIN_as_int, push_0, retrievepuò essere push_0, duplicate_0, read_STDIN_as_int, retrieveper salvare un byte. E la prima etichetta può essere vuota con NSSNinvece di NSSSN(e quindi la seconda etichetta può essere NSSSN; terza NSSTN; e quarta NSSSSN). Ciò dovrebbe salvare anche 8 byte. Inoltre, puoi rimuovere il primo Jump_to_third_labelperché hai già il Set_third_labeldiritto di seguito. In totale: 140 byte ; (o con commenti: provalo online .) -3 byte se rimuovi NNNexit.
— Kevin Cruijssen,


1

Gol> <> , 14 byte

FL:2%Z}:3=?$|B

Provalo online!

Esempio di programma completo e come funziona

1AGIE;GDlR~
FL:2%Z}:3=?$|B

1AG          Register row 1 as function G
   IE;       Take number input; halt on EOF
      GD     Call G and print the stack
        lR~  Empty the stack
             Repeat indefinitely

F           |   Repeat n times...
 L              Push loop counter (0..n-1)
  :2%Z}         If even, move to bottom of the stack
       :3=?$    If top == 3, swap top two
                  This is activated only once to make [2 0 3 1]
             B  Return

1

J , 10 byte

i./:2|1+i.

Provalo online!

Spiegazione:

  /:          sort
i.            the numbers in the range 0..n-1 
    2|        according the remainder mod 2 of 
      1+i.    the numbers in the range 1..n   

1

Java 8, 56 byte

n->{for(int i=n;i>0;)System.out.println((i+--i)%(n|1));}

Porta della risposta JavaScript (ES6) di @Neil .

Provalo online.


66 byte vecchi rispondono:

n->{String[]r={"",""};for(;n-->0;)r[n%2]+=n+" ";return r[0]+r[1];}

Provalo online.

Spiegazione:

n->{                  // Method with integer parameter and String return-type
  String[]r={"",""};  //  Result-Strings, both starting empty
  for(;n-->0;)        //  Loop in the range (n, 0]
    r[i%2]+=i+" ";    //   Append `i` and a space to one of the two result-Strings,
                      //   depending on if it is even (first) or odd (second)
  return r[0]+r[1];}  //  Return the two result-Strings appended to each other

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.