CS 331 Spring 2025
>
Assignment 2 (Coding in Lua)
CS 331 Spring 2025
Assignment 2 (Coding in Lua)
Assignment 2 is due at
5 pm on
Tuesday, February 11.
It is worth 70 points.
Procedures
This assignment is to be done individually.
Turn in answers to the exercises below on the
UA Canvas
site,
under Assignment 2 for this class.
- Your answers must consist of
the answer to Exercise A
(submitted as an attached text/PDF file),
and
the source code for Exercise B
(file
pa2.lua
).
- I may not look at your homework submission immediately.
If you have questions,
e-mail me.
Exercises (A–B, 70 pts total)
Exercise A — Running a Haskell Program
Purpose
In this exercise
you will make sure you can execute Haskell code.
Instructions
Get the file check_haskell.hs
from the class Git repository.
This is a Haskell source file for a complete program.
When it is executed,
this program prints
“Secret message #2:
”.
Below that, it prints a secret message.
Run the program.
What is the secret message?
There are several ways to execute a Haskell program.
One of them is to start up the GHCi interactive Haskell environment,
type “:l check_haskell
”
at the prompt
(that is a lower-case ELL after the colon),
and then at the next prompt, type
“main
”.
Exercise B — Programming in Lua
Purpose
In this exercise
you will write a Lua module.
The module will contain
functions dealing with tables, strings, and numbers.
One of the functions will be a coroutine.
Another will be an iterator function,
usable with Lua’s for-in loop.
Instructions
Write a Lua module pa2
,
contained in the file pa2.lua
(note the capitalization!).
Module pa2
must export the following
four functions, and nothing else:
mapArray
,
mostCommon
,
prefixSuffix
,
collatz
.
Be sure to follow the
Coding Standards.
- Function
mapArray
.
This takes a function f
and a table t
,
which is to be treated as an array.
Function f
can be assumed to be a one-parameter
function that will accept any value in array t
.
mapArray
returns an array containing
a key-value pair k, f(v)
for each
key-value pair k, v
in t
with k
ranging from 1 to the greatest positive integer
such that all keys 1, ..., k
appear in the array.
No other key-value pairs will appear in your result.
Example:
function addTen(n)
return n + 10
end
arr = { [1]=1, [2]=2, [3]=3 }
marr = pa2.mapArray(addTen, arr)
-- marr must be { [1]=11, [2]=12, [3]=13 }.
Other keys may appear in the table passed to the function.
Your code must not do anything with these.
This means that you cannot use the #
operator.
You may use function ipairs
.
function addX(s)
return s.."X"
end
arr = { [1]="emu", [2]="cat", [44]="fox", [true]="ape" }
marr = pa2.mapArray(addX, arr)
-- marr must be { [1]="emuX", [2]="catX", [3]=13 }.
- Function
mostCommon
.
This function takes a string.
It returns the character (as a string of length 1)
that occurs most often in the given string.
If there is more than one most common character,
then the one whose first appearance is earliest in the string is returned.
If the given string is empty,
then the empty string is returned.
So, for example,
the function call
mostCommon("severance")
will return "e"
,
since the character "e"
occurs three times in "severance"
,
while all other characters occur at most once.
And
mostCommon("abbbaa")
will return "a"
.
Both "a"
and "b"
appear three times,
but the first appearance of "a"
comes before that of "b"
.
The following table gives other examples.
Argument |
Return Value |
"severance" |
"e" |
"abbbaa" |
"a" |
"Mississippi" |
"i" |
"%" |
"%" |
"" (empty string) |
"" (empty string) |
"I like coconuts and pears!" |
" " (the blank character) |
- Coroutine
prefixSuffix
.
This takes a single parameter s
,
which must be a string.
It then yields the prefixes of s
,
in order from length 0 up to length n,
where n is the length of s
,
followed by the suffixes of s
,
in order from length n−1 down to length 1.
A prefix of a string is a substring that starts at the beginning.
For example, "abc"
is a prefix of "abcdefg"
.
Similarly, a suffix of a string is a substring that ends at the end.
For example, "defg"
is a suffix of "abcdefg"
.
If "wxyz"
is passed to the coroutine, in the appropriate manner,
then the following will be yielded, in the order shown.
""
"w"
"wx"
"wxy"
"wxyz"
"xyz"
"yz"
"z"
If "@"
is passed,
then the following will be yielded, in the order shown.
If ""
is passed,
then the following will be yielded, in the order shown.
- Function
collatz
.
This takes a single parameter k
,
which must be a positive integer.
It returns an iterator usable in a for-in loop.
Its iterator goes through one or more integers;
these are the entries in the Collatz sequence
starting at k
, as explained below.
Function collatz
is usable as follows.
for i in collatz(n) do
ff(i) -- Do something with i
end
The Collatz function [L. Collatz 1937]
is the following function \(c\),
defined on the positive integers.
\[
c(n) = \begin{cases} 3n+1, & \text{if } n \text{ is odd;}\\
n/2, & \text{if } n \text{ is even.}
\end{cases}
\]
The Collatz sequence starting at a positive integer \(k\)
is
\[
k,\ c(k),\ c(c(k)),\ c(c(c(k))),\ \dots,\ 1.
\]
That is, the sequence begins with \(k\),
each later entry is the result of applying function \(c\) to the entry
preceding it,
and the sequence stops when it reaches \(1\).
Let us construct the Collatz sequence starting at \(3\).
- \(3\) is odd, so \(c(3) = 3\cdot 3 + 1 = 10\).
- \(10\) is even, so \(c(10) = 10/2 = 5\).
- \(5\) is odd, so \(c(5) = 3\cdot 5 + 1 = 16\).
- \(16\) is even, so \(c(16) = 16/2 = 8\).
- \(8\) is even, so \(c(8) = 8/2 = 4\).
- \(4\) is even, so \(c(4) = 4/2 = 2\).
- \(2\) is even, so \(c(2) = 2/2 = 1\).
- \(1\) has been reached; the sequence stops here.
So the Collatz sequence starting at \(3\) is
\[
3, 10, 5, 16, 8, 4, 2, 1.
\]
Therefore, this code
for i in collatz(3) do
io.write(i.." ")
end
io.write("\n")
will produce the following output:
3 10 5 16 8 4 2 1
If collatz(3)
is replaced by collatz(2)
,
then the output will be the following:
2 1
Test Program
A test program
is available in the Git repository:
pa2_test.lua
.
If you
run this program (unmodified!) with your code,
then it will test
whether your code works properly.
You may assume that the test program will pass reasonable
values to your code.
For example, the parameter to mostCommon
will always be a string,
and the parameter to collatz
will always be a positive integer.
However, as noted above,
the table passed to mapArray
may contain extra keys.
To use the test program,
place it (pa2_test.lua
)
and your source file (pa2.lua
)
in the same directory,
and then execute the test program file.
Do not execute your file.
Do not turn in the test program.