Created
May 1, 2012 03:43
-
-
Save pocketberserker/2564776 to your computer and use it in GitHub Desktop.
tddbc東京1.5のお題をF#でやってみた(途中)
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
module VendingMachine | |
type Yen = | |
| Thousand | |
| FiveHundred | |
| Hundred | |
| Fifty | |
| Ten | |
type Drink = { | |
name:string | |
amount:int | |
} | |
let recive (money:Yen) strongbox = | |
money :: strongbox | |
let convert = function | |
| Thousand -> 1000 | |
| FiveHundred -> 500 | |
| Hundred -> 100 | |
| Fifty -> 50 | |
| Ten -> 10 | |
let sum strongbox = | |
strongbox | |
|> List.map convert | |
|> List.sum | |
let getDrinkAmount drink = drink.amount | |
let getDrinkName drink = drink.name | |
let available stock money = | |
stock | |
|> List.filter (snd >> (=) 0 >> not) | |
|> List.filter (fst >> getDrinkAmount >> (>=) money) | |
let menu stock money = | |
money | |
|> available stock | |
|> List.map (fst >> getDrinkName) | |
let equalStockDrinkName x = fst >> getDrinkName >> (=) x | |
let reduce stock drink = | |
match stock |> List.tryFind (equalStockDrinkName drink) with | |
| Some (d, n) when n > 0 -> | |
(d, n - 1) :: (stock |> List.filter (equalStockDrinkName d.name >> not)) | |
| _ -> stock | |
let convertYen num = | |
let thousand, num = (num / 1000, num % 1000) | |
let fiveHundred, num = (num / 500, num % 500) | |
let hundred, num = (num / 100, num % 100) | |
let fifty, num = (num / 50, num % 50) | |
let ten = num / 10 | |
List.init thousand (fun _ -> Thousand) | |
|> List.append (List.init fiveHundred (fun _ -> FiveHundred)) | |
|> List.append (List.init hundred (fun _ -> Hundred)) | |
|> List.append (List.init fifty (fun _ -> Fifty)) | |
|> List.append (List.init ten (fun _ -> Ten)) | |
let cell stock strongbox money drink = | |
match stock |> List.tryFind (equalStockDrinkName drink) with | |
| Some (d, num) -> | |
let stock = reduce stock drink | |
let strongbox = strongbox |> List.append (money |> convertYen) |> List.sort |> List.rev | |
(true, stock, strongbox, money - d.amount) | |
| None -> (false, stock, strongbox, money) | |
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
module VendingMachineSpec | |
open NaturalSpec | |
open VendingMachine | |
let coke = { name = "coke"; amount = 120 } | |
[<Scenario>] | |
let ``投入可能なお金を1つずつ投入したときの合計金額は1660`` () = | |
Given [Thousand; FiveHundred; Hundred; Fifty; Ten] | |
|> When sum | |
|> It should equal 1660 | |
|> Verify | |
[<Scenario>] | |
let ``お金を投入していない場合の合計金額は0円`` () = | |
Given [] | |
|> When sum | |
|> It should equal 0 | |
|> Verify | |
[<Scenario>] | |
let ``120円を投入したら購入可能なリストとしてコーラを含んだリスト返る`` () = | |
Given ([(coke, 5)], 120) | |
||> When menu | |
|> It should equal ["coke"] | |
|> Verify | |
[<Scenario>] | |
let ``110円ではコーラは購入できないので空のリスト返る`` () = | |
Given ([(coke, 5)], 110) | |
||> When menu | |
|> It should equal [] | |
|> Verify | |
[<Scenario>] | |
let ``コーラの在庫がない場合は購入できないので空のリスト返る`` () = | |
Given ([(coke, 0)], 120) | |
||> When menu | |
|> It should equal [] | |
|> Verify | |
[<Scenario>] | |
let ``1660を千円札1枚と各硬貨が1枚ずつになるように変換できる`` () = | |
Given 1660 | |
|> When convertYen | |
|> It should equal [Ten; Fifty; Hundred; FiveHundred; Thousand] | |
|> Verify | |
[<Scenario>] | |
let ``コーラが1つ購入されると在庫が一つ減る`` () = | |
Given ([(coke, 5)], "coke") | |
||> When reduce | |
|> It should equal [(coke, 4)] | |
|> Verify | |
[<Scenario>] | |
let ``別のものを指定されるとコーラの在庫は減らない`` () = | |
Given ([(coke, 5)], "おいしい水") | |
||> When reduce | |
|> It should equal [(coke, 5)] | |
|> Verify | |
[<Scenario>] | |
let ``コーラの在庫が0ならコーラは減らない`` () = | |
Given ([(coke, 0)], "coke") | |
||> When reduce | |
|> It should equal [(coke, 0)] | |
|> Verify | |
let strongbox = | |
List.init 5 (fun _ -> Thousand) | |
|> List.append (List.init 10 (fun _ -> FiveHundred)) | |
|> List.append (List.init 10 (fun _ -> Hundred)) | |
|> List.append (List.init 10 (fun _ -> Fifty)) | |
|> List.append (List.init 10 (fun _ -> Ten)) | |
let resultStrongbox = | |
List.init 5 (fun _ -> Thousand) | |
|> List.append (List.init 10 (fun _ -> FiveHundred)) | |
|> List.append (List.init 11 (fun _ -> Hundred)) | |
|> List.append (List.init 10 (fun _ -> Fifty)) | |
|> List.append (List.init 12 (fun _ -> Ten)) | |
[<Scenario>] | |
let ``コーラが1つ購入されると、お釣りとしてお金が減算され在庫が一つ減る`` () = | |
Given "coke" | |
|> When (cell [(coke, 5)] strongbox 120) | |
|> It should equal (true, [(coke, 4)], resultStrongbox, 0) | |
|> Verify | |
[<Scenario>] | |
let ``存在しない商品を購入しようとすると購入に失敗する`` () = | |
Given "おいしい水" | |
|> When (cell [(coke, 5)] strongbox 120) | |
|> It should equal (false, [(coke, 5)], strongbox, 120) | |
|> Verify |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment