exalysis
exalysis copied to clipboard
Valid solution fails to compile under Exalysis
Solution 17070203b36548d8aa7b2cd0e1c24802 compiles and passes tests when you run go test in the solution, but running Exalysis gives a compilation failure:
go test
PASS
ok _/Users/john/git/bitfield/exercism/users/ksimon1/go/robot-name 0.006s
exalysis
Hi there!
This looks very good!
Could you have a look at the following point so I can approve the solution?
- Unfortunately, this solution does not compile correctly. Did you run the tests? Maybe you accidentally submitted an incomplete solution? If you're having trouble getting your program to compile, you can always ask me for help!
Here's the source:
//Package robotname implements functions for creating robot
package robotname
import (
"fmt"
"math/rand"
"time"
)
//Robot hold informations about robot
type Robot struct {
name string
}
var robotNamesList = make(map[string]bool)
const (
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
//26 letters - len(11010) == 5
letterIDBits = 5
//binary masK 11111
letterIDMask = 1<<letterIDBits - 1
//how many times we can iterate in 63 bit number with letter binary mask
maxLettersMask = 63 % letterIDBits
numbers = "0123456789"
//10 numbers - len(1010) == 4
numbersIDBits = 4
//binary mask 1111
numberIDMask = 1<<numbersIDBits - 1
//how many times we can iterate in 63 bit number with number binary mask
maxNumbersMask = 63 % numbersIDBits
numberOfLetters = 2
numberOfNumbers = 3
)
//Name returns robot name
//if name doesn't exist, it generates new one
func (r *Robot) Name() (string, error) {
if r.name == "" {
var err error
r.name, err = getNewName()
if err != nil {
return "", err
}
}
return r.name, nil
}
//Reset resets robot name
func (r *Robot) Reset() string {
r.name = ""
return r.name
}
//getNewName returns new random name. If limit of name is reached returns error
func getNewName() (string, error) {
name := ""
for {
if len(robotNamesList) == maxNames {
return "", fmt.Errorf("Max number of names reached")
}
name = generateRandomName()
if ok := robotNamesList[name]; !ok {
robotNamesList[name] = true
break
}
}
return name, nil
}
//new pseudo-random Source seeded with the given value of time.Now() in unix timestamp
var src = rand.NewSource(time.Now().UnixNano())
//generateRandomName generate new name in format AA111
func generateRandomName() string {
b := make([]byte, 5)
var cache int64
remain := 0
i := numberOfLetters - 1
for i >= 0 {
//if we exhaust 63 bit random number, create new one
if remain == 0 {
cache, remain = rand.Int63(), maxLettersMask
}
//if bitwise AND operation is in interval
if id := int(cache & letterIDMask); id < len(letters) {
//save new letter
b[i] = letters[id]
i--
}
//shift random number
cache >>= letterIDBits
remain--
}
//calculate if we can still use old random number
remain = (remain * letterIDBits) % numbersIDBits
i = numberOfNumbers - 1
for i >= 0 {
//if we exhaust 63 bit random number, create new one
if remain == 0 {
cache, remain = rand.Int63(), maxNumbersMask
}
//if bitwise AND operation is in interval
if id := int(cache & numberIDMask); id < len(numbers) {
//save new letter
b[i+2] = numbers[id]
i--
}
//shift random number
cache >>= letterIDBits
remain--
}
return string(b)
}