0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Perl による next_permutation の実装と AGC022 A

Last updated at Posted at 2020-04-04

はじめに

AtCoderは、オンラインで参加できるプログラミングコンテスト(競技プログラミング)のサイトです。リアルタイムのコンテストで競い合ったり、約3000問のコンテストの過去問にいつでも挑戦することが出来ます。 では、時々、順列生成が必要な問題が出題されます。
Perl には標準モジュールとして、next_permutation が準備されていないので、自作により対応します。

Perl による実装

num.pl
my $next_perm = sub {
  my $t = shift;
  my $f = -1;
  for my $i (0..length($t)-1) {
    if (ord(substr($t, length($t)-1-$i, 1)) > ord(substr($t, length($t)-2-$i, 1))) {
      $f = length($t) - 2 - $i;
      last;
    }
  }
  return -1 if $f == -1;
  my @w = split '', substr($t, $f+1);
  my @x = sort {$a cmp $b} grep {ord($_) > ord(substr($t, $f, 1))} @w;
  my $r = shift @x;
  push @w, substr($t, $f, 1);
  @w = sort {$a cmp $b} grep {ord($_) != ord($r)} @w;
  return substr($t, 0, $f).$r.join('', @w);
};

ord 関数を使用することにより、数字・文字の両方に対応しています。

sample1.pl
print $next_perm->(13542);  # => 14235
print $next_perm->('CAEDB'); # => CBADE

while ループで -1 が返るまで回すこともできます。

while.pl
my $ans = 1234;
while ($ans != -1) {
  print $ans, "\n";
  $ans = $next_prem->($ans);
}
 # => 1234
 .
 .
 # => 4321

A - Diverse Word

AGC 022 A - Diverse Word

perl.pl
use v5.18; # strict say state
use warnings;
use List::Util qw(reduce first max min sum0);

chomp (my $s = <STDIN>);
my $next_perm = sub {
  my $t = shift;
  my $f = -1;
  for my $i (0..length($t)-1) {
    if (ord(substr($t, length($t)-1-$i, 1)) > ord(substr($t, length($t)-2-$i, 1))) {
      $f = length($t) - 2 - $i;
      last;
    }
  }
  return -1 if $f == -1;
  my @w = split '', substr($t, $f+1);
  my @x = sort {$a cmp $b} grep {ord($_) > ord(substr($t, $f, 1))} @w;
  my $r = shift @x;
  push @w, substr($t, $f, 1);
  @w = sort {$a cmp $b} grep {ord($_) != ord($r)} @w;
  return substr($t, 0, $f).$r.join('', @w);
};
my $ans;
if (length($s)==26) {
  $ans = $next_perm->($s);
} else {
  my %h;
  $h{$_}++ for ('a'..'z');
  $h{$_}++ for split('', $s);
  my @w = sort {$a cmp $b} grep {$h{$_}==1} keys %h;
  $ans = $s . $w[0];
}
say $ans;

まとめ

  • next_permutation を自作した

参照したサイト
Javaでnext_permutationメソッドを作ってみる
Perl と Ruby で解く AtCoder ABC146 B - ROT N

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?