Sprawdź, czy można wykonać ciąg z podciągami!


23

Biorąc pod uwagę ciąg znaków si tablicę / listę l, określ, czy smożna wykonać z części l.

Na przykład, jeśli ciąg jest, "Hello, world!"a lista jest [' world!', 'Hello,'], to program / funkcja powinna zwrócić prawdziwą wartość, ponieważ można ustawić listę w celu utworzenia ciągu. Poniższa lista będzie również zwrócić wartość truthy: ['l', 'He', 'o, wor', 'd!']. Wyobraź sobie 'l'wypełnienie tam, gdzie jest potrzebne. Tak, możesz powtórzyć elementy listy, aby utworzyć ciąg. Jeśli nie może utworzyć ciągu, powinien zwrócić wartość fałszowania. Obowiązują standardowe metody IO, standardowe luki.

Przypadki testowe:

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

Czy to ważne, czy tablica zawiera więcej łańcuchów niż potrzeba do skonstruowania łańcucha głównego?
Kudłaty

Jaka powinna być w takich przypadkach wartość zwrotu?
Kudłaty

@Shaggy Truthy. Jeśli jest więcej, to ciąg może być skonstruowany ze wszystkimi nie-dodatkowymi częściami. Dodam przypadek testowy.
Towarzysz SparklePony 27.04.17

3
Polecam dodanie tego przypadku testowego:"ababab", ["a","ba","ab"]
ćpun matematyki

3
Sugeruję dodanie przypadku testowego zawierającego metaznaki wyrażenia regularnego.
Joey,

Odpowiedzi:


11

Brachylog , 8 bajtów

~c¬{∋¬∈}

Wypróbuj online!

To jest naprawdę powolne. Zajęło około 37 sekund na „Witaj, świecie!” test skrzynki na moim komputerze i przekroczony limit czasu w TIO.

Spowoduje to przejście ciągu przez zmienną wejściową i listę przez zmienną wyjściową

Wyjaśnienie

             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 .

„la lal al” ponad 60 sekund ...
RosLuP

1
@RosLuP Dzięki tym danym wejściowym i ["la", " l", "al "]jako lista zakończyła się na moim komputerze i poprawnie odpowiedziała false.po 6800 sekundach, i „tylko” 113 miliardów wniosków.
Fatalize

Mam wrażenie, że napisanie czegokolwiek w tym języku spowoduje, że program nie będzie działał na TIO haha.
Magic Octopus Urn

@carusocomputing Język dla większości programów nie jest zbyt wolny, po prostu w niektórych przypadkach, ze względu na deklaratywność programu, powoduje bardzo bardzo wolne czasy wykonywania (które można znacznie poprawić kosztem długości kodu)
Fatalize

@Fatalize errr ... Chciałem powiedzieć, że golf nie pisze, wydaje się, że im mniej instrukcji, tym szersze staje się „pytanie” i więcej kalkulacji potrzebujesz. Wygląda jak niesamowity język dla teoretycznych problemów matematycznych.
Magic Octopus Urn

7

Mathematica, 29 bajtów

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

Wyjaśnienie:

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

Graniczne rozwiązanie oszukiwania, 21 bajtów

