← run

go-01-unique

1.000
3/3 tests· basic
Challenge · difficulty 1/5
# Unique preserving order

Implement **`solution.go`** in `package challenge` exporting:

```go
func Unique(xs []int) []int
```

Return a new slice containing the elements of `xs` with duplicates removed, keeping each value at
the position of its **first occurrence**.

Rules:

- Preserve **first-occurrence order** — do not sort the result.
- Each distinct value appears exactly once.
- Do **not** mutate the input slice.
- For an empty (or nil) input, return an **empty, non-nil** slice (length 0).

Examples:

```go
Unique([]int{3, 1, 3, 2, 1}) // => [3, 1, 2]
Unique([]int{1, 2, 3})       // => [1, 2, 3]
Unique([]int{5, 5, 5})       // => [5]
Unique([]int{})              // => [] (non-nil, length 0)
```
tests/solution_test.go
package challenge

import (
	"reflect"
	"testing"
)

func TestUnique(t *testing.T) {
	cases := []struct {
		name string
		in   []int
		want []int
	}{
		{"removes duplicates preserving order", []int{3, 1, 3, 2, 1}, []int{3, 1, 2}},
		{"already unique unchanged", []int{1, 2, 3}, []int{1, 2, 3}},
		{"all same collapses to one", []int{5, 5, 5}, []int{5}},
		{"empty returns empty", []int{}, []int{}},
		{"single element", []int{42}, []int{42}},
		{"negatives and zero", []int{0, -1, 0, -1, 2}, []int{0, -1, 2}},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			got := Unique(tc.in)
			if !reflect.DeepEqual(got, tc.want) {
				t.Errorf("Unique(%v) = %v, want %v", tc.in, got, tc.want)
			}
		})
	}
}

func TestUniqueReturnsNonNil(t *testing.T) {
	if Unique([]int{}) == nil {
		t.Error("Unique should return a non-nil slice for empty input")
	}
	if Unique(nil) == nil {
		t.Error("Unique should return a non-nil slice for nil input")
	}
}

func TestUniqueDoesNotMutateInput(t *testing.T) {
	in := []int{1, 1, 2}
	_ = Unique(in)
	if !reflect.DeepEqual(in, []int{1, 1, 2}) {
		t.Errorf("input was mutated: got %v", in)
	}
}
System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.
Proposed solution
```go
package challenge

func Unique(xs []int) []int {
	seen := make(map[int]bool)
	result := make([]int, 0)
	for _, v := range xs {
		if !seen[v] {
			seen[v] = true
			result = append(result, v)
		}
	}
	return result
}
```

Test output (stdout)

