2008 Winter Scripting Games

Solution to Advanced Perl Event 9: You're Twisting My Words

Event 9 Solution


Perl solution to Event 9 in the 2008 Winter Scripting Games.

Solutions are also available for VBScript and Windows PowerShell.

*

You’re Twisting My Words


Sometimes you just have to have faith. For example, the Scripting Guys added Event 9 to the 2008 Winter Scripting Games without having the slightest idea if it was even possible to solve this event using Perl; that’s because we had no idea how to go about reversing a string in Perl. Fortunately for us, our faith was rewarded: not only were we able to solve the event using Perl, but we were able to do so using a minimal amount of code:

open (TextFile, "C:\\Scripts\\Alice.txt");
@arrTextFile = <TextFile>;
close (TextFile);

$strFile = @arrTextFile[0];

chomp($strFile);

@arrWords = split(' ',$strFile);

$x = @arrWords;

for ($i = 0; $i < $x; $i ++) 
    {
        $strValue = @arrWords[$i];
        $strValue = reverse $strValue;
        @arrWords[$i] = $strValue;
    }

$strNewContents = join(" ",@arrWords);

print $strNewContents;

As you can see, what little code we did write starts off by using these lines to open the text file C:\Scripts\Alice.txt:

open (TextFile, "C:\\Scripts\\Alice.txt");
@arrTextFile = <TextFile>;
close (TextFile);

If you’re new to Perl (which you probably aren’t considering the fact that this is the Advanced division), in line 1 we use the open function to open the file Alice.txt, giving this file the reference TextFile. Notice, too that we had to “escape” each \ in our file path, prefacing the \ character with a second \. We have to do that because the \ is a reserved character in Perl.

In line 2, we read in the entire contents of the file, storing those contents in an array named @arrTextFile. Because the file Alice.txt contains only a single line of text, that means that @arrTextFile will contain only a single item: that one line of text. And then in line 3 we simply close the file.

Although we have only one line in the file, this line still gets stored as an item in an array. In order to make this line of text easier to work with, we next use this line of code to assign the first item (item 0) in the array to a string variable named $strFile:

$strFile = @arrTextFile[0];

After using the chomp function to remove the linebreak at the end of $strFile, we then use the split function to split $strFile into an array named @arrWords:

@arrWords = split(' ',$strFile);

By splitting on the blank space, we effectively take each word in Alice.txt and make it a separate item in the array @arrWords. For example, $strFile looks like this (with some line breaks added in to make sure this displays correctly on the Web):

'Curiouser and curiouser!' cried Alice (she was so much surprised, that 
for the moment she quite forgot how to speak good English); 'now I'm 
opening out like the largest telescope that ever was! Good-bye, feet!'
(for when she looked down at her feet, they seemed to be almost out of 
sight, they were getting so far off). 'Oh, my poor little feet, I 
wonder who will put on your shoes and stockings for you now, dears? I'm 
sure _I_ shan't be able! I shall be a great deal too far off to trouble 
myself about you: you must manage the best way you can; --but I must be 
kind to them,' thought Alice, 'or perhaps they won't walk the way I 
want to go! Let me see: I'll give them a new pair of boots every 
Christmas.'

Splitting on the blank space gives us an array that starts out like this:

'Curiouser 
and 
curiouser!' 
cried 
Alice

Is that useful? You bet it is. As you might recall, our task is to reverse the letters in each individual word (counting punctuation marks as part of the word), all the while maintaining the order of those words. Now that we’ve isolated each word it should be very easy to reverse the letters in each word without doing anything to change the order of those words.

How easy should it be? This easy: after assigning the number of items in the array to the variable $x, we set up a for loop that starts at 0 and continues to run as long as the counter variable $i is less than the number of items in the array:

for ($i = 0; $i < $x; $i ++)

Inside the loop, we grab an item from the array and assign its value to the variable $strValue:

$strValue = @arrWords[$i];

Needless to say, the first time through the loop we’ll grab the first item in the array; that’s because our counter variable $i starts off equal to 0, and the first item in an array always has an index number of 0. After that, we then use the reverse function to reverse the order of all the characters in $strValue:

$strValue = reverse $strValue;

What’s that going to do? That’s going to take our first item in the array -- 'Curiouser – and turn it into this:

resuoiruC'

In other words, it’s going to reverse all the characters in the string. We’ll then take this reversed value and assign it back the first item in the array:

@arrWords[$i] = $strValue;

And then it’s back to the top of the loop where we repeat this process with the next item in the array (that is, the next word in the file). When we’re all done, the array @arrWords is going to look something like this:

resuoiruC' 
dna 
'!resuoiruc 
deirc 
ecilA

At this point we’re just about finished. We now use the join function to take the items in the array and recombine them into a new string value ($strNewContents), taking care to separate each item (word) with a blank space:

$strNewContents = join(" ",@arrWords);

And then we simply print out the value if $strNewContents. Assuming everything went right (and there’s no reason to think that it wouldn’t), that should give us output that looks like this:

resuoiruC' dna '!resuoiruc deirc ecilA ehs( saw os hcum ,desirprus that
rof eht tnemom ehs etiuq togrof woh ot kaeps doog ;)hsilgnE won' m'I 
gninepo tuo ekil eh t tsegral epocselet taht reve !saw ,eyb-dooG '!teef 
rof( nehw ehs dekool nwod ta reh ,teef yeht demees ot eb tsomla tuo fo 
,thgis yeht erew gnitteg os raf .)ffo  ,hO' ym roop elttil ,teef I 
rednow ohw lliw tup no ruoy seohs dna sgnikcots rof  uoy ,won ?sraed m'I 
erus _I_ t'nahs eb !elba I llahs eb a taerg laed oot raf ffo ot elbuort 
flesym tuoba :uoy uoy tsum eganam eht tseb yaw uoy ;nac tub-- I tsum eb 
dnik ot ',meht thguoht ,ecilA ro' spahrep yeht t'now klaw eht yaw I 
tnaw ot !og teL em :ees ll'I evig meht a wen riap fo stoob yreve 
'.samtsirhC

These are the same words, in the same order, as we started with. The only difference is that we reversed the order of all the characters in each individual word.

Cool, huh?


Top of pageTop of page