http://qs321.pair.com?node_id=950374

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

Hi everyone, I am a beginner to programming and perl. I have a hash (a=>2, b=>1, c=>5, d=>3, e=>4); all i have to do is take a string and slide through the string and calculate the i+(i+3) value and print it. Forgive me I make it so complex so i coudn't paste the entire code. Plz help me. Here is the pseudo code

%hash = (a=>2, b=>1, c=>5, d=>3, e=>4); $input = "abcdaeec"; $calculate = $i+($i+n) of $input; #where n = 2 or 3 (sliding window:- #like a+c b+d c+a d+e a+e e+c 2+5 1+3 5+2 3+4 2+4 4+5) prints= 7 4 7 7 6 9

Replies are listed 'Best First'.
Re: Sliding window
by Eliya (Vicar) on Jan 27, 2012 at 14:59 UTC

    As I understand your task (which seems to be different from BrowserUk), this should do it:

    #!/usr/bin/perl -w use strict; my %hash = (a=>2, b=>1, c=>5, d=>3, e=>4); my $input = "abcdaeec"; for (2, 3) { print "n=$_: "; my $n = $_ - 1; my @sums; while ( $input =~ /(.)(?=.{$n}(.))/g ) { push @sums, $hash{$1} + $hash{$2}; } print "@sums\n"; } __END__ n=2: 7 4 7 7 6 9 n=3: 5 3 9 7 7

    Update: let YAPE::Regex::Explain explain what the regex does:

    use YAPE::Regex::Explain; print YAPE::Regex::Explain->new( qr/(.)(?=.{1}(.))/ )->explain; __END__ The regular expression: (?-imsx:(.)(?=.{1}(.))) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- ( group and capture to \1: ---------------------------------------------------------------------- . any character except \n ---------------------------------------------------------------------- ) end of \1 ---------------------------------------------------------------------- (?= look ahead to see if there is: ---------------------------------------------------------------------- .{1} any character except \n (1 times) ---------------------------------------------------------------------- ( group and capture to \2: ---------------------------------------------------------------------- . any character except \n ---------------------------------------------------------------------- ) end of \2 ---------------------------------------------------------------------- ) end of look-ahead ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------

    And see perlop for what m//g does in scalar context (like the while (...) here).

Re: Sliding window
by choroba (Archbishop) on Jan 27, 2012 at 14:22 UTC
    This can help you to implement the sliding window:
    $s = "abcdef"; print "$1,$2\n" while $s =~ /(.)(?=.(.))/g;
    Update: Using while instead of for to simplify getting the pairs.
Re: Sliding window
by BrowserUk (Patriarch) on Jan 27, 2012 at 14:47 UTC

    "Sliding window" is a decptive title, but the problem is interesting.

    A not very perlish solution:

    #! perl -slw use strict; my %hash = (a=>2, b=>1, c=>5, d=>3, e=>4); my $input = "abcdaeec"; our $N //= 2; $,= ' '; print map{ my $iplus = ord() - ord('a'); $iplus = ( $iplus + $N ) % keys %hash; $iplus = chr( ord('a') + $iplus ); $hash{ $_ } + $hash{ $iplus }; } split '', $input; __END__ C:\test>junk41 -N=2 7 4 9 5 7 5 5 9 C:\test>junk41 -N=3 5 5 7 4 5 9 9 7 C:\test>junk41 -N=4 6 3 6 8 6 7 7 6

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

Re: Sliding window
by JavaFan (Canon) on Jan 27, 2012 at 15:21 UTC
    my %hash = (a=>2, b=>1, c=>5, d=>3, e=>4); my $input = "abcdaeec"; my @input = split //, $input; for my $w (2, 3) { for (my $i = $w; $i < @input; $i++) { printf "%s+%s = %d+%d = %d\n", $input[$i-$w], $input[$i], $hash{$input[$i-$w]}, $hash{$input[$i]}, $hash{$input[$i-$w]} + $hash{$input[$i]}; } } __END__ a+c = 2+5 = 7 b+d = 1+3 = 4 c+a = 5+2 = 7 d+e = 3+4 = 7 a+e = 2+4 = 6 e+c = 4+5 = 9 a+d = 2+3 = 5 b+a = 1+2 = 3 c+e = 5+4 = 9 d+e = 3+4 = 7 a+c = 2+5 = 7
Re: Sliding window
by repellent (Priest) on Jan 29, 2012 at 00:28 UTC
    my %hash = (a=>2, b=>1, c=>5, d=>3, e=>4); my $input = "abcdaeec"; my @v = map $hash{$_}, (split //, $input); for my $n (2, 3) { my @w = map $v[$_] + $v[$_ + $n], 0 .. $#v - $n; print "@w\n"; } __END__ 7 4 7 7 6 9 5 3 9 7 7