Dan Anglin
1b9c390ce6
Add the third solution to the shuffle experiment which happens to be the most performant solution according to the basic benchmark test.
91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package main
|
|
|
|
type shuffleDirection int
|
|
|
|
const (
|
|
left shuffleDirection = iota
|
|
right
|
|
)
|
|
|
|
// shuffleFuncOne creates a new list where an element in one position is repositioned
|
|
// to the index of another element. All affected elements then shuffleFuncOne one place to the left
|
|
// or right depending on the direction of the move.
|
|
func shuffleFuncOne(input []any, oldPos, newPos int) []any {
|
|
var direction shuffleDirection
|
|
|
|
if newPos < oldPos {
|
|
direction = right
|
|
} else {
|
|
direction = left
|
|
}
|
|
|
|
output := make([]any, len(input))
|
|
|
|
for i := range input {
|
|
switch {
|
|
case (direction == right) && (i < newPos || i > oldPos):
|
|
output[i] = input[i]
|
|
case (direction == right) && (i == oldPos):
|
|
output[newPos] = input[i]
|
|
case (direction == right):
|
|
output[i+1] = input[i]
|
|
case (direction == left) && (i < oldPos || i > newPos):
|
|
output[i] = input[i]
|
|
case (direction == left) && (i == oldPos):
|
|
output[newPos] = input[i]
|
|
case (direction == left):
|
|
output[i-1] = input[i]
|
|
}
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
// shuffleFuncTwo produces the same output as shuffleFuncOne using a slightly different method.
|
|
// The original slice is copied into a new slice and the element is immediately placed in the new
|
|
// position. The for loop then only focuses on the elements in range between the two positions and
|
|
// are shuffled left or right as required.
|
|
func shuffleFuncTwo(input []any, oldPos, newPos int) []any {
|
|
output := make([]any, len(input))
|
|
|
|
copy(output, input)
|
|
|
|
output[newPos] = input[oldPos]
|
|
|
|
if newPos < oldPos {
|
|
for i := newPos; i <= oldPos; i++ {
|
|
if i != oldPos {
|
|
output[i+1] = input[i]
|
|
}
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
for i := oldPos; i <= newPos; i++ {
|
|
if i != oldPos {
|
|
output[i-1] = input[i]
|
|
}
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
// shuffleFuncThree produces the same output as the above two functions by simply swapping
|
|
// the target element with the element one above or below in the list until that element reaches
|
|
// the desired index.
|
|
func shuffleFuncThree(list []any, oldPos, newPos int) []any {
|
|
if newPos < oldPos {
|
|
for i := oldPos; i > newPos; i-- {
|
|
list[i], list[i-1] = list[i-1], list[i]
|
|
}
|
|
|
|
return list
|
|
}
|
|
|
|
for i := oldPos; i < newPos; i++ {
|
|
list[i], list[i+1] = list[i+1], list[i]
|
|
}
|
|
|
|
return list
|
|
}
|