#!/usr/local/bin/perl

use 5.040.3;

# Vamos a suponer que se trata de simular una combinación física o química
# que no es binaria. La tentación sería usar base 3 pero habría una ida y
# venida del número ternario a la combinación.

my @trit = (-1, 0, 1);

my $size = scalar @trit;

my @info;  # una lista o cadena de @trit de longitud $n

my @flag;  # una lista de enteros no negativos sobre el número de veces
           # que se ha pasado por encima de $info[$n] siendo éste un @trit

my $n = 127;   # ejemplo 0 .. 127

say "El espacio de combinaciones es ", scalar(@trit) ** ($n+1);

my @pos;  # será lo más parecido al ternario. Posición [0|1|2] del @trit
          # en $info[$n] = $trit[ $pos[$n] ]
          # Pero la cosa es tratar de golpe a todo el @trit de $n, que se
          # puede hacer de uno en uno o todo
          # Se elige todo. Se hace en sub grupo {} y se devuelve 3 @info
          # en su debido orden, y se incrementa $flag[$n]

# INICIALIZACIÓN

my $tmp = 0;
for (0 .. $n){
    $tmp = int(rand() * scalar(@trit));      # 0,1,2 
    $pos[$_] = $tmp;
    $info[$_] = $trit[ $tmp ];              # -1,0,1
}


# EXPERIMENTACIÓN

my $ITER = 1_000_000;

for (1 .. $ITER){
        
    my $i = int (rand()*($n+1));

    my ($i1, $i2, $i3) = grupo($i);    # primera forma de uso

    $info[$i] = $i1;
    my $R1 = experiment(int(rand()*($n+1)));
    $info[$i] = $i2;
    my $R2 = experiment(int(rand()*($n+1)));
    $info[$i] = $i3;
    my $R3 = experiment(int(rand()*($n+1)));
    
    # elegir un escalar
    
    say "$R1 $R2 $R3  -> \t", $R1+$R2+$R3, "   ";
    
#    last if $R1+$R2+$R3 == -3;
}
say "";


exit 3;


sub grupo {
    my $i = shift;
    my $j = $pos[$i];
    my $r1 = $trit[ ++$j % $size ];
    my $r2 = $trit[ ++$j % $size ];
    my $r3 = $trit[ ++$j % $size ];   # la vuelta completa a @trit
    
    warn "Error de paridad" if ( $j % $size != $pos[$i] );

#    my (@info1, @info2, @info3) = (@info, @info, @info);   # aux       
#    ($info1[$i], $info2[$i], $info3[$i]) = ($r1, $r2, $r3);
    
    if (wantarray()){
	$flag[$i]++;
	return ($r1, $r2, $r3); 
    }else{
	$pos[$i] = ++$j % $size;	# esto es duda porque es sólo si se quiere avanzar
#	my $resultado = join " ", @info1;
	return $r1;   # se retorna una referencia a @info1 pero que es local,
    }                        # de manera que NO USADO
}

sub experiment {
    my $i = shift;    
    # hacer algo con esta @info particular
    return $info[$i];   # ejemplo
}


