Test if a string can be made with substrings!

23

5

Given a string s and an array/list l, determine whether or not s can be made with parts from l.

For example, if the string is "Hello, world!" and the list is [' world!', 'Hello,'], then the program/function should return a truthy value, because you can arrange the list to form the string. The following list would also return a truthy value: ['l', 'He', 'o, wor', 'd!']. Just imagine the 'l' filling in where it needs to in he string. So yes, you may repeat elements of the list to form the string. If it cannot form the string, it should return a falsy value. Standard methods of IO, standard loopholes apply.

Test cases:

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

Comrade SparklePony

Posted 2017-04-27T23:13:29.207

Reputation: 5 784

Does it matter if the array contains more strings than are needed to construct the main string? – Shaggy – 2017-04-27T23:36:29.250

What should the return value be in those cases? – Shaggy – 2017-04-27T23:38:37.217

@Shaggy Truthy. If there is extra, then the string can be constructed with all the non-extra parts. I will add a test case. – Comrade SparklePony – 2017-04-27T23:39:55.550

3I recommend adding this test case: "ababab", ["a","ba","ab"] – math junkie – 2017-04-27T23:51:54.347

When you say capitiization does not matter do you mean that "tEsT", ["t","e","S"] will return true? If so, you should add that as a test case too – math junkie – 2017-04-27T23:57:02.777

@mathjunkie Capitalization does matter, I don't know why I said it doesn't. Edited. – Comrade SparklePony – 2017-04-27T23:58:21.600

3I'd suggest you add a test case containing regex metacharacters. – Joey – 2017-04-28T07:22:12.477

Missing test case: the string to construct is empty. – Peter Taylor – 2017-04-28T10:11:11.097

@Joey Interesting idea, but it does not fit the challenge in my point of view. This is not a regex challenge. Good idea though. – Comrade SparklePony – 2017-04-28T13:10:22.547

@PeterTaylor Good idea, added. – Comrade SparklePony – 2017-04-28T13:11:52.127

@ComradeSparklePony: The point is to weed out solutions that blindly use regex and just pass the examples you posted, while something like ('abc', ['a', '.', 'b']) would pass for their solution, which shouldn't. Another point: When using unbalanced parentheses or quantifiers without anything to quantify (*) in the string list, those solutions would simply crash. – Joey – 2017-04-28T13:12:36.983

The final test case added after my submission not only breaks it, but all my mathematical intuition says the solution should be the opposite. If you're allowed to not use all the strings, then you should be allowed to use none of them. – Ørjan Johansen – 2017-04-28T18:35:00.453

@ØrjanJohansen Yes. I keep on confusing myself with this, and I think you are right. I will edit. – Comrade SparklePony – 2017-04-28T18:36:32.110

@ComradeSparklePony is it acceptable to return 0 if it can be created and a positive integer representing how far off the substrings are from the word as a falsy value? – Magic Octopus Urn – 2017-04-28T19:37:58.540

@carusocomputing Sorry, but the question asks for a truth/false value as output, and I will have to stand by that. However, feel free to post a solution that does that alongside a correct solution. – Comrade SparklePony – 2017-04-28T19:53:23.613

@ComradeSparklePony it's actually one byte less for my program to do that ;). Nbd, figured as much haha. – Magic Octopus Urn – 2017-04-28T19:56:34.163

Answers

11

Brachylog, 8 bytes

~c¬{∋¬∈}

Try it online!

This is really slow. Took about 37 seconds for the "Hello, world!" test case on my PC, and timed-out on TIO.

This takes the string through the Input variable and the list through the Output variable

Explanation

             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

Posted 2017-04-27T23:13:29.207

Reputation: 32 976

"la lal al" more than 60 seconds... – RosLuP – 2017-04-28T10:25:49.563

1@RosLuP With this input and ["la", " l", "al "] as list, it terminated on my computer and correctly answered false. after 6800 seconds, and "only" 113 billion inferences. – Fatalize – 2017-04-28T13:02:51.113

I feel like writing anything in this language would result in a program not runnable on TIO haha. – Magic Octopus Urn – 2017-04-28T19:39:05.943

@carusocomputing The language is not that slow for most programs, it's just that in some cases due to the declarativeness of the program, it results in very very slow execution times (which could be improved drastically at the cost of code length) – Fatalize – 2017-04-28T19:41:17.950

@Fatalize errr... I meant to say golfing not writing, seems like the fewer instructions, the broader the "question" becomes and the more calculation you need. Seems like an awesome langauge for theoretical math problems. – Magic Octopus Urn – 2017-04-28T19:50:13.537

False negative for "", ["The string can be constructed with nothing!"] – Jonathan Allan – 2017-04-29T19:55:49.220

7

Mathematica, 29 bytes

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

Explanation:

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

Borderline cheating solution, 21 bytes

