This assignment is worth 100 points.
You are asked to construct several function definitions in rex and test them. You should submit your functions in a single file named hw6.rex. It is easiest to start from the file /cs/cs60/assignments/assignment6/hw6.rex, which has a few lines of rex code that will help with the later problems. (Otherwise, you'll have to add those lines yourself!)
Your code should have an initial comment with the assignment number, your name, and the date. Also, each function should be clearly commented and should be neatly formatted.Important psychological note With the exception of the last problem (#15, bestThree), each of these rex functions can be built in just a few (3-4) lines of code, and many in just 1 or 2. Because of this, the ratio of thinking to coding is much higher in rex than java! So, don't get worried when most of your time is spent in thought about the problems, rather than typing them in... . Also, be sure to test things thoroughly.
This assignment touches on the early parts of Prof. Keller's text up through Chapter 3, though the topics needed will also be covered in class. There are many more examples in the book than we can cover in class.
You should submit the file you create (named hw6.rex) by running (at the unix prompt)
> cs60submit hw6.rexor
> cs60submitall
hw1.rex file.
Feel free to use
built-in rex functions (atomic, first, float, is_string,
length, map, range, reduce,
rest, remove_duplicates, reverse, second), as well as
others. There are a couple of problems that ask you not
to use a particular built-in function because it would make
it too easy, e.g., you should not use the built-in pow
function to write power.
The built-in
functions are available from the rex reference card.
rex > sum([5, 8, 9]);
22
rex > sum(range(1,10));
55
(Hint: Use reduce.)
rex > average([5, 8, 9]);
7.33333
rex > average(range(1,10));
5.5
You will want to use the float function, along with the
length of the list, in order to obtain floating point
averages. Note that
rex > 22/3;
7
rex > 22/float(3);
7.33333
rex > power(3,4);
81
rex > power(10,3);
1000
rex > power(42,-42);
1
As an example,
superpower(2,3) is "2 to the power of 2 to the power of 2"
or

which is 2 to the fourth power, or
16. Write the superpower function. Again, the two inputs
will both be nonnegative integers.
rex > superpower(2,3);
16
rex > superpower(3,3);
7625597484987
(Rex supports infinite-precision integer arithmetic -- for instance,
you might want to check out superpower(2,5), but
you might have to turn off any built-in memory limits. (Ask...)
The result has 19,730 digits!)
rex > log2(16);
4
rex > log2(31);
4
rex > log2(32);
5
rex > log2(1);
0
rex > log2(-42);
0
rex > superreverse([ [1,2,3], [4,5,6], [7,8,9] ])
[ [3,2,1], [6,5,4], [9,8,7] ]
rex > superreverse([['o','l',['I']],['e','v'],[['e','x'],'r']]);
[[[I], l, o], [v, e], [r, [e, x]]
rex > duperreverse([1, [2, 3], [4, [5, 6, [7, 8], 9] ] ]);
[[[9, [8, 7], 6, 5], 4], [3, 2], 1]
rex > duperreverse([['o','l',['I']],['e','v'],[['e','x'],'r']]);
[[r, [x, e]], [v, e], [[I], l, o]]
You will want to use the predicate atomic to implement this
function.rex > pair(1, [2, 3, 4]); [[1, 2], [1, 3], [1, 4]]
rex > all_pairs([1, 2, 3], [4, 5]); [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
Here are some example inputs and outputs:
rex > intersect([4,5,5,5,6,6],[4,4,4,5,5,7,7]);
[4,5,5]
rex > intersect(sort(explode("english")),sort(explode("language")));
[e,g,l,n]
The result of bowl(L) should be the sum of all of the frames in L.
The following examples should make this clear, and they are simpler than the wordy explanation above:
rex > bowl( [ [5, 5], [2, 7] ] );
21
rex > bowl( [ [4, 6], [1, 0] ] );
12
rex > bowl( [ [0, 1], [2, 9], [4, 6] ] );
22
rex > bowl( [ ] );
0
rex > bowl( [ [10, 0], [2, 8], [1, 2] ] );
26
Hint: Try using multiple rules and pattern matching to simplify your code.
scrabbleScores =
[
['a',1,9],
['b',3,2],
['c',3,2],
['d',2,4],
['e',1,12],
['f',4,2],
['g',2,3],
['h',4,2],
['i',1,9],
['j',8,1],
['k',5,1],
['l',1,4],
['m',3,2],
['n',1,6],
['o',1,8],
['p',3,2],
['q',10,1],
['r',1,6],
['s',1,4],
['t',1,6],
['u',1,4],
['v',4,2],
['w',4,2],
['x',8,1],
['y',4,2],
['z',10,1]
];
This list is available in the file /cs/cs60/assignments/assignment6/scrabbleScores.rex .
You can include it (and thus use scrabbleScores) by adding the line
sys(in,"/cs/cs60/assignments/assignment6/scrabbleScores.rex");
in your file (or, in theory, at the rex prompt).
This line is already in the example hw6.rex file,
available in /cs/cs60/assignments/assignment6.
Make sure that the above line is
in your hw6.rex file! That way, the variable scrabbleScores
will be bound to the above list and you can use it as necessary.
Write a function wordScore(w), which takes a word w (in the form of a string) and returns the word's scrabble score:
rex > wordScore("quiz");
22
rex > wordScore("twelve");
12
rex > wordScore("fuzz");
25
Notice that the number of letters available does not play
a role here -- but see the extra credit for a more true-to-life
scrabble-scoring function.
Hints: The built-in functions assoc and explode will be useful for this problem. See the scrabbleScores.rex file for an explanation of assoc. Here's a quick description of explode:
explode takes a string as input and outputs the same string and a list of characters, e.g.,
rex > explode("rex"); // in case you're thinking regicide by now...
[ r, e, x ]
where those three characters are literal characters and not
variables. Note that when outputting characters, rex does not print
the single quote that is necessary for inputting characters. Thus,
if you ever want to transform a list of characters into a string, you need
to type
rex > implode([ 's', 't', 'a', 'r' ]);
star // actually a black hole...
In fact, your thinking at this point may have veered more toward
the topic of four-letter words. A list of all scrabble-acceptable ones
appears in /cs/cs60/assignments/assignment6/fourLets.rex.
Write a function named bestThree that finds the highest-scoring three-letter word from a rack of letters. bestThree(rack) should accept any seven-letter string (of lowercase letters) as the rack and then return the highest-score achievable with that rack, along with the word achieving that score in a two-element list. There may be several correct answers, in which case bestThree may return any one of them.
In the process of writing bestThree you will want to write several helper functions along the way. Those are up to you... .
By including the line
sys(in,"/cs/cs60/assignments/assignment6/threeLets.rex");
in your hw6.rex file, the
variable ospd3 will be bound to a list of all legal three-letter
words. (The name ospd3 stands for the Official Scrabble Player's Dictionary's
three-letter words.) Be sure to do this.
Some input/output examples:
rex > bestThree("aaeiijx");
[10, axe]
rex > bestThree("abcdabc");
[7, cab]
rex > bestThree("eiilrrx");
[10, rex]
One caution: because bestThree is somewhat compute-intensive,
there may be a bit of a wait for it to return an answer. My solution
requires about 5 seconds; yours may be faster or slower depending
on your approach.
For example, two differences between scrabbleScore and hardScrabble are
rex > scrabbleScore("fuzzy");
29
rex > scrabbleScore("pizzazz");
45
rex > hardScrabble("fuzzy");
19
rex > hardScrabble("pizzazz");
Impossible word!
rex > realbowl([ [10, 'x'], [10, 'x'], [10, 'x'], [10, 'x'], [10, 'x'], [10, 'x'],
[10, 'x'], [10, 'x'], [10, 'x'], [10, 'x'], [10, 'x'], [10, 'x']
]);
300
rex > realbowl([ [10, 'x'], [4, 6], [5, 0] ]);
40
Note that realbowl does handle inputs that aren't real bowling
games, e.g., anything with [10, 0] in it.