Trova l'elenco secondario univoco più breve


14

Dato un elenco di elenchi trova l'elenco più breve che è un elenco secondario contiguo di esattamente un elenco.

Ad esempio se avessimo

[[1,2,3],
 [1,2,3,4],
 [2,4,5,6],
 [1,2,4,5,6]]

l'elenco [3,4]secondario contiguo più breve sarebbe poiché appare solo nel secondo elenco.

Se non esiste un elenco secondario contiguo univoco (ciò richiede almeno una voce duplicata), genera un elenco vuoto. Ecco un esempio

[[1,2,3],
 [1,2,3],
 [1,2]]

Se sono presenti più elenchi contigui contigui di dimensioni minime, è possibile generare uno qualsiasi di essi o un elenco che li contiene tutti. Ad esempio se l'input era

[[1,2,3],[2],[1],[3]]

Si potrebbe uscita sia [1,2], [2,3]o [[1,2],[2,3]]. Se si sceglie di eseguire quest'ultima opzione, è possibile generare elenchi singleton per i casi in cui esiste un'unica soluzione.

L'output può verificarsi nello stesso elenco più di una volta, purché non venga visualizzato in nessun altro elenco. Per esempio

[[1,2,1,2],[2,1]]

dovrebbe essere generato [1,2]perché [1,2]è un elenco secondario del primo elenco ma non del secondo, anche se è un elenco secondario del primo elenco in due modi diversi.

È possibile prendere come input un elenco di elenchi contenenti qualsiasi tipo, purché tale tipo abbia più di 100 valori possibili, ovvero nessun valore booleano.

Si tratta di quindi le risposte verranno classificate in byte con meno byte migliori.

Casi test

[[1,1]] : [1]
[[1],[1]] : []
[[1,1],[1]] : [1,1]

Risposte:


5

Buccia , 12 14 15 byte

+3 byte per caso [[1,1]]

Ṡḟȯ¬€Ṡ-uÖLṁȯtuQ

Provalo online!

spiegazione

          ṁ      -- map and concatenate
           ȯt    --   all but the first
             u   --   unique elements of
              Q  --   contiguous sublist
        ÖL       -- sort by length
Ṡḟ               -- find the first element satisfying this predicate
  ȯ¬€            --   not an element of
     Ṡ-          --   the list of sublists minus
       u         --   its unique elements

Nota: Ṡ f g x = f (g x) xe questo è difficile da spiegare usando il metodo sopra.


14 byte con un lambda.
Zgarb,

Ciò fallisce per[[1,1]]
H.Piz,

Hmm, e il fissaggio che lo rende oltre 15 byte. Oh bene.
Zgarb,

4

Pyth, 15 byte

halDs-M.p.:R)QY

Suite di test

Innanzitutto, generiamo tutte le sottostringhe di ciascun elenco di input con .:R)Q. Quindi, generiamo tutti i possibili ordinamenti, di quei gruppi di sottostringhe .p.

Ora per la parte difficile: -M. Questo piega la -funzione su ogni lista di ordinazione. Inizia con il primo elenco di sottostringhe, quindi filtra tutti gli occupanti di tutti gli altri elenchi.

Quindi, i risultati vengono concatenati, ordinati per lunghezza, []viene aggiunto a e quindi viene estratto il primo elemento dell'elenco risultante h.

Questo sarebbe più corto di 4 byte se potessi sbagliare su nessun elenco secondario univoco anziché visualizzare un elenco vuoto.


Qual è la tua versione a 11 byte?
Leaky Nun,

@LeakyNun hlDs-M.p.:Rè probabilmente ciò che intende.
FryAmTheEggman,


2

Haskell , 149 128 126 113 byte

import Data.List
f l=[x|x<-l,sum[1|y<-l,y==x]<2]
h[]=[]
h(x:y)=x
i=h.f.sortOn length.(>>=tail.nub.(>>=tails).inits)

Provalo online!

Risparmiato 21 byte grazie a Wheat Wizard, H.PWiz e Bruce Forte.

Altri due byte salvati grazie a H.PWiz.

Salvato 13 byte grazie a nimi.

EDIT Questa era la spiegazione originale:

  • a è una scorciatoia per unire le liste.

  • scalcola tutti gli elenchi continui (tutti tailsda tutti inits). Nota che nubmantiene solo la prima occorrenza di ciascun elemento, quindi tailrimuoverà l'elenco vuoto dalle liste secondarie.

  • g unisce tutte le liste secondarie da tutte le liste date in un grande elenco di liste secondarie e le ordina per lunghezza.

  • f f è un filtro sugli elementi che appaiono solo una volta nella grande lista

  • h è una versione sicura di head

  • i è la colla

