use 5.026; use warnings; use Test::More qw{ no_plan }; my @ORtests = ( q{degenerate case}, [ [], [], [], ], q{simple cases}, [ [ 0 ], [ 0 ], [ 0 ], ], [ [ 0 ], [ 1 ], [ 1 ], ], [ [ 1 ], [ 0 ], [ 1 ], ], [ [ 1 ], [ 1 ], [ 1 ], ], [ [ 5 ], [ 0 ], [ 1 ], ], [ [ q{x} ], [ 44 ], [ 1 ], ], q{complex cases}, [ [ 0, 1, 0, 1, ], [ 0, 0, 1, 1, ], [ 0, 1, 1, 1, ], ], [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, ], [ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], ], q{differing length cases}, [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, ], [ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], ], [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, ], [ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], ], ); say qq{\nOR tests\n}; foreach my $ORtest ( @ORtests ) { do { say $ORtest; next } unless ref $ORtest eq q{ARRAY}; my( $raT1, $raT2, $raExpected ) = @$ORtest; my @got = vec2array( vecORvec( array2vec( @$raT1 ), array2vec( @$raT2 ) ) ); is_deeply \ @got, $raExpected, qq{OR result - @got}; } my @ANDtests = ( q{degenerate case}, [ [], [], [], ], q{simple cases}, [ [ 0 ], [ 0 ], [ 0 ], ], [ [ 0 ], [ 1 ], [ 0 ], ], [ [ 1 ], [ 0 ], [ 0 ], ], [ [ 1 ], [ 1 ], [ 1 ], ], [ [ 5 ], [ 0 ], [ 0 ], ], [ [ q{x} ], [ 44 ], [ 1 ], ], q{complex cases}, [ [ 0, 1, 0, 1, ], [ 0, 0, 1, 1, ], [ 0, 0, 0, 1, ], ], [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, ], [ 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, ], ], q{differing length cases}, [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, ], [ 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, ], ], [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, ], [ 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, ], ], ); say qq{\nAND tests\n}; foreach my $ANDtest ( @ANDtests ) { do { say $ANDtest; next } unless ref $ANDtest eq q{ARRAY}; my( $raT1, $raT2, $raExpected ) = @$ANDtest; my @got = vec2array( vecANDvec( array2vec( @$raT1 ), array2vec( @$raT2 ) ) ); is_deeply \ @got, $raExpected, qq{AND result - @got}; } my @XORtests = ( q{degenerate case}, [ [], [], [], ], q{simple cases}, [ [ 0 ], [ 0 ], [ 0 ], ], [ [ 0 ], [ 1 ], [ 1 ], ], [ [ 1 ], [ 0 ], [ 1 ], ], [ [ 1 ], [ 1 ], [ 0 ], ], [ [ 5 ], [ 0 ], [ 1 ], ], [ [ q{x} ], [ 44 ], [ 0 ], ], q{complex cases}, [ [ 0, 1, 0, 1, ], [ 0, 0, 1, 1, ], [ 0, 1, 1, 0, ], ], [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, ], [ 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, ], ], q{differing length cases}, [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, ], [ 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, ], ], [ [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, ], [ 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, ], ], ); say qq{\nXOR tests\n}; foreach my $XORtest ( @XORtests ) { do { say $XORtest; next } unless ref $XORtest eq q{ARRAY}; my( $raT1, $raT2, $raExpected ) = @$XORtest; my @got = vec2array( vecXORvec( array2vec( @$raT1 ), array2vec( @$raT2 ) ) ); is_deeply \ @got, $raExpected, qq{XOR result - @got}; } sub array2vec { my $rhVec = {}; $rhVec->{ len } = scalar @_; $rhVec->{ vec } = q{}; return $rhVec unless $rhVec->{ len }; vec( $rhVec->{ vec }, $_, 1 ) = $_[ $_ ] ? 1 : 0 for 0 .. $rhVec->{ len } - 1; return $rhVec; } sub vec2array { return () unless $_[ 0 ]->{ len }; my @array = map { vec $_[ 0 ]->{ vec }, $_, 1 } 0 .. $_[ 0 ]->{ len } - 1; return @array; } sub vecANYvec { my( $rhVec1, $rhVec2, $rcOper ) = @_; my $rhNewVec = { len => 0, vec => q{} }; if ( $rhVec1->{ len } == $rhVec2->{ len } ) { return $rhNewVec unless $rhVec1->{ len }; $rhNewVec->{ len } = $rhVec1->{ len }; } elsif ( $rhVec1->{ len } > $rhVec2->{ len } ) { $rhNewVec->{ len } = $rhVec1->{ len }; vec( $rhVec2->{ vec }, $rhVec1->{ len } - 1, 1 ) = 0; } else { $rhNewVec->{ len } = $rhVec2->{ len }; vec( $rhVec1->{ vec }, $rhVec2->{ len } - 1, 1 ) = 0; } $rhNewVec->{ vec } = $rcOper->( $rhVec1->{ vec }, $rhVec2->{ vec } ); return $rhNewVec; } sub vecANDvec { my( $rhVec1, $rhVec2 ) = @_; return vecANYvec( $rhVec1, $rhVec2, sub { return $_[ 0 ] & $_[ 1 ] } ); } sub vecORvec { my( $rhVec1, $rhVec2 ) = @_; return vecANYvec( $rhVec1, $rhVec2, sub { return $_[ 0 ] | $_[ 1 ] } ); } sub vecXORvec { my( $rhVec1, $rhVec2 ) = @_; return vecANYvec( $rhVec1, $rhVec2, sub { return $_[ 0 ] ^ $_[ 1 ] } ); }