Reputation: 29
use strict;
use warnings;
use FindBin;
use lib $FindBin::Bin;
use genNumeros;
my @palabra;
open (my $ARCHIVO, '<', "palabras.txt") or warn ("No se encontro el archivo palabras.txt, $!");
while (my $palabra = <$ARCHIVO>) {
chomp $palabra;
push @palabra, $palabra;
}
close $ARCHIVO;
my $palabraAleatoria = $palabra[genNumeros::crearNumero()];
print"$palabraAleatoria";
<>;
The genNumeros module has this code:
package genNumeros;
use strict;
use warnings;
use Math::Complex;
my $seed = time();
my $a = $seed / 5;
my $c = $seed - 7;
my $x = $seed;
my $m = sqrt($seed % 574) + $seed;
my $numAleatorio;
sub generadorMultiplicativo{
$numAleatorio = ((($a*$x) + $c) % $m);
$x = $numAleatorio;
}
my $letra;
my $residuo;
sub crearNumero{
generadorMultiplicativo();
$residuo = $x/$m;
if($residuo < 0.0384615384615385){
$letra = 1;
}
if($residuo > 0.0384615384615385 && $residuo < 0.076923076923077){
$letra = 2;
}
if($residuo > 0.076923076923077 && $residuo < 0.1153846153846154){
$letra = 3;
}
if($residuo > 0.1153846153846154 && $residuo < 0.1538461538461538){
$letra = 4;
}
if($residuo > 0.1538461538461538 && $residuo < 0.1923076923076923){
$letra = 5;
}
if($residuo > 0.1923076923076923 && $residuo < 0.2307692307692308){
$letra = 6;
}
if($residuo > 0.2307692307692308 && $residuo < 0.2692307692307692){
$letra = 7;
}
if($residuo > 0.2692307692307692 && $residuo < 0.3076923076923077 ){
$letra = 8;
}
if($residuo > 0.3076923076923077 && $residuo < 0.3461538461538462){
$letra = 9;
}
if($residuo > 0.3461538461538462 && $residuo < 0.3846153846153846){
$letra = 10;
}
if($residuo > 0.3846153846153846 && $residuo < 0.4230769230769231){
$letra = 11;
}
if($residuo > 0.4230769230769231 && $residuo < 0.4615384615384615){
$letra = 12;
}
if($residuo > 0.4615384615384615 && $residuo < 0.5){
$letra = 13;
}
if($residuo > 0.4615384615384615 && $residuo < 0.5384615384615385){
$letra = 14;
}
if($residuo > 0.5384615384615385 && $residuo < 0.5769230769230769){
$letra = 15;
}
if($residuo > 0.5769230769230769 && $residuo < 0.6153846153846154){
$letra = 16;
}
if($residuo > 0.6153846153846154 && $residuo < 0.6538461538461538){
$letra = 17;
}
if($residuo > 0.6538461538461538 && $residuo < 0.6923076923076923){
$letra = 18;
}
if($residuo > 0.6923076923076923 && $residuo < 0.7307692307692308){
$letra = 19;
}
if($residuo > 0.7307692307692308 && $residuo < 0.7692307692307692){
$letra = 20;
}
if($residuo > 0.7692307692307692 && $residuo < 0.8076923076923077){
$letra = 21;
}
if($residuo > 0.8076923076923077 && $residuo < 0.8461538461538462){
$letra = 22;
}
if($residuo > 0.8461538461538462 && $residuo < 0.8846153846153846){
$letra = 23;
}
if($residuo > 0.8846153846153846 && $residuo < 0.9230769230769231){
$letra = 24;
}
if($residuo > 0.9230769230769231 && $residuo < 0.9615384615384615){
$letra = 25;
}
if($residuo > 0.9615384615384615 && $residuo < 1){
$letra = 26;
}
return $letra;
}
1;
The thing is, that when i execute the .pl, it only closes up, i've already checked the "palabras.txt" and it has 27 words, the perl -c and perl -wc says that the syntax is OK, the @INC with perl -V finishes with a '.', I really don't know what's happening, I'm on ActivePerl 5.20 in Windows 10.
Upvotes: 1
Views: 62
Reputation: 164629
Your code is working, but it's just not displaying the number before the window closes.
STDOUT (printing to the screen) is often line buffered. This means it will only display the line when it sees a newline. For example...
print "SLEEP!!!";
sleep 2;
print " AWAKE!!!\n"'
This will sleep for two seconds and then print SLEEP!!! AWAKE!!!
all at once.
Try print "$palabraAleatoria\n";
For more detail, read Suffering From Buffering.
It seems like you're making your own random number generator? Perl already has one, rand()
, and it will use a better seed than the time in seconds, and a better algorithm. rand
takes a range of numbers to produce. rand(27)
will give a number from 0 to 27 exclusive (so 0 to 26.9999). To use it to pick an element out of an array, use the size of the array.
my $random_idx = int rand @palabra;
print "$palabra[$random_idx]\n";
This also avoids having to hard code the number of elements in your array into your code.
Using rand
eliminates the need for the big if
chain, but let's talk about it anyway. It can be better written as an if/elsif
starting at the top.
if( $residuo > 0.9615384615384615 ) {
return 26;
}
elsif( $residuo > 0.9230769230769231 ) {
return 25;
}
...and so on...
This avoids having to duplicate the range twice meaning less opportunities for typos. An if/elsif
is more efficient, it doesn't have to check every condition, it will stop as soon as a condition is met. Returning immediately is also simpler and more efficient than using an intermediate return variable.
All those magic numbers makes one wonder why they're magical. Once you notice that 0.0384615384615385 is 1/26 you can use that instead.
if( $residuo > 25/26 ) {
return 26;
}
elsif( $residuo > 24/26 ) {
return 25;
}
...and so on...
Replacing the magic numbers with fractions makes it easier to read and clearer what's going on. Once that happens it becomes clear this can be replaced with some simple math.
return $residuo * 26 + 1;
Upvotes: 3