Sequenze intercalari


18

Le sequenze interfogliate rappresentano una fusione arbitraria di un certo numero di sequenze.

È possibile creare una sequenza interfogliata aggiungendo gli elementi a un elenco uno a uno da un numero di elenchi, scegliendo ogni volta l'elemento successivo da un elenco. Pertanto, una sequenza interfogliata conterrà esattamente gli stessi elementi di tutte le liste combinate, in un ordine coerente con tutte le liste.

L'unica interleaving di 1 lista è quella stessa lista.

Sfida

La tua sfida è quella di creare una funzione / programma che prenda un numero arbitrario di sequenze e produca tutti i possibili intrecci di quelle sequenze.

Esempi

Input: [1, 2], [3, 4]
Output:
    [1, 2, 3, 4]
    [1, 3, 2, 4]
    [1, 3, 4, 2] 
    [3, 1, 2, 4]
    [3, 1, 4, 2]
    [3, 4, 1, 2]

Input: [1, 2, 3, 4, 5]
Output:
    [1, 2, 3, 4, 5]

Input: []
Output:
    []

Input: <nothing>
Output:
    []

(also acceptable)
Input: <nothing>
Output: <nothing>

Input: [1, 2, 3], [4, 5]
Output:
    [1, 2, 3, 4, 5]
    [1, 2, 4, 3, 5]
    [1, 2, 4, 5, 3]
    [1, 4, 2, 3, 5]
    [1, 4, 2, 5, 3]
    [1, 4, 5, 2, 3]
    [4, 1, 2, 3, 5]
    [4, 1, 2, 5, 3]
    [4, 1, 5, 2, 3]
    [4, 5, 1, 2, 3]

Input: [1, 2], [3, 4], [5, 6]
Output:
    [1, 2, 3, 4, 5, 6]
    [1, 2, 3, 5, 4, 6]
    [1, 2, 3, 5, 6, 4]
    [1, 2, 5, 3, 4, 6]
    [1, 2, 5, 3, 6, 4]
    [1, 2, 5, 6, 3, 4]
    [1, 3, 2, 4, 5, 6]
    [1, 3, 2, 5, 4, 6]
    [1, 3, 2, 5, 6, 4]
    [1, 3, 4, 2, 5, 6]
    [1, 3, 4, 5, 2, 6]
    [1, 3, 4, 5, 6, 2]
    [1, 3, 5, 2, 4, 6]
    [1, 3, 5, 2, 6, 4]
    [1, 3, 5, 4, 2, 6]
    [1, 3, 5, 4, 6, 2]
    [1, 3, 5, 6, 2, 4]
    [1, 3, 5, 6, 4, 2]
    [1, 5, 2, 3, 4, 6]
    [1, 5, 2, 3, 6, 4]
    [1, 5, 2, 6, 3, 4]
    [1, 5, 3, 2, 4, 6]
    [1, 5, 3, 2, 6, 4]
    [1, 5, 3, 4, 2, 6]
    [1, 5, 3, 4, 6, 2]
    [1, 5, 3, 6, 2, 4]
    [1, 5, 3, 6, 4, 2]
    [1, 5, 6, 2, 3, 4]
    [1, 5, 6, 3, 2, 4]
    [1, 5, 6, 3, 4, 2]
    [3, 1, 2, 4, 5, 6]
    [3, 1, 2, 5, 4, 6]
    [3, 1, 2, 5, 6, 4]
    [3, 1, 4, 2, 5, 6]
    [3, 1, 4, 5, 2, 6]
    [3, 1, 4, 5, 6, 2]
    [3, 1, 5, 2, 4, 6]
    [3, 1, 5, 2, 6, 4]
    [3, 1, 5, 4, 2, 6]
    [3, 1, 5, 4, 6, 2]
    [3, 1, 5, 6, 2, 4]
    [3, 1, 5, 6, 4, 2]
    [3, 4, 1, 2, 5, 6]
    [3, 4, 1, 5, 2, 6]
    [3, 4, 1, 5, 6, 2]
    [3, 4, 5, 1, 2, 6]
    [3, 4, 5, 1, 6, 2]
    [3, 4, 5, 6, 1, 2]
    [3, 5, 1, 2, 4, 6]
    [3, 5, 1, 2, 6, 4]
    [3, 5, 1, 4, 2, 6]
    [3, 5, 1, 4, 6, 2]
    [3, 5, 1, 6, 2, 4]
    [3, 5, 1, 6, 4, 2]
    [3, 5, 4, 1, 2, 6]
    [3, 5, 4, 1, 6, 2]
    [3, 5, 4, 6, 1, 2]
    [3, 5, 6, 1, 2, 4]
    [3, 5, 6, 1, 4, 2]
    [3, 5, 6, 4, 1, 2]
    [5, 1, 2, 3, 4, 6]
    [5, 1, 2, 3, 6, 4]
    [5, 1, 2, 6, 3, 4]
    [5, 1, 3, 2, 4, 6]
    [5, 1, 3, 2, 6, 4]
    [5, 1, 3, 4, 2, 6]
    [5, 1, 3, 4, 6, 2]
    [5, 1, 3, 6, 2, 4]
    [5, 1, 3, 6, 4, 2]
    [5, 1, 6, 2, 3, 4]
    [5, 1, 6, 3, 2, 4]
    [5, 1, 6, 3, 4, 2]
    [5, 3, 1, 2, 4, 6]
    [5, 3, 1, 2, 6, 4]
    [5, 3, 1, 4, 2, 6]
    [5, 3, 1, 4, 6, 2]
    [5, 3, 1, 6, 2, 4]
    [5, 3, 1, 6, 4, 2]
    [5, 3, 4, 1, 2, 6]
    [5, 3, 4, 1, 6, 2]
    [5, 3, 4, 6, 1, 2]
    [5, 3, 6, 1, 2, 4]
    [5, 3, 6, 1, 4, 2]
    [5, 3, 6, 4, 1, 2]
    [5, 6, 1, 2, 3, 4]
    [5, 6, 1, 3, 2, 4]
    [5, 6, 1, 3, 4, 2]
    [5, 6, 3, 1, 2, 4]
    [5, 6, 3, 1, 4, 2]
    [5, 6, 3, 4, 1, 2]

