Проверьте, можно ли создать строку с подстрокой!

23

По заданной строке sи массиву / списку lопределите, sможно ли создавать детали из l.

Например, если строка есть, "Hello, world!"а список есть [' world!', 'Hello,'], то программа / функция должна вернуть истинное значение, потому что вы можете упорядочить список для формирования строки. Следующий список будет также возвращать значение truthy: ['l', 'He', 'o, wor', 'd!']. Просто представьте, 'l'где он должен заполнить строку. Так что да, вы можете повторить элементы списка, чтобы сформировать строку. Если он не может сформировать строку, он должен вернуть ложное значение. Применяются стандартные методы ввода-вывода, стандартные лазейки.

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

Input (In the form of s, l)
Output (1 if possible, 0 if impossible)

"Hello, world!", ["l", "He", "o, wor", "d!"]
1

"la lal al ", ["la", " l", "al "]
1

"this is a string", ["this should return falsy"]
0

"thi is a string", ["this", "i i", " a", " string"]
0

"aaaaa", ["aa"]
0

"foo bar foobar", ["foo", "bar", " ", "spam"]
1

"ababab", ["a","ba","ab"]
1

"", ["The string can be constructed with nothing!"]
1
Товарищ Спаркл Пони
источник
Имеет ли значение, если массив содержит больше строк, чем необходимо для построения основной строки?
Лохматый
Каким должно быть возвращаемое значение в этих случаях?
Лохматый
@ Shaggy Truthy. Если есть дополнительные, то строка может быть построена со всеми не лишними частями. Я добавлю тестовый пример.
Товарищ SparklePony
3
Я рекомендую добавить этот тестовый пример:"ababab", ["a","ba","ab"]
математика наркоман
3
Я бы предложил вам добавить тестовый набор, содержащий метасимволы регулярных выражений.
Джои

Ответы:

11

Брахилог , 8 байт

~c¬{∋¬∈}

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

Это действительно медленно. Потребовалось около 37 секунд для «Привет, мир!» контрольный пример на моем ПК и тайм-аут на TIO.

Это берет строку через переменную Input и список через переменную Output

объяснение

             String = ?, List = .

             It is possible to find…
~c           …a deconcatenation of ?…
  ¬{   }     …such that it is impossible…
    ∋¬∈      …that an element of that deconcatenation is not an element of .
Fatalize
источник
"ля лал" более 60 секунд ...
РосЛюП
1
@RosLuP С этим вводом и ["la", " l", "al "]списком он завершился на моем компьютере и правильно ответил false.через 6800 секунд, и «только» 113 миллиардов выводов.
Fatalize
Я чувствую, что написание чего-либо на этом языке приведет к невозможности запуска программы на TIO, хаха.
Волшебная Урна Осьминога
@carusocomputing Язык не такой медленный для большинства программ, просто в некоторых случаях из-за декларативности программы он приводит к очень очень медленному времени выполнения (которое может быть значительно улучшено за счет длины кода)
Fatalize
@Fatalize errr ... Я хотел сказать, что гольф не пишет, кажется, что чем меньше инструкций, тем шире становится "вопрос" и тем больше вычислений вам нужно. Похоже на удивительный язык для теоретических математических задач.
Волшебная Урна Осьминога
7

Mathematica, 29 байт

