Skip to content

Instantly share code, notes, and snippets.

@pocketberserker
Created May 1, 2012 03:43
Show Gist options
  • Save pocketberserker/2564776 to your computer and use it in GitHub Desktop.
Save pocketberserker/2564776 to your computer and use it in GitHub Desktop.
tddbc東京1.5のお題をF#でやってみた(途中)
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)
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