DBD-Pg-2.17.1 の日本語訳やってます(途中)

PerlPostgreSQL にアクセスするためのモジュール、DBD-Pg-2.17.1 の pod ファイルの日本語訳を github 上でやってました。まだ途中ですが、どこからもリンクされていないので、ここで自分でリンクしておきます。


https://github.com/peanutsjamjam/DBD-Pg-2.17.1-trns-ja


Pg.pod は EUC-JP で、Pg.pod.utf8 は utf8 のエンコードを使っています。中身はエンコード以外は全く同じものをコミットするようにしています。


途中なので、翻訳を完成させる方や、perldoc.jp に contribute できる形にしてくださる方がいらっしゃれば、どうぞ持って行ってください。


英語の意味がわからなくて、そのままになっている部分や、怪しいと思った部分には、XXX と書いたりしています。


また、最近 DBD-Pg-2.17.2 が出たようです。そのうち差分をとったり、翻訳したりするかもしれません。


ガセネッタ&(と)シモネッタ (文春文庫)

ガセネッタ&(と)シモネッタ (文春文庫)

ProjectEuler Problem 87

Problem 87 - Project Euler 問題のページ
Problem 87 - PukiWiki 日本語訳


普通に総当りで解いた。整数を p1^2 + p2^3 + p3^4 で表す場合、同じひとつの整数でも複数の表し方があることを見逃していて失敗。ハッシュ変数導入でクリア。

145 =  2^2 + 5^3 + 2^4 =   4 + 125 + 16
145 = 11^2 + 2^3 + 2^4 = 121 +   8 + 16


3重ループそれぞれで素数を引っぱってきて、普通に計算。同じ数が 2回以上出てきたときのために、結果の値をハッシュのキーにぶち込んで、プログラム終了直前でハッシュにキーが何個あるか調べる富豪コード。

#! /usr/bin/perl
use strict;

my $lim = 50000000;
#my $lim = 50;

my (%h, $in2, $in3, $in4, $p2, $p3, $p4, $s);

open($in2, "-|", "primes 2") or die;
while (<$in2>) {
        chomp;
        $p2 = $_ ** 2;
        last if ($p2 >= $lim);

        open($in3, "-|", "primes 2") or die;
        while (<$in3>) {
                chomp;
                $p3 = $_ ** 3;
                last if ($p2+$p3 >= $lim);

                open($in4, "-|", "primes 2") or die;
                while (<$in4>) {
                        chomp;
                        $p4 = $_ ** 4;
                        $s = $p2+$p3+$p4;
                        last if ($s >= $lim);
                        print "$s = $p2 + $p3 + $p4\n";
                        $h{$s} += 1;
                }
                close($in4);
        }
        close($in3);
}
close($in2);

print scalar(keys %h), "\n";


計 59038回、primes コマンドを起動します。

ProjectEuler Problem 191

Problem 191 - Project Euler 問題のページ
Problem 191 - PukiWiki 日本語訳


三進数を作り出してチェックする、ってのはちょっと遅いような気がしたので、ううむ、と考えてみると、

  • L (late, 遅刻) は、文字列中に最大1回しか出てこない

ということに気がついた。


ということで、

  • O (on time, 出席) をゼロで表し、 A (absent, 欠席) をイチで表す二進数を考えて
  • 三つ連続するイチが含まれていない文字列を見つけ次第、そいつをカウントする。
  • あとから、O (on time, 出席) のゼロを一個だけ L (late, 遅刻) に書き換える。

という方針でやってみたら、うまくいった。


OAOA (二進表記: 0101) の場合、まずそれを「賞を貰える文字列」のひとつとしてカウントした上で、LAOA と OALA の二つもカウントする。つまり、二進表記のゼロの数を数えてやる。


O (on time, 出席) ではなく、A (absent, 欠席) L (late, 遅刻) に書き換える方法だと、二重にカウントしちゃってよろしくない。


O (on time, 出席) ではなく、A (absent, 欠席) L (late, 遅刻) に書き換える方法だと、三つ連続した A を見つけて除外するという作業の前にそれをやらなくてはならないので、うまくない。AAA は除外だけど、ALA は除外されるべきじゃないので、L への書き換えで「三連続欠席」を分断しちゃうし。


30bit の数をカウントしていくときに、早くまわす方法は、0011100000 0000000000 0000000000 というような三つ連続したイチを見つけた時点で、その三連続1の最後の位にイチを足してやること。そこに1が三つ並んでるってことは、それより下位がどういう並びであっても興味ないからね。

  0011100000 0000000000 0000000000
+ 0000100000 0000000000 0000000000

  0100000000 0000000000 0000000000