Regole

  • Scappatoie standard vietate (duh)
  • L'input può essere preso in qualsiasi formato ragionevole, ad esempio un elenco di elenchi, un elenco vararg di elenchi, elenchi di parametri, ecc ... purché non sia chiaro dove gli elenchi iniziano e finiscono.
  • L'output può essere in qualsiasi formato ragionevole, purché sia ​​chiaro dove iniziano e finiscono gli elenchi. Gli output validi includono, ma non sono necessariamente limitati a:
    • stdout, con un elenco per riga
    • Un elenco di elenchi
    • Un iteratore su liste (può essere implementato con un generatore se la tua lingua li ha)
  • L'ordine delle intrecci ceduti non ha importanza, tuttavia, non dovrebbero esserci ripetute intrecci.
  • Per semplificare il rilevamento ripetuto, è possibile supporre che tutti gli elementi in tutte le sequenze di input siano univoci.
  • Se non viene fornito alcun elenco come input, sia l'elenco vuoto che nessun output sono output validi.
  • I tipi di elementi nelle sequenze sono irrilevanti. (ad esempio, potrebbero essere tutti un tipo o un miscuglio di tipi, a seconda di quale sia più conveniente nella tua lingua)
  • Il tuo programma / funzione deve essere garantito per terminare entro un tempo limitato.
  • Questo è , quindi vince il codice più breve per ogni lingua.

L'unica interleaving di nessuna lista è la lista vuota. Ciò significa che dobbiamo produrre [[]]invece di []quando non ci viene fornito alcun elenco come input?
Erik the Outgolfer,

Inoltre, le liste avranno la stessa lunghezza?
Erik the Outgolfer,

Suppongo che sarebbe matematicamente sano non restituire elenchi come output se non vengono forniti elenchi come input. Consentirò entrambi. Tutti gli elenchi di output avranno la stessa lunghezza. Gli elenchi di input possono variare in lunghezza.
Beefster,

Risposte:



5

Python 2 , 103 92 79 78 byte

def f(A,c=[]):
 if not[f([b[b==x:]for b in A],c+x[:1])for x in A if x]:print c

Provalo online!

O:

Python 3 , 73 byte

def f(A,c=[]):[f([b[b==x:]for b in A],c+x[:1])for x in A if x]or print(c)

Provalo online!

-1 sostituendo [x[0]]con x[:1]come da xnor

-13 byte rubando spudoratamente l' espansione [b[b==x:]for b in A]come suggerito dalla risposta di Neil invece di un enumerateapproccio più lungo .

Prende un elenco di elenchi Acome input. Se tutti gli elementi di Asono vuoti, allora l'elenco valutato in ifsarà vuoto, quindi abbiamo raggiunto la fine della ricorsione e possibile print. Altrimenti, abbiamo un elenco di uno o più None; e ricerchiamo.


[x[0]]èx[:1]
xnor

@xnor: certo! grazie!
Chas Brown,

4

Gelatina , 11 byte

FŒ!fЀ⁼ṛɗÐf

Provalo online!

Come funziona

FŒ!fЀ⁼ṛɗÐf  Main link. Argument: A (array of arrays)

F            Flatten A.
 Œ!          Take all permutations.
        ɗÐf  Filter by the chain to the left, keeping only permutations for which
             it returns a truthy value.
   fЀ         Intersect the permutation with each array in A.
      ⁼ṛ       Test if the result is equal to A.

3

Rubino, 66 byte

