はじめに
いつもお世話になっております AtCoder で、新しいジャッジシステムの負荷テストを兼ねたコンテストが行われました。
Perl AtCoderのアップデートを先取りしてライバルに差をつけよう(List::Util他) にて下準備をしていましたので、それを使用し動作の確認をしてみました。
B - Picking Balls
AtCoder Judge System Update Test Contest 202004 B - Picking Balls
従来環境(すなわち、List::Util::pairs 等が無い)でしたら、赤ボール・青ボールそれぞれの配列を準備して、解答します。
use v5.18; # strict say state
use warnings;
chomp (my $n = <STDIN>);
my (@r, @b);
for my $i (0..$n-1) {
chomp (my @a = split / /, <STDIN>);
if ($a[1] eq 'R') {
push @r, $a[0];
} else {
push @b, $a[0];
}
}
@r = sort {$a <=> $b} @r;
@b = sort {$a <=> $b} @b;
say $_ for (@r, @b);
リファレンス
配列のリファレンスを使用した解法
use v5.18; # strict say state
use warnings;
chomp (my $n = <STDIN>);
my @p;
for my $i (0..$n-1) {
chomp (my @a = split / /, <STDIN>);
$p[$i] = [$a[0], $a[1]];
}
my @q = map {$$_[0]} sort { $$b[1] cmp $$a[1] || $$a[0] <=> $$b[0] } @p;
say $_ for @q;
2次元配列として処理をしています。
pairs の使用例1
先頭の use v5.26 が光っていますね。
use v5.26; # strict say state biwise
use warnings;
use List::Util qw(pairs);
chomp (my $n = <STDIN>);
my @p;
for my $i (0..$n-1) {
chomp (my @a = split / /, <STDIN>);
push @p, $a[0];
push @p, $a[1];
}
my @q = map {$$_[0]} sort { $b->value cmp $a->value || $a->key <=> $b->key } pairs @p;
say $_ for @q;
配列 @p = (10, 'B', 6, 'R', 2, 'R', 4, 'B'); を
pairs @p とした場合、下記の状態として扱うことができます。
keys | values |
---|---|
10 | B |
6 | R |
2 | R |
4 | B |
ハッシュと異なり、keys の値が重複していてもそのまま使用可能です。 |
pairs の使用例2
use v5.26; # strict say state biwise
use warnings;
use List::Util qw(pairs unpairs pairkeys pairvalues pairfirst pairgrep pairmap);
chomp (my $n = <STDIN>);
my @p;
for my $i (0..$n-1) {
chomp (my @a = split / /, <STDIN>);
push @p, $a[0];
push @p, $a[1];
}
my @r = sort {$a <=> $b} pairkeys pairgrep {$b eq 'R'} @p;
my @b = sort {$a <=> $b} pairkeys pairgrep {$b eq 'B'} @p;
say $_ for (@r, @b);
pairkeys や pairgrep 等も使用可能です。
仮に仕様が変更され緑ボールや黄ボールが追加されても、最小限の修正で対応できます。
まとめ
- AtCoder の新環境は Perl v5.26.1 となり、List::Util が拡張された
- pairs を使用することにより、データ構造が簡易に構築できるようになった
参照したサイト
List::Util
Perl AtCoderのアップデートを先取りしてライバルに差をつけよう(List::Util他) *