-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinventory.rkt
69 lines (55 loc) · 1.96 KB
/
inventory.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#lang racket
;;;
;;; Functions for managing a simple representation of an item
;;; inventory.
;;;
;;; Item amounts are guaranteed to positive and non-zero.
;;;
;;; Uses an immutable hash for internal representation, thus
;;; all inventory manipulation functions return a new inventory
;;; object.
;;;
(provide make-inventory
inventory-available
inventory-deposit
inventory-withdraw
inventory-set
inventory-shortfall
inventory-withdraw+unsatisfied
inventory-empty?
merge-inventories)
;;; Inventory functions
(define (make-inventory . assoc-list)
(make-immutable-hasheq (filter (λ (m) (not (zero? (cdr m)))) assoc-list)))
(define (inventory-available inventory item [default 0])
(hash-ref inventory item default))
(define (inventory-deposit inventory item count)
(if (zero? count)
inventory
(hash-update inventory item (λ (value) (+ value count)) 0)))
(define (inventory-withdraw inventory item count)
(define avail (hash-ref inventory item 0))
(cond
[(< avail count)
(raise-argument-error 'inventory-withdraw "(<= (inventory-avail inventory item))" count)]
[(= avail count)
(hash-remove inventory item)]
[(> avail count)
(hash-set inventory item (- avail count))]))
(define (inventory-set inventory item count)
(if (zero? count)
(hash-remove inventory item)
(hash-set inventory item count)))
(define (inventory-shortfall inventory item count)
(max 0 (- count (inventory-available inventory item))))
(define (inventory-withdraw+unsatisfied inventory item num)
(define cur (hash-ref inventory item 0))
(cond
[(<= cur num) (values (hash-remove inventory item) (- num cur)) ]
[(> cur num) (values (hash-set inventory item (- cur num)) 0)]))
(define (inventory-empty? inventory)
(zero? (hash-count inventory)))
(define (merge-inventories a b)
(for/fold ([result a])
([(key value) b])
(inventory-deposit result key value)))