开发者

Truth Table Generation for the given input

I want to generate a truth table for the given input.Suppose if i give input 2 the output will be

10 01 11 00 

if the input is 3 the output will be

111 000 110 101 011 100 001 010

i have a code snippet

#!/usr/bin/perl

#print "a|b|c\n";

for $a (1, 0){
    for $b (1, 0){
      for  $c (1,0) {
        for $d ( 1,0) 
        {        
          print "$a $b $c $d";
          #print $x = ($a & $b & $c);
          print "\n";
        }
     }
   }
}

print "\n";

above code is for 4.

i don't know how to do this without writing multiple for loops. Here for value 2 i need to write two for loops and so on.

can any body tell me how to tweak this code for several input val开发者_Go百科ues.

Any help would be great appreciated


Recursion

Here is a simple solution using recursion:

#!/usr/bin/perl -w                                                              
my $variables=$ARGV[0]||0;
show_combinations($variables);                                                           

sub show_combinations { my($n,@prefix)=@_;                                      
  if($n > 0) {                                                                  
    show_combinations( $n-1, @prefix, 0);                                       
    show_combinations( $n-1, @prefix, 1);                                       
  } else {                                                                      
    print "@prefix\n";                                                          
  }                                                                             
}

Here are some sample cases:

> script.pl 1
0
1
> script.pl 2
0 0
0 1
1 0
1 1
> script.pl 3
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1


I'm no Perl expert, so you might need to clean this up, but if forced to use Perl I'd probably do something like this:

#!/usr/bin/perl

my ($n) = @ARGV;

printf("%0*b\n", $n, $_) for 0 .. (1 << $n) - 1;


This is simple one line Perl code using module Math::Cartesian::Product.

use Math::Cartesian::Product;

cartesian {print "@_\n"} ([0..1]) x $ARGV[0];

Output

    
./sample.pl 2

0 0
0 1
1 0
1 1

./sample.pl 3

0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1


I don't know Perl so this may not work:

-- loop from 0 to (2^n)-1, where n is the number of digits in your cases;

-- convert each number to its n-digit binary representation;


Here is a generalization of my previous solution using Math::BigInt. This is an iterative solution:

#!/usr/bin/perl

use strict;
use warnings;

use Math::BigInt try => 'GMP';

my $n_bits = $ARGV[0] || 0;

my $it = make_it($n_bits);

while ( defined(my $bits = $it->()) ) {
    print "$bits\n";
}

sub make_it {
    my ($n_bits) = @_;

    my $limit = Math::BigInt->new('2');
    $limit->blsft($n_bits - 1);

    my $next = Math::BigInt->new('-1');

    return sub {
        $next->binc;
        return unless $next->bcmp($limit) < 0;
        my $bits = $next->as_bin;
        $bits =~ s/^0b//;
        if ( (my $x = length $bits) < $n_bits ) {
            $bits = '0' x ($n_bits - $x) . $bits;
        }
        return $bits;
    }
}

You can use the %b format specifier for printf:

use strict;
use warnings;

my ($count) = @ARGV;

my $fmt = "%0${count}b";
my $n = 2**$count - 1;

for my $c (0 .. $n) {
    my @bits = split //, sprintf $fmt, $c;
    print "@bits\n";
}

This will only work for $count values less than 32.

Output:

C:\Temp> y 3
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1


I am surprised no one has mentioned glob as a solution here:

perl -e 'print join "\n", glob("{0,1}" x shift || 1 )' -- 3

This prints:

000
001
010
011
100
101
110
111

glob is very handy for computing string permutations.

Here is the above, in a cleaner, non-one-liner form:

use strict;
use warnings;

my $symbol_count = shift || 1;

my @permutations = glob( '{0,1}' x $symbol_count );

print join "\n", @permutations;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