第1回シェル芸を今度触ろうと思って問題を見たらやってるじゃないですか、FizzBuzz問題。 PowerShellでFizzBuzzとか、今更たっぷりですが先行して挑戦です。 Fizz Buzzをご存じない方は以下から
縛り
まぁPowershellだし、当然の縛りですが…
- ifとか使ってたまるか
- ワンライナーにしたいなー
ソース パターン1
まずできたのがこれでした。 FizzBuzzに該当する箇所の数字と、Fizz/Buzz/FizzBuzzを同列に表示しています。 …え?だめ?………ではパターン2へ…。
1..100 | ForEach-Object {"$_" +@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]} # Aliasで短縮版 1..100 | % {"$_" +@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]}
ソース パターン2
ダメっていわれそうだったので、FizzとBuzzとFizzBuzzの数字は文字に置き換えました。 さっくりワンライナーでかけたのですが……冗長ですね…
1..100 | ForEach-Object {((@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]),$_)[!((@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]))]} # Aliasで短縮版 1..100 | % {((@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]),$_)[!((@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]))]}
ソース パターン3
パターン2を変数にしただけです。 これをワンライナーと呼ぶと怖い方々に怒られそうです。
1..100 | ForEach-Object {$x = @("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]; ($x,$_)[!$x]} # Aliasで短縮版 1..100 | % {$x = @("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]; ($x,$_)[!$x]}
まとめ
思いのほか面白くて楽しめましたww次は、%使わず求めることにも挑戦してみようかしら。
おまけ
誰得なFizzBuzz関数作ってみましたww関数に渡した連番で、ソース1,2,3のそれぞれでFizzBuzzを出力します。 連番を渡すときは、Get-FizzBuzz -seq (1..100)な感じで-Seqパラメータに( ..)で渡してください。Format-Table -Autosizeで表示させることで、余計なスペースが削除されますが、なくてもお好きなようにどうぞ。これで10000でも好きな数でできますね。
function Get-FizzBuzz{ [CmdletBinding()] param( [int[]]$seq ) $seq ` | ForEach-Object{ New-Object PSObject -Property @{ numFizzBuzz = ($_ | ForEach-Object {"$_" +@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]}) oneFizzBuzz = ($_ | ForEach-Object {((@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]),$_)[!((@("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]))]}) varFizzBuzz = ($_ | ForEach-Object {$x = @("Fizz")[$_ % 3] + @("Buzz")[$_ % 5]; ($x,$_)[!$x]}) } } } Get-FizzBuzz -seq (1..100) | Format-Table -AutoSize
おまけのおまけ
20013/Jan/20 PM17:01現在、牟田口先生が51文字(V3.0)、54文字(V2.0)のコードを公開されています。私ので57文字。
よこけんさんが2007年に私のパターン3と同一のソースを出されているんですね……悔しい…
おまけのおまけでswitch
何のおもしろみもありませんがswitchでloopの特性使ってます。…どーぞ
switch(1..100){ {!($_%15)}{'FizzBuzz';continue} {!($_%3)}{'Fizz';continue} {!($_%5)}{'Buzz';continue} default{$_} }