IMP: analyseur de multiplication implicite

9

Jack aime le langage de programmation C, mais déteste écrire des expressions comme V=a*b*h; multiplier les valeurs.

Il aimerait écrire à la V=abh;place, pourquoi le compilateur devrait-il se plaindre du fait que le abhsymbole n'est pas défini car ils int a, b, h;sont définis, afin que nous puissions en déduire la multiplication?

Aidez-le à implémenter un analyseur qui déchiffre un seul terme de multiplication, à condition que l'ensemble des variables définies dans la portée actuelle soit connu.

Par souci de simplicité, la multiplication par le nombre (comme dans 2*a*b) n'est pas prise en compte, seules les variables apparaissent.

L'entrée est un terme de multiplication T , remplissant l'expression rationnelle:

[a-zA-Z_][a-zA-Z_0-9]*

et un ensemble de variables Z .

Une analyse P du terme T sur l'ensemble de variables Z est une chaîne remplissant ce qui suit:

  1. après avoir supprimé toutes les occurrences de *P, nous recevons T,
  2. soit un nom de variable de Z, soit un nom de variable approprié de Z divisé en *caractères uniques .

La solution doit imprimer toutes les analyses d'un terme.

Échantillon:

Vars           a, c, ab, bc
Term           abc
Solution       ab*c, a*bc

Vars           ab, bc
Term           abc
Solution       -

Vars           -
Term           xyz
Solution       -

Vars           xyz
Term           xyz
Solution       xyz

Vars           width, height
Term           widthheight
Solution       width*height

Vars           width, height
Term           widthheightdepth
Solution       -

Vars           aaa, a
Term           aaaa
Solution       aaa*a, a*aaa, a*a*a*a

L'entrée (la liste des variables et le terme) peut être fournie de n'importe quelle manière adaptée à la langue.

La sortie peut être sous n'importe quelle forme sensible (une analyse par ligne ou une liste séparée par des virgules, etc.) - mais elle doit être sans ambiguïté et être lisible.

Une sortie vide est acceptable s'il n'y a pas d'analyse possible d'un terme (dans les exemples, j'ai utilisé «-» pour plus de clarté).

C'est un golf de code, donc le code le plus court l'emporte.

pawel.boczarski
la source
1
Dans votre premier exemple, je pense que ab*cc'est une analyse incorrecte, car ce cn'est pas une variable autorisée.
isaacg
1
Avec un scan récursif, je trouve exactement votre résultat dans l'échantillon. Mais c'est discutable: pourquoi a*aaa aaa*aet nonab*c c*ab
edc65
En raison de la règle 1. d'analyse. Oui, la multiplication est généralement commutative, mais nous n'allons pas si loin - nous voulons simplement "reconstruire" la multiplication dans l'ordre où elle a été effectuée. En fait, dans le langage de Jack, nous pourrions avoir un type de matrice - la multiplication n'est donc pas commutative. Et "aaaa" peut être à la fois une juxtaposition de "aaa" et "a" ou "a" et "aaa" - ceci pas pour la commutativité, plutôt pour l'ambiguïté que nous prenons en compte.
pawel.boczarski
Copie
feersum

Réponses:

4

Pyth, 18 caractères

mj\*dfqzsTsm^Qkhlz

Cette solution est adaptée de ma solution Interpreting Fish . Les problèmes sont en fait très similaires.

Attend une entrée en tant que telle:

aaaa
"a", "aaa"

Donne une sortie comme ceci:

['a*aaa', 'aaa*a', 'a*a*a*a']

Essayez-le ici.

  • sm^Qkhlz: Génère toutes les séquences de variables contenant jusqu'à la longueur du nombre de chaînes d'entrée de variables.

  • fqzsT: Filtre les séquences variables qui correspondent à la chaîne d'entrée

  • mj\*d: Insère le *symbole et imprime.

isaacg
la source
3

Python 2 - 147 94 octets


R=lambda S,V,F=[]:S and[R(S[len(v):],V,F+[v])for v in V if v==S[:len(v)]]or print("*".join(F))

Cela définit une fonction Rà utiliser comme:

>>> R("abc", ["a", "bc", "ab", "c"])

Imprime la sortie comme:

a*bc
ab*c
matsjoyce
la source
1

JavaScript (ES6) 111

Adapté de ma réponse «poisson» , la principale différence est de trouver toutes les solutions, pas seulement la première.

F=(v,t)=>(k=(s,r)=>s?v.map(v=>s.slice(0,l=v.length)==v&&k(s.slice(l),[...r,v])):console.log(r.join('*')))(t,[])

La sortie est imprimée sur la console. Le résultat de la fonction n'a aucune signification et doit être ignoré.

Tester dans la console Firefox / FireBug

F(['a','c','ab','bc'],'abc')  
a*bc  
ab*c

F(['ab','bc'],'abc')

F(['aaa','a'],'aaaa')
aaa*a
a*aaa
a*a*a*a

F(['xyz'],'xyz')
xyz
edc65
la source