• Publicidad

[RETO] Obtener valor de dígitos

Aprende Perl

[RETO] Obtener valor de dígitos

Notapor Aceitunas » 2014-01-09 11:48 @533

Hola, os dejo este reto que he encontrado en otros foros. El objetivo es solucionarlo utilizando Perl.

Cada letra tiene un valor y hay que encontrar mediante un algoritmo cuáles son los valores de las letras.
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
      MM +
      AA +
      DD
     ---
     MAD
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Voy a llegar hasta el final, voy a subir la velocidad - Migue Benítez.
Aceitunas
Perlero nuevo
Perlero nuevo
 
Mensajes: 117
Registrado: 2013-11-07 15:25 @684
Ubicación: Ciudad Real, España.

Publicidad

Re: [RETO] Obtener valor de dígitos

Notapor explorer » 2014-01-09 13:29 @603

Bueno, como a mí me gustan las expresiones regulares, lo he resuelto usando (su) fuerza bruta.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.16;
  3.  
  4. my($M,$A,$D);
  5. ("M" x (9*3))
  6.     =~  /
  7.             ^
  8.             (M{1,9})
  9.             (M{1,9})
  10.             (M{1,9})
  11.             (?(?{
  12.                     $M = length $1;
  13.                     $A = length $2;
  14.                     $D = length $3;
  15.                    
  16.                     "$M$M"+"$A$A"+"$D$D" == "$M$A$D"
  17.                 })
  18.                 (?{
  19.                     say "$M$A$D";
  20.                 })
  21.             )
  22.             (*FAIL)
  23.         /x;
  24.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: [RETO] Obtener valor de dígitos

Notapor Aceitunas » 2014-01-09 13:37 @609

Buen código, explorer, el mio es más humilde :lol: .

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use v5.16;
  2.  
  3. my ($m,$a,$d);
  4.  
  5. for ($m = 1; $m < 10; $m++)
  6. {
  7.     for ($a = 1; $a < 10; $a++)
  8.     {
  9.         for ($d = 1; $d < 10; $d++)
  10.         {      
  11.             my $dx = "$d$d";
  12.             my $ax = "$a$a";
  13.             my $mx = "$m$m";
  14.  
  15.             say "$m$a$d" if ($dx + $ax + $mx == "$m$a$d");
  16.         }
  17.     }
  18. }
  19.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


EDITO: Lo he resumido un poco el código ¡je,je!
Voy a llegar hasta el final, voy a subir la velocidad - Migue Benítez.
Aceitunas
Perlero nuevo
Perlero nuevo
 
Mensajes: 117
Registrado: 2013-11-07 15:25 @684
Ubicación: Ciudad Real, España.

Re: [RETO] Obtener valor de dígitos

Notapor explorer » 2014-01-09 14:47 @657

Es la misma solución, así que no es una solución humilde. Enhorabuena también para ti.

Si acaso, una forma más perlera de escribir los bucles sería así:

