http://www.perlmonks.org?node_id=418836


in reply to Comparison by position and value

I keep thinking that this can be done using string-wise boolean operations, but I cannot see how?

Like this:

sub compatible { my( $l, $r ) = @_; # underscores are insignificant tr/_/\0/ for $l, $r; # cancel out identical values my $xor = $l ^ $r; # convert to bitmasks tr/\0/\377/c for $l, $r; my $mask = $l & $r; # masked chars must be identical return !1 if ( $xor & $mask ) =~ tr/\0//c; # and there may not be dupes of non-identical characters return 0 == grep { my $char = substr( $xor, $_, 1 ); $char ne "\0" and index( $xor, $char, $_ + 1 ) != -1 } 0 .. length( $xor ) - 1; }

Test suite in the readmore.

#!/usr/bin/perl use strict; use warnings; use Test::More; my @testcase = ( 1 => [ '_8__3__19', '48____7__', ], 1 => [ '_8__3__19', '48__3_7__', ], !1 => [ '_8__3__19', '4_8___7__', ], !1 => [ '____3__19', '3________', ], !1 => [ '____3__19', '________8', ], !1 => [ '_8__3__19', '48_____7_', ], !1 => [ '__8_3__19', '84____7__', ], ); plan tests => @testcase / 2; while( my( $result, $strings ) = splice @testcase, 0, 2 ) { my $testname = join "\n" . ( " " x 18 ), ( ( $result ? 'compatible' : 'conflicting' ) . ':', @$strings ); is( compatible( @$strings ), $result, $testname ); }

Makeshifts last the longest.

Replies are listed 'Best First'.
Re^2: Comparison by position and value
by BrowserUk (Patriarch) on Jan 03, 2005 at 23:59 UTC

    Your code appears to fail on '__8_3__19' and '84____7__', passing this as compatible when it should not be as the digit 8 appears in both strings in different positions.

    It could be that in moving your function into my test script, I have broken it, but as your post doesn't contain a stand-alone testcase that I can run, I cannot verify this conjecture.


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.

      Are you sure it's my posted code? I just dropped your example into my test suite as an incompatible case and it passes.

      Makeshifts last the longest.

        You're right, I screwed up. Sorry for the false call.


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.