sironekotoroの日記

Perl で楽をしたい

Perlで練習スクリプト(ダイヤモンドツリー,素数,2進数)

ダイヤモンドツリー

  • 結城先生本でも書いてあったけど、あの時はただ写経するだけだった。
  • 今回は自分で考えてみる。
use strict;
use warnings;

my $line = 19;

my $foo = int( $line / 2 );

for my $i ( 0 .. $foo ) {
    my $space = $i * (-1) + int( $line / 2 );
    print '_' x $space;
    my $star = $line - ( $space * 2 );
    print '*' x $star, "\n";
}

for my $i (1..$foo){
    my $space = $i;
    print '_' x $space;
    my $star = $line - ($space *2);
    print '*' x $star,"\n";
    
}
  • 実行結果(http://seiitaishougun.com/lleval.cgi/permalink/wkimaPjB4xG5xADVNjOSrA)
  • 一番太いところと高さが同一であると気付く事が出来たのが大きい。
  • で、そこを基点に上下でfor文を分けた
    • 一番太いところから上は空白,*,空白で、空白はデクリメント
    • 一番太いところから下も空白,*,空白だが、空白はインクリメント

素数

use strict;
use warnings;
use Data::Dumper;

my $prime;

for my $num ( 1 .. 100 ) {
    for my $div ( 1 .. ( $num / 2 ) ) {
        if ( $num % $div == 0 ) {
            $prime->{$num}++;
        }
    }
}

for my $i ( sort { $a <=> $b } keys %$prime ) {
    if ( $prime->{$i} == 1 ) {
        print $i, "\n";
    }
}
  • 実行結果(http://seiitaishougun.com/lleval.cgi/permalink/7Mar4fnB4xG1TiLVNjOSrA)
  • for文で1~100の数を用意して1ずつ取り出す
  • 取り出した数を1から「取り出した数の半分」まで順繰りに割る
  • 取り出した数をkeyに、「割り切れた回数」をvalueにしてハッシュリファレンスに入れていく。
    • valueにそのまま入れるのではなく、{$num}++として合致した回数インクリメントさせていく
  • 最後に、割り切れた数が1のみ(1以外で割り切れなかった)ものをソートして出力
    • 素数は1とその数以外で割り切れない数、だけど、最初に2で割っているので、判断している数そのものはここで考慮しなくても良い

2進数

use strict;
use warnings;

for my $i (0..15){
    print "$i",':',&bd($i),"\n";
}

sub bd {
    my $num = shift @_;
    my ( $n8, $n4, $n2, $n1 ) = 0;

    return '0000', if ( $num == 0 );

    if ( $num >= 8 ) {
        $n8  = 1;
        $num = $num - 8;
    }else{
        $n8 = 0;
    }

    if ( $num >= 4 ) {
        $n4  = 1;
        $num = $num - 4;
    }else{
        $n4 = 0;
    }

    if ( $num >= 2 ) {
        $n2  = 1;
        $num = $num - 2;
    }else{
        $n2 = 0;
    }

    if ($num == 1){
        $n1 = 1;
    }else{
        $n1 = 0;
    }

    return $n8 . $n4 . $n2 . $n1;
}
  • 実行結果(http://seiitaishougun.com/lleval.cgi/permalink/PuBUxvvB4xGI3EPVNjOSrA)
  • Perlに2進数へ変換する関数が無いってのは不思議
    • 8進数とか16進数はあるのにね
  • あまり賢くない感じだけど、昔習った10進数から2進数への変換をコードにしてみました。
    • だたし、2進数で4桁まで。マイナスは考慮しない
  • pack関数とunpack関数を使うのが常識らしい