Re: pop() on a fast multi-core cpu
by jdporter (Paladin) on Oct 31, 2024 at 02:13 UTC
|
I always (well, sometimes) enjoy trying my hand at rewriting other people's crap code.
#!/usr/bin/perl
use Time::HiRes qw(gettimeofday tv_interval);
use List::Util 'shuffle'; # perlfaq4
use warnings;
use strict;
my @ups = ('0') x 10;
# four suits are added to a deck and then shuffled
my @deck = shuffle(('A' .. 'M') x 4);
#print "@deck\n"; exit 0;
print "\n";
my $t0 = gettimeofday;
$ups[0] = shift @deck;
eval
{
my $done = 0;
while (!$done)
{
print "@ups\n";
$done = 1;
scan:
for (my $j=1;$j<10;$j++)
{
$ups[$j] eq '0' and $ups[$j] = (shift @deck or die);
for (my $k=0;$k<$j;$k++)
{
if ( $ups[$j] eq $ups[$k] )
{
$ups[$j] = (shift @deck or die);
$ups[$k] = (shift @deck or die);
$done = 0;
last scan;
}
}
}
}
};
print "\n@ups\tExit row\n";
my $usec = sprintf("%.2f", (gettimeofday - $t0) * 10**6);
print "\n".(52-@deck)." passes in $usec microseconds. ";
print !@deck
? "Succeeded in consuming the entire deck.\n\n"
: "Failed to consume the entire deck.\n\n";
Of course, if you have input/output, such as those print statements, there's virtually no meaning to any timings you get.
One thing I don't like about the OP's solution (which I didn't change in mine) is that there is a lot of unnecessary checking on every pass.
For example, if on pass N we cover spots 5 and 6, then there's no need to check on pass N+1 whether spots 3 and 4 are a pair.
| [reply] [d/l] |
|
|
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11162510
use warnings;
use Time::HiRes qw( time );
use List::AllUtils qw( shuffle );
my @stock = shuffle split //, 'A23456789TJQK' x 4;
my $ninecardlist = join '', splice @stock, 0, 9;
my $start = time;
while( @stock > 1 )
{
print "$ninecardlist\n";
my ($left, $right) = splice @stock, 0, 2;
$ninecardlist =~ s/(.)(.*?)\1/
print "play $left & $right over $1's\n";
"$left$2$right"/e or last;
}
@stock > 1 or print "$ninecardlist\n";
print @stock < 2
? "Succeeded in consuming the entire deck.\n"
: "Failed to consume the entire deck.\n";
printf "%d passes in %d microseconds\n", 52 - @stock, (time - $start)
+* 1e6;
Outputs:
T7AJJQ342
play A & 9 over J's
T7AA9Q342
play 8 & T over A's
T78T9Q342
play T & 3 over T's
T7839Q342
play 8 & 5 over 3's
T7889Q542
play 5 & 6 over 8's
T7569Q542
play 6 & 7 over 5's
T7669Q742
play 9 & 8 over 7's
T9669Q842
play A & 6 over 9's
TA666Q842
play 4 & K over 6's
TA4K6Q842
play 3 & A over 4's
TA3K6Q8A2
play Q & J over A's
TQ3K6Q8J2
play 7 & 6 over Q's
T73K668J2
play T & 4 over 6's
T73KT48J2
play K & Q over T's
K73KQ48J2
play 7 & 3 over K's
7733Q48J2
play 2 & 4 over 7's
2433Q48J2
play 8 & 9 over 2's
8433Q48J9
play J & 2 over 8's
J433Q42J9
play 9 & K over J's
9433Q42K9
play 2 & K over 9's
2433Q42KK
play Q & 5 over 2's
Q433Q45KK
Succeeded in consuming the entire deck.
51 passes in 125 microseconds
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
Note the OP used a ten card list (or am I missing something?)
| [reply] |
|
|
Re: pop() on a fast multi-core cpu
by LanX (Saint) on Oct 30, 2024 at 19:27 UTC
|
I'd say the problem is most likely in front of the keyboard.
Of course you could prove us wrong by supplying an SSCCE to reproduce the "issue" instead of prose blaming Perl for warnings about obviously broken code...
But hey, we all know that baseless ranting is more entertaining, right?
| [reply] |
Re: pop() on a fast multi-core cpu
by Anonymous Monk on Oct 30, 2024 at 19:23 UTC
|
Additionally, all code is sequential, NO events!
Very simple structure allows all redirections to be goto Top of code for next pass.
| [reply] |
|
|
Unless you show the code, your post is meaningless at best, more likely just a troll.
| [reply] |
|
|
I dont get an warnings or errors running your code - but I have not tried to figure out its logic because, with respect, it written like garbage. What version of perl are you running?
| [reply] |
Re: pop() on a fast multi-core cpu
by Anonymous Monk on Oct 30, 2024 at 22:18 UTC
|
#!/usr/bin/perl
use warnings; use strict; use Time::HiRes qw(gettimeofday tv_interval)
+;
my( @suit, @deck); my @ups = qw( 0 0 0 0 0 0 0 0 0 0); my $cntr = 0;
Deck(); # four shuffled suits are added to a deck and then shuffled
print "\n"; my $t0 = gettimeofday;
T0: $ups[0] = Card(); $ups[1] = Card(); # draw cards for pos #0 & #
+1
T1: if($ups[0] eq $ups[1]) { goto T0; } # cover a pair & go back
if($ups[2] eq '0') { $ups[2] = Card(); } # fill pos#2 if vacant
# check pos#2 against pos#0 - cover a pair & go back
if($ups[2] eq $ups[0]) { Cover(2,0); goto T1; }
# check pos#2 against pos#1 - cover a pair & go back
if($ups[2] eq $ups[1]) { Cover(2,1); goto T1; }
# watch the rows for pairs that don't get covered
foreach my $x (@ups) { print "$x "; } print "\n";
for(my $j=3;$j<10;$j++) {
if($ups[$j] eq '0') { $ups[$j] = Card(); }
for(my $k=0;$k<$j;$k++) {
if($ups[$j] eq $ups[$k]) { Cover($j,$k); goto T1; } } }
+
TX: print "\n";
foreach my $x (@ups) { print "$x "; } print "\t\tExit row\n";
my $del_t = (gettimeofday - $t0) * 10**6;
my $usec = sprintf("%.2f",$del_t);
print "\n$cntr passes in $usec microseconds. ";
if($cntr == @deck) { print "Success!\n\n"; }
else { print "{sigh...}\n\n"; }
#========================================
sub Card { my $tmp = $deck[$cntr]; $cntr++;
if($tmp ne 'X') { return $tmp; } else { goto TX; } }
sub Suit { @suit = qw(A B C D E F G H I J K L M );
for(my $i=$#suit;$i>0;$i--) {
my $j = int(rand($i + 1));
@suit[$i, $j] = @suit[$j, $i]; } }
sub Deck { for(my $i=0;$i<4;$i++) { Suit(); @deck = (@deck,@suit);
+}
for(my $i=$#deck;$i>0;$i--) {
my $j = int(rand($i + 1));
@deck[$i, $j] = @deck[$j, $i];
} push(@deck,"X"); }
sub Cover { my $x = $_[0]; my $y = $_[1];
$ups[$x] = Card(); $ups[$y] = Card(); }
pre tags replaced by Code tags by Grandfather | [reply] [d/l] |
|
|
Use <code> tags, otherwise array indices are turned into links.
#!/usr/bin/perl
use warnings; use strict; use Time::HiRes qw(gettimeofday tv_interval)
+;
my( @suit, @deck); my @ups = qw( 0 0 0 0 0 0 0 0 0 0); my $cntr = 0;
Deck(); # four shuffled suits are added to a deck and then shuffled
print "\n"; my $t0 = gettimeofday;
T0: $ups[0] = Card(); $ups[1] = Card(); # draw cards for pos #0 & #
+1
T1: if($ups[0] eq $ups[1]) { goto T0; } # cover a pair & go back
if($ups[2] eq '0') { $ups[2] = Card(); } # fill pos#2 if vacant
# check pos#2 against pos#0 - cover a pair & go back
if($ups[2] eq $ups[0]) { Cover(2,0); goto T1; }
# check pos#2 against pos#1 - cover a pair & go back
if($ups[2] eq $ups[1]) { Cover(2,1); goto T1; }
# watch the rows for pairs that don't get covered
foreach my $x (@ups) { print "$x "; } print "\n";
for(my $j=3;$j<10;$j++) {
if($ups[$j] eq '0') { $ups[$j] = Card(); }
for(my $k=0;$k<$j;$k++) {
if($ups[$j] eq $ups[$k]) { Cover($j,$k); goto T1; } } }
+
TX: print "\n";
foreach my $x (@ups) { print "$x "; } print "\t\tExit row\n";
my $del_t = (gettimeofday - $t0) * 10**6;
my $usec = sprintf("%.2f",$del_t);
print "\n$cntr passes in $usec microseconds. ";
if($cntr == @deck) { print "Success!\n\n"; }
else { print "{sigh...}\n\n"; }
#========================================
sub Card { my $tmp = $deck[$cntr]; $cntr++;
if($tmp ne 'X') { return $tmp; } else { goto TX; } }
sub Suit { @suit = qw(A B C D E F G H I J K L M );
for(my $i=$#suit;$i>0;$i--) {
my $j = int(rand($i + 1));
@suit[$i, $j] = @suit[$j, $i]; } }
sub Deck { for(my $i=0;$i<4;$i++) { Suit(); @deck = (@deck,@suit);
+}
for(my $i=$#deck;$i>0;$i--) {
my $j = int(rand($i + 1));
@deck[$i, $j] = @deck[$j, $i];
} push(@deck,"X"); }
sub Cover { my $x = $_[0]; my $y = $_[1];
$ups[$x] = Card(); $ups[$y] = Card(); }
I tried running the script 1000 times in 5.26.1 and the current blead (5.41.5-22-ga8a74a872d). There was no warning.
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
|
|
Your code is based on 4 normal goto plus one which is called inside Card() to leave the sub, which is called 4 more times, plus 2 times inside Cover() which is called thrice.
These are 16 jumps in total.
All this is "determined" on randomized data.
Respect, you put the spaghetti into spaghetti code.
That's highly unpredictable, and the missing code indentation doesn't make it easier to grasp.
If your problems didn't or rarely happened before but are now, one reason might be differences in arithmetics.
We just had a talk at the London Perl Workshop about an undiscovered bug only showing up if the same code and Perl version was run on a newer Ubuntu version.
The precision jumped and the code crashed because a threshold was exceeded.
Nota Bene: the code was already buggy before, but this went unnoticed.
| [reply] |