StringMatchQ[#,""|##&@@#2..]&

Объяснение:

             #,               (* The first argument *)
StringMatchQ[                 (* matches the string pattern *)
               ""|##&         (*   Alternatives *)
                     @@       (*     applied to *)
                       #2     (*     the second argument *)
                         ..   (*   repeated *)
                           ]&

Пограничный читерский раствор, 21 байт

StringMatchQ[#,#2..]&

Поскольку Mathematica является символическим языком программирования, нет никакой разницы между выражениями List[a,b,...]и Alternatives[a,b,...]другими, кроме того, как они взаимодействуют с другими символами и как они отображаются ( {a,b,...}и a|b|..., соответственно). При использовании второго аргумента StringMatchQ, Alternativesвыражение трактуется как строка рисунок, и , таким образом , мы можем сохранить 8байты над моим выше решением, взяв второй аргумент в качестве Alternativesвыражения.

* Технически Listтакже Locked, что не позволяет пользователям использовать Unprotectего и изменять его поведение.

ngenisis
источник
1
{x,y,z}обрабатывается так же, как и x|y|zпри сопоставлении с образцом строки. Я думаю, что вы можете заменить ""|##&@@#2..просто #2...
Не дерево
5

Pyth, 23 байта

AQW&GhGJ.(G0Vf!xJTH aG>JlN;G

Принимает участие как [['string'],['list', 'of', 'parts']]. Выходными данными является либо пустой список, либо список со значениями внутри. В Pyth список, содержащий что-либо, даже пустую строку ( ['']), оценивается как true.

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

Объяснение:

                             | Implicit: Q = eval(input())
AQ                           | Assign the first value of Q to G and the second to H
  W&GhG                      | While G is not empty and G doesn't contain an empty string:
       J.(G0                 |  Pop the first value of G and store into J
            Vf!xJTH          |  For N in elements in H that match the beginning of J:
                             |   Additional space for suppressing printing 
                    aG>JlN   |   Append to G the elements of J from the length of N to the end
                          ;  | End all loops
                           G | Print G

Это решение непрерывно пытается удалить каждую возможную часть из начала строки и отслеживает, какие значения ему еще нужно просмотреть.

Если мы посмотрим на значение Gв тестовом примере [['ababab'],['a','ba','ab']]после каждой итерации цикла while, мы получим следующее:

['ababab']
['babab', 'abab']
['abab', 'bab']
['bab', 'bab', 'ab']
['bab', 'ab', 'b']
['ab', 'b', 'b']
['b', 'b', '']
['b', '']
['']   <---Remember, this evaluates to True

И в тестовом примере [['aaaaa'],['aa']]это то, что мы получаем:

['aaaaa']
['aaa']
['a']
[]   <---And this evaluates to False

Я создал еще один тестовый пример, [['aaaaaa'],['a','aa','aaa']]и результат был такой:

['', 'aaa', 'aa', 'a', 'aa', 'a', '', 'a', '', 'aa', 'a', '', 'a', '', '', 'a', '', '']

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

К Чжан
источник
5

Perl 5 , 39 байт

38 байт кода + -pфлаг.

map{chop;$v.="\Q$_\E|"}<>;$_=/^($v)*$/

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

Для ввода "Hello, world!", ["l", "He", "o, wor", "d!"](фактически разделенного символом новой строки) он создает шаблон l|He|o, wor|d!|(с экранированными метасимволами, спасибо \Q..\E), а затем проверяет, соответствует ли первая строка этому шаблону /^($v)*$/.

На TryItOnline обратите внимание, что должен быть завершающий перевод строки.

папа
источник
"Привет, мир! Я, он!" этот ввод с пробелом после "l" не дает результата
RosLuP
@RosLuP Можете ли вы дать мне ссылку TryItOnline, пожалуйста? (Я не понимаю, что именно вы имеете в виду. Обратите внимание, что «false» на самом деле ничего не печатает, так как это Perl)
Dada
Так что за ложная печать ничего? В этом случае извините, но это никакое выходное значение не кажется мне слишком полезным ...
RosLuP
@RosLuP Это верно. В Perl undefэто ложное значение, возвращаемое большинством встроенных функций. И при печати это фактически ничего не печатает. И это именно то, что я делаю. Печать «1/0» естественна для языков, подобных C, но для Perl «1 / undef» естественен.
Дада
Нет вывода имеет одну двусмысленность "он работает или уже конец программы ложь?"
РосЛюП
4

PHP, 69 байт

<?=($s=$_GET[0])>""?ctype_digit(strtr($s,array_flip($_GET[1])))?:0:1;

Testcases

Йорг Хюльсерманн
источник
Очень умно, мне потребовалась минута, чтобы понять, что ты делаешь. +1 за нестандартное мышление
Мартейн
Ложный минус для этого надоедливого случая["", ["The string can be constructed with nothing!"]]
Джонатан Аллан
@JonathanAllan это пустая строка строка?
Йорг Хюльсерманн
Да, проблема пустого разбиения является проблемой во многих решениях.
Джонатан Аллан
3

Python 2, 141 байт

lambda s,l:s in[''.join(i)for r in range(len(s)+1)for j in combinations_with_replacement(l,r)for i in permutations(j)]
from itertools import*

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

Крайне неэффективно. Первый тестовый случай истекает на TIO.

математик наркоман
источник
3

JavaScript (ES6), 59 байт

Принимает массив подстрок aи строку sв синтаксисе каррирования (a)(s). Возвращает false/ true.

a=>g=s=>!s||a.some(e=>s.split(e)[0]?0:g(s.slice(e.length)))

комментарии

a =>                          // main function that takes 'a' as input
  g = s =>                    // g = recursive function that takes 's' as input
    !s ||                     // if 's' is empty, return true (success!)
    a.some(e =>               // else, for each element 'e' in 'a':
      s.split(e)[0] ?         //   if 's' doesn't begin with 'e':
        0                     //     do nothing
      :                       //   else:
        g(s.slice(e.length))  //     remove 'e' at the beginning of 's' and
    )                         //     do a recursive call on the remaining part

Контрольные примеры

Arnauld
источник
3

Haskell , 35 байт

#принимает Stringи список Strings, и возвращает Bool.

s#l=elem s$concat<$>mapM("":)(l<$s)

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

Только не берите в голову тестовый пример, который я пропустил, потому что он побил мой скудный ноутбук, даже с -O2. Я подозреваю, что GHC не расплавляет этот промежуточный список элементов 30517578125, у него слишком много общего доступа, чтобы быстро собрать мусор, и поскольку тестовый случай ложный, программа должна генерировать все это ... не стесняйтесь пробовать, если можете справиться с этим.

mapM("":)(l<$s)список всех способов составления length sсписка элементов, которые являются либо пустыми строками, либо строками из l.

Орджан Йохансен
источник
3

Pyth, 17 15 11 14 байт

AQ|!G}Ym-dH./G

Требование к пустой строке изменилось, добавив 3 байта.

объяснение

AQ|!G}Ym-dH./G
AQ                     Save the input into G, H.
           ./G         Get all partitions of G.
       m-dH            Check if the parts are in H.
     }Y                The empty list should be present if and only
                           if the string can be made...
  |!G                  ... or the string might be empty.

Старые версии

AQ}Ym-dH./G