f=->a,*p{(a-=[[]])[0]?a.flat_map{|b|h,*t=b;f[a-[b]+[t],*p,h]}:[p]}

Se non ci sono sequenze non vuote, restituire una sequenza vuota. Altrimenti, per ogni sequenza non vuota, ricorrere con il primo elemento rimosso, quindi aggiungerlo all'inizio di ogni risultato. L'implementazione utilizza il presupposto che gli elementi siano garantiti come globalmente unici, altrimenti a-[b]potrebbe potenzialmente rimuovere più di 1 sequenza dalla chiamata ricorsiva. Anche se riflettendo, forse sarebbe effettivamente il comportamento giusto per evitare duplicati di output.

Esempio IO:

f[[[1,2],[3,4]]] => [[1, 3, 2, 4], [1, 3, 4, 2], [1, 2, 3, 4], [3, 1, 4, 2], [3, 1, 2, 4], [3, 4, 1, 2]]


2

Wolfram Language (Mathematica) , 76 75 71 byte

Cases[Permutations[Join@@#],x_/;And@@OrderedQ/@(x~Position~#&/@#&/@#)]&
(* or *)
Cases[Join/*Permutations@@#,x_/;And@@(x~Position~#&/@#&/*OrderedQ/@#)]&

Provalo online!

Approccio ingenuo: trova tutte le permutazioni che sono intrecci dell'input.

Spiegazione

Permutations[Join@@#]

Appiattire <input>e trovare tutte le sue permutazioni.

Cases[ ... ,x_/; ...]

Trova tutti gli elementi in xmodo che ...

(x~Position~#&/@#&/@#)

Sostituire tutti gli elementi in profondità-2 <input>con la rispettiva posizione in x.

And@@OrderedQ/@ ...

Controllare se tutti gli elenchi di profondità 1 sono ordinati (ovvero in ordine crescente).

Implementazione effettiva di interleaving, 117 byte

Cases[{}~(f=ReplaceList[#2,{{a___,{b_,c___},d___}/;b>0:>#~Join~{b}~f~{a,{c},d},_:>#}]&)~#,{___},{Tr[1^(Join@@#)]+1}]&

Provalo online!


2

Python 2 , 87 84 byte

f=lambda a:any(a)and[b[:1]+c for b in a if b for c in f([c[c==b:]for c in a])]or[[]]

Provalo online! Porta della mia risposta JavaScript. Modifica: 3 byte salvati grazie a @ChasBrown.


-3 sostituendo sum(a,[])con any(a).
Chas Brown,

@ChasBrown Grazie, non conosco bene Python.
Neil,

Neil: Abbastanza bene, penso :). sum(a,[])ha un buon uso in alcune situazioni, però!
Chas Brown,

2

Haskell , 45 byte

f l=max[[]][h:y|h:t<-l,y<-f$t:filter(/=h:t)l]

Provalo online!

Adattato dalla risposta Python di Chas Brown .

La max[[]]è un trucco che invia un caso base [[]]quando l'ingresso contiene solo []elementi. In tal caso, l'elenco utilizzato per vuoto, ricorsivo è vuoto e max[[]][]fornisce [[]].

Durante la ricorrenza, anziché eliminare selettivamente il primo elemento dell'elenco scelto h:t, creiamo un nuovo elenco con tin primo piano e h:tfiltrato.


0

JavaScript (Firefox 30-57), 92 byte

f=a=>a.some(b=>b+b)?[for(b of a)if(b+b)for(c of f(a.map(c=>c.slice(c==b))))[b[0],...c]]:[[]]

0

Japt -Q , 14 byte

c á f@e_XfZ eZ
c              // Flatten the input into a single array
  á            // and find all permutations.
    f          // Then filter the results for items
     @e_       // where for each original input
        XfZ eZ // the ordering of the items is unchanged.

Accetta l'input come una matrice di array. -Qfa in modo che l'output conservi la notazione dell'array.

Provalo qui.


0

Scala: (non inteso come minimo, più una chiara risorsa di riferimento)

object Interleave {

  private def interleavePair[A](x: Seq[A], y: Seq[A]): Seq[Seq[A]] =
    (x, y) match {
      case (a +: c, b +: d) =>
        interleavePair(x, d).map(b +: _) ++ interleavePair(c, y).map(a +: _)
      case _ => Seq(x ++ y)
    }

  def interleave[A](ssa: Seq[Seq[A]]): Seq[Seq[A]] =
    ssa.foldLeft[Seq[Seq[A]]](Seq(Seq.empty)) {
      case (sssat, sa) => sssat.flatMap(interleavePair(sa, _))
    }
}

object Main extends App {

  import Interleave._

  println(interleave(Seq()))
  println(interleave(Seq(Seq(1, 2), Seq(3, 4))))
}

Provalo online!


1
Dovresti almeno provare a giocare a golf con questo codice ...
Timtech,
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.