[Ruby] to rewrite unless

4 minute read

Origin

There is a ↓ code in the code of others who are currently watching.

tgt


unless hash.has_key?("1") || hash.has_key?("2") || hash.has_key?("3") || arr1.size == 0 || arr2.size == 0
  ....
end

Actually, it is mixed with denial. It’s in the middle of a huge amount of code to run a test.
There are many other ʻunless` statements with multiple conditions …
I can’t imagine the behavior with my crazy brain miso. I’m sorry.

Even if you try Gugu, the explanation of De Morgan is explained under two conditions at best.

There is no help for it, so make a template script for confirmation.

concept

First, under two conditions.
Call the values 0, 1 instead of the conditional expression.

2.pl


my @d = ( [0,0],[1,0],[0,1],[1,1] ) ;
for my $r ( @d ){
    print join "", @{$r} unless $r->[0] || $r->[1] ;
}
$ perl -l 2.pl
00

unless A || BAs for the condition that holds, the first conditional expression is false(0), The second conditional expression is also false(0)I know that. In other wordsif ! A and ! B

Main subject

So what about tgt?

Since there are at most 5 pieces, the cord is pushed

python


$ ruby -e 'p [0,1].product([0,1],[0,1],[0,1],[0,1])'
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 1], [0, 1, 0, 0, 0], [0, 1, 0, 0, 1],
 [0, 1, 1, 0, 0], [0, 1, 1, 0, 1], [1, 0, 0, 0, 0], [1, 0, 0, 0, 1], [1, 0, 1, 0, 0], [1, 0, 1, 0, 1], 
[1, 1, 0, 0, 0], [1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 1, 1, 0, 1]]

Embed this in the source code

5.pl


#!/usr/bin/env perl
my @d = (
    [0, 0, 0, 0, 0], [0, 0, 0, 0, 1],
    [0, 0, 0, 1, 0], [0, 0, 0, 1, 1],
    [0, 0, 1, 0, 0], [0, 0, 1, 0, 1],
    [0, 0, 1, 1, 0], [0, 0, 1, 1, 1],
    [0, 1, 0, 0, 0], [0, 1, 0, 0, 1],
    [0, 1, 0, 1, 0], [0, 1, 0, 1, 1],
    [0, 1, 1, 0, 0], [0, 1, 1, 0, 1],
    [0, 1, 1, 1, 0], [0, 1, 1, 1, 1],
    [1, 0, 0, 0, 0], [1, 0, 0, 0, 1],
    [1, 0, 0, 1, 0], [1, 0, 0, 1, 1],
    [1, 0, 1, 0, 0], [1, 0, 1, 0, 1],
    [1, 0, 1, 1, 0], [1, 0, 1, 1, 1],
    [1, 1, 0, 0, 0], [1, 1, 0, 0, 1],
    [1, 1, 0, 1, 0], [1, 1, 0, 1, 1],
    [1, 1, 1, 0, 0], [1, 1, 1, 0, 1],
    [1, 1, 1, 1, 0], [1, 1, 1, 1, 1]
) ;

for my $r ( @d ){
    print join "", @{$r} unless $r->[0] || $r->[1] || $r->[2] || $r->[3] || $r->[4] ;
}

Execute.

python


$ perl -l 5.pl
00000

Improvement

In addition, the @ d generation is described by perl so that the number can be changed [^ 1].

perl:5.2.pl


#!/usr/bin/env perl
sub comb{
	my $in = shift ;
	#Combinations of binary numbers from 0-After converting hexadecimal numbers up to 1 to 0x padded binary numbers,
	#Divide one character at a time. Use as an array reference. And the return value is Array of Arrays
	map{ [ unpack '(A)*', sprintf "%0${in}b", $_ ] } 0 .. 2 ** $in - 1 ;
}

my @d = comb $ARGV[0] ;
for my $r ( @d ){
    # $ARGV[0] -Even once||It's a hassle to write, so
    # ||The character string concatenated with is eval and it is used as an argument of unless.
    #Actually, change to the code that matches the verification target
    print join "", @{$r} unless eval join '||', map{ $r->[$_] } 0 .. $ARGV[0] - 1 ;
}
$ perl -l 5.2.pl 12
000000000000

later,||To&&Or!Or, according to the conditional statement you want to test, respond on the spot.

Oh, this is less stressful and you can change ʻunless to ʻif.

Serpentine

When not using binary numbers.

python


sub comb {
    my $in = shift ;
    # ([0,0,0..])Make an array
    my @d = ( [(0)x$in] ) ;
    #Hash for cache
    my %seen ;
    # @I lick d,@Because d is pushed in the loop and increases in number
    #Separate conditions for exiting
    for my $r ( @d ){
        # $r = [ x,x,x,x,x ... ]Change the elements of to 1 in order,
        #If it's an unknown [email protected] to d
        push @d, grep{ ! $seen{ join "", @{$_} } ++ }
                 map { my @k = @{$r} ;  $k[$_] = 1 ; [@k] }
                 0 .. $in - 1  ;
        # [All 1]Is the last combination
        last if +(join '', @{$d[-1]}) eq '1' x $in ;
    }
    return @d ;
}

A taboo code [^ 2].
In this case, it is difficult to make it double digits.