Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, Bit lost on where to go on this problem. I have 2 files of x, y and z co-ords, each file is of different size. I need to take the first x co-ord in file 1, and substract the x value in file 2 from it - repeat for all x values in file 2.
e.g file1 10 12 14 8 10 11 file2 3 4 5 1 2 3 6 7 8 so in new file: diffs in x's for 10 7 9 4

Replies are listed 'Best First'.
Re: hash or nest loop
by zejames (Hermit) on Sep 20, 2004 at 13:40 UTC
    Hum... Sounds like homework to me. It would be better if you provided your code...
    open F, "file1" or die "Problem with file1"; open G, "file2" or die "Problem with file2"; @file1 = map { (split /\s+/, $_)[0]; } <F>; @file2 = map { (split /\s+/, $_)[0]; } <G>; while ($coord2 = shift @file2) { $coord1 = shift @file1; push @result, $coord1 - $coord2; unshift @file1, $coord1; } open H, "> result.txt" or die "Unable to open result.txt"; print H join ("\n", @result);

    Warning : this code is untested.

    update : changed a indice error : 2 -> 0. Now the code is tested.

    HTH

    --
    zejames
      trying to pick up perl while studying in the field of bioinformatics thanks though u've helped me getting started!
Re: hash or nest loop
by Limbic~Region (Chancellor) on Sep 20, 2004 at 14:47 UTC
    Anonymous Monk,
    Sometimes a problem just needs to be solved quickly and all that matters is getting the result (throw away code). Here is some code that might help get a feel for how quickly you can solve problems with Perl.
    #!/usr/bin/perl use strict; use warnings; open (FILE1, '<', 'file1.txt') or die $!; open (FILE2, '<', 'file2.txt') or die $!; open (FILE3, '>', 'file3.txt') or die $!; my ($X) = <FILE1> =~ /^(\d+)/; print FILE3 $X - $_, "\n" for map { /^(\d+)/ } <FILE2>;
    Of course, memory constraints may mean that this isn't feasible and more thought has to go into it and might end up not being throw-away.

    Cheers - L~R

      damn sweet. Those few lines made my day today (at least thus far -- its only noon here). Sheer elegance.
Re: hash or nest loop
by doowah2004 (Monk) on Sep 20, 2004 at 13:47 UTC
    I am sure that a lot of people can offer a better, cleaner and more efficient solution, but a couple of simple loops should do the trick.

    open (FILE1, "<$file1"); @lines1 = <FILE1>; close (FILE1); open (FILE2, "<$file2"); @lines2 = <FILE1>; close (FILE1); open (FILE3, ">$file3"); foreach $line1(@lines1) { chomp $line1; ($x1,$y1,$z1) = split (/ /,$line1); foreach $line2(@lines2) { chomp $line2; ($x2,$y2,$z2) = split (/ /,$line2); print FILE3 $x1 - $x2 . "\n"; } } close (FILE3);


    This code is not tested, and lacks the appropriate my,our... but it should give you a good idea of one method to tackle the problem.

    Cameron
Re: hash or nest loop
by dragonchild (Archbishop) on Sep 20, 2004 at 13:58 UTC
    Your requirements:

    I need to take the first x co-ord in file 1, and substract the x value in file 2 from it - repeat for all x values in file 2.

    My code:

    use strict; use warnings; $|++; use constant X => 0; use constant Y => 1; use constant Z => 2; # take the first x co-ord in file 1 my @f1_coords = do { my $filename = 'file1'; open( my $fh, "<$filename" ) or die "Cannot open '$filename' for reading: $!\n"; my $line = <$fh>; close $fh; split( ' ', $line ); }; # substract the x value in file 2 from it - repeat for all x values in + file 2 my $filename = 'file2'; open( my $fh, "<$filename" ) or die "Cannot open '$filename' for reading: $!\n"; my $outname = 'file3'; open( my $out_fh = ">$outname" ) or die "Cannot open '$outname' for writing: $!\n"; while (my $line = <$fh>) { my @f2_coords = split( ' ', $line ); print $out_fh $f1_coords[X] - $f2_coords[X], $/; } close $out_fh; close $fh;

    You will want to read through my code a few times. It contains a ton of Perl idioms that may help you learn your way. Enjoy!

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: hash or nest loop
by Jasper (Chaplain) on Sep 20, 2004 at 14:42 UTC
    Seems to me it's much more simple to just (mostly pseudo-code)
    # open FILE1 and FILE2 my ($f1, $f2); while (($f1 = <FILE1>) && ($f2 = <FILE2>) { # split and subtract and print with $f1 and $f2 as in other suggesti +ons. } # close all.
    This way, while you do have two (probably three, with the printing and all) filehandles open, you don't have to slurp any of them.
      Jasper,
      I am not sure if you looked at the desired output, but the AM said all the x values from file 2 subtracted from just the first x value in file 1. Your proposed solution would be corresponding x values, which I do not believe is desired.

      Cheers - L~R

      but i guess the above is only useful if both files are of same size?