StringMatchQ[#,#2..]&

Ponieważ Mathematica jest symbolicznym językiem programowania, nie ma * różnicy między wyrażeniami List[a,b,...]i Alternatives[a,b,...]innymi, niż sposób, w jaki oddziałują one z innymi symbolami i sposób ich wyświetlania ( {a,b,...}i a|b|...odpowiednio). Przy stosowaniu w drugim argumencie StringMatchQ, AnAlternatives wyrażenie jest traktowany jako wzorzec strun, a zatem możemy zapisać 8bajtów ponad mojego powyższego roztworu poprzez drugi argument jakoAlternatives wyrazu.

* Technicznie Listjest również Locked, co uniemożliwia użytkownikom wprowadzanie Unprotectgo i zmianę jego zachowania.


1
{x,y,z}jest traktowany tak samo, jak w x|y|zprzypadku dopasowania wzorca ciągu. Myślę, że możesz zastąpić ""|##&@@#2..tylko #2...
Nie drzewo

5

Pyth, 23 bajty

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

Przyjmuje dane wejściowe jak [['string'],['list', 'of', 'parts']]. Dane wyjściowe to pusta lista lub lista z wartościami w środku. W Pyth lista zawierająca cokolwiek, nawet łańcuch zerowy ( ['']), ma wartość true.

Wypróbuj online!

Wyjaśnienie:

                             | 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

To rozwiązanie nieustannie próbuje usunąć każdą możliwą część z początku łańcucha i śledzi, jakie wartości musi jeszcze przejrzeć.

Jeśli spojrzymy na wartość Gw przypadku testowym [['ababab'],['a','ba','ab']]po każdej iteracji pętli while, otrzymamy:

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

A w przypadku testowym [['aaaaa'],['aa']]otrzymujemy:

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

Utworzyłem inny przypadek testowy, [['aaaaaa'],['a','aa','aaa']]a wynik był następujący:

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

Lista wyjściowa zawiera garść śmieci, ale wciąż jest to prawdziwa wartość.


5

Perl 5 , 39 bajtów

38 bajtów kodu + -pflaga.

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

Wypróbuj online!

Dla danych wejściowych "Hello, world!", ["l", "He", "o, wor", "d!"](faktycznie oddzielonych znakami nowej linii) konstruuje wzór l|He|o, wor|d!|(dzięki metaznakom, dzięki \Q..\E), a następnie sprawdza, czy pierwszy ciąg znaków pasuje do tego wzorca /^($v)*$/.

W TryItOnline zauważ, że musi być końcowy nowy wiersz.


„Witaj, świecie! L He o, wor d!” to wejście ze spacją po „l” nie generuje żadnego wyniku
RosLuP

@RosLuP Czy możesz mi podać link TryItOnline? (Nie rozumiem, co dokładnie masz na myśli. Zauważ, że „fałsz” tak naprawdę nic nie drukuje, ponieważ to jest Perl)
Dada

Czyli dla fałszywego wydruku nic? W tym przypadku przepraszam, ale ta wartość wyjściowa nie wydaje mi się zbyt przydatna ...
RosLuP

@RosLuP Zgadza się. W Perlu undefjest wartością fałszowania zwracaną przez większość wbudowanych. A kiedy go drukujesz, w rzeczywistości nic nie drukuje. I właśnie to robię. Drukowanie „1/0” jest naturalne dla języków podobnych do C, ale dla Perla „1 / undef” jest naturalnym sposobem.
Dada

Żadne wyjście nie ma jednej dwuznaczności „jest uruchomione, czy już program jest fałszywy?”
RosLuP

4

PHP, 69 bajtów

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

Przypadki testowe


Bardzo sprytne, zajęło mi chwilę, aby zrozumieć, co robisz. +1 za nieszablonowe myślenie
Martijn

Fałszywy negatyw dla tej nieznośnej sprawy krawędzi["", ["The string can be constructed with nothing!"]]
Jonathan Allan

@JonathanAllan zrobione jest pusty ciąg ciąg?
Jörg Hülsermann

Tak, problem pustych partycji jest problemem w wielu rozwiązaniach.
Jonathan Allan

3

Python 2, 141 bajtów

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*

Wypróbuj online!

Niezwykle nieefektywny. Limit czasu pierwszego przypadku testowego dla TIO.


3

JavaScript (ES6), 59 bajtów

Pobiera tablicę podciągów ai ciąg znaków sw składni curry (a)(s). Zwraca false/ true.

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

Skomentował

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

Przypadki testowe


3

Haskell , 35 bajtów

#pobiera Stringai listę Strings, i zwraca a Bool.

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

Wypróbuj online!

Po prostu nie przejmuj się przypadkiem testowym, który pominąłem, ponieważ uderzył mojego skromnego laptopa nawet z -O2. Podejrzewam, że GHC nie usuwa tej pośredniej listy elementów 30517578125, ma zbyt dużo współużytkowania, aby szybko zebrać śmieci, a ponieważ test jest fałszywy, program musi wygenerować wszystko ... możesz spróbować, jeśli możesz załatw to.

mapM("":)(l<$s)to lista wszystkich sposobów tworzenia length slisty elementów, które są albo pustymi ciągami, albo ciągami z l.


3

Pyth, 17 15 11 14 bajtów

AQ|!G}Ym-dH./G

