Iron Scripter\2021-02-09 Another PowerShell Math Challenge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-NChooseK | |
{ | |
<# | |
.SYNOPSIS | |
Returns all the possible combinations by choosing K items at a time from N possible items. | |
.DESCRIPTION | |
Returns all the possible combinations by choosing K items at a time from N possible items. | |
The combinations returned do not consider the order of items as important i.e. 123 is considered to be the same combination as 231, etc. | |
.PARAMETER ArrayN | |
The array of items to choose from. | |
.PARAMETER ChooseK | |
The number of items to choose. | |
.PARAMETER AllK | |
Includes combinations for all lesser values of K above zero i.e. 1 to K. | |
.PARAMETER Prefix | |
String that will prefix each line of the output. | |
.EXAMPLE | |
PS C:\> Get-NChooseK -ArrayN '1','2','3' -ChooseK 3 | |
123 | |
.EXAMPLE | |
PS C:\> Get-NChooseK -ArrayN '1','2','3' -ChooseK 3 -AllK | |
1 | |
2 | |
3 | |
12 | |
13 | |
23 | |
123 | |
.EXAMPLE | |
PS C:\> Get-NChooseK -ArrayN '1','2','3' -ChooseK 2 -Prefix 'Combo: ' | |
Combo: 12 | |
Combo: 13 | |
Combo: 23 | |
.NOTES | |
Author : nmbell | |
#> | |
# Use cmdlet binding | |
[CmdletBinding()] | |
# Declare parameters | |
Param | |
( | |
# [ValidateCount(1,9)] | |
[ValidatePattern("^\d$")] | |
[String[]] | |
$ArrayN | |
, [Int] | |
$ChooseK | |
, [Switch] | |
$AllK | |
, [String] | |
$Prefix = '' | |
) | |
BEGIN | |
{ | |
} | |
PROCESS | |
{ | |
# Validate the inputs | |
$nMax = 9 | |
$ArrayN = $ArrayN | Sort-Object -Unique | |
If ($ArrayN.Length -gt $nMax) | |
{ | |
Write-Error "Can't choose from more than $nMax distinct items." -ErrorAction Stop | |
} | |
If ($ChooseK -gt $ArrayN.Length) | |
{ | |
Write-Error "Can't choose $ChooseK items when only $($ArrayN.Length) are available." -ErrorAction Stop | |
} | |
# Track recursion | |
$Depth++ | |
# Control the output | |
$firstK = If ($AllK) { 1 } Else { $ChooseK } | |
# Get combinations | |
$firstK..$ChooseK | ForEach-Object { | |
$thisK = $_ | |
$ArrayN[0..($ArrayN.Length-($thisK--))] | ForEach-Object { | |
Write-Verbose ("Found ($Depth):"+(' '*$Depth)+$_) | |
If ($thisK -eq 0) | |
{ | |
Write-Output ($Prefix+$_) | |
} | |
Else | |
{ | |
Get-NChooseK -Array ($ArrayN[($ArrayN.IndexOf($_)+1)..($ArrayN.Length-1)]) -Choose $thisK -AllK:$false -Prefix ($Prefix+$_) | |
} | |
} | |
} | |
} | |
END | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-StringSum | |
{ | |
<# | |
.SYNOPSIS | |
Gets the sum of the digits from an integer-only string. | |
.DESCRIPTION | |
Gets the sum of the digits from an integer-only string. | |
.PARAMETER InString | |
The input string of digits. | |
.PARAMETER CustomOut | |
Returns a custom object with details of the calculation. | |
.EXAMPLE | |
PS C:\>Get-StringSum -InString '1234' | |
10 | |
.EXAMPLE | |
PS C:\>Get-StringSum -InString '1234' -CustomOut | |
Input Elements Calc Sum | |
----- -------- ---- --- | |
1234 4 1+2+3+4 = 10 10 | |
.NOTES | |
Author : nmbell | |
#> | |
# Use cmdlet binding | |
[CmdletBinding()] | |
# Declare parameters | |
Param | |
( | |
[Parameter( | |
Mandatory = $true | |
, ValueFromPipeline = $true | |
)] | |
[ValidatePattern("^\d{1,10}$")] | |
[String] | |
$InString | |
, [Switch] | |
$CustomOut | |
) | |
BEGIN | |
{ | |
} | |
PROCESS | |
{ | |
$ints = $InString.ToCharArray() | ForEach-Object { [int]::Parse($_) } | |
$sums = $ints | Measure-Object -Sum | |
$calc = "$($ints -join '+') = $($sums.Sum)" | |
Write-Verbose "$InString`: $calc" | |
If ($CustomOut) | |
{ | |
[PSCustomObject]@{ | |
Input = $InString | |
Elements = $sums.Count | |
Calc = $calc | |
Sum = $sums.Sum | |
} | |
} | |
Else | |
{ | |
$sums.Sum | |
} | |
} | |
END | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Intermediate Level
Get-StringSum
Knowing that every string can be treated as an array of characters made the approach a lot simpler here.
Advanced Level
Get-NChooseK
This was a lot more challenging. Most of my brain power was used to come up with an algorithm that would handle the arrays correctly at each level of recursion.
So the final solution is to pipe the output of Get-NChooseK into Get-StringSum: