-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrps.rsh
66 lines (54 loc) · 3.7 KB
/
rps.rsh
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
'reach 0.1';
export const [isHand, ROCK, PAPER, SCISSORS] = makeEnum(3);
export const [isOutcome, B_WINS, DRAW, A_WINS] = makeEnum(3);
/*
* winner
* returns outcome of two hands
*/
export const winner = (handC, handD) => ((handC + (4 - handD)) % 3)
assert(winner(ROCK, PAPER) == B_WINS);
assert(winner(PAPER, ROCK) == A_WINS);
assert(winner(ROCK, ROCK) == DRAW);
forall(UInt, handA =>
forall(UInt, handB =>
assert(isOutcome(winner(handA, handB)))));
forall(UInt, (hand) =>
assert(winner(hand, hand) == DRAW));
/*
* min
* returns min of two values
*/
const min = (a, b) => a < b ? a : b
assert(min(0, 1) === 0)
assert(min(1, 0) === 0)
assert(min(1, 1) === 1)
/*
* resolveWinner
* returns winner of sets of order hands
*/
export const resolveWinner = (a, b) =>
((aMin) => (a.hands).zip(b.hands)
.mapWithIndex(([x, y], i) => i > aMin ? DRAW : winner(x, y))
.reduce(DRAW, (acc, val) => acc == DRAW ? val : acc))
(min(a.count, b.count))
assert(resolveWinner({ count: 0, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 0, hands: array(UInt, [PAPER, ROCK, ROCK, ROCK]) }) == B_WINS)
assert(resolveWinner({ count: 0, hands: array(UInt, [PAPER, ROCK, ROCK, ROCK]) }, { count: 0, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }) == A_WINS)
assert(resolveWinner({ count: 0, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 0, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }) == DRAW)
forall(UInt, handA =>
forall(UInt, handB =>
assert(isOutcome(resolveWinner({ count: 0, hands: array(UInt, [handA, ROCK, ROCK, ROCK]) }, { count: 0, hands: array(UInt, [handB, ROCK, ROCK, ROCK]) })))));
forall(UInt, (hand) =>
assert(resolveWinner({ count: 0, hands: array(UInt, [hand, ROCK, ROCK, ROCK]) }, { count: 0, hands: array(UInt, [hand, ROCK, ROCK, ROCK]) }) == DRAW));
assert(resolveWinner({ count: 0, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [PAPER, PAPER, ROCK, ROCK]) }) == B_WINS)
assert(resolveWinner({ count: 0, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [SCISSORS, PAPER, ROCK, ROCK]) }) == A_WINS)
assert(resolveWinner({ count: 0, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [ROCK, PAPER, ROCK, ROCK]) }) == DRAW)
assert(resolveWinner({ count: 1, hands: array(UInt, [ROCK, PAPER, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [PAPER, ROCK, ROCK, ROCK]) }) == B_WINS)
assert(resolveWinner({ count: 1, hands: array(UInt, [PAPER, ROCK, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [PAPER, PAPER, ROCK, ROCK]) }) == B_WINS)
assert(resolveWinner({ count: 1, hands: array(UInt, [PAPER, ROCK, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [ROCK, PAPER, ROCK, ROCK]) }) == A_WINS)
assert(resolveWinner({ count: 1, hands: array(UInt, [PAPER, PAPER, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [PAPER, ROCK, ROCK, ROCK]) }) == A_WINS)
assert(resolveWinner({ count: 1, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 1, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }) == DRAW)
assert(resolveWinner({ count: 2, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 2, hands: array(UInt, [ROCK, ROCK, PAPER, ROCK]) }) == B_WINS)
assert(resolveWinner({ count: 2, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 2, hands: array(UInt, [ROCK, ROCK, ROCK, PAPER]) }) == DRAW)
assert(resolveWinner({ count: 3, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 3, hands: array(UInt, [ROCK, ROCK, ROCK, PAPER]) }) == B_WINS)
assert(resolveWinner({ count: 3, hands: array(UInt, [PAPER, ROCK, ROCK, ROCK]) }, { count: 3, hands: array(UInt, [ROCK, ROCK, ROCK, PAPER]) }) == A_WINS)
assert(resolveWinner({ count: 3, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }, { count: 3, hands: array(UInt, [ROCK, ROCK, ROCK, ROCK]) }) == DRAW)