#!/usr/bin/perl

use 5.038.2;
# no warnings;

# $|++;
  
my @target = (14,25,47,91) ;   # 2 * 7; 5 * 5; 1 * 47; 1 * 91
# my $count = 0;
# my $kount = 0;
my @op = ( '*','+','-','%','/','**', '**-', '**1/' );     # 0j0 que puede convertir ops en strings de ops
my $oper ;
my %hash ;
my ($i,$j, $iant, $ib) ;

my $ok = 0;

for my $num (@target){
    
    $i = 0;  # podría no ser así
    while ( ++$i <= $target[-1] ){                    # posición baja, podría ser hasta 7  

	$iant = $i;
	$ib = $i;
	
	for ( $j = -$target[-1]; $j <= $target[-1]; $j++ ){  # posición alta, podría partir de 5. Lo elijo negativo también pq está contemplado			
#	    $kount++; 
#	    print "\r$kount";
	    
	    for ($oper = 0 ; $oper <= scalar(@op)-1-2 ; $oper++) {  # nada aleatorio
		
		$i = $iant;  # reseteo
		$ib = $num;  # objetivo, el que toca
		
		if ($oper == 0 && $j != 0 ) { 
		    $ib = $i * $j; } # mult
		elsif ($oper == 1 && $j != 0 ) {
		    $ib = $i + $j; } # add
		elsif ($oper == 2 && $j != 0) {
		    $ib = $i - $j; } # minus
		elsif ($oper == 3 && $j != 0 && $j < $i) {
		    $ib = $i % $j; } # mod
		elsif ($oper == 4 && $j != 0) {
		    $ib = $i / $j; } # div
		elsif ($oper == 5) {       
		    $ib = $i ** $j;  # pot    (incluye exponentes postivos, mayores y menores que 1, y negativos) 
		}elsif ($j == 0){
		    # por $j feo
		    next;
		}else{
#		    warn "Outbound $oper";     # esto suele pasar por condiciones adicionales
		    next;
		}
		    
		if ( $num == $ib || $num eq $ib ){ 
		    $ok++;    # esto es válido
		    # en este caso, no creo haya posibilidad de solución repetida (5 5?), pero casos similares hay 
#		    if ( ++$hash{ "$i $op[$oper] " . '(' . $j .') =' . $ib } <= 1) {     # $j no puede ser cero en algunos casos y podría necesitar ser < 0 
			    
		    say "$i $op[$oper] " . '('. $j . ') = ' . $ib;			# éxito			    
#			$count++;    # esto es válido y además no repetido
			
#		    }
#		    goto lastnumberdone if $count >= scalar(@target);                           # de los 4 bucles, se sale al primero
		}  
		
	    }   # bucle de oper, aquí se altera la i, por lo que se debe restaurar, se hace al principio
	  
	}     # bucle de j

	select (undef, undef, undef, 0.0001);
	
    }       # bucle de i
    
}
    
lastnumberdone:    

say "\n$ok soluciones únicas"; 
say "Logging out... ";

exit 2;

