Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

"Hello again, Peabody here..." -- Mister Peabody


devel / comp.lang.perl.misc / 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

1
compare two sorted array, item by item, which one is bigger

<slrnutkg19.kdq.hymie@nasalinux.net>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=10035&group=comp.lang.perl.misc#10035

  copy link   Newsgroups: comp.lang.perl.misc
Path: i2pn2.org!i2pn.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: hym...@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
 by: hymie! - Sat, 24 Feb 2024 19:14 UTC

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

Re: compare two sorted array, item by item, which one is bigger

<87msrnyz6g.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=10036&group=comp.lang.perl.misc#10036

  copy link   Newsgroups: comp.lang.perl.misc
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweiku...@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)
 by: Rainer Weikusat - Mon, 26 Feb 2024 16:20 UTC

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.

Re: compare two sorted array, item by item, which one is bigger

<87ttltex4y.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=10037&group=comp.lang.perl.misc#10037

  copy link   Newsgroups: comp.lang.perl.misc
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweiku...@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)
 by: Rainer Weikusat - Tue, 27 Feb 2024 15:37 UTC

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;
}

Re: compare two sorted array, item by item, which one is bigger

<slrnutuklq.mp3.hymie@nasalinux.net>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=10038&group=comp.lang.perl.misc#10038

  copy link   Newsgroups: comp.lang.perl.misc
Path: i2pn2.org!i2pn.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: hym...@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
 by: hymie! - Wed, 28 Feb 2024 15:35 UTC

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!

Re: compare two sorted array, item by item, which one is bigger

<87il28pmxw.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=10039&group=comp.lang.perl.misc#10039

  copy link   Newsgroups: comp.lang.perl.misc
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweiku...@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)
 by: Rainer Weikusat - Wed, 28 Feb 2024 16:34 UTC

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.

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor