-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Lots of new test cases based on wiki exercises.
- Loading branch information
Showing
19 changed files
with
640 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{-- | ||
Write a function which conducts an auction given | ||
a list of "bidder" sites and a starting bid. An | ||
auction consists of a number of bidding rounds | ||
performed in sequence. A bidding round consists | ||
of calling every bidder site in parallel, passing | ||
the current maximum bid. Each bidder site may | ||
return a higher value (a bid). The first caller | ||
to return a higher bid sets a new maximum bid for | ||
the next round. If no callers return a bid within | ||
5 seconds, the auction (and round) ends. Your | ||
function should return the value of the winning | ||
bid. | ||
--} | ||
|
||
def auction(bidders, max) = | ||
val (done, bid) = | ||
Rtimer(100) >> (true, max) | ||
| each(bidders) >bidder> | ||
bidder(max) >bid> | ||
if(bid > max) >> | ||
(false, bid) | ||
println("Current bid: " + max) >> | ||
if done then max else auction(bidders, bid) | ||
|
||
def bidder(max)(n) = if(n < max) >> n + 1 | ||
auction(map(lambda (_) = bidder(random(10)), range(0,10)), 1) | ||
|
||
{- | ||
OUTPUT: | ||
Current bid: 1 | ||
Current bid: 2 | ||
Current bid: 3 | ||
Current bid: 4 | ||
Current bid: 5 | ||
Current bid: 6 | ||
Current bid: 7 | ||
Current bid: 8 | ||
Current bid: 9 | ||
9 | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{-- | ||
Write a function which takes an input channel (in), | ||
an output channel (out), and a list of sites (ps) | ||
as arguments. The function must repeatedly read an | ||
input value from in, call one of the sites in ps | ||
with the value (using each site in the list in turn), | ||
and write the result to out. The order values are | ||
written to the output channel must correspond to the | ||
order values were received on the input channel. | ||
--} | ||
|
||
def balance(in, out, ps) = | ||
val bs = map(ignore(Buffer), ps) | ||
def write(b:bs) = out.put(b.get()) >> write(append(bs, [b])) | ||
def read((p,b):pbs) = | ||
( in.get() ; b.close() >> stop ) >x> | ||
( b.put(p(x)) >> stop | read(append(pbs, [(p,b)])) ) | ||
write(bs) | read(zip(ps,bs)) | ||
|
||
val in = Buffer() | ||
val out = Buffer() | ||
def compute(n)(x) = println("Site " + n) >> x*x | ||
|
||
( balance(in, out, [compute(1), compute(2), compute(3), compute(4)]) | ||
; out.close() >> stop ) | ||
| ( upto(10) >n> in.put(n) >> stop | ||
; in.close() >> stop ) | ||
| repeat(out.get) | ||
|
||
{- | ||
OUTPUT: | ||
Site 1 | ||
0 | ||
Site 2 | ||
1 | ||
Site 3 | ||
4 | ||
Site 4 | ||
9 | ||
Site 1 | ||
16 | ||
Site 2 | ||
25 | ||
Site 3 | ||
36 | ||
Site 4 | ||
49 | ||
Site 1 | ||
64 | ||
Site 2 | ||
81 | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{-- | ||
You are given a data type for binary trees with the | ||
constructors <code>Tree(left, value, right)</code> and | ||
<code>Leaf()</code>. Write a function which, given a tree, | ||
returns a list of values in the tree ordered by | ||
depth. I.e. the first element should be the root | ||
value, followed by the root's children, followed by | ||
its grandchildren, and so on. | ||
--} | ||
|
||
type Tree = Tree(_, _, _) | Leaf() | ||
|
||
def levels(tree) = | ||
def helper([]) = [] | ||
def helper(Leaf():rest) = helper(rest) | ||
def helper(Tree(l,v,r):rest) = | ||
v:helper(append(rest, [l, r])) | ||
helper([tree]) | ||
|
||
levels(Tree( | ||
Tree( | ||
Tree(Leaf(), 3, Leaf()), | ||
2, | ||
Tree(Leaf(), 3, Leaf())), | ||
1, | ||
Tree( | ||
Tree(Leaf(), 3, Leaf()), | ||
2, | ||
Tree(Leaf(), 3, Leaf())))) | ||
|
||
{- | ||
OUTPUT: | ||
[1, 2, 2, 3, 3, 3, 3] | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{-- | ||
Write a program with three functions: inc, dec, and read. | ||
Each of these functions modifies a shared state which is | ||
a natural number (n), initially = 0. When inc is called, | ||
increment n. When dec is called, decrement n. When read | ||
is called, publish the value of n. Each of these | ||
functions must act atomically, so that the expression | ||
<code>inc() | dec()</code> is guaranteed to leave the | ||
counter state unchanged after it completes. | ||
|
||
Hint: use a semaphore to control access to the shared state. | ||
--} | ||
|
||
val n = Ref(0) | ||
val lock = Semaphore(1) | ||
|
||
def inc() = | ||
lock.acquire() >> | ||
n := n? + 1 >> | ||
lock.release() | ||
|
||
def dec() = | ||
lock.acquire() >> | ||
n := n? - 1 >> | ||
lock.release() | ||
|
||
def read() = | ||
lock.acquire() >> | ||
n? >out> | ||
lock.release() >> | ||
out | ||
|
||
inc() >> signals(10) >> (inc(), dec()) >> stop | ||
; read() | ||
|
||
{- | ||
OUTPUT: | ||
1 | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{-- | ||
Write a function which, given a number (n) and a channel (c), | ||
returns a list of the first n values received from c. | ||
--} | ||
|
||
def firstN(0, c) = [] | ||
def firstN(n, c) = c.get() >x> x:firstN(n-1, c) | ||
|
||
val c = Buffer() | ||
firstN(5, c) | ||
| upto(10) >n> c.put(n) >> stop | ||
|
||
{- | ||
OUTPUT: | ||
[0, 1, 2, 3, 4] | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{-- | ||
Write a program which calls a definition f, which | ||
may publish multiple values. Publish the first 10 | ||
values published by <code>f()</code>, and then | ||
terminate the call to f. | ||
--} | ||
|
||
{- Publish first n values received on c, then release s -} | ||
def allow(0, c, s) = c.closenb() >> s.release() >> stop | ||
def allow(n, c, s) = c.get() >x> ( x | allow(n-1, c, s) ) | ||
|
||
{- Example f -} | ||
def f() = upto(10) >x> Rtimer(x) >> x | ||
|
||
{- Main program -} | ||
val c = Buffer() | ||
val s = Semaphore(0) | ||
allow(5, c, s) << | ||
s.acquire() | f() >x> c.put(x) >> stop | ||
|
||
{- | ||
OUTPUT: | ||
0 | ||
1 | ||
2 | ||
3 | ||
4 | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{-- | ||
Write a function which, given a list of sites, calls | ||
each site in the list in parallel and publishes a | ||
signal when all site calls have returned. | ||
--} | ||
|
||
def forkjoin([]) = signal | ||
def forkjoin(f:rest) = (f(), forkjoin(rest)) >> signal | ||
|
||
def example() = println("called") | ||
forkjoin([example, example, example, example]) | ||
|
||
{- | ||
OUTPUT: | ||
called | ||
called | ||
called | ||
called | ||
signal | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{-- | ||
Write a function to solve the | ||
<ulink url="http://en.wikipedia.org/wiki/Tower_of_Hanoi">Towers of Hanoi</ulink> | ||
problem. There are three pegs, numbered 0..2; | ||
disks are to be moved from peg 0 to peg 2. Your | ||
function should take as its argument the number | ||
of disks initially on peg 0, and it should return | ||
a list of moves, where a move is a tuple (source | ||
peg number, destination peg number), e.g. <code>(0,1)</code>. | ||
Since the point of this exercise is to practice Orc, | ||
not solve puzzles, feel free to use the algorithm | ||
given in Wikipedia. | ||
--} | ||
|
||
{-- | ||
Algorithm as described in | ||
http://en.wikipedia.org/wiki/Tower_of_Hanoi | ||
--} | ||
def hanoi(n) = | ||
{- arguments: h(eight), f(rom peg), | ||
r(emaining peg), t(o peg), m(ove)s -} | ||
def move(1, f, r, t, ms) = (f,t):ms | ||
def move(h, f, r, t, ms) = | ||
move(h-1, f, t, r, ms) >ms> | ||
move(1, f, r, t, ms) >ms> | ||
move(h-1, r, f, t, ms) | ||
reverse(move(n, 0, 1, 2, [])) | ||
|
||
hanoi(3) | ||
|
||
{- | ||
OUTPUT: | ||
[(0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2)] | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{-- | ||
Write a function which, given a list, returns | ||
the number of elements in the list. | ||
--} | ||
|
||
def length([]) = 0 | ||
def length(x:xs) = 1 + length(xs) | ||
|
||
length([0,0,0,0]) | ||
|
||
{- | ||
OUTPUT: | ||
4 | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{-- | ||
You are given the site <code>ls(x)</code> which returns | ||
a list of file names found in the directory named | ||
by the path <code>x</code>, or an empty list if <code>x</code> is | ||
not a directory. Paths are written as strings | ||
using POSIX conventions, e.g. "/foo/bar/baz". | ||
So for example <code>ls("/usr/")</code> might return | ||
<code>["local/", "bin/", "lib/]</code>. Unlike POSIX, you | ||
can assume that directory paths always end in "/". | ||
Write a function <code>find(x)</code> which returns a list | ||
of all paths in the directory tree starting at the | ||
given path. E.g. <code>find("/")</code> might return | ||
<code>["/", "/usr/", "/usr/bin/", "/usr/bin/ls"]</code>. | ||
--} | ||
{-- | ||
Example ls function which lists | ||
files in directories: results are | ||
hard-coded. | ||
--} | ||
def ls("/") = ["usr/", "bin/", "lib/"] | ||
def ls("/usr/") = ["local/", "bin/", "lib/"] | ||
def ls("/usr/bin/") = ["ls", "sh", "find"] | ||
def ls(_) = [] | ||
-------- main program ------ | ||
{- | ||
This implementation makes use of map | ||
and foldr to achieve a much more concise | ||
and readable solution. | ||
-} | ||
def flatten(lists) = foldr(append, [], lists) | ||
def find(root) = | ||
def resolve(file) = root + file | ||
root:flatten(map(find, map(resolve, ls(root)))) | ||
find("/") | ||
{- | ||
OUTPUT: | ||
[/, /usr/, /usr/local/, /usr/bin/, /usr/bin/ls, /usr/bin/sh, /usr/bin/find, /usr/lib/, /bin/, /lib/] | ||
-} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{-- | ||
Write a program with two functions: dec and wait. | ||
These functions share a state which is a natural number | ||
(n), initially = 5. When <code>dec()</code> is called, | ||
decrement n. When <code>wait()</code> is called, wait until | ||
<code>n = 0</code> and then publish a signal. Write the program | ||
without using <code>Ref</code>. | ||
|
||
Hint: create a single process running in the background which | ||
manages the shared state. | ||
--} | ||
|
||
val m = Buffer() | ||
type Message = Dec() | Wait(_) | ||
def actor(n, waiters) = | ||
def on(Dec()) = | ||
if n = 1 then join(waiters) | ||
else actor(n-1, waiters) | ||
def on(Wait(callback)) = | ||
if n = 0 then callback() | ||
else actor(n, callback:waiters) | ||
on(m.get()) | ||
|
||
def dec() = println("Decrementing") >> m.put(Dec()) | ||
def wait() = | ||
val b = Semaphore(0) | ||
b.acquire() | m.put(Wait(b.release)) >> stop | ||
|
||
actor(5, []) >> stop | ||
| dec() >> stop | ||
| dec() >> stop | ||
| dec() >> stop | ||
| dec() >> stop | ||
| Rtimer(100) >> dec() >> stop | ||
| wait() >> "Zero!" | ||
|
||
{- | ||
OUTPUT: | ||
Decrementing | ||
Decrementing | ||
Decrementing | ||
Decrementing | ||
Decrementing | ||
Zero! | ||
-} |
Oops, something went wrong.