Problem 1

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

訳.

10未満で3と5の倍数である自然数をあげると,3,5,6,9であり,その和は23である.

では,1000未満の3と5の倍数の和を求めよ.

プログラムを組まなくても解けますね.

とりあえず,Haskell

{-
e1.hs Project Euler Problem 1
-}
import System

isok:: Int->Bool
isok n 
    | mod n 3 == 0 = True
    | mod n 5 == 0 = True
    | otherwise    = False

main = do n <- getArgs
          putStr.show.sum $ filter isok [1..(read $ head n)]

引数に数字をいれて,それ「以下」の数での和を求めます.

C:\usr\local\euler>ghc e1.hs -o e1

C:\usr\local\euler>e1 999
233168

次はPerl

#
#e1.pl Project Euler Problem 1
#
use strict;
use warnings;

my $sum;
$sum += $_ foreach grep { $_ % 3 == 0 || $_ % 5 ==0 } (1..$ARGV[0]) ;
print $sum;

実行すると

c:\usr\local\euler>perl e1.pl 999
perl e1.pl 999
233168

これは都合二回リストを構築してるので、そのうちの一回を省いてみるとこんな感じでしょうか.

#
#e1'.pl Project Euler Problem 1
#
use strict;
use warnings;

my $sum;
foreach (1..$ARGV[0]){
   $sum+=$_ if ( $_ % 3 == 0 || $_ % 5 ==0 )
}
print $sum;

もうちょっと細工してリストの構築をやめてみます.

#
#e1''.pl Project Euler Problem 1
#
use strict;
use warnings;

my $sum;

sub iterator{
    my ($upper,$cond) = @_;
    my $state=0;
    return sub {
        $state++;
        return if $upper < $state; 
        $state++ while ( not $cond->($state) );
        return $state;
    };
}

my $it = iterator($ARGV[0], sub {$_[0] % 3==0 || $_[0] % 5 ==0 } );

while( defined (my $i = $it->()) ){$sum += $i;};
print $sum;

これが一番長くて,やってることも複雑です.
(追記:whileの中にdefinedを追加.こうしないと,0と偽の区別が付かないのでした)

数学(笑)

1000未満の3の倍数は333個,5の倍数は199個,15の倍数は66個なので,求める和は
 \frac{(3+999)\times333}{2} + \frac{(5+995)\times199}{2} -  \frac{(15+990)\times66}{2} = 166833 + 99500 - 33165 = 233168