Hone logo
Hone
Problems

Mastering Go Slices: Building Fundamental Operations

Go slices are a powerful and flexible data structure, serving as dynamic views into underlying arrays. Understanding how to manipulate them is crucial for efficient Go programming. This challenge will guide you through implementing common slice operations from scratch, deepening your comprehension of their mechanics.

Problem Description

Your task is to implement several fundamental slice operations in Go. You will create functions that mimic the behavior of built-in slice operations, allowing you to control how slices are accessed, modified, and combined. This will involve working with slice indexing, slicing syntax, and potentially capacity and underlying array behavior.

Specifically, you need to implement the following functions:

  1. GetElement(slice []int, index int) (int, error): Returns the element at a given index. Returns an error if the index is out of bounds.
  2. SubSlice(slice []int, start, end int) ([]int, error): Returns a new slice containing elements from start (inclusive) to end (exclusive). Returns an error for invalid start or end indices.
  3. AppendElement(slice []int, element int) []int: Appends a single element to the end of a slice.
  4. AppendSlice(slice1, slice2 []int) []int: Appends all elements of slice2 to the end of slice1.
  5. CopySlice(source []int, destination []int) (int, error): Copies elements from source to destination. Returns the number of elements copied and an error if the destination is too small.

Examples

Example 1: Input: slice = []int{1, 2, 3, 4, 5} index = 2 Output: 2, nil Explanation: The element at index 2 (0-based) is 3.

Example 2: Input: slice = []int{1, 2, 3, 4, 5} start = 1 end = 4 Output: []int{2, 3, 4}, nil Explanation: Elements from index 1 up to (but not including) index 4 are {2, 3, 4}.

Example 3: Input: slice = []int{1, 2, 3} element = 4 Output: []int{1, 2, 3, 4} Explanation: The element 4 is appended to the original slice.

Example 4: Input: slice1 = []int{1, 2} slice2 = []int{3, 4, 5} Output: []int{1, 2, 3, 4, 5} Explanation: All elements of slice2 are appended to slice1.

Example 5: Input: source = []int{1, 2, 3} destination = []int{0, 0, 0, 0, 0} Output: 3, nil destination becomes []int{1, 2, 3, 0, 0} Explanation: The first 3 elements of source are copied into destination.

Example 6 (Edge Case): Input: slice = []int{1, 2, 3} index = 5 Output: 0, errors.New("index out of bounds") Explanation: The index 5 is greater than the length of the slice (3), so an out-of-bounds error is returned.

Example 7 (Edge Case): Input: source = []int{1, 2, 3} destination = []int{0, 0} Output: 0, errors.New("destination slice is too small") Explanation: The destination slice can only hold 2 elements, but source has 3 elements to copy.

Constraints

  • Slice elements will be integers (int).
  • Indices for GetElement and SubSlice will be non-negative.
  • For SubSlice, start will be less than or equal to end.
  • Performance is not a primary concern for this challenge; focus on correctness and understanding slice mechanics.

Notes

  • Consider how Go handles slice indexing and slicing syntax.
  • Pay attention to the lengths and capacities of slices when performing append operations.
  • For error handling, use the errors package.
  • You are implementing these functions as if the built-in equivalents did not exist. Do not use append directly within your AppendElement or AppendSlice implementations, and do not use copy directly within your CopySlice implementation. Instead, simulate their behavior using loops and slice indexing.
Loading editor...
go