Более короткие и бежит в жизни вселенной!

объяснение

AQ}Ym-dH./G
AQ                  Save the input into G, H.
        ./G         Get all partitions of G.
    m-dH            Check if the parts are in H.
  }Y                The empty list should be present if and only
                        if the string can be made.

AQ&G}GsMs.pMy*HlG

Это ужасно медленно, но это работает для моих (тривиально маленьких) тестовых случаев.

объяснение

AQ&G}GsMs.pMy*HlG
AQ                  Save the input into G, H.
             *HlG   Repeat the list of substrings for each character of G.
            y       Take the power set.
         .pM        Take every permutation of each set of substrings.
      sMs           Get a list of all the joined strings.
    }G              Check if G is one of them.
  &G                Make sure G is not empty.

источник
3

Желе , 14 12 8 байт

;FŒṖḟ€Ạ¬

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

Как это работает

;FŒṖḟ€Ạ¬   - main function, left argument s, right argument l
;F         - concatenate to the string the list, flattened to deal with "" as string
  ŒṖ       - Get all partitions of s, that is, all ways to make s from substrings
     €     - For each partition...
    ḟ      -   Filter out (exclude) those elements which are not in... 
           -   (implicit right arg) the list l. This leaves the empty set (falsy) if the partition can be made of elements from the list
      Ạ    - If any element is falsy (thus constructable from l), return 0; else return 1
       ¬   - Apply logical not to this, to yield the proper 1 = constructable from list, 0 otherwise.

