diff --git a/experiments/go/shuffle-elements/shuffle.go b/experiments/go/shuffle-elements/shuffle.go index 1ccfca3..5db67b8 100644 --- a/experiments/go/shuffle-elements/shuffle.go +++ b/experiments/go/shuffle-elements/shuffle.go @@ -7,10 +7,10 @@ const ( right ) -// shuffle creates a new list where an element in one position is repositioned -// to the index of another element. All affected elements then shuffle one place to the left +// 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 shuffle(list []any, oldPos, newPos int) []any { +func shuffleFuncOne(list []any, oldPos, newPos int) []any { var direction shuffleDirection if newPos < oldPos { @@ -40,3 +40,33 @@ func shuffle(list []any, oldPos, newPos int) []any { return newList } + +// 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(list []any, oldPos, newPos int) []any { + newList := make([]any, len(list)) + + copy(newList, list) + + newList[newPos] = list[oldPos] + + if newPos < oldPos { + for i := newPos; i <= oldPos; i++ { + if i != oldPos { + newList[i+1] = list[i] + } + } + + return newList + } + + for i := oldPos; i <= newPos; i++ { + if i != oldPos { + newList[i-1] = list[i] + } + } + + return newList +} diff --git a/experiments/go/shuffle-elements/shuffle_test.go b/experiments/go/shuffle-elements/shuffle_test.go index c0acfd8..55ef074 100644 --- a/experiments/go/shuffle-elements/shuffle_test.go +++ b/experiments/go/shuffle-elements/shuffle_test.go @@ -1,57 +1,66 @@ package main import ( - "fmt" "reflect" "testing" ) -func TestShuffle(t *testing.T) { - cases := []struct { - list []any - oldPosition int - newPosition int - want []any - }{ - { - list: []any{1, 2, 3, 4, 5, 6, 7, 8}, - oldPosition: 5, - newPosition: 2, - want: []any{1, 2, 6, 3, 4, 5, 7, 8}, - }, - { - list: []any{1, 2, 3, 4, 5, 6, 7, 8}, - oldPosition: 7, - newPosition: 0, - want: []any{8, 1, 2, 3, 4, 5, 6, 7}, - }, - { - list: []any{"zero", "one", "two", "three", "four", "five"}, - oldPosition: 0, - newPosition: 5, - want: []any{"one", "two", "three", "four", "five", "zero"}, - }, - { - list: []any{"zero", "one", "two", "three", "four", "five"}, - oldPosition: 2, - newPosition: 3, - want: []any{"zero", "one", "three", "two", "four", "five"}, - }, - } - - for i := range cases { - t.Run(fmt.Sprintf("Test Case %d", i), testFunc(cases[i].list, cases[i].oldPosition, cases[i].newPosition, cases[i].want)) - } +type Cases struct { + list []any + oldPosition int + newPosition int + want []any } -func testFunc(list []any, oldPosition, newPosition int, want []any) func(t *testing.T) { - return func(t *testing.T) { - t.Logf("Input list: %v", list) - t.Logf("We want '%v' to move to position %d", list[oldPosition], newPosition) +var cases = []Cases{ + { + list: []any{1, 2, 3, 4, 5, 6, 7, 8}, + oldPosition: 5, + newPosition: 2, + want: []any{1, 2, 6, 3, 4, 5, 7, 8}, + }, + { + list: []any{1, 2, 3, 4, 5, 6, 7, 8}, + oldPosition: 7, + newPosition: 0, + want: []any{8, 1, 2, 3, 4, 5, 6, 7}, + }, + { + list: []any{"zero", "one", "two", "three", "four", "five"}, + oldPosition: 0, + newPosition: 5, + want: []any{"one", "two", "three", "four", "five", "zero"}, + }, + { + list: []any{"zero", "one", "two", "three", "four", "five"}, + oldPosition: 2, + newPosition: 3, + want: []any{"zero", "one", "three", "two", "four", "five"}, + }, +} - got := shuffle(list, oldPosition, newPosition) - if !reflect.DeepEqual(want, got) { - t.Errorf("TEST FAILED: want: %v, got %v", want, got) +func TestShuffleFuncOne(t *testing.T) { + for i := range cases { + t.Logf("Input list: %v", cases[i].list) + t.Logf("We want '%v' to move to position %d", cases[i].list[cases[i].oldPosition], cases[i].newPosition) + + got := shuffleFuncOne(cases[i].list, cases[i].oldPosition, cases[i].newPosition) + if !reflect.DeepEqual(cases[i].want, got) { + t.Errorf("TEST FAILED: want: %v, got %v", cases[i].want, got) + } else { + t.Logf("TEST PASSED: got %v", got) + } + } +} + +func TestShuffleFuncTwo(t *testing.T) { + for i := range cases { + t.Logf("Input list: %v", cases[i].list) + t.Logf("We want '%v' to move to position %d", cases[i].list[cases[i].oldPosition], cases[i].newPosition) + + got := shuffleFuncTwo(cases[i].list, cases[i].oldPosition, cases[i].newPosition) + if !reflect.DeepEqual(cases[i].want, got) { + t.Errorf("TEST FAILED: want: %v, got %v", cases[i].want, got) } else { t.Logf("TEST PASSED: got %v", got) }