This, the first graded assignment of the semester, asks you to solve a simple problem in each of five programming languages (six if you’re in 454):
As it turns out, there are 42 different trees with 6 nodes (only three of which are shown above). With 4 nodes there are only five trees:
These are most easily output in “parenthesized” form:
((())()) (((()))) (()()()) ((()())) (()(()))Examine those carefully: they correspond, in order, to the five trees above. Each pair of parentheses corresponds to a node; the nested parens are children; empty (innermost) parens are leaves.
Enumerating trees is a naturally recursive problem, for which there are
several possible solutions.
The most obvious, perhaps, is to observe that you need one node for the
root (assuming n ≠ 0).
You can then
A simpler approach is to trace out a left-to-right, depth-first traversal of the tree, keeping track at each step of the current depth and the number of remaining nodes. At each step, you can choose to move down the tree (adding a left paren to the output, increasing the depth by one, and decreasing the number of remaining nodes by one) or move up the tree (adding a right paren to the output, decreasing the depth by one, and leaving the number of remaining nodes the same—except, of course, that you can’t move up if you’re at depth 0, and you can’t move down if you’re out of remaining nodes. When you’re at depth 0 with no remaining nodes, you’ve found a possible tree. The only tricky part is that when you have a real choice, you have to explore both options.
If you already knew all of the required languages, you’d probably find your task easiest in Prolog and hardest in Ada, with the other three somewhere in the middle. (Of course you probably don’t know all the languages already, so the unfamiliar ones will be the hardest.) A hint: you can easily find toy programs in all these languages on the web. For Ada and C# in particular, you might find it helpful to start with one of these toys: it will already import appropriate libraries and contain examples of the control constructs, I/O calls, etc. For what it’s worth, I wrote a solution in Scheme as part of designing the project; that solution is 16 lines long.
When run, your programs (in all languages other than Prolog) should read
a single integer n from standard
input, and then output the appropriate trees to standard output (in
parenthesized form), one per line, in arbitrary order.
For Prolog, please arrange for trees(n, L)
to produce successive trees (values for L
) in response
to a semicolon prompt.
You may work alone on this project or in teams of two. If you split up
the languages, whoever takes Ada should probably do two; the other
person should do three.
However you divide the programming,
each team member must write their own
README
file (no sharing of text on this allowed), and turn in
the project separately (with all five or six programs, which
will be the same as the partner’s code).
This means, of course, that you’ll need to really
understand your partner’s code.
Be sure to read the instructions on the
grading page regarding the turn-in
procedure and requirements.
You may also wish to consult the grading
rubric on Blackboard.
To turn in your code, use the following procedure, which will be the
same for all assignments this semester:
On a csug
machine,
put your write-up in a README.txt
or
README.pdf
file in the same directory as your code, and
(while still in that directory) run
the script ~cs254/bin/TURN_IN
.
The script will package the contents of the directory (and any
subdirectories) into a bundle and send it to the TAs for grading (so
clean up any mess you might have in the directory first).
Be sure your write-up (README
file) describes any features
of your code that the TAs might not immediately notice. In
addition, for this assignment, your
README
file must compare and contrast the
programming experience in the different languages you used (all five/six
of them). What was easy? What was hard?
Are there noticeable differences in speed?
What do you like/dislike?
We will be using the following language implementations.
The Go compiler is installed in /u/cs254/bin
, which you
should add to your PATH
environment variable (ask a
friend or one of the TAs if you
don’t know how).
All the rest of the languages are in /usr/bin
or
/usr/staff/bin
, both of which should already be on your
PATH
by default.
gnatmake
(a wrapper for the
GNU Ada translator). It produces native executables.
mcs
(the Mono project C#
compiler) and run with the mono
JIT/run-time system.
go
.
ghci
interpreter, or
compile with ghc
(the Glasgow Haskell Compiler) to
produce native binaries.
swipl
interpreter.
python3
interpreter.
ocaml
interpreter, or
compile with ocamlc
to produce native binaries.
ruby
interpreter.
rustc
.
plt-r5rs
or, under X, with the drracket
GUI.
Be sure to configure the latter to use the R5RS language standard
(it boots up expecting a vastly expanded language that will try to
force you to use modules and other features you don’t want to
have to learn at this point.)
swift
interpreter, or
compile with swiftc
.
You are welcome to work with other language implementations and/or platforms, but you must ensure that your final versions compile and run correctly using the implementations listed above. We will be testing using only these.
I won’t be devoting lecture time to how to use these languages. You’ll need to find on-line tutorials or other resources, and teach yourself. Here are some decent starting points:
Before end of day on Friday, September 9, each individual student (even if planning to work in a team) should complete the T1 trivia assignment found on Blackboard.