Исправление в случае, "", ["The string can be constructed with nothing"]благодаря @JonathanAllan

fireflame241
источник
Ложный минус для"", ["The string can be constructed with nothing!"]
Джонатан Аллан
Это будет намного медленнее, но ;FŒṖḟ⁹$€Ạ¬исправит это.
Джонатан Аллан
... и вы можете использовать неявный правильный аргумент для , так что вам не нужны $или : ;FŒṖḟ€Ạ¬.
Джонатан Аллан
Грр, это то, что я получаю за то, что не тестирую каждый тестовый пример. Я мог бы поддерживать 8 байтов, заменив ¬их операцией, которая всегда возвращает истину с правильным аргументом "".
fireflame241
^ хорошо, я вернул его к 8 :)
Джонатан Аллан
2

Pyth, 10 8 байт

f!-TQ./+zh

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

Это займет список в первой строке STDIN и строку (без кавычек) во второй.

Для начала список сохраняется в Q, а строка сохраняется в z. Далее мы формируем все возможные разделы z. Каждый раздел будет отфильтрован ( f), чтобы проверить, использует ли он только части Q. Для этого мы удаляем все элементы Qиз Tраздела, который мы разбиваем, и логически отрицаем результат !, так что Qсохраняются только те разделы, в которых был каждый элемент .

Чтобы решить проблему, в ''которой нет разделов, мы добавляем первое слово словаря к z, чтобы оно не было пустой строкой.

isaacg
источник
Набор тестов пропускает нижнюю строку (пустую строку). Нужно ли заключать в кавычки? С пустой строкой или ""кажется, что это не так.
Джонатан Аллан
Пустая строка не имеет разделов, поэтому на самом деле она дает неправильный ответ. Черт, я постараюсь это исправить.
Исаак
Исправление, которое я предложил для Jelly, заключалось в объединении входной строки со сглаженным входным массивом, может быть, вы можете сделать то же самое?
Джонатан Аллан
@JonathanAllan Я сделал нечто подобное, спасибо.
Исаак
Случаи "", [""]и "", []не были охвачены - давайте не
Джонатан Аллан
2

PowerShell, 61 58 57 байт

{$s,$l=$_;$l|sort -d length|%{$s=$s.replace($_,'')};+!$s}

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

Старые решения:

{$s,$l=$_;$l|sort -d length|%{$s=$s.replace($_,'')};[int]!$s}
{$s,$l=$_;$l|sort -d length|%{$s=$s.replace($_,'')};0+!$s}  
Андрей Одегов
источник
Этот почти не читается, поэтому я рекомендую немного его изменить. Я вполне уверен, что большинство других людей согласятся.
17
Спасибо за объяснение причины вашего исправления моего решения.
Андрей Одегов
1

Python 2, 64 байта

lambda s,l:len(re.findall("^("+"|".join(l)+")*$",s))>0
import re

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

Нил
источник
Я думаю, что это не совсем работает, попробуйте ("aaaaaaa",["aa","aaa"]).
xnor
@xnor Я обновил его. Приходите, чтобы узнать, регулярное выражение идеально подходит для этого.
Нил
4
Должен потерпеть неудачу ('x', '.'), я думаю, но это не так.
Джои
1
@nfnneil А ты? Ваше последнее редактирование было 10 часов назад.
Деннис
1
... или "Hello", ["\w"]др.
Джонатан Аллан
1

PowerShell, 78

$s,$l=$args;!($s-creplace(($l|sort -d length|%{[regex]::escape($_)})-join'|'))

Довольно простой подход на основе регулярных выражений.

детеныш
источник
1

CJam (16 байт)

{Ma+1$,m*:e_\a&}

Это анонимный блок (функция), принимающий строку и массив строк в стеке. Online demo.

It uses the obvious algorithm:

