#!/usr/bin/perl use strict; use warnings; my @cube = ( [[qw/p g p y/], [qw/g g y r/], [qw/g g r p/]], rotations('rprrgy'), rotations('ppryyg'), ); my %cube4 = map {("@$_" => 1)} @{rotations('rrygpy')}; for my $c1 (@{$cube[0]}) { for my $c2 (@{$cube[1]}) { for my $c3 (@{$cube[2]}) { my $sol = find_sol($c1, $c2, $c3); print "@$c1\n@$c2\n@$c3\n$sol\n\n" if $cube4{$sol}; } } } sub find_sol { my ($c1, $c2, $c3) = @_; my @sol; for my $i (0 .. 3) { my %free = map {$_ => undef} qw/r g y p/; delete @free{ map $_->[$i], $c1, $c2, $c3 }; push @sol, keys %free; } return "@sol"; } sub rotations { my (%seen, @rot); my @cube = split //, shift @_; for ([0 .. 3], [1, 4, 3, 5], [4, 0, 5, 2]) { my @col = @cube[@$_]; push @rot, map {push @col, shift @col; $seen{"@col"}++ ? () : [@col]} 1..4; @col = reverse @{$rot[-1]}; push @rot, map {push @col, shift @col; $seen{"@col"}++ ? () : [@col]} 1..4; } return \@rot; } #### #!/usr/bin/perl use strict; use warnings; my @cube = ( [[qw/p g p y/], [qw/g g y r/], [qw/g g r p/]], rotations('rprrgy'), rotations('ppryyg'), ); my %cube4 = map {("@$_" => 1)} @{rotations('rrygpy')}; my @used; for my $c1 (@{$cube[0]}) { @used = map {{$_ => 1}} @$c1; CUBE2: for my $c2 (@{$cube[1]}) { $used[$_]{$c2->[$_]} && next CUBE2 for 0 .. 3; $used[$_]{$c2->[$_]} = 1 for 0 .. 3; CUBE3: for my $c3 (@{$cube[2]}) { $used[$_]{$c3->[$_]} && next CUBE3 for 0 .. 3; my $sol = find_sol($c1, $c2, $c3); print "@$c1\n@$c2\n@$c3\n$sol\n\n" if $cube4{$sol}; } $used[$_]{$c2->[$_]} = 0 for 0 .. 3; } } sub find_sol { my ($c1, $c2, $c3) = @_; my @sol; for my $i (0 .. 3) { my %free = map {$_ => undef} qw/r g y p/; delete @free{ map $_->[$i], $c1, $c2, $c3 }; push @sol, keys %free; } return "@sol"; } sub rotations { my (%seen, @rot); my @cube = split //, shift @_; for ([0 .. 3], [1, 4, 3, 5], [4, 0, 5, 2]) { my @col = @cube[@$_]; push @rot, map {push @col, shift @col; $seen{"@col"}++ ? () : [@col]} 1..4; @col = reverse @{$rot[-1]}; push @rot, map {push @col, shift @col; $seen{"@col"}++ ? () : [@col]} 1..4; } return \@rot; }