Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

BOFH excuse #285: Telecommunications is upgrading.


comp / comp.lang.perl.misc / Re: compare two sorted array, item by item, which one is bigger

SubjectAuthor
* compare two sorted array, item by item, which one is biggerhymie!
+* Re: compare two sorted array, item by item, which one is biggerRainer Weikusat
|+- Re: compare two sorted array, item by item, which one is biggerRainer Weikusat
|`* Re: compare two sorted array, item by item, which one is biggerhymie!
| `- Re: compare two sorted array, item by item, which one is biggerRainer Weikusat
`* Re: compare two sorted array, item by item, which one is biggerBouras George
 `- Re: compare two sorted array, item by item, which one is biggerStefan Ram

1
Subject: compare two sorted array, item by item, which one is bigger
From: hymie!
Newsgroups: comp.lang.perl.misc
Organization: Eric Conspiracy Secret Labs
Date: Sat, 24 Feb 2024 19:14 UTC
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx10.iad.POSTED!not-for-mail
Newsgroups: comp.lang.perl.misc
From: hymie@nasalinux.net (hymie!)
Subject: compare two sorted array, item by item, which one is bigger
Organization: Eric Conspiracy Secret Labs
User-Agent: slrn/pre1.0.4-6 (Linux)
Message-ID: <slrnutkg19.kdq.hymie@nasalinux.net>
Lines: 52
X-Complaints-To: abuse@usenet-news.net
NNTP-Posting-Date: Sat, 24 Feb 2024 19:14:49 UTC
Date: Sat, 24 Feb 2024 19:14:49 GMT
X-Received-Bytes: 2229
View all headers

I'm sure this is an FAQ if I can just find the correct words to ask my
question.

I have two people, 0 and 1, which are denoted by the $player variable.

I have a hash of sorted arrays

@{$scores{$player}}
104 92 92 90 87
104 92 92 89 88

And I have a %percent hash that holds the sum of those elements.
In this case, $percent{$player} is 465 for both.

(I can safely assume that all numbers are non-negative, so I'm fine with
an empty value being treated as zero)

(I also have a bunch of lousy code that I'm not proud of)

So I have this construct

foreach $player (sort {$percent{$b} <=> $percent{$a}} keys %percent)

that will sort the %percent hash by value ... but since the two are
equal, I think I'm getting a random choice.

So then I wrote this construct

foreach $player (sort
{$percent{$b} <=> $percent{$a} || ${$scores{$b}}[0] <=> ${$scores{$a}}[0] }
keys %percent)

which will check the first element in each array from the %scores hash
to see which value is larger.

The question is -- how can I (or can I) programatically keep checking
entries in the arrays of the %scores hash until I find a pair of
entries that are not equal? I'd rather not have (in my case) 9
individual tests of the items. Is there a simple subroutine I can
use?

My first thought is to compare $a[0] and $b[0] ... and then if they're
the same, shift them both and try again. But I'm a little nervous that
shifting the arrays will lose the values, and I don't want to do that.
My second thought is use an array slice -- if $a[0] == $b[0] then
recursively check $a[1-x] against $b[1-x] ...

I'm hoping somebody knows something simpler.

Thanks.

--hymie! https://nasalinux.net/~hymie hymie@nasalinux.net

Subject: Re: compare two sorted array, item by item, which one is bigger
From: Rainer Weikusat
Newsgroups: comp.lang.perl.misc
Date: Mon, 26 Feb 2024 16:20 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.lang.perl.misc
Subject: Re: compare two sorted array, item by item, which one is bigger
Date: Mon, 26 Feb 2024 16:20:55 +0000
Lines: 68
Message-ID: <87msrnyz6g.fsf@doppelsaurus.mobileactivedefense.com>
References: <slrnutkg19.kdq.hymie@nasalinux.net>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net falAZ12vuJgAVoKwr//nLAJ6W3OIqHFPtim7g/6cHSXm9HdE4=
Cancel-Lock: sha1:exmALpNCm7zrMDWqglRds8pKcVE= sha1:130kz3dWADQ8Z8RiQRjCzYvgQSk= sha256:Qa7hG8AwNirjj1FxFrfJmK5MxAEAAHlvSuwHAf1S8B4=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
View all headers

hymie! <hymie@nasalinux.net> writes:
> I have two people, 0 and 1, which are denoted by the $player variable.
>
> I have a hash of sorted arrays
>
> @{$scores{$player}}
> 104 92 92 90 87
> 104 92 92 89 88
>
> And I have a %percent hash that holds the sum of those elements.
> In this case, $percent{$player} is 465 for both.

[...]

> So I have this construct
>
> foreach $player (sort {$percent{$b} <=> $percent{$a}} keys %percent)
>
> that will sort the %percent hash by value ... but since the two are
> equal, I think I'm getting a random choice.
>
> So then I wrote this construct
>
> foreach $player (sort
> {$percent{$b} <=> $percent{$a} || ${$scores{$b}}[0] <=> ${$scores{$a}}[0] }
> keys %percent)
>
> which will check the first element in each array from the %scores hash
> to see which value is larger.
>
> The question is -- how can I (or can I) programatically keep checking
> entries in the arrays of the %scores hash until I find a pair of
> entries that are not equal?

If you're arrays are always of equal length, you could use

sub ary_cmp
{ my ($a0, $a1) = @_;
my $rc;

for (0 .. $#$a0) {
$rc = $$a0[$_] - $$a1[$_];
return $rc < 0 ? -1 : 1 if $rc;
}

return 0;
}

otherwise, it's a bit more difficult.

sub ary_cmp
{ my ($a0, $a1) = @_;
my ($last, $rc);

$last = $#$a0;
$_ < $last and $last = $_ for $#$a1;

for (0 .. $last) {
$rc = $$a0[$_] - $$a1[$_];
return $rc < 0 ? -1 : 1 if $rc;
}

return @$a0 <=> @$a1;
}

could do.

Subject: Re: compare two sorted array, item by item, which one is bigger
From: Rainer Weikusat
Newsgroups: comp.lang.perl.misc
Date: Tue, 27 Feb 2024 15:37 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.lang.perl.misc
Subject: Re: compare two sorted array, item by item, which one is bigger
Date: Tue, 27 Feb 2024 15:37:33 +0000
Lines: 45
Message-ID: <87ttltex4y.fsf@doppelsaurus.mobileactivedefense.com>
References: <slrnutkg19.kdq.hymie@nasalinux.net>
<87msrnyz6g.fsf@doppelsaurus.mobileactivedefense.com>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net 1cxkdnyJWqRfhGXDXZbwQQnTu1stsufodMu7x1Vprqpge1xXI=
Cancel-Lock: sha1:/STZdbKBsVJAL/pslnF3gum0tHE= sha1:I0eb972P5W0tHxbLnT9ug5xZcw8= sha256:pqgmLlEPCgK32XN9FMcAPA4325ZvbW5fCa6YhukrgFY=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
View all headers

Rainer Weikusat <rweikusat@talktalk.net> writes:
> hymie! <hymie@nasalinux.net> writes:

[...]

>> foreach $player (sort
>> {$percent{$b} <=> $percent{$a} || ${$scores{$b}}[0] <=> ${$scores{$a}}[0] }
>> keys %percent)
>>
>> which will check the first element in each array from the %scores hash
>> to see which value is larger.
>>
>> The question is -- how can I (or can I) programatically keep checking
>> entries in the arrays of the %scores hash until I find a pair of
>> entries that are not equal?
>
> If you're arrays are always of equal length, you could use
>
> sub ary_cmp
> {
> my ($a0, $a1) = @_;
> my $rc;
>
> for (0 .. $#$a0) {
> $rc = $$a0[$_] - $$a1[$_];
> return $rc < 0 ? -1 : 1 if $rc;
> }
>
> return 0;
> }

This can be simplified somewhat by using the <=> operator for the check
inside the loop as that already produces the desired result of either
-1, 0 or 1.

sub ary_cmp
{ my ($a0, $a1) = @_;

for (0 .. $#$a0) {
$_ and return $_ for $$a0[$_] <=> $$a1[$_];
}

return 0;
}

Subject: Re: compare two sorted array, item by item, which one is bigger
From: hymie!
Newsgroups: comp.lang.perl.misc
Organization: Eric Conspiracy Secret Labs
Date: Wed, 28 Feb 2024 15:35 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!weretis.net!feeder6.news.weretis.net!newsfeed.hasname.com!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer02.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx18.iad.POSTED!not-for-mail
Newsgroups: comp.lang.perl.misc
From: hymie@nasalinux.net (hymie!)
Subject: Re: compare two sorted array, item by item, which one is bigger
References: <slrnutkg19.kdq.hymie@nasalinux.net>
<87msrnyz6g.fsf@doppelsaurus.mobileactivedefense.com>
Organization: Eric Conspiracy Secret Labs
User-Agent: slrn/pre1.0.4-6 (Linux)
Message-ID: <slrnutuklq.mp3.hymie@nasalinux.net>
Lines: 64
X-Complaints-To: abuse@usenet-news.net
NNTP-Posting-Date: Wed, 28 Feb 2024 15:35:22 UTC
Date: Wed, 28 Feb 2024 15:35:22 GMT
X-Received-Bytes: 2282
View all headers

In our last episode, the evil Dr. Lacto had captured our hero,
Rainer Weikusat <rweikusat@talktalk.net>, who said:
> hymie! <hymie@nasalinux.net> writes:
>> The question is -- how can I (or can I) programatically keep checking
>> entries in the arrays of the %scores hash until I find a pair of
>> entries that are not equal?
>
> If your arrays are always of equal length, you could use

I don't think I can depend on that :(

> otherwise, it's a bit more difficult.
>
> sub ary_cmp
> {
> my ($a0, $a1) = @_;
> my ($last, $rc);
>
> # we need the length of the shorter array
> # start with the length of array a0
> # and see if the length of array a1 is less
> $last = $#$a0;
> $_ < $last and $last = $_ for $#$a1;
>
> # for each entry in the shorter array
> # compare that numbered entry in the two arrays
> # return <=> if the result is not 0
> for (0 .. $last) {
> $_ and return $_ for $$a0[$_] <=> $$a1[$_];
> }
>
> # all of the elements are equal, so return the longer array
> return @$a0 <=> @$a1;
> }

I took the liberty of adding your improvement to this function.

I'll definitely try this out and see how well it work.

I have a few followup questions...

(*) I added some comments. Can you tell me if I'm correct?

(*) Could I have set $last this way?

$last = $#$a0 < $#$a1 ? $#$a0 : $#$a1 ;

or

$last = @$a0 < @$a1 ? @$a0 : @$a1 ;

?

(*) In this construct

> for (0 .. $last) {
> $_ and return $_ for $$a0[$_] <=> $$a1[$_];

is it safe to reuse $_ like that? The scoping will work itself out,
even without a bracket set?

Thank you very much.

--hymie!

Subject: Re: compare two sorted array, item by item, which one is bigger
From: Rainer Weikusat
Newsgroups: comp.lang.perl.misc
Date: Wed, 28 Feb 2024 16:34 UTC
References: 1 2 3
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.lang.perl.misc
Subject: Re: compare two sorted array, item by item, which one is bigger
Date: Wed, 28 Feb 2024 16:34:35 +0000
Lines: 78
Message-ID: <87il28pmxw.fsf@doppelsaurus.mobileactivedefense.com>
References: <slrnutkg19.kdq.hymie@nasalinux.net>
<87msrnyz6g.fsf@doppelsaurus.mobileactivedefense.com>
<slrnutuklq.mp3.hymie@nasalinux.net>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net RBzLvBRFrWQxwNJfo8jxQwcWlMRXgowQ6B+8z6lPFkb4gMzM4=
Cancel-Lock: sha1:Sq8agzM0N/hPndlB31M+aPk9N+Q= sha1:1/ybBJig7Icni5ZQkWf9TqvIDHk= sha256:Bb0gZ4hQ7c+s/I9Ho1ScGeGEsi8pvthLhky9qgDH49c=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
View all headers

hymie! <hymie@nasalinux.net> writes:
> In our last episode, the evil Dr. Lacto had captured our hero,
> Rainer Weikusat <rweikusat@talktalk.net>, who said:
>> hymie! <hymie@nasalinux.net> writes:
>>> The question is -- how can I (or can I) programatically keep checking
>>> entries in the arrays of the %scores hash until I find a pair of
>>> entries that are not equal?
>>
>> If your arrays are always of equal length, you could use
>
> I don't think I can depend on that :(
>
>> otherwise, it's a bit more difficult.
>>
>> sub ary_cmp
>> {
>> my ($a0, $a1) = @_;
>> my ($last, $rc);
>>
>> # we need the length of the shorter array
>> # start with the length of array a0
>> # and see if the length of array a1 is less
>> $last = $#$a0;
>> $_ < $last and $last = $_ for $#$a1;
>>
>> # for each entry in the shorter array
>> # compare that numbered entry in the two arrays
>> # return <=> if the result is not 0
>> for (0 .. $last) {
>> $_ and return $_ for $$a0[$_] <=> $$a1[$_];
>> }
>>
>> # all of the elements are equal, so return the longer array
>> return @$a0 <=> @$a1;
>> }
>
> I took the liberty of adding your improvement to this function.
>
> I'll definitely try this out and see how well it work.
>
> I have a few followup questions...
>
> (*) I added some comments. Can you tell me if I'm correct?

Yes.

>
> (*) Could I have set $last this way?
>
> $last = $#$a0 < $#$a1 ? $#$a0 : $#$a1 ;
>
> or
>
> $last = @$a0 < @$a1 ? @$a0 : @$a1 ;

The first yes, second no as $#$a0 == @$a0 - 1. It's just syntactically a
bit more repetitive.

>
> ?
>
> (*) In this construct
>
>> for (0 .. $last) {
>> $_ and return $_ for $$a0[$_] <=> $$a1[$_];
>
> is it safe to reuse $_ like that?

Yes. The foreach-for aliases a localized $_ to the first element and
then executes the loop body, ie, either the block in case of for (...) {
} or the statement for the statement modifier. Then, it does the same
with the second element and so forth, until the body has been run for
all list elements. This means $_ reverts back to the current index after
the

$_ and return $_

has been executed.

Subject: Re: compare two sorted array, item by item, which one is bigger
From: Bouras George
Newsgroups: comp.lang.perl.misc
Organization: A noiseless patient Spider
Date: Mon, 20 May 2024 10:09 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: g-bouras@otenet.gr (Bouras George)
Newsgroups: comp.lang.perl.misc
Subject: Re: compare two sorted array, item by item, which one is bigger
Date: Mon, 20 May 2024 13:09:28 +0300
Organization: A noiseless patient Spider
Lines: 59
Message-ID: <v2f7hc$3u75q$1@dont-email.me>
References: <slrnutkg19.kdq.hymie@nasalinux.net>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Mon, 20 May 2024 12:09:48 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="d21705497033fe18f477611ff0ae7abd";
logging-data="4136122"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18IlznoKRS7ix7R105igBR+mhi6HljLl8E="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:/gYK5jKJEwlXRcG91hF+q4kHE64=
In-Reply-To: <slrnutkg19.kdq.hymie@nasalinux.net>
Content-Language: en-US
View all headers

On 24/2/2024 9:14 μ.μ., hymie! wrote:
> I'm sure this is an FAQ if I can just find the correct words to ask my question.

I hope it is not too late for this, or whatever.
My usenet account was deleted , just create a new one , and have a look
at my favorite group.

About the request now.
We must stop writing code no matter the language , everything is about
the right data structures for every specific problem.
So here it is. Thanks, George Bouras

---------------------------

#!/usr/bin/perl
use strict; use warnings; use feature qw/say/;
use Data::Dumper; $Data::Dumper::Purity=1; $Data::Dumper::Terse=1;
$Data::Dumper::Indent=1;
my ($i, %scores, %percent)=(0,,);

$scores{0} = [
[ qw(104 92 92 90 87) ],
[ qw(104 92 92 89 88) ],
[ qw(1 1 1 1 1 ) ],
[ qw(2 2 2 2 2 ) ]
];

$scores{1} = [
[ qw(1 2 3 4 5) ],
[ qw(5 1 2 3 4) ],
[ qw(3 3 3 3 3) ],
[ qw(4 4 4 4 4) ]
];

# Fill the %percent with sums per user for every list
$,=',';
foreach my $player (keys %scores) {
$i=0;
foreach my $list ( @{ $scores{$player} } ) {
push @{$percent{$player}->{ sub {my $s=0; map { $s += $_ } @{$_[0]};
$s}->($list)} } , $i++
}
}

#print Dumper $scores{0};
#print Dumper $scores{1};
#print Dumper \%percent;

# Just print two different list sums of %percent of the person 0
#$"=',';
$i=-1;
foreach (keys %{$percent{0}}) {
last if 2 == ++$i;
say "person:0 , sum:$_, scores_list_offset=@{$percent{0}->{$_}}"
}

Subject: Re: compare two sorted array, item by item, which one is bigger
From: Stefan Ram
Newsgroups: comp.lang.perl.misc
Organization: Stefan Ram
Date: Tue, 21 May 2024 08:48 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!fu-berlin.de!uni-berlin.de!not-for-mail
From: ram@zedat.fu-berlin.de (Stefan Ram)
Newsgroups: comp.lang.perl.misc
Subject: Re: compare two sorted array, item by item, which one is bigger
Date: 21 May 2024 08:48:11 GMT
Organization: Stefan Ram
Lines: 11
Expires: 1 Feb 2025 11:59:58 GMT
Message-ID: <Pike-20240521094733@ram.dialup.fu-berlin.de>
References: <slrnutkg19.kdq.hymie@nasalinux.net> <v2f7hc$3u75q$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Trace: news.uni-berlin.de YuDpUnlZmQENKq4AKivZGgq8t/i5EN7YHt6bh7rc5JiY3K
Cancel-Lock: sha1:Ese3itX5xAIHmwErZROJh5ixkTw= sha256:ieKIpUgDFZi7excvvTq+wizQtKdJRK3zy50oW8Y2fl0=
X-Copyright: (C) Copyright 2024 Stefan Ram. All rights reserved.
Distribution through any means other than regular usenet
channels is forbidden. It is forbidden to publish this
article in the Web, to change URIs of this article into links,
and to transfer the body without this notice, but quotations
of parts in other Usenet posts are allowed.
X-No-Archive: Yes
Archive: no
X-No-Archive-Readme: "X-No-Archive" is set, because this prevents some
services to mirror the article in the web. But the article may
be kept on a Usenet archive server with only NNTP access.
X-No-Html: yes
Content-Language: en-US
View all headers

Bouras George <g-bouras@otenet.gr> wrote or quoted:
>We must stop writing code no matter the language , everything is about
>the right data structures for every specific problem.

Rob Pike's "Rule 5" Data dominates:

|If you've chosen the right data structures and organized things
|well, the algorithms will almost always be self-evident.
|Data structures, not algorithms, are central to programming.

.

1

rocksolid light 0.9.8
clearnet tor