Zmieniono wymaganie dotyczące pustego ciągu, dodając 3 bajty.

Wyjaśnienie

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.

Stare wersje

AQ}Ym-dH./G

Krótszy i trwa w całym wszechświecie!

Wyjaśnienie

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

Jest to przerażająco wolne, ale działa w moich (trywialnie małych) testach.

Wyjaśnienie

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

Galaretka , 14 12 8 bajtów

;FŒṖḟ€Ạ¬

Wypróbuj online!

Jak to działa

;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"]poprawka błędu w sprawie dzięki @JonathanAllan


Fałszywie negatywny dla"", ["The string can be constructed with nothing!"]
Jonathan Allan

Będzie znacznie wolniej, ale ;FŒṖḟ⁹$€Ạ¬to naprawi.
Jonathan Allan

... i można korzystać z niejawnego prawy argument , więc nie potrzebne są $albo : ;FŒṖḟ€Ạ¬.
Jonathan Allan

Grr, właśnie to dostaję za to, że nie testowałem każdej pojedynczej skrzynki testowej. Mogę być w stanie utrzymać 8 bajtów, zastępując ¬operacją, która zawsze zwraca true z poprawnym argumentem „”.
fireflame241

^ cóż, wróciłem do 8 :)
Jonathan Allan


2

Pyth, 10 8 bajtów

f!-TQ./+zh

Zestaw testowy

To pobiera listę w pierwszym wierszu STDIN, a ciąg znaków (bez cudzysłowów) w drugim.

Aby rozpocząć, lista jest przechowywana w Q, a ciąg jest przechowywany w z. Następnie tworzymy wszystkie możliwe partycje z. Każda partycja zostanie przefiltrowana ( f), aby sprawdzić, czy używa tylko elementów w Q. Aby to zrobić, usuwamy wszystkie elementy Qz Tpartycji, na której partycjonujemy, i logicznie negujemy wynik !, aby tylko partycje, w których znajdował się każdy elementQ przechowywane są .

Aby rozwiązać problem, który ''nie ma partycji, dodajemy pierwsze słowo słownika do z, aby nie był to pusty ciąg.


W pakiecie testowym brakuje dolnej linii (pusty ciąg) - Czy trzeba cytować? Z pustą linią lub ""wygląda na to, że zawiodła.
Jonathan Allan

Pusty ciąg nie ma partycji, więc w rzeczywistości podaje po prostu złą odpowiedź. Cholera, spróbuję to naprawić.
isaacg

Sugerowana przeze mnie poprawka dla Jelly polegała na połączeniu łańcucha wejściowego ze spłaszczoną tablicą wejściową. Może możesz zrobić to samo?
Jonathan Allan

@JonathanAllan Zrobiłem coś podobnego, dzięki.
isaacg

The cases of "", [""] and "", [] have not been covered - lets not go there :)
Jonathan Allan

2

PowerShell, 61 58 57 bytes

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

Try it online!

Old solutions:

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

This one is almost unreadable, so I'd reccommend changing it a bit. I'm fairly certain most other people would agree.
Rɪᴋᴇʀ

Thank you for the explanation of the reason of your correction of my solution.
Andrei Odegov

1

Python 2, 64 bytes

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

Try this online!


I think this doesn't totally work, try ("aaaaaaa",["aa","aaa"]).
xnor

@xnor I updated it. Come to find out, regex is perfect for this.
Neil

4
Should fail for ('x', '.'), I guess, but doesn't.
Joey

1
@nfnneil Did you? Your last edit was 10 hours ago.
Dennis

1
...or "Hello", ["\w"] etc.
Jonathan Allan

1

PowerShell, 78

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

Pretty straightforward regex-based approach.


1

CJam (16 bytes)

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

This is an anonymous block (function) taking the string and the array of strings on the stack. 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.


@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];}

Gotta love C++! :)
MEMark

1

Python, 66 bytes

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

0

Microsoft Sql Server, 353 bytes

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

Test it online.

Readable version:

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 bytes

I'm sure there is a shorter way to do this in C but I wanted to create a solution that tests all the possible combinations of substrings instead of the usual find/replace method.

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

Try it online

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));
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.