{        e# Declare a block. Call the args str and arr
  Ma+    e#   Add the empty string to the array
  1$,m*  e#   Take the Cartesian product of len(str) copies of (arr + [""])
  :e_    e#   Flatten each element of the Cartesian product into a single string
  \a&    e#   Intersect with an array containing only str
}

The return value is an empty array/string (falsy) if str can't be made, or an array containing str (truthy, even if str is itself the empty string) if it can be made.

Peter Taylor
источник
@RosLuP, I'm not sure what you mean. That particular test case executes so fast that I can't actually time it. Other test cases do take a long time to execute, but the spec doesn't include any time constraints.
Peter Taylor
@RosLuP, online demo. But I don't understand what your complaint is.
Peter Taylor
1

C++(Bcc), 287 bytes

#include<algorithm.h>
f(a,b)char*a,**b;{int i,j,k,v,p[256];if(!a||!b||!*b)return-1;for(v=0;v<256&&b[v];++v)p[v]=v;if(v>=256)return-1;la:for(i=0,j=0;j<v&&a[i];){for(k=0;b[p[j]][k]==a[i]&&a[i];++i,++k);j=b[p[j]][k]?(i-=k),j+1:0;}if(a[i]&&next_permutation(p,p+v)) goto la;return i&&!a[i];}

because i do not wrote or used too much the next_permutation() i don't know if is all ok. I don't know 100% if it is a solution too possibly this is out of quality... One list of string is here one array of pointers to char; NULL terminated The algo is easy, there is one algo that linearity try if all string in the list fit with argument "a" string there is one other algo that permute the index of the list of string so it try all possible combination.

ungolf it, test code and results here

#include<stdio.h>
g(a,b)char*a,**b;
{int i,j,k,v,p[256];
 if(!a||!b||!*b) return -1;
 for(v=0;v<256&&b[v];++v) p[v]=v;
 if(v>=256)      return -1; // one array of len >256 is too much
la: 
 for(i=0,j=0;j<v&&a[i];)
   {for(k=0;b[p[j]][k]==a[i]&&a[i];++i,++k); 
    j=b[p[j]][k]?(i-=k),j+1:0;
   } 
 if(a[i]&&next_permutation(p,p+v)) goto la;
 return i&&!a[i];  
}

#define F for
#define P printf

test(char* a, char** b)
{int i;
 P("f(\"%s\",[",a);
 F(i=0;b[i];++i) 
       P("\"%s\"%s", b[i], b[i+1]?", ":"");
 P("])=%d\n", f(a,b));
}

main()
{char *a1="Hello, world!",    *b1[]={"l","He", "o, worl", "d!",      0};//1
 char *a2="la lal al ",       *b2[]={"la", " l", "al ",              0};//1
 char *a3="this is a string", *b3[]={"this should return falsy",     0};//0
 char *a4="thi is a string",  *b4[]={"this", "i i", " a", " string", 0};//0
 char *a5="aaaaa",            *b5[]={"aa",                           0};//0
 char *a6="foo bar foobar",   *b6[]={"foo","bar"," ","spam",         0};//1
 char *a7="ababab",           *b7[]={"a","ba","ab",                  0};//1
 char *a8="",                 *b8[]={"This return 0 even if has to return 1", 0};//0
 char *a9="ababc",            *b9[]={"a","abc", "b", 0};//1

  test(a1,b1);test(a2,b2);test(a3,b3);test(a4,b4);test(a5,b5);test(a6,b6);
  test(a7,b7);test(a8,b8);test(a9,b9);
}

f("Hello, world!",["l", "He", "o, worl", "d!"])=1
f("la lal al ",["la", " l", "al "])=1
f("this is a string",["this should return falsy"])=0
f("thi is a string",["this", "i i", " a", " string"])=0
f("aaaaa",["aa"])=0
f("foo bar foobar",["foo", "bar", " ", "spam"])=1
f("ababab",["a", "ba", "ab"])=1
f("",["This return 0 even if has to return 1"])=0
f("ababc",["a", "abc", "b"])=1

this would compile in gcc C++ compiler

#include<algorithm>

