102 lines
3.9 KiB
PowerShell
102 lines
3.9 KiB
PowerShell
function Test-Palindrome ( [String]$String )
|
|
{
|
|
# Default value
|
|
$IsPalindrome = $True
|
|
|
|
# For each position in the string from the start to the middle
|
|
ForEach ( $Index in ( 0..($String.Length -shr 1 ) ) )
|
|
{
|
|
# Check if the character at this position matches the corresponding character at the other end
|
|
$IsPalindrome = $IsPalindrome -and $String[$Index] -eq $String[$String.Length - $Index - 1]
|
|
}
|
|
|
|
return $IsPalindrome
|
|
}
|
|
|
|
function Get-LychrelNumbers ( [int]$Upto, [int]$IterationLimit = 500 )
|
|
{
|
|
# Initialize empty collections
|
|
# (More typically, PowerShell will use Arrays, but we are using
|
|
# ArrayLists here to optimize speed and memory usage.)
|
|
$Seeds = New-Object System.Collections.ArrayList
|
|
$Related = New-Object System.Collections.ArrayList
|
|
$Palindromes = New-Object System.Collections.ArrayList
|
|
|
|
# For each integer in the test range...
|
|
ForEach ( $N in [bigint]1..[bigint]$Upto )
|
|
{
|
|
# If N was already identified as a related Lychrel in another
|
|
# Lychrel series, we don't need to test it
|
|
If ( $N -notin $Related )
|
|
{
|
|
# Default value
|
|
$IsRelated = $False
|
|
|
|
# Initialize empty collection
|
|
$NSeries = New-Object System.Collections.ArrayList
|
|
|
|
# Starting at N
|
|
$S = $N
|
|
|
|
# Convert S to a string for testing and processing
|
|
$SString = $S.ToString()
|
|
|
|
# For each iteration up to the maximum...
|
|
# (Generally we would not use ForEach with Break for a loop with
|
|
# these requirements, but this script is optimized for speed
|
|
# and ForEach ( $x in $y ) is the fastest loop in PowerShell.)
|
|
ForEach ( $i in 1..$IterationLimit )
|
|
{
|
|
# Add the reverse of S to S
|
|
$S += [bigint]($SString[($SString.Length)..0] -join '' )
|
|
|
|
# If S appears in the series of a smaller seed Lychrel
|
|
If ( $S -in $Related )
|
|
{
|
|
# S is a related Lychrel; exit processing loop
|
|
$IsRelated = $True
|
|
Break
|
|
}
|
|
|
|
# Convert S to a string for testing and processing
|
|
$SString = $S.ToString()
|
|
|
|
If ( Test-Palindrome $SString )
|
|
{
|
|
Break
|
|
}
|
|
|
|
# Add S to the series we are testing
|
|
# (for possible inclusion as a related number if N turns out to be a seed)
|
|
$NSeries.Add( $S )
|
|
}
|
|
|
|
# If series did not terminate before the iteration limit...
|
|
# (Including if we stopped early because it join up with an earlier non-terminating series)
|
|
If ( $IsRelated -or $i -eq $IterationLimit )
|
|
{
|
|
# Add everything in the series above N to the list of related Lychrel numbers
|
|
$Related.AddRange( $NSeries )
|
|
|
|
# If N is a related Lychrel number, add it to the list
|
|
If ( $IsRelated ) { $Related. Add( $N ) }
|
|
|
|
# Otherwise add it to the list of Seed Lychrel numbers
|
|
Else { $Seeds. Add( $N ) }
|
|
|
|
# If N is a palindrome, add it to the list of palindrome Lychrel numbers
|
|
If ( Test-Palindrome $N ) { $Palindromes.Add( $N ) }
|
|
}
|
|
}
|
|
}
|
|
|
|
# Convert the various arraylists of big integers to arrays of integers and assign
|
|
# them as properties of a custom return object. Filter out those Related Lychrel
|
|
# numbers which exceed our search range.
|
|
$LychrelNumbers = [pscustomobject]@{
|
|
Seeds = [int[]]$Seeds
|
|
Related = [int[]]$Related.Where{ $_ -le $Upto }
|
|
Palindromes = [int[]]$Palindromes }
|
|
|
|
return $LychrelNumbers
|
|
}
|