Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Random (Animal Magic) missing hint about difference of slices with string literals vs strings on the heap #2844

Closed
woeps opened this issue Nov 21, 2024 · 1 comment

Comments

@woeps
Copy link

woeps commented Nov 21, 2024

I tried to implement ShuffleAnimals

// ShuffleAnimals returns a slice with all eight animal strings in random order.
func ShuffleAnimals() []string {
panic("Please implement the ShuffleAnimals function")
}

like this:

// ShuffleAnimals returns a slice with all eight animal strings in random order.
var animals = []string{"ant", "beaver", "cat", "dog", "elephant", "fox", "giraffe", "hedgehog"}
func ShuffleAnimals() []string {
	rand.Shuffle(len(animals), func(i, j int) {
		animals[i], animals[j] = animals[j], animals[i]
	})
	return animals
}

This consistently produced the following error when running tests:

$ go test
--- FAIL: TestShuffleAnimals (0.00s)
    animal_magic_test.go:85: ShuffleAnimals() always generates the same slice: [cat beaver giraffe fox ant
 elephant dog hedgehog]
FAIL
exit status 1
FAIL    chance  0.007s

I smashed my head against the wall for about an hour to solve this. I partially got mislead by the readme's chapter on seeds, which has nothing to do with the solution or the problem I hit:

## Seeds
The number sequences generated by package `math/rand` are not truly random.
Given a specific "seed" value, the results are entirely deterministic.
In Go 1.20+ the seed is automatically picked at random so you will see a different sequence of random numbers each time you run your program.
In prior versions of Go, the seed was `1` by default.
So to get different sequences for various runs of the program, you had to manually seed the random number generator, e.g. with the current time, before retrieving any random numbers.
```go
rand.Seed(time.Now().UnixNano())
```

Doing lots of search and digging more into the rand.Shuffle implementation I learned, that the function's behavior depends on the slice-elements' memory-address: A slice of string literals having constant memory addresses will result in a constant order by rand.Shuffle.

Previous concepts didn't mention differences of string literals vs heap allocated strings and I didn't know about this, which cost me some time and a lot of nerves.

Is it possible to ...

  • detect the usage of string literals in the test and print a distinct error?
  • add a hint about string literals?
  • cover this detail in previous concepts?
Copy link
Contributor

Hello. Thanks for opening an issue on Exercism 🙂

At Exercism we use our Community Forum, not GitHub issues, as the primary place for discussion. That allows maintainers and contributors from across Exercism's ecosystem to discuss your problems/ideas/suggestions without them having to subscribe to hundreds of repositories.

This issue will be automatically closed. Please use this link to copy your GitHub Issue into a new topic on the forum, where we look forward to chatting with you!

If you're interested in learning more about this auto-responder, please read this blog post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant