Reducció de programes

Cada cas d’entrada d’aquest exercici és un string sobre l’alfabet
{+,*,=,<,{,},(,),;,v,n,i,e,w}

Per exemple, aquest seria un possible string d’entrada:
"v=n+n*v;i(v<n){v=v+n;}ew(n<v*v)v=n+v;"

Aquestes entrades tenen una pinta una mica críptica. A continuació donem
una petita explicació del seu significat i el sentit de l’exercici.
Remarquem, però, que aquesta explicació no és imprescindible per a poder
resoldre l’exercici. La podeu obviar si voleu.

Explicació (la podeu ometre)

Aquests strings d’entrada son una manera simplificada de descriure la
seqüència de tokens d’un programa en un cert llenguatge de programació.
Per a tenir una visió més intuitiva, podeu interpretar cada lletra com
segueix:

- v: variable

- n: number

- i: if

- e: else

- w: while

Per exemple, l’string anterior seria la versió simplificada d’aquesta
seqüència de tokens:

    variable = number + number * variable ;
    if ( variable < number ) {
      variable = variable + number ;
    } else
      while ( number < variable * variable )
        variable = number + variable ;

Final d’explicació

Per a cada string d’entrada, haureu de donar com a sortida el resultat
d’aplicar sobre aquesta entrada el següent conjunt de regles de
reemplaçament amb una derivació per l’esquerra, és a dir, aplicant a
cada pas una regla el més a l’esquerra possible:

- n → E

- v → E no es pot aplicar si ve seguida de =

- E*E → E

- E+E → E no es pot aplicar si ve seguida de *

- E<E → E no es pot aplicar si ve seguida de * o +

- v=E; → I

- (E) → E no es pot aplicar si ve precedida de i o w

- i(E)I → I no es pot aplicar si ve seguida de e

- i(E)IeI → I

- w(E)I → I

- LI → L

- I → L no es pot aplicar si ve precedida de ) o L

- {L} → I

- L → P només es pot aplicar si aquest L és l’únic caràcter que queda,
  és a dir, si tot l’string inicial ha estat reduït a exactament L.

Aquestes regles tenen una pinta una mica críptica. A continuació donem
una petita explicació del seu significat i el sentit de l’exercici.
Remarquem, però, que aquesta explicació no és imprescindible per a poder
resoldre l’exercici. La podeu obviar si voleu.

Explicació (la podeu ometre)

Aquestes regles son una manera simplificada de descriure com reduir una
seqüencia de tokens d’un cert llenguatge de programació. Les lletres
majúscules tenen el següent significat intuitiu:

- E: expression

- I: instruction

- L: list of instructions

- P: program

Per exemple, la regla i(E)IeI → I es pot interpretar com:

if ( expression ) instruction else instruction → instruction

Final d’explicació

Nota: el sistema de regles anterior acaba, però no és convergent. Per
exemple, l’string d’entrada v=n;v=n; té dues formes normals LL i P, com
es mostra amb les següents dues derivacions:

- v=n;v=n; ⇒ v=n;v=E; ⇒ v=n;I ⇒ v=n;L ⇒ v=E;L ⇒ IL ⇒ LL

- v=n;v=n; ⇒ v=E;v=n; ⇒ Iv=n; ⇒ Lv=n; ⇒ Lv=E; ⇒ LI ⇒ L ⇒ P

Tot i així, hem dit que volem el resultat d’anar aplicant les regles el
més a l’esquerra possible. Per tant, només la P, que és el resultat de
la segona de les derivacions anteriors, es consideraria com a sortida
vàlida del programa amb entrada v=n;v=n;.

Observació: Podeu seguir l’enfoc que considereu oportú, i podeu
utilitzar qualsevol de les classes presentades al curs (string, vector,
stack, queue, list, map, set) de la manera que considereu oportuna.
Noteu, però, que enfocaments diferents poden donar lloc a solucions més
o menys eficients, i que superin només els jocs de proves públics o tots
els jocs de proves, de manera que la nota acabarà depenent d’això.

Recomanació: Aquest exercici pot ser bastant tediós de resoldre si no
s’agafa un enfocament convenient. Considerem que és recomanable
utilitzar un vector v com si fos una pila, enlloc de fer servir un stack
directament. El motiu és que el tipus stack només permet comprovar el
valor del cim de la pila, però no del segon valor des del cim, del
tercer valor des del cim, etc, sense haver de desapilar elements.
L’enfocament que us recomanem usant v és el següent. Teniu un bucle
general que recorre els caràcters de l’string d’entrada. A cada pas del
bucle general, afegiu un nou caràcter a v amb push_back. Dins del bucle
general, teniu un bucle intern que intenta aplicar regles al final de v
mentre sigui possible. A cada pas del bucle intern, verifiqueu si el
final de v coincideix amb una part esquerra de regla, i satisfà les
condicions per a poder aplicar aquesta regla. Noteu que les condicions
sobre caràcters que precedeixen la part esquerra de regla s’hauran de
comprovar sobre el propi v, mentre que les condicions sobre caràcters
que segueixen la part esquerra de regla s’hauran de comprovar sobre el
que queda per llegir de l’string d’entrada. Quan poguem aplicar alguna
regla, modificarem el final de v reemplaçant la part esquerra de regla
per la corresponent part dreta.

Entrada

L’entrada conté un nombre arbitrari de casos, un per línia. Cada cas
consisteix en un string no buit sobre {+,*,=,<,{,},(,),;,v,n,i,e,w}.

Sortida

Per a cada cas, escriviu en una línia el resultat d’aplicar les regles
de reemplaçament tant com sigui possible i sempre donant prioritat a
aplicar regles el més a l’esquerra possible (o sigui, la forma normal
obtinguda amb una derivació per l’esquerra).

Observació

Avaluació sobre 10 punts:

- Solució lenta: 5 punts.

- solució ràpida: 10 punts.

Entenem com a solució ràpida una que és correcta, de cost lineal i capaç
de superar els jocs de proves públics i privats. Entenem com a solució
lenta una que no és ràpida, però és correcta i capaç de superar els jocs
de proves públics.

Informació del problema

Autoria: PRO2

Generació: 2026-01-25T14:05:24.424Z

© Jutge.org, 2006–2026.
https://jutge.org
