人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

perl の構文に関する質問です。
このコードが何をやっているのか教えてください。

$_=3x(1E3-1),s/3/++$p%3*$p%5?7:5x$p/ge,print s/5//g

以下のコードと同じで3または5で割り切れる1000までの数を足した結果が得られることは知っていまが、それぞれの記号が何を意味するのか分かりません。

$sum=0;
map {$sum += $_ if(!($_%3) || !($_%5))} 1..1000;
print $sum;

最近 perl を使い始めたので良くわかっていません。
よろしくお願いします。

●質問者: phji
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:GE MAP Perl print コード
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● cubick
●11ポイント
$sum=0;

変数 $sum に 0 を代入。

map {$sum += $_ if(!($_%3) || !($_%5))} 1..1000;

map { } 1..1000 で「1?1000まで、{}の中を繰り返し実行」します。

{}の中では実行されるたび、変数 $_ に1?1000が代入されます。そして

変数($_)が3で割り切れる、または変数($_)が5で割り切れるなら、合計($sum)に

仮変数($_)の値を足していきます。

print $sum;

最後に変数 $sum の値を表示。

◎質問者からの返答

すみませんが、私が知りたかったのは上の方のコードです…


2 ● y-kawaz
●59ポイント ベストアンサー

まず一番の大外だけを見ると以下のようになっており、カンマ演算子が使われています。

A, B, C;

カンマ演算子は、左辺の値を捨てて右辺の値を返す演算子です。上記は、Aを評価して結果を捨てて、Bを評価して結果を捨てて、Cを評価してその値を返していおり、この例では以下のように解釈して構わないと思います。

$_=3x(1E3-1);
s/3/++$p%3*$p%5?7:5x$p/ge;
print s/5//g;

次に、$_=3x(1E3-1) の説明です。


次に、s/3/++$p%3*$p%5?7:5x$p/ge の説明です。

つまり上記は $_ で 3 を見つける度に ++$p%3*$p%5?7:5x$p というPerlの式を実行することになります。$_ は3が999個並んだ文字列なので ++$p%3*$p%5?7:5x$p が実行されるので以下のように解釈が可能です。

$new = "";
for($i=0, $i<999, $i++) {
 $new .= ++$p%3*$p%5?7:5x$p;
}
$_ = $new;

ここで、

これらをふまえると上記は以下のように解釈できます。

$new = "";
for($i=0, $i<999, $i++) {
 $p = $p + 1;
 #↓ここでは計算結果の値に余り意味はなく剰余計算を行う際に$pが3の倍数か5の倍数の時にゼロが掛け算されてゼロ(偽値)になります
 if($p%3*$p%5) {
 #↓$pが3の倍数か5の倍数のときに実行される
 $new .= 7;
 } else {
 #↓$pが3の倍数でなく、5の倍数でもないときに実行される
 $new .= 5x$p; #5を$p回繰り返した文字列
 }
}
$_ = $new;

さて、頭のいくつかの3を置換してみましょう

3が置換される値 コメント
1回目 7 $p=1なので7
2回目 7 $p=2なので7
3回目 555 $p=3で3の倍数なので5x3で555
4回目 7 $p=4なので
5回目 55555 $p=5で5の倍数なので5x5で55555
6回目 555555 $p=6で3の倍数なので5x6で555555
7回目 7 $p=7なので
8回目 7 $p=8なので
9回目 555555555 $p=9で3の倍数なので5x9で555555555

最終的に $_ は 7755575555555555577555555555... という文字列になります。


最後に、print s/5//g を説明します。


さて、ここで上の 3 を 7 や 5x$p に置換したときの表を見てみます。

よく見ると$pが3の倍数の場合は5が$p個、$pが7の倍数の場合も5が$p個出力されており、$pは1から1000までの値をとります。

すなわち $_ に入っている5の数を数えることは、1から1000までの5の倍数と7の倍数の値を数えることと同じ意味になることが分かります。

以上です。


ここまでの説明で疲れたので、後者の $sum=0? の説明は適当です。

◎質問者からの返答

詳細な回答ありがとうございます。

上のワンライナーのコードが私の質問でして、下のは私が書いたコードでした。

もう少し分かりやすく質問をするべきでした。

単純な演算子の説明までさせてしまってすみません。

三項演算子を展開して if 文で書いてくれているところのコメントが if と else で逆だと思います。

$p%3*$p%5 で論理演算子を使わなくても、「3または5で割りきれない」を表現できるんですね!

置換して、条件を満たす置換した箇所を数えるのが全体の流れだと分かりました。

また、それぞれの式の満たす意味も分かりました。

ありがとうございました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