user1539348 user1539348 - 2 months ago 10
Perl Question

Perl how to circular shift some characters / bits?

what is a good approach to circular shifting some characters / bit in perl?

Example (reversing character strings):

1010
1110
hello


Result:

0101
0111
olleh


Thanks!

Answer

However, if you really want to circular shift values, it's easy to write a function that does it with arbitrary lists for training:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

# circular shift lists
sub circular {
    my ($i, @values) = @_;
    return @values[ map +($_ + $i) % @values => 0 .. $#values ];
}

say circular  4, 1 .. 9;                # 567891234
say circular -2, 1 .. 9;                # 891234567
say circular  3, split '' => 'hello';   # lohel

A few words of explanation for the return line of circular:

return @values[ ... ];

We're returning an array slice of @values here, which means we evaluate it with a list of indices and return the list of values.

map ... => 0 .. $#values

We're returning a list of values here that we calculate from all indices of @values, 0 is the first, $#values is the last.

+($_ + $i) % @values

This is what we do with these indices. The + sign is only used to tell perl that the parantheses are not the argument paratheses for map. We add $i to the index and to prevent that it becomes > $#values we modulo divide it by the length of @values. Note that it's not important to call length @values here because % evaluates its second operand in scalar context and arrays in scalar context evaluate to their length.

I leave it up to you as a simple exercise to convert your things like hello or 1110 to lists and back to scalars.