package mergesort import ( "reflect" "testing" ) // MergeSort returns a sorted copy of nums using merge sort. func MergeSort(nums []int) []int { if len(nums) <= 1 { return append([]int(nil), nums...) } mid := len(nums) / 2 left := MergeSort(nums[:mid]) right := MergeSort(nums[mid:]) return merge(left, right) } // merge combines two sorted slices into one sorted slice. func merge(left, right []int) []int { result := make([]int, 0, len(left)+len(right)) i, j := 0, 0 for i < len(left) && j < len(right) { if left[i] <= right[j] { result = append(result, left[i]) i++ } else { result = append(result, right[j]) j++ } } result = append(result, left[i:]...) result = append(result, right[j:]...) return result } func TestMergeSort(t *testing.T) { input := []int{5, 2, 9, 1, 5, 6} want := []int{1, 2, 5, 5, 6, 9} if got := MergeSort(input); !reflect.DeepEqual(got, want) { t.Fatalf("MergeSort(%v) = %v, want %v", input, got, want) } } func TestMergeSortHandlesEmptyAndSingleItem(t *testing.T) { tests := []struct { name string input []int want []int }{ {name: "empty", input: []int{}, want: []int{}}, {name: "single", input: []int{42}, want: []int{42}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := MergeSort(tt.input); !reflect.DeepEqual(got, tt.want) { t.Fatalf("MergeSort(%v) = %v, want %v", tt.input, got, tt.want) } }) } } func TestMergeSortDoesNotMutateInput(t *testing.T) { input := []int{3, 1, 2} original := append([]int(nil), input...) _ = MergeSort(input) if !reflect.DeepEqual(input, original) { t.Fatalf("MergeSort mutated input: got %v, want %v", input, original) } }