perlで解いた「積み木の水槽」
オフラインリアルタイムどう書く第13回の問題を解きました。 問題はこちら
うんうん、唸って考えて布団の中でも 色々考えて、半ば諦めかけてしまったけど。 すべて自力で解けた。すごく嬉しい。
同じ高さの積み木を1で積み木のないところを「0」で 表現して、それを正規表現で0をカウントしてやれば いいのではと閃いた。
「10+1」で正規表現で検索しにいくけれど、 カウントしたいのは0というところが すごく工夫したところ。正規表現の?の使い方 を知らなかったので、すごく勉強になった。
最後に、恒例のCMです。 IT系勉強会の検索に、dokechinの作った、ATNDフルカレンダーをよろしくお願いします。
package Water; use strict; use warnings; sub getBitString { my $height = shift; if ( $height == 0 ) { return '00000000'; } if ( $height == 1 ) { return '10000000'; } if ( $height == 2 ) { return '11000000'; } if ( $height == 3 ) { return '11100000'; } if ( $height == 4 ) { return '11110000'; } if ( $height == 5 ) { return '11111000'; } if ( $height == 6 ) { return '11111100'; } if ( $height == 7 ) { return '11111110'; } if ( $height == 8 ) { return '11111111'; } } sub cal { my $heights = shift; my @mountain = (); my $walls = []; my $index = 0; my $water = 0; while ( length $heights > $index) { my $height = substr($heights,$index++,1); if ( $height == 0 && scalar($walls) > 0 ) { push( @mountain, $walls ); $walls = []; } if ( $height > 0 ) { push( $walls, getBitString( $height - 1 ) ); } } if ( scalar($walls) > 0 ) { push( @mountain, $walls ); } foreach my $mountain (@mountain) { my $walls = $mountain; for my $i ( 0 .. 7 ) { my $str = ""; foreach my $wall (@$walls) { $str = $str . substr( $wall, $i, 1 ); } my $result = 0; while ( $str =~ /1(?=0+1)(0+)/g ) { $result = $result + length $1; } printf "%d:%s,%d\n", $i, $str, $result; $water = $water + $result; } print "--------\n"; } return $water; } 1;