読者です 読者をやめる 読者になる 読者になる

初代Masteries

きっとモヒカンにもなれないお前たちに告げる!!!

2代目オイラー王の座を奪取? しました

弊社プログラミング部でオイラー王決定戦が開催されたので, 参加してきました.

「オイラー王決定戦」とは, Project Eulerの問題をみんなで解き, その解答速度や実行速度を争う... という, 部活内でのプチ競技プログラミング, と思って頂ければと思います.
第1回は, 現在自分のメンターを担当して頂いている@先輩が勝利して初代オイラー王になったのですが, 第2回目, 第3回目は時間内に解答できた人がおらず, オイラー王が暫く空位となっていたので, 「奪い取ってやる!」という意気込みで参加したのですが...


...というわけで, 今回書いたコードです.
問題は第52問, 既に一度解いている問題です.
結果としては, こんな感じになりました.

use strict;
use warnings;
L: for my $i (123456 .. 999999) {
    my $mul = $i;
    for my $j (2, 3, 4, 5, 6) {
        $mul += $i;
        for my $check (split //, $i) {
            next L unless $mul =~ /$check/;
        }
    }
    print $i;
    last;
}

以前のコードでは, チェック部分をサブルーチンに分けていたのですが, サブルーチンを使わずに処理するように書き換えてみました.
これだけで, 結構ガクっと実行速度が落ちたので, 「関数呼び出しって, 結構コストかかるんだなあ...」と思ったり.
これ以上高速化するアイデアがなかったので, 余った時間はコードゴルフ風に極力短いコードにしたりして遊んでいました.

で, 結果ですが... 何故か規定時間終了時点でこのコードが一番早かったので, 2代目のオイラー王を襲名することになってしまいました.

f:id:papix:20130826235131j:plain

▲2代目オイラー王を襲名するpapix

ただまあ, 個人的には満足できていない部分がたくさんあって, 特に今回はPerlで書いていたのは自分だけで, 自分以外の方はみんなRubyで書いてたりしたので, 「言語の差も出ているのでは...?」という気がしたりしています*1.
この辺り, もっと切磋琢磨して, 次こそは胸を張って「俺がオイラー王だ!」と名乗れるようなりたいですね!!!

*1:「言語の差は甘え!!!」という声が挙がったりしましたが...!