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;
精彩评论