趣旨
F#と関数プログラミングの勉強がてら、唐揚げの問題をやってみた。
課題:
唐揚げ弁当がいくつかあるとします。それぞれ唐揚げが複数入っています。
この中からx個の唐揚げをつまみ食いするプログラムを作りましょう。
つまみ食いはバレないようにするために、
その時点で最も唐揚げ数が多いお弁当から取るという仕様にします。
コード
open System
let stealOne(list:List<int>) =
let stole = list.Head - 1
List.append [stole] list.Tail
let rec stealing(list:List<int>, times:int) =
let stoleList =
list |> List.sortDescending |> stealOne
printfn "%A" stoleList
if List.max stoleList = 0 || times = 1 then
()
else
stealing(stoleList, (times-1))
[<EntryPoint>]
let main argv =
// 何個奪うか(コマンドライン引数から取得)
let times = int argv.[0]
printfn "唐揚げを%d回奪い取る" times
stealing([8;6;10], times)
Console.ReadLine() |> ignore
0
実行結果
唐揚げを5回奪い取る
[9; 8; 6]
[8; 8; 6]
[7; 8; 6]
[7; 7; 6]
[6; 7; 6]
やってみて
mapとかreduce使わなくても、必要な要素を整理したらシンプルに書けた
シンプルに実装しすぎて、結局勉強になってない気がするけども。
- 唐揚げは個数だけ保持したリストで管理
- 最大数は降順ソートさせる
- 先頭の要素を一個減らしたリストを再組立て
ソートさせるのが副作用に含まれるかがよくわからない部分。
元々のものに破壊的変更を加えてないから、副作用は発生していないって考えですが...
もっと綺麗に書けないか悩み中。
ご意見など
もっと綺麗に書けるよとか考え方おかしいよとか
ご意見ありましたらぜひ教えてください!!