int f(char*a,char**b){int i,j,k,v,p[256];if(!a||!b||!*b)return -1;for(v=0;v<256&&b[v];++v)p[v]=v;if(v>=256)return -1;la:;for(i=0,j=0;j<v&&a[i];){for(k=0;b[p[j]][k]==a[i]&&a[i];++i,++k);j=b[p[j]][k]?(i-=k),j+1:0;}if(a[i]&&std::next_permutation(p,p+v))goto la;return i&&!a[i];}
RosLuP
источник
Должен любить C ++! :)
MEMark
1

Python, 66 байт

lambda s,l:s==''or any(x==s[:len(x)]and f(s[len(x):],l)for x in l)

Ungolfed:

def f(s,l):
    if s=='': 
        return 1
    for x in l:
        if s.startswith(x) and f(s[len(x):],l):
            return 1
    return 0
RootTwo
источник
0

Microsoft Sql Server, 353 байта

u as(select s.n,s collate Latin1_General_BIN s,l collate Latin1_General_BIN l,
row_number()over(partition by l.n order by len(l)desc)r from s,l where s.n=l.n),
v as(select n,s,l,replace(s,l,'')c,r from u where r=1 union all
select u.n,u.s,u.l,replace(v.c,u.l,''),u.r from v,u where v.n=u.n and v.r+1=u.r)
select s,iif(min(c)='',1,0)u from v group by n,s

Проверьте это онлайн.

Читаемая версия:

with s as(
  select n,s
  from(values(1,'Hello, world!'),
             (2,'la lal al '),
             (3,'this is a string'),
             (4,'thi is a string'),
             (5,'aaaaa'),
             (6,'foo bar foobar'),
             (7,'ababab'),
             (8,''))s(n,s)),
l as(
  select n,l
  from(values(1,'l'),(1,'He'),(1,'o, wor'),(1,'d!'),
             (2,'la'),(2,' l'),(2,'al '),
             (3,'this should return falsy'),
             (4,'this'),(4,'i i'),(4,' a'),(4,' string'),
             (5,'aa'),
             (6,'foo'),(6,'bar'),(6,' '),(6,'spam'),
             (7,'a'),(7,'ba'),(7,'ab'),
             (8,'The string can be constructed with nothing!'))l(n,l)),
--The solution starts from the next line.
u as(
  select s.n,
    s collate Latin1_General_BIN s,
    l collate Latin1_General_BIN l,
    row_number()over(partition by l.n order by len(l)desc)r
  from s,l
  where s.n=l.n),
v as(
  select n,s,l,replace(s,l,'')c,r from u where r=1
    union all
  select u.n,u.s,u.l,replace(v.c,u.l,''),u.r
  from v,u
  where v.n=u.n and v.r+1=u.r
)
select s,iif(min(c)='',1,0)u from v group by n,s
Андрей Одегов
источник
0

C, 140 байтов

Я уверен, что есть более короткий способ сделать это в C, но я хотел создать решение, которое тестирует все возможные комбинации подстрок вместо обычного метода поиска / замены.

char p[999];c,o;d(e,g,l,f)int*e,**g,**l;{c=f&&c;for(l=g;*l;)strcpy(p+f,*l++),(o=strlen(p))<strlen(e)?d(e,g,0,o):(c|=!strcmp(e,p));return c;}

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

Ungolfed:

#include <string.h>
#include <stdio.h>

char buf[999];
int result;
int temp;

int test(char *text, char **ss, char **ptr, int length) 
{
    if (length == 0)
        result = 0;

    for(ptr = ss; *ptr; ptr++)
    {
        strcpy(buf + length, *ptr);
        temp = strlen(buf);
        if (temp < strlen(text))
        {
            // test recursivly
            test(text, ss, 0, temp);
        }
        else
        {
            if (strcmp(buf, text) == 0)
                result = 1;
        }
    }
    return result;
}

int main()
{
    char *text = "Hello,World";
    char *keywords[] = { "World", "Hello", ",", 0 };
    printf("%d", test(text, keywords, 0, 0));
}
Йохан дю Туа
источник