StringMatchQ[#,#2..]&

Since Mathematica is a symbolic programming language, there is no* difference between the expressions List[a,b,...] and Alternatives[a,b,...] other than how they interact with other symbols and how they are displayed ({a,b,...} and a|b|..., respectively). When used in the second argument of StringMatchQ, an Alternatives expression is treated as a string pattern, and thus we can save 8 bytes over my above solution by taking the second argument as an Alternatives expression.

* Technically List is also Locked, which prevents users from Unprotecting it and changing its behavior.

ngenisis

Posted 2017-04-27T23:13:29.207

Reputation: 4 600

1{x,y,z} is treated the same as x|y|z for string pattern matching. I think you can replace ""|##&@@#2.. with just #2... – Not a tree – 2017-04-28T00:24:14.850

5

Pyth, 23 bytes

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

Takes input like [['string'],['list', 'of', 'parts']]. The output is either an empty list or a list with values inside. In Pyth, a list containing anything, even a null string (['']), evaluates to true.

Try it online!

Explanation:

                             | 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

This solution continuously tries to remove every possible part from the beginning of the string, and keeps track of what values it still needs to look through.

If we look at the value of G in the test case [['ababab'],['a','ba','ab']] after each iteration of the while loop, this is what we get:

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

And, in the test case [['aaaaa'],['aa']], this is what we get:

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

I created another test case, [['aaaaaa'],['a','aa','aaa']] and the output was this:

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

The output list contains a bunch of garbage inside of it, but it's still a truthy value.

K Zhang

Posted 2017-04-27T23:13:29.207

Reputation: 5 698

5

Perl 5, 39 bytes

38 bytes of code + -p flag.

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

Try it online!

For the input "Hello, world!", ["l", "He", "o, wor", "d!"] (separated by newlines actually), it construct the pattern l|He|o, wor|d!| (with the metacharacters escaped, thanks to \Q..\E), and then looks if the first string matches this pattern with /^($v)*$/.

On the TryItOnline, note that there need to be a trailing newline.

Dada

Posted 2017-04-27T23:13:29.207

Reputation: 8 279

"Hello, world! l He o, wor d!" this input with a space after the "l" generate no result – RosLuP – 2017-04-28T10:35:11.217

@RosLuP Can you give me a TryItOnline link please? (I don't understand what you mean exactly. Note that "false" actually prints nothing as this is Perl) – Dada – 2017-04-28T11:12:39.157

So for false print nothing? In this case excuse me, but this no output value not seems to me too much useful... – RosLuP – 2017-04-28T11:19:09.327

@RosLuP That's right. In Perl, undef is the falsy value returned by most builtin. And when printing it, it actually prints nothing. And that's exactly what I'm doing. Printing "1/0" is natural for C-like languages, but for Perl, "1/undef" is the natural way. – Dada – 2017-04-28T11:23:36.617

No output has one ambiguity "it is running or already the program end false?" – RosLuP – 2017-04-28T12:20:36.507

4

PHP, 69 Bytes

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

Testcases

Jörg Hülsermann

Posted 2017-04-27T23:13:29.207

Reputation: 13 026

Very clever, took me a minute to understand what you're doing. +1 for thinking outside the box – Martijn – 2017-04-28T10:39:58.707

False negative for that pesky edge case ["", ["The string can be constructed with nothing!"]] – Jonathan Allan – 2017-04-29T20:40:43.533

@JonathanAllan done is an empty string a string? – Jörg Hülsermann – 2017-04-29T20:56:00.107

Yeah, the problem of empty partitioning is an issue in many solutions. – Jonathan Allan – 2017-04-29T20:59:12.007

3

Python 2, 141 bytes

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*

Try it Online!

Extremely inefficient. The first test case times out on TIO.

math junkie

Posted 2017-04-27T23:13:29.207

Reputation: 2 490

3

JavaScript (ES6), 59 bytes

Takes the array of substrings a and the string s in currying syntax (a)(s). Returns false / true.

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

Commented

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

Test cases

let f =

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

console.log(f(["l", "He", "o, wor", "d!"])("Hello, world!"))        // true
console.log(f(["la", " l", "al "])("la lal al "))                   // true
console.log(f(["this should return falsy"])("this is a string"))    // false
console.log(f(["this", "i i", " a", " string"])("thi is a string")) // false
console.log(f(["aa"])("aaaaa"))                                     // false
console.log(f(["foo", "bar", " ", "spam"])("foo bar foobar"))       // true
console.log(f(["a","ba","ab"])("ababab"))                           // true

Arnauld

Posted 2017-04-27T23:13:29.207

Reputation: 111 334

3

Haskell, 35 bytes

# takes a String and a list of Strings, and returns a Bool.

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

Try it online!

Just don't mind the test case I left out because it thrashed my meager laptop, even with -O2. I suspect GHC doesn't fuse away that intermediate 30517578125 element list, it has too much sharing to get swiftly garbage collected, and because the test case is false the program has to generate all of it... feel free to try if you can handle that.

mapM("":)(l<$s) is a list of all ways of making a length s list of elements that are either empty strings or strings from l.

Ørjan Johansen

Posted 2017-04-27T23:13:29.207

Reputation: 6 914

3

Pyth, 17 15 11 14 bytes

AQ|!G}Ym-dH./G

The requirement for the empty string changed, adding 3 bytes.

Explanation

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.

Old versions

AQ}Ym-dH./G

