
Solution to Event 2 in the 2008 Winter Scripting Games Sudden Death Challenge.
We included this event in our Sudden Death Challenge in part because we were interested to see how people decided to tackle the problem. To us the solution seemed obvious; however, we know that there are a lot of creative people out there who see things differently than the Scripting Guys see them. (Which, needless to say, is definitely not a bad thing.) We were curious how other people would approach this problem; on top of that, we knew we’d get to see some very interesting – and very original – scripts.
Hey, even the Scripting Guys occasionally do something for their own benefit.
At any rate, here’s the script that we came up with. As will be the case throughout the Sudden Death Challenge, we’ll show you only a VBScript soltuion; however, this event could have just as easily been resolved using Windows PowerShell or Perl:
Const ForReading = 1
Dim arrFileLines()
i = 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Vertical.txt", ForReading)
Do Until objFile.AtEndOfStream
Redim Preserve arrFileLines(i)
arrFileLines(i) = objFile.ReadLine
i = i + 1
Loop
objFile.Close
For i = 1 to 4
For Each strLine in arrFileLines
strCharacters = strCharacters & Mid(strLine, i, 1)
Next
Next
Wscript.Echo strCharacters
As we said, this was actually a fairly easy event to complete, provided you took a moment to think about it. Once you did that, the pieces should have all fallen into place.
If those pieces didn’t fall into place, well, let’s explain how we managed to solve the puzzle. To begin with, we define a constant named ForReading and set the value to 1; we’ll use this constant when we open the text file C:\Scripts\Vertical.txt. We then do two more quick housekeeping chores: we initialize a dynamic array named arrFileLines, and we set the value of a counter variable named i to 0.
With our housekeeping tasks out of the way we create an instance of the Scripting.FileSystemObject object, then use this line of code to open the file Vertical.txt for reading:
Set objFile = objFSO.OpenTextFile("C:\Scripts\Vertical.txt", ForReading)
At this point there are several different ways we could have solved this problem. The approach we settled on involves reading the file line-by-line and storing each line as a separate item in our dynamic array; that makes it easy for us to go through each line in the text file and grab the desired character from those lines. (More on that in a moment.)
In order to do all that we first set up a Do Until loop that runs until we reach the end of the file. (Or, to put it a bit more technically, that runs until the file’s AtEndOfStream property is True.) Inside the loop, we use the Redim Preserve statement to redimension our array, making the array the same size as the counter variable i. Because i is currently 0, that gives us an array of size 0; in other words, an array that can hold one item. And what item is that array going to hold? It’s going to hold the first line in the text file, something we can retrieve using the ReadLine method:
arrFileLines(i) = objFile.ReadLine
From there we increment the value of i by 1, then repeat the process with the second line in the text file. (Which will become the second item in the array.) And so on.
When we’ve finished with the text file (and used the Close method to close that file), the array arrFileLines will contain the following items:
T Sg hWc eirG nia 2tpm 0ete 0ris 8 n!
In other words, we have an array of 8 items, with each item containing 4 characters:
T | S | g | |
h | W | c | |
e | i | r | G |
n | I | a | |
2 | t | p | m |
0 | e | t | e |
0 | r | I | s |
8 | n | ! |
If you look closely at the preceding grid you can see there’s an easy solution to our problem. Suppose we take the first character from each item in the array and string them together; that would give us a string equal to this:
The 2008
Now, what if we take the second character in each item and tack that onto the end of our string? That’s going to give us this:
The 2008 Winter
You can probably see where we’re going with this. If we next grab the third character from each item and then the fourth character from each item we’ll end up with this:
The 2008 Winter Scripting Games!
Which is pretty much what we want to end up with.
So how do we go about grabbing these characters? Well, to begin with, we set up a For Next loop that runs from 1 to 4, the 4 representing the four character positions in each array item:
For i = 1 to 4
Inside that For Next loop we then set up a For Each loop, a loop that will cycle through each item in the array:
For Each strLine in arrFileLines
Inside that loop we grab the first character from each line and append it to a variable named strCharacters; that’s what this line of code is for:
strCharacters = strCharacters & Mid(strLine, i, 1)
And what happens after we finish grabbing character 1 from each array item? That’s right: we then go back to the top of our For Next loop and repeat the process, this time grabbing character 2 from each item in the array. By the time we’re done, strCharacters will be equal to this:
The 2008 Winter Scripting Games!
You know what? Event 2 in the Sudden Death Challenge might be the easiest point you’ll ever earn.