Encuentra la sublista única más corta

14

Dada una lista de listas, encuentre la lista más corta que sea una sublista contigua de exactamente una lista.

Por ejemplo si tuviéramos

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

la sublista contigua más corta sería [3,4]ya que solo aparece en la segunda lista.

Si no hay una sublista contigua única (esto requiere al menos una entrada duplicada), envíe una lista vacía. Aquí hay un ejemplo

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

Si hay varias sublistas contiguas de tamaño mínimo, puede generar cualquiera de ellas o una lista que las contenga a todas. Por ejemplo, si la entrada fue

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

Puede generar cualquiera [1,2], [2,3]o [[1,2],[2,3]]. Si elige hacer la última opción, puede generar listas singleton para los casos en los que solo hay una solución.

La salida puede aparecer en la misma lista más de una vez, siempre que no aparezca en ninguna otra lista. Por ejemplo

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

debería salir [1,2]porque[1,2] es una sublista de la primera lista pero no la segunda, aunque es una sublista de la primera lista de dos maneras diferentes.

Puede tomar como entrada una lista de listas que contienen cualquier tipo siempre que ese tipo tenga más de 100 valores posibles, es decir, no Booleanos.

Esto es por lo que las respuestas se puntuarán en bytes, siendo mejores menos bytes.

Casos de prueba

[[1,1]] : [1]
[[1],[1]] : []
[[1,1],[1]] : [1,1]
Post Rock Garf Hunter
fuente

Respuestas:

5

Casco , 12 14 15 bytes

+3 bytes por caso [[1,1]]

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

Pruébalo en línea!

Explicación

          ṁ      -- 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) xy esto es difícil de explicar usando el método anterior.

H.PWiz
fuente
14 bytes con una lambda.
Zgarb
Eso falla para[[1,1]]
H.PWiz
Hmm, y su reparación lo hace más de 15 bytes. Oh bien.
Zgarb
4

Pyth, 15 bytes

halDs-M.p.:R)QY

Banco de pruebas

Primero, generamos todas las subcadenas de cada lista de entrada con .:R)Q. Luego, generamos todos los pedidos posibles, de esos grupos de subcadenas.p .

Ahora viene la parte difícil: -M. Esto dobla el- función sobre cada lista de pedidos. Comienza con la primera lista de subcadenas, luego filtra a todos los ocupantes de todas las demás listas.

Luego, los resultados se concatenan, se ordenan por longitud, []se agrega a, y luego se extrae el primer elemento de la lista resultante conh .

Esto sería 4 bytes más corto si pudiera error en ninguna sublista única en lugar de generar una lista vacía.

isaacg
fuente
¿Cuál es su versión de 11 bytes?
Leaky Nun
@LeakyNun hlDs-M.p.:Res probablemente lo que quiere decir.
FryAmTheEggman
3

Pyth - 20 bytes

Ksm.:d)QhalDfq1/KTKY

Test Suite .

Maltysen
fuente
Tengo 16 bytes , pero no estoy seguro de que esto sea correcto. De lo contrario, es bastante similar.
FryAmTheEggman
@FryAmTheEggman genial, deberías publicarlo.
Maltysen
Falla para la prueba de caso de borde recientemente agregada [[1,1]].
Jonathan Allan
2

Haskell , 149 128 126 113 bytes

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)

Pruébalo en línea!

Ahorró 21 bytes gracias a Wheat Wizard, H.PWiz y Bruce Forte.

Ahorró dos bytes más gracias a H.PWiz.

Guardado 13 bytes gracias a nimi.

EDITAR Esta fue la explicación original:

  • a es un atajo para unir listas.

  • scalcula todas las sublistas continuas (todas tailsde todas inits). Tenga en cuenta que nubsolo conserva la primera aparición de cada elemento, por taillo que eliminará la lista vacía de las sublistas.

  • g combina todas las sublistas de todas las listas dadas en una gran lista de sublistas y las ordena por longitud.

  • f f es un filtro de elementos que aparecen solo una vez en la lista grande

  • h es una versión segura de head

  • i es el pegamento

¡Muy poco elegante! Debería haber una mejor solución ...

jferard
fuente
2
Parece que algunas de sus funciones podrían ser más cortas si se escriben como funciones sin puntos.
Post Rock Garf Hunter
1
Tampoco tiene que contar i=al final de su programa porque no es necesario asignar funciones sin puntos de acuerdo con nuestras reglas.
Post Rock Garf Hunter
2
Es foldl1(++)justo concat?
H.PWiz
2
(length$filter(==x)l)podría ser más corto length(filter(==x)l)o incluso más cortosum[1|y<-l,y==x]
Post Rock Garf Hunter
2
@ H.PWiz Excepto porque []lo es, pero >>=ides aún más corto;) También @jferard: puede incorporar muchas funciones (por ejemplo f, getc.) ya que solo las usa una vez.
ბიმო
2

Java 8, 251 + 19 = 270 bytes

Una lambda muy asquerosa de, mínimamente, List<List>a List(mejor lanzarlo aFunction<List<List<Integer>>, List<Integer>> aunque ). Es una solución de fuerza bruta que itera longitudes de fragmentos desde 1 hasta el tamaño de la lista más grande, en cada caso iterando sobre cada fragmento de esa longitud en cada lista y verificando cada fragmento en cada fragmento del mismo tamaño en todas las demás listas.

Teme, recolector de basura.

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 sin golf

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();
}

Pruébalo en línea

Java 8, 289 + 45 = 334 bytes

Este es un enfoque más funcional que utiliza flujos. Si hubiera un método Streampara reducir a solo elementos que aparecen una vez, esta solución habría superado la anterior. Asignar al mismo tipo que el anterior.

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 sin golf

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();
}

Pruébalo en línea

Jakob
fuente
1

Jalea , 15 bytes

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

Pruébalo en línea!

-3 bytes gracias a Jonathan Allan

Hiperneutrino
fuente
Se ċ1puede reemplazar con S?
@ThePirateBay De hecho puede, gracias. Aunque hice una versión diferente. (aunque lo llevaría al mismo bytecount)
HyperNeutrino
Su nueva solución imprime [1, 2, 1]para entrada [[1,2],[1,2,1],[2,1,1]]mientras [1,1]es más corta.
@ThePirateBay Solucionado, gracias.
HyperNeutrino
1
@ JonathanAllan oh um. No puedo contar whoops. : P
HyperNeutrino