Shorter and runs in the lifespan of the universe!

Explanation

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

This is horrifyingly slow, but it works for my (trivially small) test cases.

Explanation

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.

user48543

Posted 2017-04-27T23:13:29.207

Reputation:

3

Jelly, 14 12 8 bytes

;FŒṖḟ€Ạ¬

Try it online!

How it works

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

bugfix on case "", ["The string can be constructed with nothing"] thanks to @JonathanAllan

fireflame241

Posted 2017-04-27T23:13:29.207

Reputation: 7 021

False negative for "", ["The string can be constructed with nothing!"] – Jonathan Allan – 2017-04-29T19:54:47.047

It'll be much slower but ;FŒṖḟ⁹$€Ạ¬ would fix it. – Jonathan Allan – 2017-04-29T20:05:25.363

...and you can use an implicit right argument for , so you dont need the $ or the : ;FŒṖḟ€Ạ¬. – Jonathan Allan – 2017-04-29T20:08:11.107

Grr, that's what I get for not testing every single testcase. I might be able to maintain 8 bytes by replacing ¬ with an operation which always returns true with right argument "". – fireflame241 – 2017-04-29T20:08:35.813

^ well I got it back to 8 :) – Jonathan Allan – 2017-04-29T20:09:15.540

2

R, 49 bytes

function(s,l)gsub(paste(l,collapse='|'),"",s)==""

Try it online!

Neil

Posted 2017-04-27T23:13:29.207

Reputation: 2 417

2Should fail for ('x', '.'), but doesn't. – Joey – 2017-04-28T07:32:36.620

2

Pyth, 10 8 bytes

f!-TQ./+zh

Test suite

This takes the list on the first line of STDIN, and the string (without quotes) on the second.

To start, the list is stored in Q, and the string is stored in z. Next, we form all possible partitions of z. Each partition will be filtered (f) to check if it uses only pieces in Q. To do this, we remove all elements of Q from T, the partition we're partitioning, and logically negate the result with !, so that only partitions where every element was in Q are kept.

To fix the problem that '' has no partitions, we add the first word of the dictionary to z, so that it won't be an empty string.

isaacg

Posted 2017-04-27T23:13:29.207

Reputation: 39 268

The test suite misses the bottom line (an empty string) - Does it need quoting? With an empty line or "" it seems to fail that case. – Jonathan Allan – 2017-04-29T20:34:18.300

An empty string has no partitions, so it actually just gives the wrong answer here. Darn, I'll try to fix it. – isaacg – 2017-04-29T21:32:43.337

The fix I suggested for Jelly was to concatenate the input string with the input array flattened, maybe you can do the same? – Jonathan Allan – 2017-04-29T22:03:33.973

@JonathanAllan I did something similar, thanks. – isaacg – 2017-04-29T22:45:19.580

The cases of "", [""] and "", [] have not been covered - lets not go there :) – Jonathan Allan – 2017-04-29T22:54:24.317

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}  

Andrei Odegov

Posted 2017-04-27T23:13:29.207

Reputation: 939

This one is almost unreadable, so I'd reccommend changing it a bit. I'm fairly certain most other people would agree. – Rɪᴋᴇʀ – 2017-04-30T21:55:54.940

Thank you for the explanation of the reason of your correction of my solution. – Andrei Odegov – 2017-05-01T04:13:49.787

1

Python 2, 64 bytes

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

Try this online!

Neil

Posted 2017-04-27T23:13:29.207

Reputation: 2 417

I think this doesn't totally work, try ("aaaaaaa",["aa","aaa"]). – xnor – 2017-04-28T01:44:30.103

@xnor I updated it. Come to find out, regex is perfect for this. – Neil – 2017-04-28T03:55:51.427

4Should fail for ('x', '.'), I guess, but doesn't. – Joey – 2017-04-28T07:31:39.880

1@nfnneil Did you? Your last edit was 10 hours ago. – Dennis – 2017-04-28T14:25:10.510

1...or "Hello", ["\w"] etc. – Jonathan Allan – 2017-04-29T20:30:40.400

1

PowerShell, 78

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

Pretty straightforward regex-based approach.

Joey

Posted 2017-04-27T23:13:29.207

Reputation: 12 260

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.

Peter Taylor

Posted 2017-04-27T23:13:29.207

Reputation: 41 901

@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 – 2017-04-28T10:47:06.903

@RosLuP, online demo. But I don't understand what your complaint is.

– Peter Taylor – 2017-04-28T11:54:30.017

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

Posted 2017-04-27T23:13:29.207

Reputation: 3 036

Gotta love C++! :) – MEMark – 2017-04-29T06:50:14.103

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

RootTwo

Posted 2017-04-27T23:13:29.207

Reputation: 1 749

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

Andrei Odegov

Posted 2017-04-27T23:13:29.207

Reputation: 939

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

Johan du Toit

Posted 2017-04-27T23:13:29.207

Reputation: 1 524