PowerShellで総当り

紛れもない普通の総当たりです……。Non Determinism - Rubyのある風景で紹介されている、

Baker, Cooper, Fletcher, MillerとSmithは五階建てアパートの異なる階に住んでいる。Bakerは最上階に住むのではない。Cooperは最下階に住むのではない。 Fletcherは最上階にも最下階にも住むのではない。MillerはCooperより上の階に住んでいる。SmithはFletcherの隣の階に住むのではない。FletcherはCooperの隣の階に住むのではない。それぞれはどの階に住んでいるか。

を解きます。


1..5 | % { ( $baker = $_ ) } | % {
1..5 | % { ( $cooper = $_ ) } } | % {
1..5 | % { ( $fletcher = $_ ) } } | % {
1..5 | % { ( $miller = $_ ) } } | % {
1..5 | % { ( $smith = $_ ) } } |
foreach { , @($baker, $cooper, $fletcher, $miller, $smith) } |
where {
($_ | Select-Object -Unique).Count -eq 5 -and
$baker -ne 5 -and
$cooper -ne 1 -and
$fletcher -ne 1 -and $fletcher -ne 5 -and
$miller -gt $cooper -and
[Math]::Abs($smith - $fletcher) -ne 1 -and
[Math]::Abs($fletcher - $cooper) -ne 1
}
ForEach-Objectでパイプをつなぎながら五重にループさせ、パイプの結果は捨てて、それぞれのForEach-Objectブロックのなかで代入しておいた変数を配列にしてます。( $miller = $_ ) が()で括られているのは、ただ代入文を書いておくと値を返さないのに対し、代入文を括弧で括ると値を返す式になるみたいだからです。理由はわかりませんが……。

PS > $x = 0
PS > ($x = 0)
0
PS > $x = $y = 0
PS > ($x = $y = 0)
0
パイプで繋がれたブロックに代入文しかないと、そこでパイプが止まってしまうので、使わないけど値を返すために()で括ってます。