Testez si une chaîne peut être faite avec des sous-chaînes!


23

Étant donné une chaîne set un tableau / liste l, déterminez si vous spouvez ou non créer des pièces à partir de l.

Par exemple, si la chaîne est "Hello, world!"et la liste est [' world!', 'Hello,'], alors le programme / fonction doit retourner une valeur véridique, car vous pouvez organiser la liste pour former la chaîne. La liste suivante redonnerait aussi une valeur truthy: ['l', 'He', 'o, wor', 'd!']. Imaginez simplement le 'l'remplissage là où il le faut dans la chaîne. Alors oui, vous pouvez répéter des éléments de la liste pour former la chaîne. S'il ne peut pas former la chaîne, il doit renvoyer une valeur fausse. Les méthodes standard d'E / S, les échappatoires standard s'appliquent.

Cas de test:

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

Est-il important que le tableau contienne plus de chaînes que nécessaire pour construire la chaîne principale?
Shaggy

Quelle devrait être la valeur de retour dans ces cas?
Shaggy

@Shaggy Truthy. S'il y a plus, alors la chaîne peut être construite avec toutes les parties non supplémentaires. J'ajouterai un cas de test.
Camarade SparklePony

3
Je recommande d'ajouter ce cas de test:"ababab", ["a","ba","ab"]
junkie de mathématiques

3
Je vous suggère d'ajouter un scénario de test contenant des métacaractères d'expression régulière.
Joey

Réponses:


11

Brachylog , 8 octets

~c¬{∋¬∈}

Essayez-le en ligne!

C'est vraiment lent. Il a fallu environ 37 secondes pour le "Bonjour, monde!" cas de test sur mon PC, et expiré sur TIO.

Cela prend la chaîne à travers la variable d'entrée et la liste à travers la variable de sortie

Explication

             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" plus de 60 secondes ...
RosLuP

1
@RosLuP Avec cette entrée et ["la", " l", "al "]comme liste, elle s'est terminée sur mon ordinateur et a répondu correctement false.après 6800 secondes, et "seulement" 113 milliards d'inférences.
Fatalize

J'ai l'impression qu'écrire quoi que ce soit dans cette langue entraînerait un programme non exécutable sur TIO haha.
Urne de poulpe magique du

@carusocomputing Le langage n'est pas si lent pour la plupart des programmes, c'est juste que dans certains cas en raison de la déclarativité du programme, il en résulte des temps d'exécution très très lents (qui pourraient être considérablement améliorés au prix de la longueur du code)
Fatalize

@Fatalize errr ... Je voulais dire que le golf n'écrivait pas, il semble que moins il y a d'instructions, plus la "question" devient large et plus vous avez besoin de calcul. On dirait une langue impressionnante pour les problèmes mathématiques théoriques.
Urne de poulpe magique du

7

Mathematica, 29 octets

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

Explication:

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

Solution de triche limite, 21 octets

StringMatchQ[#,#2..]&

Puisque Mathematica est un langage de programmation symbolique, il n'y a pas de différence * entre les expressions List[a,b,...]et Alternatives[a,b,...]autre que la façon dont elles interagissent avec les autres symboles et la façon dont elles sont affichées ( {a,b,...}et a|b|..., respectivement). Lorsqu'il est utilisé dans le deuxième argument de StringMatchQ, unAlternatives expression est traitée comme un modèle de chaîne, et nous pouvons donc économiser des 8octets sur ma solution ci-dessus en prenant le deuxième argument comme Alternativesexpression.

* Techniquement Listaussi Locked, ce qui empêche les utilisateurs de Unprotectle modifier et de modifier son comportement.


1
{x,y,z}est traité de la même manière que x|y|zpour la correspondance de motifs de chaînes. Je pense que vous pouvez remplacer ""|##&@@#2..par juste #2...
Pas un arbre le

5

Pyth, 23 octets

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

Prend l'entrée comme [['string'],['list', 'of', 'parts']]. La sortie est soit une liste vide, soit une liste avec des valeurs à l'intérieur. En Pyth, une liste contenant n'importe quoi, même une chaîne nulle ( ['']), a la valeur true.

Essayez-le en ligne!

Explication:

                             | 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

Cette solution essaie continuellement de supprimer toutes les parties possibles depuis le début de la chaîne et garde une trace des valeurs qu'il doit encore parcourir.

Si nous regardons la valeur de Gdans le cas de test [['ababab'],['a','ba','ab']]après chaque itération de la boucle while, voici ce que nous obtenons:

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

Et, dans le cas de test, voici [['aaaaa'],['aa']]ce que nous obtenons:

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

J'ai créé un autre cas de test, [['aaaaaa'],['a','aa','aaa']]et la sortie était la suivante:

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

La liste de sortie contient un tas de déchets à l'intérieur, mais c'est toujours une valeur vraie.


5

Perl 5 , 39 octets

38 octets de code + -pindicateur.

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

Essayez-le en ligne!

Pour l'entrée "Hello, world!", ["l", "He", "o, wor", "d!"](séparée par des sauts de ligne en fait), elle construit le modèle l|He|o, wor|d!|(avec les métacaractères échappés, grâce à \Q..\E), puis cherche si la première chaîne correspond à ce modèle avec /^($v)*$/.

Sur TryItOnline, notez qu'il doit y avoir une nouvelle ligne de fin.


"Bonjour, monde! L Il o, wor d!" cette entrée avec un espace après le "l" ne génère aucun résultat
RosLuP

@RosLuP Pouvez-vous me donner un lien TryItOnline s'il vous plaît? (Je ne comprends pas exactement ce que vous voulez dire. Notez que "faux" n'imprime en fait rien car c'est Perl)
Dada

Donc, pour faux rien imprimer? Dans ce cas, excusez-moi, mais cette valeur de sortie ne me semble pas trop utile ...
RosLuP

@RosLuP C'est vrai. En Perl, undefest la valeur de falsification renvoyée par la plupart des commandes intégrées. Et lors de l'impression, il n'imprime en fait rien. Et c'est exactement ce que je fais. L'impression "1/0" est naturelle pour les langages de type C, mais pour Perl, "1 / undef" est la méthode naturelle.
Dada

Aucune sortie n'a une ambiguïté "il est en cours d'exécution ou déjà le programme se termine faux?"
RosLuP

4

PHP, 69 octets

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

Cas de test


Très intelligent, m'a pris une minute pour comprendre ce que tu fais. +1 pour sortir des sentiers battus
Martijn

Faux négatif pour ce cas embêtant["", ["The string can be constructed with nothing!"]]
Jonathan Allan

@JonathanAllan done est une chaîne vide une chaîne?
Jörg Hülsermann

Oui, le problème du partitionnement vide est un problème dans de nombreuses solutions.
Jonathan Allan

3

Python 2, 141 octets

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*

Essayez-le en ligne!

Extrêmement inefficace. Le premier cas de test arrive à expiration sur TIO.


3

JavaScript (ES6), 59 octets

Prend le tableau de sous a- chaînes et la chaîne sdans la syntaxe de curry(a)(s) . Renvoie false/ true.

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

Commenté

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

Cas de test


3

Haskell , 35 octets

#prend a Stringet une liste de Strings, et retourne a Bool.

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

Essayez-le en ligne!

Ne vous occupez pas du cas de test que j'ai laissé de côté, car il a détruit mon maigre ordinateur portable, même avec -O2. Je soupçonne que GHC ne fusionne pas cette liste d'éléments 30517578125 intermédiaire, il a trop de partage pour être rapidement récupéré, et parce que le cas de test est faux, le programme doit générer tout cela ... n'hésitez pas à essayer si vous le pouvez gérer cela.

mapM("":)(l<$s)est une liste de toutes les façons de créer une length sliste d'éléments qui sont des chaînes vides ou des chaînes l.


3

Pyth, 17 15 11 14 octets

AQ|!G}Ym-dH./G

L'exigence pour la chaîne vide a changé, ajoutant 3 octets.

Explication

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.

anciennes versions

AQ}Ym-dH./G

Plus court et court dans la durée de vie de l'univers!

Explication

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

C'est horriblement lent, mais cela fonctionne pour mes cas de test (trivialement petits).

Explication

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

Gelée , 14 12 8 octets

;FŒṖḟ€Ạ¬

Essayez-le en ligne!

Comment ça marche

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

correction "", ["The string can be constructed with nothing"]de bug sur le cas grâce à @JonathanAllan


Faux négatif pour"", ["The string can be constructed with nothing!"]
Jonathan Allan

Ce sera beaucoup plus lent, mais ;FŒṖḟ⁹$€Ạ¬le réparerait.
Jonathan Allan

... et vous pouvez utiliser un argument droit implicite , de sorte que vous ne avez pas besoin du $ou : ;FŒṖḟ€Ạ¬.
Jonathan Allan

Grr, c'est ce que j'obtiens pour ne pas tester chaque cas de test. Je pourrais peut-être conserver 8 octets en remplaçant ¬par une opération qui retourne toujours vrai avec le bon argument "".
fireflame241