Abbastanza inelegante! Dovrebbe esserci una soluzione migliore ...


2
Sembra che un paio delle tue funzioni potrebbero essere più brevi se scritte come funzioni senza punti.
Post Rock Garf Hunter,

1
Inoltre, non è necessario contare la i=fine del programma perché non è necessario assegnare funzioni prive di punti in base alle nostre regole.
Post Rock Garf Hunter,

2
È foldl1(++)giusto concat?
H.Piz,

2
(length$filter(==x)l)potrebbe essere più breve length(filter(==x)l)o addirittura più breve disum[1|y<-l,y==x]
Post Rock Garf Hunter il

2
@ H.PWiz Tranne per il fatto []che è, ma >>=idè ancora più breve;) Anche @jferard: puoi incorporare molte funzioni (ad es. f, gEcc.) Poiché le usi solo una volta.
ბიმო

2

Java 8, 251 + 19 = 270 byte

Un lambda molto grossolano da, minimamente, List<List>a List(meglio lanciarlo Function<List<List<Integer>>, List<Integer>>però). È una soluzione di forza bruta che esegue l'iterazione di lunghezze di blocco da 1 alle dimensioni dell'elenco più grande, in ogni caso iterando su ogni blocco di quella lunghezza in ogni elenco e controllando ciascuno di questi blocchi rispetto a ciascun blocco di uguale dimensione in ogni altro elenco.

Temimi, spazzino.

import java.util.*;

i->{int x,l=x=0,s,t;for(List z:i)x=Math.max(x,z.size());List r=i;while(l++<=x)for(List a:i)c:for(s=0;s<=a.size()-l;s++){for(List b:i)for(t=0;t<=b.size()-l;)if(b.subList(t,l+t++).equals(r=a.subList(s,s+l))&a!=b)continue c;return r;}return new Stack();}

Lambda ungolfed

i -> {
    int
        x,
        l = x = 0,
        s, t
    ;
    for (List z : i)
        x = Math.max(x, z.size());
    List r = i;
    while (l++ <= x)
        for (List a : i)
            c: for (s = 0; s <= a.size() - l; s++) {
                for (List b : i)
                    for (t = 0; t <= b.size() - l; )
                        if (b.subList(t, l + t++).equals(r = a.subList(s, s + l)) & a != b)
                            continue c;
                return r;
            }
    return new Stack();
}

Provalo online

Java 8, 289 + 45 = 334 byte

Questo è un approccio più funzionale usando i flussi. Se esistesse un metodo Streamper ridurre a soli elementi che appaiono una volta, questa soluzione avrebbe battuto quella sopra. Assegna allo stesso tipo di cui sopra.

import java.util.*;import java.util.stream.*;

l->{List<List>o=l.stream().flatMap(a->IntStream.range(1,a.size()+1).boxed().flatMap(n->IntStream.range(0,a.size()-n+1).mapToObj(k->a.subList(k,k+n)))).collect(Collectors.toList());o.sort((a,b)->a.size()-b.size());for(List a:o)if(o.indexOf(a)==o.lastIndexOf(a))return a;return new Stack();}

Lambda ungolfed

l -> {
    List<List> o = l.stream()
        .flatMap(a -> IntStream.range(1, a.size() + 1)
            .boxed()
            .flatMap(n -> IntStream.range(0, a.size() - n + 1)
                .mapToObj(k -> a.subList(k, k + n))
            )
        )
        .collect(Collectors.toList())
    ;
    o.sort((a, b) -> a.size() - b.size());
    for (List a : o)
        if (o.indexOf(a) == o.lastIndexOf(a))
            return a;
    return new Stack();
}

Provalo online


1

Gelatina , 15 byte

Ẇ€Q€ẎɓċỊµÐf⁸LÐṂ

Provalo online!

-3 byte grazie a Jonathan Allan


Può ċ1essere sostituito con S?

@ThePirateBay In effetti può, grazie. Ho realizzato una versione diversa però. (anche se lo porterebbe allo stesso conto)
HyperNeutrino,

La tua nuova soluzione stampa [1, 2, 1]per input [[1,2],[1,2,1],[2,1,1]]mentre [1,1]è più breve.

@ThePirateBay Risolto, grazie.
HyperNeutrino,

1
@JonathanAllan oh um. Non posso contare whoops. : P
HyperNeutrino,


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.