Hatena::Groupperl

perl初心者

2008-12-13

クリスマスツリーを書く

| 16:41

時期的にも合うのでこのクイズを解いてみました。

このようなクリスマスツリーを書くプログラムを作るという課題です。

     *
    *!*
   *!*!*
  *!*%*!*
 *!*%/%*!*
*!*%/*/%*!*
              *
             *!*
            *!*!*
           *!*%*!*
          *!*%/%*!*
         *!*%/+/%*!*
        *!*%/+-+/%*!*
       *!*%/+-!-+/%*!*
      *!*%/+-!.!-+/%*!*
     *!*%/+-!.*.!-+/%*!*
    *!*%/+-!.***.!-+/%*!*
   *!*%/+-!.**%**.!-+/%*!*
  *!*%/+-!.**%/%**.!-+/%*!*
 *!*%/+-!.**%/*/%**.!-+/%*!*
*!*%/+-!.**%/*+*/%**.!-+/%*!*

 

最初に考えたのは

#! /bin/perl -w
use strict;

my @takasa = ('6', '16',);
my @parts = qw(* ! * % / * + - ! . * * % / * +);

foreach my $h(@takasa){
	for (my $i = 1; $i <= $h; $i++){
		print ' ' x ($h - $i);
		for (my $m = 0; $m < $i; $m++){
			print $parts[$m];
		}
		for (my $n = ($i - 2); $n >= 0; $n--){
			print $parts[$n];
		}
		print "\n";
	}
	print "\n";
}

forループで右側+中央と左側をprintするのを高さ分だけ繰りかえす2重ループ

 

次にヒントありでできたのが

#! /bin/perl -w
use strict;

my @tree = ('*!*%/*', '*!*%/+-!.**%/*+'); #葉
foreach (@tree) {
	my @leaf = split(//, $_);
	my @branch = ();
	while (@leaf) {
		my $center = shift(@leaf);
		print " " x @leaf, @branch, $center, reverse(@branch), "\n";
		push (@branch, $center);
	}
}

すっきりできました。

解答は結城浩の『Perlクイズ』 [まぐまぐ!]にありますが、2文で出来るとはびっくりです。まだ、学んでいない関数を使ってるとはいえ驚きました。

2008-12-07

うるう年かどうかチェックする。

| 19:30

練習問題として、任意の年($year)がうるう年かどうかチェックするというのを考えてみました。

うるう年の判定条件は、

4で割り切れる年はうるう年

しかし、100で割り切れる年はうるう年ではない

しかし、400で割り切れる年はうるう年

最初に書いたスクリプト

use strict;
use warnings;

my $year = "2008"; #ここに調べたい年を入れる
if ($year % 4 != 0) {
	print "$year年はうるう年ではない\n";
} elsif ($year % 100 == 0) {
	if ($year % 400 == 0) {
		print "$year年はうるう年\n";
	} else {
		print "$year年はうるう年ではない\n";
	}
} else {
	print "$year年はうるう年\n";
}

わかりにくいです。条件が複数ある場合は、一番厳しい条件から書いたほうが良いとのことで、この場合は、400で割り切れるかどうかを最初に判定すると、

use strict;
use warnings;

my $year = "2008"; #ここに調べたい年を入れる
if ($year % 400 == 0) {
	print "$year年はうるう年\n";
} elsif ($year % 100 == 0) {
	print "$year年はうるう年ではない\n";
} elsif ($year % 4 == 0) {
	print "$year年はうるう年\n";
} else {
	print "$year年はうるう年ではない\n";
}

こちらのほうがわかりやすくなりました。

 

ネットでみつけた、シンプルな解答

use strict;
use warnings;
 
my $year = "2008"; #ここに調べたい年を入れる
if ($year % 400 == 0 or ($year % 100 != 0 and $year % 4 == 0)) {
	print "$year年はうるう年\n";
} else {
	print "$year年はうるう年ではない\n";
}

わかりやすいです。

 

追記

トラックバックいただきました。

「うるう年かどうかチェックする」をif~elseを使わずに書いてみた - ishiducaの日記 - Hatena::Group::Perl

うるう年 - negipoのPerl日記 - Hatena::Group::Perl

ありがとうございます。