^ eh bien je suis revenu à 8 :)
Jonathan Allan


2

Pyth, 10 8 octets

f!-TQ./+zh

Suite de tests

Cela prend la liste sur la première ligne de STDIN et la chaîne (sans guillemets) sur la seconde.

Pour commencer, la liste est stockée dans Qet la chaîne est stockée dans z. Ensuite, nous formons toutes les partitions possibles de z. Chaque partition sera filtrée ( f) pour vérifier si elle n'utilise que des morceaux Q. Pour ce faire, on enlève tous les éléments QdeT la partition que nous sommes le partitionnement, et nions logiquement le résultat avec !, de sorte que seules les partitions où chaque élément étaitQ sont conservés.

Pour résoudre le problème qui ''n'a pas de partitions, nous ajoutons le premier mot du dictionnaire à z, afin qu'il ne soit pas une chaîne vide.


La suite de tests manque la ligne du bas (une chaîne vide) - A-t-elle besoin de citation? Avec une ligne vide ou ""il semble échouer dans ce cas.
Jonathan Allan

Une chaîne vide n'a pas de partitions, donc elle donne juste la mauvaise réponse ici. Bon sang, je vais essayer de le réparer.
isaacg

Le correctif que j'ai suggéré pour Jelly était de concaténer la chaîne d'entrée avec le tableau d'entrée aplati, peut-être pouvez-vous faire de même?
Jonathan Allan

@JonathanAllan J'ai fait quelque chose de similaire, merci.
isaacg

Les cas de "", [""]et "", []n'ont pas été couverts - ne nous y
Jonathan Allan

2

PowerShell, 61 58 57 octets

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

Essayez-le en ligne!

Anciennes solutions:

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

Celui-ci est presque illisible, donc je recommanderais de le changer un peu. Je suis pratiquement certain que la plupart des autres personnes seraient d'accord.
Rɪᴋᴇʀ

Merci pour l'explication de la raison de votre correction de ma solution.
Andrei Odegov

1

Python 2, 64 octets

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

Essayez ceci en ligne!


Je pense que cela ne fonctionne pas totalement, essayez ("aaaaaaa",["aa","aaa"]).
xnor

@xnor Je l'ai mis à jour. Venez découvrir, regex est parfait pour cela.
Neil

4
Devrait échouer ('x', '.'), je suppose, mais ce n'est pas le cas.
Joey

1
@nfnneil L'avez-vous fait? Votre dernière modification remonte à 10 heures.
Dennis

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

1

PowerShell, 78

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

Approche assez simple basée sur les regex.


1

CJam (16 octets)

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

Il s'agit d'un bloc (fonction) anonyme prenant la chaîne et le tableau de chaînes sur la pile. Démo en ligne .

Il utilise l'algorithme évident:

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

La valeur renvoyée est un tableau / chaîne vide (falsy) s'il strne peut pas être créé, ou un tableau contenant str(véridique, même si strc'est lui-même la chaîne vide) s'il peut être créé.


@RosLuP, je ne sais pas ce que tu veux dire. Ce cas de test particulier s'exécute si rapidement que je ne peux pas vraiment le chronométrer. Les autres cas de test sont longs à exécuter, mais la spécification n'inclut aucune contrainte de temps.
Peter Taylor

@RosLuP, démo en ligne . Mais je ne comprends pas quelle est votre plainte.
Peter Taylor

1

C ++ (Cci), 287 octets

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

parce que je n'ai pas écrit ou utilisé trop de next_permutation () je ne sais pas si tout va bien. Je ne sais pas à 100% si c'est une solution aussi peut-être que c'est de mauvaise qualité ... Une liste de chaînes est ici un tableau de pointeurs vers char; NULL terminé L'algo est facile, il y a un algo que la linéarité essaie si toutes les chaînes de la liste correspondent à l'argument "une" chaîne, il y a un autre algo qui permute l'index de la liste des chaînes afin d'essayer toutes les combinaisons possibles.

dé-golfez-le, testez le code et les résultats ici

#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

cela compilerait dans le compilateur gcc C ++

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

Je dois aimer C ++! :)
MEMark

1

Python, 66 octets

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

Non golfé:

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

Serveur Microsoft SQL, 353 octets

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

Testez-le en ligne.

Version lisible:

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 octets

Je suis sûr qu'il existe un moyen plus court de le faire en C, mais je voulais créer une solution qui teste toutes les combinaisons possibles de sous-chaînes au lieu de la méthode de recherche / remplacement habituelle.

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

Essayez-le en ligne

Non golfé:

#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));
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.