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 theintn. 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 namedfilenameand returns two things:- A
map[string]intwhose 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
nilif the file was successfully opened and read. If the file cannot be read (e.g. it doesn’t exist), then the returned map should beniland 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.txtcontains this:The big big dog ate the big apple
Then if you call:
results, err := countWords("sample.txt") // ...
errshould benil, andresultsshould be:map[The:1 big:3 dog:1 ate:1 the:1 apple:1]
Note that case matters: strings like
theandTheare 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)returnstrueifaandbare exactly the same time, andfalseotherwise.The function
lessThanTime24(a, b)returnstrue, if timeacomes strictly beforeb, andfalseotherwise.The method (not a function!)
t.String()that converts atto 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 forStringimplements the fmt.Stringer interface, and functions likefmt.Printknow to callString()on objects that implement it.The method (not a function!)
t.validTime24()returnstrueiftis a validTime24object (i.e. it meets the constraints listed in the comments below thestruct), andfalseotherwise.The function
minTime24, which returns the smallest time in a slice ofTime24objects. It has this signature:func minTime24(times []Time24) (Time24, error)
If
timesis empty, thenTime24{0, 0, 0}is returned, along with an error object with a helpful message.If
timeshas 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 ofxin 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 ofxis not the same as the type of the elements inlst, thenlinearSearchshould callpanicwith 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
[][]intdoesn’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
nitallBitSeqswill take too much time and memory to actually run. Nonetheless, the algorithm you use to calculate the bit sequences should work with anyintgreater than 0, if given enough time and memory.