概要

  • オブジェクト指向プログラミング
  • 3x3のビットパターンを表現するクラスを作成し、これを使って回転しても重複しないパターンを探索する。
  • ソース
    BitPattern.zip

BitPattern.pm

# BitPattern.pm
# ビットパターンクラス
# 数値に対応するNxNのマトリックスを表現するクラス
#
# N=3 (default)
# | bit0 | bit1 | bit2 |
# | bit3 | bit4 | bit5 |
# | bit6 | bit7 | bit8 |

package BitPattern;

use strict;
use warnings;
use utf8;

sub new {
	my $pkg = shift;
	bless {
		number	=> 0,
		unit	=> 3,
		pattern	=> [ [0,0,0], [0,0,0], [0,0,0], ],
	}, $pkg;
}

sub toString {
	my $self = shift;
	my $unit = $self->{unit};
	my $pattern = "[ ";
	for( my $i=0; $i<$unit; $i++ ){
		$pattern .= "[ ";
		for( my $j=0; $j<$unit; $j++ ){
			$pattern .= ${$self->{pattern}}[ $i ][ $j ] . " ";
		}
		$pattern .= "] ";
	}
	$pattern .= "]";

	return sprintf( "%04x / %s", $self->{number}, $pattern );
}

sub clone {
	my $self = shift;
	my $unit = $self->{unit};
	my $tmp = BitPattern->new();
	# $tmp->{number}		= $self->{number};
	# $tmp->{unit}			= $self->{unit};
	# @{$tmp->{pattern}}	= @{$self->{pattern}};	# rotateで失敗する?
	$tmp->set( $self->{number}, $self->{unit} );
	return $tmp;
}

sub equals {
	my $self = shift;
	my $target = shift;
	return ( $self->{number} == $target->{number} );
}

sub set {
	my $self = shift;
	my $num = $self->{number} = int( shift );
	my $unit = $self->{unit} = int( shift || $self->{unit} || 3 );	# default=3
	my @pattern = ();
	for( my $i=0; $i<$unit; $i++ ){
		for( my $j=0; $j<$unit; $j++ ){
			if ( $num & 1 ){
				$pattern[ $i ][ $j ] = 1;
			} else {
				$pattern[ $i ][ $j ] = 0;
			}
			$num >>= 1;
		}
	}
	@{$self->{pattern}} = @pattern;
	return $self;
}

sub getNumber {
	my $self = shift;
	return $self->{number};
}

sub getPatternArray {
	my $self = shift;
	return wantarray ? @{$self->{pattern}} : $self->{pattern};
}

sub getPattern {
	my $self = shift;
	my $unit = $self->{unit};
	my $pattern = "";
	for( my $i=0; $i<$unit; $i++ ){
		for( my $j=0; $j<$unit; $j++ ){
			$pattern .= ${$self->{pattern}}[ $i ][ $j ] ? "*" : "-" ;
		}
		$pattern .= "\n";
	}
	return $pattern;
}

# 時計回りに回転
sub rotate {
	my $self = shift;
	my $unit = $self->{unit};
	my $tmp = $self->clone();
	for( my $i=0; $i<$unit; $i++ ){
		for( my $j=0; $j<$unit; $j++ ){
			${$self->{pattern}}[ $i ][ $j ] = 
				${$tmp->{pattern}}[ $unit - 1 - $j ][ $i ];
		}
	}

	my $num = 0;
	for( my $i=$unit-1; $i>=0; $i-- ){
		for( my $j=$unit-1; $j>=0; $j-- ){
			$num <<= 1;
			$num += ${$self->{pattern}}[ $i ][ $j ];
		}
	}
	$self->{number} = $num;

	return $self;
}

1;

# EOF

testBitPattern.pl

ソース

# testBitPattern.pl
# ビットパターンクラスの動作テスト

use strict;
use warnings;
use utf8;
use Data::Dump qw(dump);

use BitPattern;

my $unit = 3;

my $pattern = BitPattern->new();
my( @pat1, @pat2, $pattern2 );

$pattern->set( 0, $unit );

