Tag Archives: string

Silly Saturday PowerShell Palindromes

242px-Sator_Square_at_OppèdeNormally I post amusing PowerShell-related content on Fridays as part of my Friday Fun series. These are light-hearted articles about using PowerShell. Almost always they are not practical but they serve as a learning vehicle. My topic this week seems extra silly so I’m moving it to Saturday. I’m a pushover for alliteration.

Last week I came across a comment on Facebook that involved palindromes. A palindrome is a word that is spelled the same backwards and forwards. Names like Otto and ABBA are palindromes. So are words like madam, civic, and redder. I thought it would be fun to use PowerShell to test if a string was a palindrome. To figure this out I would need to find the midpoint of the string, get the first part of the string and then compare it to the last part of the string, but in reverse order.


PS C:\> $t = "madam"
PS C:\> $mid=[math]::Truncate($t.length/2)
PS C:\> $mid
2

I’m using the Truncate method from the [Math] class so that when I divide the string length by 2, the value is rounded down. This will be important in a moment. Getting the first half of the string is pretty simple.


PS C:\> $start = -join ($t[0..($mid-1)])
PS C:\> $start
ma

I’m getting characters in $t by their index number. In this case going from 0 to the midpoint minus 1. This would give me an array of characters so I regroup them using the -join operator. As an alternative, I could also have done this:


PS C:\> $start = $t.Substring(0,($mid))

Now to get the last half. Remember, I need to get the end of the string in reverse order until I reach the midpoint again. I can use the same technique I used for the front, except this time starting at the end and going backwards.


PS C:\> $end = -join ($t[-1..-($mid)])
PS C:\> $end
ma

Now to compare $start and $end.


PS C:\> $start -eq $end
True

You may be wondering, “What about the ‘d’?” Well, in this case it is irrelevant because going backwards or forwards the ‘d’ is in the same place. I think of these as pivot letters. But this technique also works for strings without a pivot point.


PS C:\> $t="redder"
PS C:\> $mid=[math]::Truncate($t.length/2)
PS C:\> $start = -join ($t[0..($mid-1)])
PS C:\> $end = -join ($t[-1..-($mid)])
PS C:\> $start -eq $end
True
PS C:\> $start
red
PS C:\> $end
red
PS C:\>

So how about a simple function to test if a string is a palindrome?


Function Test-IsPalindrome {
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True)]
[ValidateNotNullorEmpty()]
[string]$Text,
[switch]$IgnoreSpace
)

Process {
Write-Verbose "Testing $Text"
if ($IgnoreSpace) {
Write-Verbose "Removing spaces from text"
$text = $text.Replace(" ","")
Write-Verbose $text
}
$l = $text.length
Write-Verbose "Length is $l"
$mid = [math]::Truncate($l/2)
Write-Verbose "Midpoint is $mid"

#could also use Substring()
$start = -join ($text[0..($mid-1)]) #$text.Substring(0,($mid))
$end = -join ($text[-1..-($mid)])
Write-Verbose "Start: $start"
Write-Verbose "Pivot: $($Text[$mid])"
Write-Verbose "End : $end"
if ($start -eq $end) {
$True
}
else {
$false
}

} #process
} #end Test-IsPalindrome

This is an advanced function so I could add some verbose messages, which is great for troubleshooting and debugging. I also wanted to be able to pipe strings to the function. The intent is to test a string and return True or False. The code is essentially the same thing I showed you, except now it is a little easier to use.


PS C:\> "redder","foo","civic","madam" | Test-IsPalindrome

True
False
True
True

I added an extra feature to strip out spaces.


PS C:\> Test-IsPalindrome "Madam Im Adam" -IgnoreSpace -Verbose
VERBOSE: Testing Madam Im Adam
VERBOSE: Removing spaces from text
VERBOSE: MadamImAdam
VERBOSE: Length is 11
VERBOSE: Midpoint is 5
VERBOSE: Start: Madam
VERBOSE: Pivot: I
VERBOSE: End : madAm
True
PS C:\> Test-IsPalindrome "A nut for a jar of tuna" -IgnoreSpace
True

Yes, this is a silly application of PowerShell. But I hope it gives you an idea of how to use the -Join operator and to work with strings. By the way, I could use these techniques to turn a string into a palindrome.


PS C:\> $text="sum"
PS C:\> -join ($Text, -join $Text[-1..-($Text.length)])
summus

Ok, perhaps not a valid word in English but see if you can follow what the -Join operators are doing and how this snippet works. If you’d like to play with this, you can download Test-IsPalindrome.

Convert to Title Case

After a long holiday break, some travel and a few training classes its time to get back in the swing of things. Today I have a relatively simple function, that if nothing else demonstrates how to use object methods. The challenge is to take a string of text and convert it into title case; so that “great expectations” becomes “Great Expectations”. Continue reading