for $m (1 .. 9) {
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: [RETO] Obtener valor de dígitos

Notapor Aceitunas » 2014-01-10 06:12 @300

Dándole vueltas y siguiendo tu consejo sobre los for, lo he conseguido resumir aún más.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use v5.16;
  2.  
  3. for my $m(1..9)
  4. {
  5.     for my $a(1..9)
  6.     {
  7.         for my $d(1..9)
  8.         {      
  9.             say "$m$a$d" if ("$d$d" + "$a$a"+ "$m$m" == "$m$a$d");
  10.         }
  11.     }
  12. }
  13.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Creo que ya está resumido al máximo.

También he intentado entender la expresión regular tuya, pero no comprendo este trozo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. (?(?{
  2.                     $M = length $1;
  3.                     $A = length $2;
  4.                     $D = length $3;
  5.                    
  6.                     "$M$M"+"$A$A"+"$D$D" == "$M$A$D"
  7.                 })
  8.                 (?{
  9.                     say "$M$A$D";
  10.                 })
  11.             )
  12.             (*FAIL)
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Me lo podrías explicar? Lo he intentado entender buscando más información, pero nada.
Voy a llegar hasta el final, voy a subir la velocidad - Migue Benítez.
Aceitunas
Perlero nuevo
Perlero nuevo
 
Mensajes: 117
Registrado: 2013-11-07 15:25 @684
Ubicación: Ciudad Real, España.

Re: [RETO] Obtener valor de dígitos

Notapor explorer » 2014-01-10 10:53 @495

La estructura es:

(?(condición)patrón-sí|patrón-no)

(En este caso concreto, no está la parte de patrón-no)

Se trata de una estructura que comprueba una condición. Si la condición es verdadera, el resultado de la estructura será un patrón: el indicado por patrón-sí. Si no es verdadera, devuelve el patrón-no.

Esto se usa para indicar distintos patrones de búsqueda según el valor de una condición.

En este caso, la condición es

(?{ ... })

que es una estructura que contiene una expresión Perl, que es evaluada. En este caso, se pasan a las variables $M, $A y $D la longitud de las capturas de paréntesis realizadas antes (líneas anteriores a las mostradas). Y se termina con una comparación de igualdad, similar a la de tu último código.

Si el resultado de esta condición es verdadera, se ejecuta la parte de patrón-sí, que resulta que es:

(?{ say "$M$A$D"; })

que a su vez es otro código Perl ejecutable. En este caso, un simple say(), sacando el resultado correcto de la búsqueda.

Como no hay patrón-no, pues no hace nada en caso de que la condición falle.

Después de eso, hay un patrón predefinido:

(*FAIL)

Este patrón no coincide con nada. Solo provoca un "fallo de coincidencia" al motor de expresiones regulares, haciéndole creer que la búsqueda actual ha fracasado, y que debe reintentarlo con otro patrón distinto. Lo que hace el motor de expresiones regulares es volver atrás, y volver a ajustar los parámetros de búsqueda de las 'M', en la parte de '{1,9}', probando con otra combinación.

Todo esto es para imitar el funcionamiento de tres bucles anidados: el motor de expresiones regulares probará con todas las combinaciones de '{1,9}'.


Más información en tu propio ordenador en perldoc perlre, y en la Web (traducido al español).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: [RETO] Obtener valor de dígitos

Notapor Aceitunas » 2014-01-10 11:26 @518

Gracias, explorer, pero entonces en tu código ¿qué condición se supone que se cumple aquí? (?(?{, debajo de los M{1..9}. ¿Y por qué la condición que muestra el mensaje del número correcto está fuera de los paréntesis que contienen la comparación?

Perdón por ser pesado pero no lo termino de comprender. :cry:
Voy a llegar hasta el final, voy a subir la velocidad - Migue Benítez.
Aceitunas
Perlero nuevo
Perlero nuevo
 
Mensajes: 117
Registrado: 2013-11-07 15:25 @684
Ubicación: Ciudad Real, España.

Re: [RETO] Obtener valor de dígitos

Notapor explorer » 2014-01-10 17:05 @754

¿Seguro que está fuera :) ? Está a continuación. Y hay un paréntesis de cierre de la condición.

Cuando me refiero a condición, me refiero a esta estructura:

(?(condición)patrón-sí)

(condición) es la condición que comprueba si hemos encontrado los valores correctos que cumplen con la condición matemática. Si se cumple, se devuelve patrón-sí. Tanto condición como patrón-sí son, a su vez, ejecución de código, así que tienen sus propios paréntesis adicionales.

Fíjate en el código que publiqué al principio.
  • en la línea 5 se crea la cadena de caracteres donde vamos a realizar las búsquedas
  • en la línea 6 está el operador de exp. reg., y el delimitador del patrón, que termina en la línea 23
  • en la línea 7 indicamos que todas las búsquedas deben estar ancladas al principio de la cadena
  • en las líneas 8 a 9 indicamos que esperamos tres conjuntos de letras 'M', de entre una a nueve letras
  • en la línea 11 comienza la condición, que termina en la línea 21
  • la condición que se va a probar está entre las líneas 11 y 17, incluidas; y la parte que se ejecuta si la condición se cumple, son las líneas 18 a 20, incluidas
  • después de la condición, viene el FAIL, que está en la 22, así que se ejecuta siempre (no está dentro de la condición)
  • en la línea 23 termina el patrón, junto con la opción x, que es la que nos permite escribir el patrón con espacios en blanco y en varias líneas
Espero que quede claro. Si no, vuelve a preguntar, que no pasa nada.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: [RETO] Obtener valor de dígitos

Notapor Aceitunas » 2014-01-10 19:48 @867

Vale... creo que ahora sí lo entiendo pero, si es como yo quiero entender, la condición es así:

(? (?{CONDICION-A-CUMPLIR}) (?{VERDADERO}) | (?{FALSO}) )

¿No?

EDITO: Vale, ya he comprobado mi teoría, ¡je,je!

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use v5.16;
  2.  
  3. my $i = 1;
  4.  
  5. ("M" x 15)
  6.     =~  /
  7.             ^
  8.             (M{1,15})
  9.             (?(?{
  10.                     $i < 10
  11.               })
  12.               (?{
  13.                     say "menor: " . $i;
  14.                     $i++;
  15.               })
  16.               |
  17.               (?{
  18.                     say "MAYOR O IGUAL: " . $i;
  19.                     $i++;
  20.               })
  21.             )
  22.             (*FAIL)
  23.         /x;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Voy a llegar hasta el final, voy a subir la velocidad - Migue Benítez.
Aceitunas
Perlero nuevo
Perlero nuevo
 
Mensajes: 117
Registrado: 2013-11-07 15:25 @684
Ubicación: Ciudad Real, España.


Volver a Formación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados