Найдите самый короткий уникальный подсписок

14

По заданному списку списков найдите самый короткий список, который является непрерывным подсписком ровно одного списка.

Например, если бы мы имели

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

самый короткий непрерывный подсписок будет, [3,4]поскольку он появляется только во втором списке.

Если нет уникального смежного подсписка (для этого требуется хотя бы одна повторяющаяся запись), выведите пустой список. Вот пример

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

Если имеется несколько смежных подсписков минимального размера, вы можете вывести любой из них или список, содержащий их все. Например, если вход был

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

Вы можете вывести либо [1,2], [2,3]либо [[1,2],[2,3]]. Если вы выберете последний вариант, вы можете вывести одноэлементные списки для случаев, когда существует только одно решение.

Вывод может происходить в одном и том же списке более одного раза, если он отсутствует в другом списке. Например

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

должен выводить, [1,2]потому что[1,2] это подсписок первого списка, но не второй, хотя это подсписок первого списка двумя разными способами.

Вы можете использовать в качестве входных данных список списков, содержащих любой тип, при условии, что этот тип имеет более 100 возможных значений, т.е. не имеет логических значений.

Это поэтому ответы будут оцениваться в байтах, причем меньше байтов будет лучше.

Тестовые случаи

[[1,1]] : [1]
[[1],[1]] : []
[[1,1],[1]] : [1,1]
Пост Рок Гарф Хантер
источник

Ответы:

5

Шелуха , 12 14 15 байт

+3 байта для случая [[1,1]]

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

Попробуйте онлайн!

Explaination

          ṁ      -- 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

Примечание: Ṡ f g x = f (g x) xи это трудно объяснить, используя метод выше.

H.PWiz
источник
14 байт с лямбдой.
Згарб
Это терпит неудачу для[[1,1]]
H.PWiz
Хм, и исправление, которое делает это более 15 байтов. Ну что ж.
Згарб
4

Pyth, 15 байт

halDs-M.p.:R)QY

Тестирование

Сначала мы генерируем все подстроки каждого входного списка с помощью .:R)Q. Затем мы генерируем все возможные упорядочения этих групп подстрок.p .

Теперь сложная часть: -M. Это складывает- функцию по каждому списку заказов. Он начинается с первого списка подстрок, затем отфильтровывает всех жителей всех остальных списков.

Затем результаты объединяются, упорядочиваются по длине, []добавляется a , а затем первый элемент результирующего списка извлекается с помощьюh .

Это было бы на 4 байта короче, если бы я мог выдавать ошибку ни в одном уникальном списке, а не выводить пустой список.

isaacg
источник
Какая у вас 11-байтовая версия?
Утренняя монахиня
@LeakyNun hlDs-M.p.:R, вероятно, то, что он имеет в виду.
FryAmTheEggman
3

Pyth - 20 байт

Ksm.:d)QhalDfq1/KTKY

Тестовый пакет .

Maltysen
источник
Получил 16 байтов , но я не уверен, что это правильно. В остальном это довольно похоже.
FryAmTheEggman
@FryAmTheEggman круто, вы должны опубликовать это.
Maltysen
Сбой для недавно добавленного краевого теста [[1,1]].
Джонатан Аллан
2

Haskell , 149 128 126 113 байтов

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)

Попробуйте онлайн!

Сохранено 21 байт благодаря Wheat Wizard, H.PWiz и Брюсу Форте.

Сохранено еще два байта благодаря H.PWiz.

Сохранено 13 байтов благодаря NIMI.

РЕДАКТИРОВАТЬ Это было оригинальное объяснение:

  • a это ярлык для присоединения к спискам.

  • sвычисляет все непрерывные списки (все tailsиз всех inits). Обратите внимание, что nubсохраняет только первый вхождение каждого элемента, поэтому tailудалит пустой список из подсписков.

  • g объединяет все подсписки из всех заданных списков в большой список подсписков и сортирует их по длине.

  • f f - фильтр для элементов, которые появляются только один раз в большом списке

  • h это безопасная версия head

  • i это клей

Совершенно не элегантно! Там должно быть лучшее решение ...

jferard
источник
2
Похоже, что пара ваших функций может быть короче, если они написаны как бессмысленные функции.
Пост Рок Гарф Хантер
1
Вам также не нужно считать i=в конце вашей программы, потому что бессмысленные функции не нужно назначать в соответствии с нашими правилами.
Пост Рок Гарф Охотник
2
Это foldl1(++)просто concat?
H.PWiz
2
(length$filter(==x)l)может быть короче length(filter(==x)l)или даже корочеsum[1|y<-l,y==x]
Post Rock
2
@ H.PWiz За исключением []этого есть, но >>=idеще короче;) Также @jferard: Вы можете встроить много функций (например f, gи т . Д.), Так как вы используете их только один раз.
ბიმო
2

Java 8, 251 + 19 = 270 байт

Очень грубая лямбда от минимально List<List>до List(лучше всегоFunction<List<List<Integer>>, List<Integer>> хотя ). Это решение грубой силы, которое итерирует длины чанков от 1 до размера самого большого списка, в каждом случае итерируя по каждому чанку этой длины в каждом списке и проверяя каждый такой чанк по каждому чанку равного размера в любом другом списке.

Бойся меня, сборщик мусора.

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

Неуправляемая лямбда

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

Попробуйте онлайн

Java 8, 289 + 45 = 334 байта

Это более функциональный подход с использованием потоков. Если бы существовал метод, Streamпозволяющий сократить количество элементов, которые появляются один раз, это решение было бы лучше, чем приведенное выше. Присвойте тому же типу, что и выше.

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

Неуправляемая лямбда

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

Попробуйте онлайн

Jakob
источник
1

Желе , 15 байт

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

Попробуйте онлайн!

-3 байта благодаря Джонатану Аллану

HyperNeutrino
источник
Можно ċ1заменить на S?
@ThePirateBay Действительно, может, спасибо. Я сделал другую версию, хотя. (хотя это привело бы к тому же счету)
HyperNeutrino
Ваше новое решение печатается [1, 2, 1]для ввода, [[1,2],[1,2,1],[2,1,1]]пока [1,1]короче.
@ThePirateBay Исправлено, спасибо.
HyperNeutrino
1
@JonathanAllan о, гм. Я не могу сосчитать. : P
HyperNeutrino