e":"2026-07-21T16:11:45.380205155+02:00","Action":"output","Package":"challenge","Test":"TestUnique/all_same_collapses_to_one","Output":"--- PASS: TestUnique/all_same_collapses_to_one (0.00s)\n"}
{"Time":"2026-07-21T16:11:45.380206795+02:00","Action":"pass","Package":"challenge","Test":"TestUnique/all_same_collapses_to_one","Elapsed":0}
{"Time":"2026-07-21T16:11:45.380208225+02:00","Action":"run","Package":"challenge","Test":"TestUnique/empty_returns_empty"}
{"Time":"2026-07-21T16:11:45.380209475+02:00","Action":"output","Package":"challenge","Test":"TestUnique/empty_returns_empty","Output":"=== RUN   TestUnique/empty_returns_empty\n"}
{"Time":"2026-07-21T16:11:45.380211245+02:00","Action":"output","Package":"challenge","Test":"TestUnique/empty_returns_empty","Output":"--- PASS: TestUnique/empty_returns_empty (0.00s)\n"}
{"Time":"2026-07-21T16:11:45.380212835+02:00","Action":"pass","Package":"challenge","Test":"TestUnique/empty_returns_empty","Elapsed":0}
{"Time":"2026-07-21T16:11:45.380216545+02:00","Action":"run","Package":"challenge","Test":"TestUnique/single_element"}
{"Time":"2026-07-21T16:11:45.380217885+02:00","Action":"output","Package":"challenge","Test":"TestUnique/single_element","Output":"=== RUN   TestUnique/single_element\n"}
{"Time":"2026-07-21T16:11:45.380220295+02:00","Action":"output","Package":"challenge","Test":"TestUnique/single_element","Output":"--- PASS: TestUnique/single_element (0.00s)\n"}
{"Time":"2026-07-21T16:11:45.380221825+02:00","Action":"pass","Package":"challenge","Test":"TestUnique/single_element","Elapsed":0}
{"Time":"2026-07-21T16:11:45.380223855+02:00","Action":"run","Package":"challenge","Test":"TestUnique/negatives_and_zero"}
{"Time":"2026-07-21T16:11:45.380226655+02:00","Action":"output","Package":"challenge","Test":"TestUnique/negatives_and_zero","Output":"=== RUN   TestUnique/negatives_and_zero\n"}
{"Time":"2026-07-21T16:11:45.380229725+02:00","Action":"output","Package":"challenge","Test":"TestUnique/negatives_and_zero","Output":"--- PASS: TestUnique/negatives_and_zero (0.00s)\n"}
{"Time":"2026-07-21T16:11:45.380231135+02:00","Action":"pass","Package":"challenge","Test":"TestUnique/negatives_and_zero","Elapsed":0}
{"Time":"2026-07-21T16:11:45.380232655+02:00","Action":"output","Package":"challenge","Test":"TestUnique","Output":"--- PASS: TestUnique (0.00s)\n"}
{"Time":"2026-07-21T16:11:45.380234375+02:00","Action":"pass","Package":"challenge","Test":"TestUnique","Elapsed":0}
{"Time":"2026-07-21T16:11:45.380235745+02:00","Action":"run","Package":"challenge","Test":"TestUniqueReturnsNonNil"}
{"Time":"2026-07-21T16:11:45.380237365+02:00","Action":"output","Package":"challenge","Test":"TestUniqueReturnsNonNil","Output":"=== RUN   TestUniqueReturnsNonNil\n"}
{"Time":"2026-07-21T16:11:45.380239165+02:00","Action":"output","Package":"challenge","Test":"TestUniqueReturnsNonNil","Output":"--- PASS: TestUniqueReturnsNonNil (0.00s)\n"}
{"Time":"2026-07-21T16:11:45.380240785+02:00","Action":"pass","Package":"challenge","Test":"TestUniqueReturnsNonNil","Elapsed":0}
{"Time":"2026-07-21T16:11:45.380242545+02:00","Action":"run","Package":"challenge","Test":"TestUniqueDoesNotMutateInput"}
{"Time":"2026-07-21T16:11:45.380244125+02:00","Action":"output","Package":"challenge","Test":"TestUniqueDoesNotMutateInput","Output":"=== RUN   TestUniqueDoesNotMutateInput\n"}
{"Time":"2026-07-21T16:11:45.380245965+02:00","Action":"output","Package":"challenge","Test":"TestUniqueDoesNotMutateInput","Output":"--- PASS: TestUniqueDoesNotMutateInput (0.00s)\n"}
{"Time":"2026-07-21T16:11:45.380247355+02:00","Action":"pass","Package":"challenge","Test":"TestUniqueDoesNotMutateInput","Elapsed":0}
{"Time":"2026-07-21T16:11:45.380248755+02:00","Action":"output","Package":"challenge","Output":"PASS\n"}
{"Time":"2026-07-21T16:11:45.380392866+02:00","Action":"output","Package":"challenge","Output":"ok  \tchallenge\t0.001s\n"}
{"Time":"2026-07-21T16:11:45.380405846+02:00","Action":"pass","Package":"challenge","Elapsed":0.001}
Reasoning (chain-of-thought)
The user wants a Go function `Unique` that removes duplicates from a slice of integers while preserving the order of first occurrences.

Key requirements:
1. Return a new slice (don't mutate input)
2. Preserve first-occurrence order
3. Each distinct value appears exactly once
4. Empty/nil input returns empty, non-nil slice

Implementation approach:
- Use a map to track seen values
- Iterate through input, add to result if not seen before
- Return the result

Let me write the solution:

```go
package challenge

func Unique(xs []int) []int {
    seen := make(map[int]bool)
    result := make([]int, 0)
    for _, v := range xs {
        if !seen[v] {
            seen[v] = true
            result = append(result, v)
        }
    }
    return result
}
```

This handles all cases:
- Empty/nil input: loop doesn't execute, returns empty non-nil slice
- Preserves order: we iterate in order and append in order
- Doesn't mutate input: we create a new slice
- Each value appears once: we check the map before adding