foreach ( 1, 2, 4, 8, 16, 32, 64, 128, 256, 170, 325 ){
	$pattern->set( $_ );
	@pat1 = split( "\n", $pattern->getPattern() );
	$pattern2 = $pattern->clone();
	$pattern2->rotate();
	@pat2 = split( "\n", $pattern2->getPattern() );
	printf( 
		"%s\n%d\n%s\neq: %b\n", 
		$pattern->toString(), $pattern->getNumber(), 
		dump( $pattern->getPatternArray() ), $pattern->equals($pattern2) 
	);
	for( my $i=0; $i<$unit; $i++ ){
		printf( "%s  ->  %s\n", $pat1[ $i ], $pat2[ $i ] );
	}
	print "\n";
}

# EOF

実行結果

0001 / [ [ 1 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ]
1
([1, 0, 0], [0, 0, 0], [0, 0, 0])
eq: 0
*--  ->  --*
---  ->  ---
---  ->  ---

0002 / [ [ 0 1 0 ] [ 0 0 0 ] [ 0 0 0 ] ]
2
([0, 1, 0], [0, 0, 0], [0, 0, 0])
eq: 0
-*-  ->  ---
---  ->  --*
---  ->  ---

0004 / [ [ 0 0 1 ] [ 0 0 0 ] [ 0 0 0 ] ]
4
([0, 0, 1], [0, 0, 0], [0, 0, 0])
eq: 0
--*  ->  ---
---  ->  ---
---  ->  --*

0008 / [ [ 0 0 0 ] [ 1 0 0 ] [ 0 0 0 ] ]
8
([0, 0, 0], [1, 0, 0], [0, 0, 0])
eq: 0
---  ->  -*-
*--  ->  ---
---  ->  ---

0010 / [ [ 0 0 0 ] [ 0 1 0 ] [ 0 0 0 ] ]
16
([0, 0, 0], [0, 1, 0], [0, 0, 0])
eq: 1
---  ->  ---
-*-  ->  -*-
---  ->  ---

0020 / [ [ 0 0 0 ] [ 0 0 1 ] [ 0 0 0 ] ]
32
([0, 0, 0], [0, 0, 1], [0, 0, 0])
eq: 0
---  ->  ---
--*  ->  ---
---  ->  -*-

0040 / [ [ 0 0 0 ] [ 0 0 0 ] [ 1 0 0 ] ]
64
([0, 0, 0], [0, 0, 0], [1, 0, 0])
eq: 0
---  ->  *--
---  ->  ---
*--  ->  ---

0080 / [ [ 0 0 0 ] [ 0 0 0 ] [ 0 1 0 ] ]
128
([0, 0, 0], [0, 0, 0], [0, 1, 0])
eq: 0
---  ->  ---
---  ->  *--
-*-  ->  ---

0100 / [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 1 ] ]
256
([0, 0, 0], [0, 0, 0], [0, 0, 1])
eq: 0
---  ->  ---
---  ->  ---
--*  ->  *--

00aa / [ [ 0 1 0 ] [ 1 0 1 ] [ 0 1 0 ] ]
170
([0, 1, 0], [1, 0, 1], [0, 1, 0])
eq: 1
-*-  ->  -*-
*-*  ->  *-*
-*-  ->  -*-

0145 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 0 1 ] ]
325
([1, 0, 1], [0, 0, 0], [1, 0, 1])
eq: 1
*-*  ->  *-*
---  ->  ---
*-*  ->  *-*

checkPattern.pl

ソース

# checkPattern.pl
# ビットパターンのチェック
# 回転しても重複しないビットパターンを探索する

use strict;
use warnings;
use utf8;

use BitPattern;

my $pattern = BitPattern->new();
my @check = ();
my $count = 0;

for( my $i=1; $i<512; $i++ ){
	if ( !defined( $check[ $i ] ) ){
		$count++;
		$pattern->set( $i );
		printf( "%s\n", $pattern->toString() );
		$check[ $pattern->rotate()->getNumber() ] = 0;
		$check[ $pattern->rotate()->getNumber() ] = 0;
		$check[ $pattern->rotate()->getNumber() ] = 0;
		$check[ $i ] = 1;
	}
}
printf( "count: %d\n", $count );

# EOF

実行結果

