Reputation: 1067
I have a string of digits. Say for eg: "234615". Now I should flip the digits between the first lowest digit and second lowest digit.
From the above string, first lowest digit is "1" and second lowest digit is "2". The digits between the first lowest digit and second lowest digit are "346". Now, this "346" should be written as "643".
Hope I stated the problem clearly.
Here is the code I tried,
my $a = "234615";
my @g = split("", $a);
@g = sort(@g);
my $first = $g[0];
my $second = $g[1];
print "$first \t $second\n\n";
for(my $i = 0; $i < $#g; $i++) {
if ($g[$i] == $first) {
}
if ($g[$i] == $second) {
}
}
I above code can find first lowest digit and second lowest digit. But I am not sure about the reverse part.
Can some one help me in this?
Thanks in advance !!
Upvotes: 1
Views: 1524
Reputation: 1
print "Enter the String to be reversed : ";
$name = <STDIN>;
chomp $name;
@array = split(undef,$name);
$len = length($name);
for($i=$len; $i>=0; $i--)
{
print "@array[$i]";
}
Upvotes: -1
Reputation: 67900
If I understood your question correctly, you could do something like this:
perl -lwe '$_ = 234615;
@a = /\pN/g;
my ($n1,$n2) = (sort @a)[0,1];
s/$n2.*?$n1/reverse $&/e;
print;'
Which produces the output 164325
. The full code for this oneliner is:
use strict;
use warnings;
$_ = shift; # first arg is the number
my @digits = /\pN/g; # extract digits
my($n1, $n2) = (sort @digits)[0, 1]; # take the two lowest
s/$n2.*?$n1/reverse $&/e; # reverse digits using /e
print;
As you can see, it depends on $n1
and $n2
appearing in the specified order, e.g. 2 ... 1. This can of course be reversed, but is hardcoded. If you need it to be flexible, e.g. either 1 ... 2 OR 2 ... 1, it becomes more complicated.
You could do something like this:
if (/$n2.*?$n1/ { # if $n2 appears first
s/$n2.*?$n1/reverse $&/e;
else {
s/$n1.*?$n2/reverse $&/e;
}
The benefit of using a regex instead of a split to extract the numbers is that you do not risk having any non-digits in your input. The reverse procedure is done by matching the entire string 23461
and reversing it, using the reverse()
function inside an evaluation inside the substitution (/e
option). The sort is the default sort, which will work when dealing with single digits.
Upvotes: 2
Reputation: 286
Another way:
my $a = "234615";
my @g=split("",$a);
@g=sort(@g);
my $first=$g[0]; my $second=$g[1];
my @ar = split(/($first|$second)/,$a);
$ar[2] = reverse($ar[2]);
print join("",@ar)."\n\n";
returns 264315 too
edit after I am's update:
use Data::Dumper;
my $a = "234615";
my @g=split("",$a);
@g=sort(@g);
my $first=$g[0]; my $second=$g[1];
my @ar = split(/($first|$second)/,$a);
my @result;
push(@result,
$ar[0],
$ar[1].$ar[2].$ar[3],
$ar[4]);
$result[1] = reverse($result[1]);
print join("",@result)."\n\n";
returns 164325
Upvotes: 2
Reputation: 126722
The program below will do what you need, as long as the digits in the string never occur more than once. If either of the lowest values occur multiple times then you need to define which of them delmits the substring that must be reversed.
It starts by putting a sorted list of the digits into @sorted
, much as your own program does. Then it takes the first two of those digits, uses map
with index
to convert them into a pair of offsets into the string, sorts them so that the first is the earliest is first, and then does the replacement.
The for
is there to avoid the need to call substr
twice. It aliases the required substring with $_
and just reverses it in-place.
use strict;
use warnings;
my $str = '234615';
my @sorted = sort split //, $str;
my @indices = sort { $a <=> $b } map { index $str, $_ } @sorted[0,1];
for (substr $str, $indices[0] + 1, $indices[1] - $indices[0] - 1) {
$_ = reverse $_;
}
print $str;
output
264315
Upvotes: 1