Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Simple Logic Problem with Perl

by Anonymous Monk
on Oct 19, 2005 at 09:30 UTC ( [id://501231]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Sir,
I have the following problem, which I really don't know how to deal with it. Look at my hopeless code:
# col1 col2 index my $sample1 = ['str1 str2 1', 'str3 str4 2', 'str5 str6 3', 'str7 str8 4', 'str9 str10 5']; my $sample2 = ['str1 str2 0', 'str3 str4 4']; my $sample3 = ['str1 str2 3', 'str3 str4 4'];
The intended result for each sample is like this:
$result_spl1 = [ 'str1', 'str3', 'str5', 'str7', 'str9', 'str10' ]; $result_spl2 = [ 'str1', 'str2', 'str3', 'str4', ]; $result_spl3 = [ 'str1', 'str3', 'str4', ];
The flow/logic of the algo is like this:
In each sample
  • If the index difference of two consecutive sample is 1 take the first colum of the first string PLUS the 2nd column - last one- of the last string.
  • If the difference of two consecutive sample is >1 take all the colum in between
What's wrong with my code below? Such that I still can't get those result? How can I fix it? Is there a better way to achieve the result than my approach:
use Data::Dumper; get_column($sample1); sub get_column { my $ar = shift; my $all; foreach my $str ( @{$ar} ) { my @ar = (split " ",$str)[0,1,2]; push @$all, [ @ar ]; } my @clean; my $flag = $all->[0][2]+1; my $idx; my $diff; push @clean, $all->[0][0],$all->[0][1]; foreach my $i ( 1 .. @$all-1 ) { $idx = $all->[$i][2]; $diff = abs($idx-$flag); if ( $diff == 1 ) { push @clean, $all->[$i][1]; } else { push @clean, $all->[$i][0],$all->[$i][1]; } $flag = $idx; } print Dumper \@clean ; return ; }

Replies are listed 'Best First'.
Re: Simple Logic Problem with Perl
by CountZero (Bishop) on Oct 19, 2005 at 10:27 UTC
    I'm not sure if your results and algorithm are in step:
    If the index difference of two consecutive sample is 1 take the first colum of the first string PLUS the 2nd column -last one- of the last string.

    In your first sample, the index of the first item is 1 and the index of the second item is 2, so the difference is 1 and this rule applies.

    We then take the first colum of the first string, which is str1, PLUS the 2nd column -last one- of the last string. Here I'm already stuck: there are three columns, so the second one cannot be the last one. We will assume you mean col2, so the second item in your output should be str4. But in your result it shows str3. Assuming that your results are correct your description of the algorithm must be wrong or I have misunderstood it.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      Dear Sir,

      I'm terribly sorry if my description was not clear. You are right about my statement above, it was not precise, the first one it should be:
      If the index difference of two consecutive elements of the array is 1 take the 1st colum of all the array i.e  $sample->[0] .. $sample->[-1] PLUS the 2nd column of the last element of the array   $sample->[-1].
      Let me give you the illustration of how I get the result. Basically those enclosed with bar (|) and dash (_) are the one which get selected. Notice also the index difference change.
      my $sample1 |str1 |index = 1 |str3 |index = 2 |str5 |index = 3 |str7 |index = 4 | |_______________ |str9 str10 index = 5 |______________________ my $sample2 |str1 str2 | index = 0 |_________ | |str3 str4 | index = 4' |__________| my $sample3 |str1 | index = 3 | |_________ |str3 str4 index = 4 ____________________ my $sample4 = |str1 | index = 1 |str3 | index = 2 |str5 | index = 3 | |______________ |str7 str8 index = 4 ____________________ |str7 str8 | index = 4 |__________| |str9 str10| index = 6 ___________
      I hope it's clear to you now
Re: Simple Logic Problem with Perl
by tphyahoo (Vicar) on Oct 19, 2005 at 14:31 UTC
Re: Simple Logic Problem with Perl
by jdporter (Paladin) on Oct 19, 2005 at 14:21 UTC
    What about in a situation like the following:
    my $sample6 = ['str1 str2 1', 'str3 str4 5', 'str5 str6 6'];
      Thanks so much for your respons, Mr.jdporter.
      If that's the case the result will be:
      my $sample6 = |str1 str2 |index = 1 |__________| |str3 str4 |index = 5 |str3 str4| index = 5 |_________| |str5 str6| index = 6 $output_sample6 = [ $str1, $str2, $str3, $str4, $str3, $str4, $str5, $str6, ];
      I truly don't know how to go about it.
      Thanks and hope to hear from you.
Re: Simple Logic Problem with Perl
by Anonymous Monk on Oct 19, 2005 at 09:39 UTC
    Sorry there is another case when there is a tie like this:
    my $sample4 = ['str1 str2 1', 'str3 str4 2', 'str5 str6 3', 'str7 str8 4', 'str9 str10 6'];
    The result is this:
    $result_spl4 = [ 'str1', 'str3', 'str5', 'str7', 'str8', 'str10' 'str7', 'str8', 'str10' ];
    In principle the algo above is applied separately to those two tie area.

    Truly sorry for missing out this one. Thanks so much, cause I don't know who to turn to.
      That doesn't look right. I think it should be
      $result_spl4 = [ 'str1', 'str3', 'str5', 'str7', 'str8', 'str7', 'str8', 'str9' 'str10' ];

      What am I missing?

      We're building the house of the future together.
Re: Simple Logic Problem with Perl
by pajout (Curate) on Oct 19, 2005 at 09:49 UTC
    I am sorry for my English, but I am not able to understand your output conditions.
Re: Simple Logic Problem with Perl
by sauoq (Abbot) on Oct 19, 2005 at 20:27 UTC

    After reading your initial post a few times and looking at the responses and your followups, it seems to me that your real problem here is that you don't understand your problem well enough to explain it thoroughly.

    The two closest things you gave us to a spec were the following descriptons:

    • If the index difference of two consecutive sample is 1 take the first colum of the first string PLUS the 2nd column - last one- of the last string.
    • If the difference of two consecutive sample is >1 take all the colum in between
    If the index difference of two consecutive elements of the array is 1 take the 1st colum of all the array i.e $sample->[0] .. $sample->[-1] PLUS the 2nd column of the last element of the array $sample->[-1].
    Both of which seem to suffer from a lack of clarity. It might help you to describe the problem better if you try to be precise with the language you use. Saying things like 'PLUS' when you don't actually mean addition could be counterproductive here. Also, your "samples" are strings but you talk about their "difference" as an integer. Presumably, you mean the difference of what you are calling their "indexes" but that's ambiguous because they are in an array and array elements already have an "index". You are also using "last" ambiguously. Are you referring to the last string in the array or the last of the two you've taken? (I think you tried to clear that up, but are you done at that point or what?) And, you are talking about things like "first column of the first string" but your code actually turns those strings into arrays at the outset so your description fails to match your code.

    The first thing I'd do is abstract away the format of your data in your presentation of the problem. It doesn't matter whether they are whitespace separated substrings, hashes, multidimensional arrays, or objects with member variables. As it is, your code quickly turns the strings into mulidimensional arrays anyway. That's fine but if you are going to do that, it might be helpful to use constants for the indices. (They'll be easier to remember than 0, 1, and 2.) Alternatively, use a hash and name the columns. There's a little more overhead but it might make for clearer code. You can always change it later if it's actually an issue. The important thing is to get a handle on what you are doing.

    Secondly, I'd change my way of labeling the columns, in particular I would call your third column something other than "index" to avoid the term overlapping with Perl's notion of "index". Maybe "position" or "id" would work. I don't know how to rename "col1" and "col2" but, as is, they don't visually stand out from each other. I'll use 'X' and 'Y' instead but expect you could come up with something better.

    Putting that together, I'd try to start explaining the problem with a data structure that looked more like this...

    $sample = [ { X => 'str1', Y => 'str2', position => 1 }, X => 'str3', Y => 'str4', position => 2 }, X => 'str5', Y => 'str6', position => 3 }, X => 'str7', Y => 'str8', position => 4 }, X => 'str9', Y => 'str10', position => 5 } ];
    And that would allow you to be very specific in your explanation of the problem.

    You could start by saying something like... "I need a function which will take an array reference like $sample shown above and which will return an array reference like $result" (here filling in what $result looks like.) And then you can fill in the details about how you need to construct $result by referring to the actual sample data, $sample, that you provided.

    In other words, you'll be able to refer to values like $sample->[0]{position} - $sample[1]{position} and you'll be able to say things like push $sample[0]{X} onto @$result without there being any question what you actually mean.

    If you take the time to describe your problem clearly, you might very well figure it out on your own. And, if it is still giving you trouble, it will be much easier for others to get a handle on what you want and provide you with advice. I, for one, have no idea what you are trying to accomplish because I see a lot of ambiguity and a general lack of clarity in the way you've presented your problem and I haven't seen much improvement in your follow-ups.

    † Note the similarity to the word specification.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Simple Logic Problem with Perl
