Subscribed unsubscribe Subscribe Subscribe

Perl, Pythonで1以上100未満の『2個の素数の積』である整数を列挙する

Perl Python

1以上100未満の『2個の素数の積』である整数をワンライナーで列挙する - すぎゃーんメモの続き。
普通にスクリプトを書くとどうなるか。

Perl

モジュールを使うとなるとやはりMath::Big::Factorsが便利。

#!/opt/local/bin/perl
use strict;
use warnings;

use Math::Big::Factors qw(factors_wheel);

for my $num (1..99) {
    my @factors = factors_wheel($num);
    print "$num\n" if scalar(@factors) == 2;
}


モジュールを使わずに書くにはどうするのが一番分かりやすくてキレイなんだろう。。
どういうサブルーチンを定義してどうやって使うか、が大事なところなのかなぁ。

#!/usr/bin/perl
use strict;
use warnings;

# 最小の素因数を返すサブルーチン
# 引数が素数だった場合はundefを返す
sub get_factor {
    my $target = shift;
    for my $num (2 .. $target-1) {
        if ($target % $num == 0) {
            return $num;
        }
    }
    return;
}

TARGET: for my $num (1..99) {
    my $first_factor = get_factor($num);
    if (!defined($first_factor)) {
        next TARGET;
    }

    my $second_factor = get_factor($num / $first_factor);
    if (!defined($second_factor)) {
        print "$num\n";
    }
}


http://github.com/sugyan/CodePocket/commit/21f8016acae34d9dbd61b1cf06d8fcec64372371
他の人がどう書くのかを見てみたい。

Python

結局Perlのモジュール使わない版を翻訳しただけのものしか思いつかなかった。
これまた上手い書き方がわからない。どうしても条件分岐が多くなるとインデントが深くなっちゃうしなぁ。。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

def get_factor(target):
    for index in range(2, target-1):
        if target % index == 0:
            return index

if __name__ == '__main__':
    for target in range(1, 100):
        factor = get_factor(target)
        if factor and get_factor(target / factor) == None:
            print target

http://github.com/sugyan/CodePocket/blob/10fd5f543b0303d05ad182d96e86777fdd7c2b3e/lang/python/semiprime/semiprime.py