Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use Tie::Handle::CSV;
- use Data::Dumper;
- our $foundZero = 0;
- my $currentPO = '';
- my $countCurrentPO = 0;
- my $debug = 1;
- my @amounts;
- my $fh = Tie::Handle::CSV->new('test2.csv', header => 1);
- open MATCHES, ">matches.csv";
- open VARIANCES, ">variances.csv";
- my @lines = <$fh>;
- undef my @matchedLines;
- print "FINDING MATCHES...\n";
- for (my $k = 0; $k < $#lines + 1; $k++) {
- $countCurrentPO++;
- print "k: " . $k . "\n" if $debug;
- my $csv_line = $lines[$k];
- my $debit = ($csv_line->{'DEBIT_AMOUNT'} eq '') ? 0 : $csv_line->{'DEBIT_AMOUNT'};
- my $credit = ($csv_line->{'CREDIT_AMOUNT'} eq '') ? 0 : $csv_line->{'CREDIT_AMOUNT'};
- my $po = $csv_line->{'PO_NUM'};
- my $total = $credit - $debit;
- # print "matchedLines[k]: ". $matchedLines[$k - 1] . "\n" if defined($matchedLines[$k - 1]);
- if (!(defined($matchedLines[$k]))) { # if the current line haven't been matched previously
- if (@amounts < 1) {$currentPO = $po} # if it's the first one, it becomes the current PO
- print "PO/CURRENTPO: " . $po . "/" . $currentPO . " countCurrentPO: " . $countCurrentPO . "\n" if $debug;
- if ((($po eq $currentPO) || ($k == 0))) {
- # dont add a duplicate amount (with same row number)
- # my $temp = defined($amounts[0][1]) ? $amounts[0][1] : 6666666; # will never get 6666666 rows, so it should be safe..
- push(@amounts, [$total, $k]);# if ($temp != $k);
- if ($k == 77) {
- my $d = Data::Dumper->new(\@amounts);
- print $d->Dump;
- }
- if ($k == $#lines) {
- print "TOTAL1: " . $total . " I3: " . $k . "\n" if $debug;
- my $output = allSums_f2(\@amounts);
- print "OUTPUT3: " . $output . "\n" if $debug;
- my @numbers = split(/ /, $output);
- if ($foundZero == 1) {
- foreach(@numbers) {
- $matchedLines[$_] = 1;
- print "(1) SETTING NUMBER $_ AS MATCHED\n" if $debug;
- }
- $foundZero = 0;
- # $k = $k - $countCurrentPO;
- # $countCurrentPO = 0;
- }
- }
- } else { # this amount is part of a new PO, process old ones
- print "TOTAL2: " . $total . " I3: " . $k . "\n" if $debug;
- # if ($k == 77) {
- # my $d = Data::Dumper->new(\@amounts);
- # print $d->Dump;
- # }
- my $output = allSums_f2(\@amounts);
- print "OUTPUT4: $output \n" if $debug;
- my @numbers = split(/ /, $output);
- my $tempK = $k;
- if ($foundZero == 1) {
- foreach(@numbers) {
- $matchedLines[$_] = 1;
- print "(2) matchedLines[_]: ". $matchedLines[$_] . "\n" if (( $matchedLines[$_] == 1) && $debug);
- print "(2) SETTING NUMBER $_ AS MATCHED\n" if $debug;
- }
- $foundZero = 0;
- $k = $k - $countCurrentPO;
- print "tempK: " . $tempK . " K: " .$k . "\n" if $debug;
- @amounts = ();
- print "TOTAL: $total\n" if $debug;
- push(@amounts, [$total, $tempK]);
- $countCurrentPO = 1;
- # $currentPO = $po;
- }
- else {
- @amounts = ();
- push(@amounts, [$total, $k]);
- $countCurrentPO = 1;
- $currentPO = $po;
- }
- # print "DUMP1: ";
- # my $d = Data::Dumper->new(\@amounts);
- # print $d->Dump;
- }
- }
- }
- print "WRITING RESULT FILES...\n";
- for (my $j = 0; $j < $#matchedLines + 1; $j++) {
- if (defined($matchedLines[$j])) {
- print MATCHES $lines[$j] . "\n";
- } else {
- print VARIANCES $lines[$j] . "\n";
- }
- }
- close $fh;
- sub allSums_f2 {
- my($check_ref) = @_;
- my @check = @{$check_ref};
- my $desired = 0;
- # foreach my $index (0..2**@check-1) {
- for (my $index = 0; $index <= 2**@check-1; $index++) {
- my $sum = 0;
- foreach my $pos (0..@check-1) {
- my $bit = ($index >> $pos) % 2;
- # my $d = Data::Dumper->new(\@check);
- # print $d->Dump;
- $sum += $bit * $check[$pos][0];
- }
- if ($sum == $desired) {
- my @combo;
- foreach my $pos (0..@check-1) {
- push @combo, $check[$pos][1] if ($index >> $pos) % 2;
- }
- if (@combo > 0) {
- print join " ", @combo, "\n";
- $foundZero = 1;
- return join(' ',@combo)
- }
- }
- }
- }
Add Comment
Please, Sign In to add comment