by JamesNC (Chaplain) on Oct 19, 2005 at 23:19 UTC
    Here's my stab at it:
    use strict; use warnings; use Data::Dumper; my $sample1 = ['str1 str2 1', 'str3 str4 2', 'str5 str6 3', 'str7 str8 4', 'str9 str10 5']; my $sample2 = ['str1 str2 0', 'str3 str4 4']; my $sample3 = ['str1 str2 3', 'str3 str4 4']; get_column($sample1); sub get_column { my $ar = shift; my $all; foreach my $str ( @{$ar} ) { my @ar = (split " ",$str); push @{$all}, [ @ar ]; } my @clean; my $diff; foreach my $i ( 1..$#{$all} ) { $diff = abs($all->[$i][2]- $all->[$i-1][2] ); print "$i\t$diff\n"; if ( $diff == 1 ) { push @clean, $all->[$i-1][0]; } if ( $diff > 1 ) { push @clean, $all->[$i-1][0], $all->[$i-1][1], $all->[$i][ +0], $all->[$i][1]; } if( $diff == 1 && $i == $#{$all} ){ push @clean, $all->[$i][0], $all->[$i][1]; } } print Dumper \@clean; return ; }

    JamesNC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://501231]
Approved by g0n
Front-paged by monkfan
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (9)
As of 2024-04-23 10:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found