0001 / [ [ 1 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ]
0002 / [ [ 0 1 0 ] [ 0 0 0 ] [ 0 0 0 ] ]
0003 / [ [ 1 1 0 ] [ 0 0 0 ] [ 0 0 0 ] ]
0005 / [ [ 1 0 1 ] [ 0 0 0 ] [ 0 0 0 ] ]
0006 / [ [ 0 1 1 ] [ 0 0 0 ] [ 0 0 0 ] ]
0007 / [ [ 1 1 1 ] [ 0 0 0 ] [ 0 0 0 ] ]
000a / [ [ 0 1 0 ] [ 1 0 0 ] [ 0 0 0 ] ]
000b / [ [ 1 1 0 ] [ 1 0 0 ] [ 0 0 0 ] ]
000c / [ [ 0 0 1 ] [ 1 0 0 ] [ 0 0 0 ] ]
000d / [ [ 1 0 1 ] [ 1 0 0 ] [ 0 0 0 ] ]
000e / [ [ 0 1 1 ] [ 1 0 0 ] [ 0 0 0 ] ]
000f / [ [ 1 1 1 ] [ 1 0 0 ] [ 0 0 0 ] ]
0010 / [ [ 0 0 0 ] [ 0 1 0 ] [ 0 0 0 ] ]
0011 / [ [ 1 0 0 ] [ 0 1 0 ] [ 0 0 0 ] ]
0012 / [ [ 0 1 0 ] [ 0 1 0 ] [ 0 0 0 ] ]
0013 / [ [ 1 1 0 ] [ 0 1 0 ] [ 0 0 0 ] ]
0015 / [ [ 1 0 1 ] [ 0 1 0 ] [ 0 0 0 ] ]
0016 / [ [ 0 1 1 ] [ 0 1 0 ] [ 0 0 0 ] ]
0017 / [ [ 1 1 1 ] [ 0 1 0 ] [ 0 0 0 ] ]
001a / [ [ 0 1 0 ] [ 1 1 0 ] [ 0 0 0 ] ]
001b / [ [ 1 1 0 ] [ 1 1 0 ] [ 0 0 0 ] ]
001c / [ [ 0 0 1 ] [ 1 1 0 ] [ 0 0 0 ] ]
001d / [ [ 1 0 1 ] [ 1 1 0 ] [ 0 0 0 ] ]
001e / [ [ 0 1 1 ] [ 1 1 0 ] [ 0 0 0 ] ]
001f / [ [ 1 1 1 ] [ 1 1 0 ] [ 0 0 0 ] ]
0021 / [ [ 1 0 0 ] [ 0 0 1 ] [ 0 0 0 ] ]
0023 / [ [ 1 1 0 ] [ 0 0 1 ] [ 0 0 0 ] ]
0025 / [ [ 1 0 1 ] [ 0 0 1 ] [ 0 0 0 ] ]
0027 / [ [ 1 1 1 ] [ 0 0 1 ] [ 0 0 0 ] ]
0028 / [ [ 0 0 0 ] [ 1 0 1 ] [ 0 0 0 ] ]
0029 / [ [ 1 0 0 ] [ 1 0 1 ] [ 0 0 0 ] ]
002a / [ [ 0 1 0 ] [ 1 0 1 ] [ 0 0 0 ] ]
002b / [ [ 1 1 0 ] [ 1 0 1 ] [ 0 0 0 ] ]
002c / [ [ 0 0 1 ] [ 1 0 1 ] [ 0 0 0 ] ]
002d / [ [ 1 0 1 ] [ 1 0 1 ] [ 0 0 0 ] ]
002e / [ [ 0 1 1 ] [ 1 0 1 ] [ 0 0 0 ] ]
002f / [ [ 1 1 1 ] [ 1 0 1 ] [ 0 0 0 ] ]
0031 / [ [ 1 0 0 ] [ 0 1 1 ] [ 0 0 0 ] ]
0033 / [ [ 1 1 0 ] [ 0 1 1 ] [ 0 0 0 ] ]
0035 / [ [ 1 0 1 ] [ 0 1 1 ] [ 0 0 0 ] ]
0037 / [ [ 1 1 1 ] [ 0 1 1 ] [ 0 0 0 ] ]
0038 / [ [ 0 0 0 ] [ 1 1 1 ] [ 0 0 0 ] ]
0039 / [ [ 1 0 0 ] [ 1 1 1 ] [ 0 0 0 ] ]
003a / [ [ 0 1 0 ] [ 1 1 1 ] [ 0 0 0 ] ]
003b / [ [ 1 1 0 ] [ 1 1 1 ] [ 0 0 0 ] ]
003c / [ [ 0 0 1 ] [ 1 1 1 ] [ 0 0 0 ] ]
003d / [ [ 1 0 1 ] [ 1 1 1 ] [ 0 0 0 ] ]
003e / [ [ 0 1 1 ] [ 1 1 1 ] [ 0 0 0 ] ]
003f / [ [ 1 1 1 ] [ 1 1 1 ] [ 0 0 0 ] ]
0044 / [ [ 0 0 1 ] [ 0 0 0 ] [ 1 0 0 ] ]
0045 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 0 0 ] ]
0046 / [ [ 0 1 1 ] [ 0 0 0 ] [ 1 0 0 ] ]
0047 / [ [ 1 1 1 ] [ 0 0 0 ] [ 1 0 0 ] ]
004c / [ [ 0 0 1 ] [ 1 0 0 ] [ 1 0 0 ] ]
004d / [ [ 1 0 1 ] [ 1 0 0 ] [ 1 0 0 ] ]
004e / [ [ 0 1 1 ] [ 1 0 0 ] [ 1 0 0 ] ]
004f / [ [ 1 1 1 ] [ 1 0 0 ] [ 1 0 0 ] ]
0054 / [ [ 0 0 1 ] [ 0 1 0 ] [ 1 0 0 ] ]
0055 / [ [ 1 0 1 ] [ 0 1 0 ] [ 1 0 0 ] ]
0056 / [ [ 0 1 1 ] [ 0 1 0 ] [ 1 0 0 ] ]
0057 / [ [ 1 1 1 ] [ 0 1 0 ] [ 1 0 0 ] ]
005c / [ [ 0 0 1 ] [ 1 1 0 ] [ 1 0 0 ] ]
005d / [ [ 1 0 1 ] [ 1 1 0 ] [ 1 0 0 ] ]
005e / [ [ 0 1 1 ] [ 1 1 0 ] [ 1 0 0 ] ]
005f / [ [ 1 1 1 ] [ 1 1 0 ] [ 1 0 0 ] ]
0061 / [ [ 1 0 0 ] [ 0 0 1 ] [ 1 0 0 ] ]
0062 / [ [ 0 1 0 ] [ 0 0 1 ] [ 1 0 0 ] ]
0063 / [ [ 1 1 0 ] [ 0 0 1 ] [ 1 0 0 ] ]
0065 / [ [ 1 0 1 ] [ 0 0 1 ] [ 1 0 0 ] ]
0066 / [ [ 0 1 1 ] [ 0 0 1 ] [ 1 0 0 ] ]
0067 / [ [ 1 1 1 ] [ 0 0 1 ] [ 1 0 0 ] ]
0069 / [ [ 1 0 0 ] [ 1 0 1 ] [ 1 0 0 ] ]
006a / [ [ 0 1 0 ] [ 1 0 1 ] [ 1 0 0 ] ]
006b / [ [ 1 1 0 ] [ 1 0 1 ] [ 1 0 0 ] ]
006c / [ [ 0 0 1 ] [ 1 0 1 ] [ 1 0 0 ] ]
006d / [ [ 1 0 1 ] [ 1 0 1 ] [ 1 0 0 ] ]
006e / [ [ 0 1 1 ] [ 1 0 1 ] [ 1 0 0 ] ]
006f / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 0 0 ] ]
0071 / [ [ 1 0 0 ] [ 0 1 1 ] [ 1 0 0 ] ]
0072 / [ [ 0 1 0 ] [ 0 1 1 ] [ 1 0 0 ] ]
0073 / [ [ 1 1 0 ] [ 0 1 1 ] [ 1 0 0 ] ]
0075 / [ [ 1 0 1 ] [ 0 1 1 ] [ 1 0 0 ] ]
0076 / [ [ 0 1 1 ] [ 0 1 1 ] [ 1 0 0 ] ]
0077 / [ [ 1 1 1 ] [ 0 1 1 ] [ 1 0 0 ] ]
0079 / [ [ 1 0 0 ] [ 1 1 1 ] [ 1 0 0 ] ]
007a / [ [ 0 1 0 ] [ 1 1 1 ] [ 1 0 0 ] ]
007b / [ [ 1 1 0 ] [ 1 1 1 ] [ 1 0 0 ] ]
007c / [ [ 0 0 1 ] [ 1 1 1 ] [ 1 0 0 ] ]
007d / [ [ 1 0 1 ] [ 1 1 1 ] [ 1 0 0 ] ]
007e / [ [ 0 1 1 ] [ 1 1 1 ] [ 1 0 0 ] ]
007f / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 0 0 ] ]
008d / [ [ 1 0 1 ] [ 1 0 0 ] [ 0 1 0 ] ]
008e / [ [ 0 1 1 ] [ 1 0 0 ] [ 0 1 0 ] ]
008f / [ [ 1 1 1 ] [ 1 0 0 ] [ 0 1 0 ] ]
009d / [ [ 1 0 1 ] [ 1 1 0 ] [ 0 1 0 ] ]
009e / [ [ 0 1 1 ] [ 1 1 0 ] [ 0 1 0 ] ]
009f / [ [ 1 1 1 ] [ 1 1 0 ] [ 0 1 0 ] ]
00aa / [ [ 0 1 0 ] [ 1 0 1 ] [ 0 1 0 ] ]
00ab / [ [ 1 1 0 ] [ 1 0 1 ] [ 0 1 0 ] ]
00ad / [ [ 1 0 1 ] [ 1 0 1 ] [ 0 1 0 ] ]
00af / [ [ 1 1 1 ] [ 1 0 1 ] [ 0 1 0 ] ]
00ba / [ [ 0 1 0 ] [ 1 1 1 ] [ 0 1 0 ] ]
00bb / [ [ 1 1 0 ] [ 1 1 1 ] [ 0 1 0 ] ]
00bd / [ [ 1 0 1 ] [ 1 1 1 ] [ 0 1 0 ] ]
00bf / [ [ 1 1 1 ] [ 1 1 1 ] [ 0 1 0 ] ]
00c5 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 1 0 ] ]
00c6 / [ [ 0 1 1 ] [ 0 0 0 ] [ 1 1 0 ] ]
00c7 / [ [ 1 1 1 ] [ 0 0 0 ] [ 1 1 0 ] ]
00cd / [ [ 1 0 1 ] [ 1 0 0 ] [ 1 1 0 ] ]
00ce / [ [ 0 1 1 ] [ 1 0 0 ] [ 1 1 0 ] ]
00cf / [ [ 1 1 1 ] [ 1 0 0 ] [ 1 1 0 ] ]
00d5 / [ [ 1 0 1 ] [ 0 1 0 ] [ 1 1 0 ] ]
00d6 / [ [ 0 1 1 ] [ 0 1 0 ] [ 1 1 0 ] ]
00d7 / [ [ 1 1 1 ] [ 0 1 0 ] [ 1 1 0 ] ]
00dd / [ [ 1 0 1 ] [ 1 1 0 ] [ 1 1 0 ] ]
00de / [ [ 0 1 1 ] [ 1 1 0 ] [ 1 1 0 ] ]
00df / [ [ 1 1 1 ] [ 1 1 0 ] [ 1 1 0 ] ]
00e5 / [ [ 1 0 1 ] [ 0 0 1 ] [ 1 1 0 ] ]
00e7 / [ [ 1 1 1 ] [ 0 0 1 ] [ 1 1 0 ] ]
00ed / [ [ 1 0 1 ] [ 1 0 1 ] [ 1 1 0 ] ]
00ee / [ [ 0 1 1 ] [ 1 0 1 ] [ 1 1 0 ] ]
00ef / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 1 0 ] ]
00f5 / [ [ 1 0 1 ] [ 0 1 1 ] [ 1 1 0 ] ]
00f7 / [ [ 1 1 1 ] [ 0 1 1 ] [ 1 1 0 ] ]
00fd / [ [ 1 0 1 ] [ 1 1 1 ] [ 1 1 0 ] ]
00fe / [ [ 0 1 1 ] [ 1 1 1 ] [ 1 1 0 ] ]
00ff / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 1 0 ] ]
0145 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 0 1 ] ]
0147 / [ [ 1 1 1 ] [ 0 0 0 ] [ 1 0 1 ] ]
014f / [ [ 1 1 1 ] [ 1 0 0 ] [ 1 0 1 ] ]
0155 / [ [ 1 0 1 ] [ 0 1 0 ] [ 1 0 1 ] ]
0157 / [ [ 1 1 1 ] [ 0 1 0 ] [ 1 0 1 ] ]
015f / [ [ 1 1 1 ] [ 1 1 0 ] [ 1 0 1 ] ]
016d / [ [ 1 0 1 ] [ 1 0 1 ] [ 1 0 1 ] ]
016f / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 0 1 ] ]
017d / [ [ 1 0 1 ] [ 1 1 1 ] [ 1 0 1 ] ]
017f / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 0 1 ] ]
01ef / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 1 1 ] ]
01ff / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 1 1 ] ]
count: 139

リンク