Assignment 5: Practice with Go¶
The following questions are meant as practice for learning some of the basic
features of Go. Write all your solution code in a single file named
a5.go
, in a package named main
.
Each question is out of 2 marks: 1 for correctness, and 1 for code style and readability. Readability includes using Go features in an appropriate way.
You may import any standard Go packages. Write all other code yourself: don’t use any packages or code from outside of the Go standard library. Please clearly cite the source of any ideas you used in this work.
Please submit your final a5.go
file on Canvas.
(2 marks) Implement a function called
countEmirpsLessThan(n)
that returns the number of emirps less than theint
n
. An emirp is prime number that is a different prime when you reverse its digits. For example, the emirps less than 100 are 13, 17, 31, 37, 71, 73, 79, and 97, and socountEmirpsLessThan(100)
should return 8.Note that primes such as 11 and 101 are not emirps since there reversals are not different primes.
(2 marks) Implement the following function:
func countWords(filename string) (map[string]int, error)
countWords(filename)
reads the contents of the text file namedfilename
and returns two things:- A
map[string]int
whose keys are all the different words in the file, and whose values are the number of times the corresponding key occurs in the file. - An error code that is
nil
if the file was successfully opened and read. If the file cannot be read (e.g. it doesn’t exist), then the returned map should benil
and the error should be the error returned by your file-reading function.
For this questions, words are defined to be strings separated by either a space or a newline character.
For example, suppose you have the text file
sample.txt
contains this:The big big dog ate the big apple
Then if you call:
results, err := countWords("sample.txt") // ...
err
should benil
, andresults
should be:map[The:1 big:3 dog:1 ate:1 the:1 apple:1]
Note that case matters: strings like
the
andThe
are considered different strings.- A
(2 marks) Here’s a simple way to represent a moment in time:
type Time24 struct { hour, minute, second uint8 } // 0 <= hour < 24 // 0 <= minute < 60 // 0 <= second < 60
Implement the following functions and methods:
The function
equalsTime24(a, b)
returnstrue
ifa
andb
are exactly the same time, andfalse
otherwise.The function
lessThanTime24(a, b)
returnstrue
, if timea
comes strictly beforeb
, andfalse
otherwise.The method (not a function!)
t.String()
that converts at
to human-readable string. It has this signature:func (t Time24) String() string { // ... }
The returned string should have the form “hh:mm:ss”. For example:
t := Time24{hour: 5, minute: 39, second: 8} fmt.Println(t) // "05:39:08"
Notice that each number is written as 2-digits, possibly with a leading 0. Thus the returned string will always be the same length.
Also, notice that you don’t need to call
t.String()
insidefmt.Println
. That’s because the signature forString
implements the fmt.Stringer interface, and functions likefmt.Print
know to callString()
on objects that implement it.The method (not a function!)
t.validTime24()
returnstrue
ift
is a validTime24
object (i.e. it meets the constraints listed in the comments below thestruct
), andfalse
otherwise.The function
minTime24
, which returns the smallest time in a slice ofTime24
objects. It has this signature:func minTime24(times []Time24) (Time24, error)
If
times
is empty, thenTime24{0, 0, 0}
is returned, along with an error object with a helpful message.If
times
has one, or more, items, then the smallest time is returned, and the error isnil
.
(2 marks) Write a function called
linearSearch(x, lst)
that uses linear search to return the first index location ofx
in the slicelst
. It must work with (at least) both strings and ints as in these examples:linearSearch(5, []int{4, 2, -1, 5, 0})
returns 3linearSearch(3, []int{4, 2, -1, 5, 0})
returns -1 (because 3 is not in the slice)linearSearch("egg", []string{"cat", "nose", "egg"})
returns 2linearSearch("up", []string{"cat", "nose", "egg"})
returns -1
You can use helper functions, but you must have only one function named
linearSearch
. If the type ofx
is not the same as the type of the elements inlst
, thenlinearSearch
should callpanic
with a helpful message.(2 marks) Implement a function the returns all bit sequences of length n. It should have this signature:
func allBitSeqs(n int) [][]int
A bit sequence is a slice of ints that contains only 0s and 1s.
For example:
allBitSeqs(1)
returns[[0] [1]]
.allBitSeqs(2)
returns[[0 0] [0 1] [1 0] [1 1]]
.allBitSeqs(3)
returns[[0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] [1 0 1] [1 1 0] [1 1 1]]
.
The exact order of the slices in the returned
[][]int
doesn’t matter. So, for example,allBitSeqs(2)
could instead return[[1 1] [1 0] [0 0] [0 1]]
.If
n <= 0
, then return an empty[][]int
.Of course, for large values of
n
itallBitSeqs
will take too much time and memory to actually run. Nonetheless, the algorithm you use to calculate the bit sequences should work with anyint
greater than 0, if given enough time and memory.