Subject: | List::Util reduce oddly repeating input |
Date: | Thu, 6 Dec 2018 20:46:04 +0900 |
To: | bug-Scalar-List-Utils [...] rt.cpan.org |
From: | Daniel Lamblin <dlamblin [...] gmail.com> |
I'm getting a seemingly randomly chosen single input being repeated for
input to reduce.
EG a {say "$a $b";$hash{$a}<$hash{$b}?$a:$b} inside a reduce block is just
printing out:
a 380
a 380
over and over, with 380 not even being one of the items in the list of keys
passed in.
This happens in Perl 5.28 (homebrew built) and Perl 5.18 (system build) on
a Macbook.
Here's some examples where things are normal:
~$ perl -MList::Util=reduce -E'say reduce {say "$a $b";$a>$b?$a:$b} 1..3'
1 2
2 3
3
~$ perl -MList::Util=reduce -E'%h=();map{$h{$_}=3-$_}1..4;say reduce {say
"$a $b";$h{$a}>$h{$b}?$a:$b} keys %h'
3 2
2 4
2 1
1
~$ perl -MList::Util=reduce -E'%h=();map{$h{$_}=3-$_}1..3;say reduce {say
"$a $b";$h{$a}>$h{$b}?$a:$b} keys %h'
2 3
2 1
1
~$ perl -MList::Util=reduce -E'%k=();map{$k{$_}=4-$_}1..4;say reduce {say
"$a $b";$k{$a}>$k{$b}?$a:$b} grep {$k{$_}>-0} keys %k'
3 1
1 2
1
But when trying to solve https://adventofcode.com/2018/day/6
I wrote some code where top level I defined my $b and assigned something to
it (380) for the example, and then things just didn't work right with it.
Here's a reproduction of the problem minimally:
~$ perl -MList::Util=reduce -E'use warnings;use strict;use feature
":5.28";my ($b,%k)=(100,());map{$k{$_}=4-$_}1..4;say reduce {say "$a
$b";$k{$a}>$k{$b}?$a:$b} grep {$k{$_}>0} keys %k'
3 100
Use of uninitialized value in numeric gt (>) at -e line 1.
3 100
Use of uninitialized value in numeric gt (>) at -e line 1.
3
Compared to not setting $b:
~$ perl -MList::Util=reduce -E'use warnings;use strict;use feature
":5.28";my %k=();map{$k{$_}=4-$_}1..4;say reduce {say "$a
$b";$k{$a}>$k{$b}?$a:$b} grep {$k{$_}>0} keys %k'
1 2
1 3
1
So; I was surprised to have this happen, I thought the $a and $b in the
block would be locally scoped. Is this a bug? If so is it mentioned
somewhere that this pre-defined $b thing is a known issue or gotcha?
My Advent of Code attempt is here [apologies re:style]:
#!/usr/bin/env perl
use warnings;
use strict;
use feature ":5.28";
use List::Util qw/reduce min max/;
use POSIX "ceil";
my @z=("a".."z","A".."Z","0".."9");my$x=0;
my ($n,%p,%e,@x,@y)=('aa',()x4);
for (<DATA>){
m/^(\d+), (\d+)$/;
#($p{n}{a}, $p{$n}{x}, $p{$n++}{y}) = (0, int($1), int($2));
($p{$z[$x]}{a}, $p{$z[$x]}{x}, $p{$z[$x++]}{y}) = (0, int($1), int($2));
push @x, int($1);
push @y, int($2);
}
my ($l,$r,$t,$b) = (min(@x), max(@x), min(@y), max(@y));
$l -= ceil($r/9);
$r += ceil($r/9);
$t -= ceil($b/9);
$b += ceil($b/9);
sub d{my($x, $y, $i, $j) = @_; abs($x - $i) + abs($y - $j)}
sub c{
my ($x, $y) = @_;
my ($k, $n, $d) = ((0)x2,$r+$b);
for (keys %p){
┆ ┆$n = d($x, $y, $p{$_}{x}, $p{$_}{y});
┆ ┆$k .= "_$_" if ($d == $n);
┆ ┆($k, $d) = ($_, $n) if ($d > $n);
}
($k, $d);
}
for my $j ($t..$b){
for my $i ($l..$r){
┆ my ($k, $d) = c($i, $j);
┆ $p{$k}{a}++ if $p{$k};
┆ if ($i==$l || $i==$r || $j==$t || $j==$b){
┆ ┆ $e{$k} = 1;
┆ }
┆ #print $p{$k} ? $k : ".";
}
#say"";
}
say map {sprintf "%2s:%3d,%3d=%5d\n",exists $e{$_} ? "^$_" :
"=$_",$p{$_}{x},$p{$_}{y},$p{$_}{a}} sort keys %p;
say "None of: ".join(" ", sort keys %e);
say "Only of: ".join(" ", sort grep {!exists $e{$_}} keys %p);
my $k = reduce {say "$a $b"; $p{$a}{a} > $p{$b}{a} ? $a : $b} grep {!exists
$e{$_}} keys %p;
say "WHAT";
say "$k at $p{$k}{x}, $p{$k}{y} is $p{$k}{a} big."
#There's more data but, you don't need it do you?
__DATA__
81, 157
209, 355
111, 78
179, 211
224, 268
93, 268
237, 120
345, 203
72, 189
298, 265
190, 67
319, 233
328, 40
323, 292
125, 187
343, 186
46, 331
106, 350
247, 332
349, 145
217, 329