// Week 3 – Arrays and slices in Go
// Run: go run ./w03/arraybasics
package main

import (
	"fmt"
	"slices"
)

func main() {
	// Array: the size is PART OF THE TYPE ([5]int and [6]int are different types)
	var a [5]int // every element is 0
	primes := [5]int{2, 3, 5, 7, 11}
	auto := [...]string{"a", "b", "c"} // the compiler counts the size
	fmt.Println("a =", a, "primes =", primes, "auto =", auto, "len =", len(auto))

	// Direct access – O(1)
	primes[0] = 1
	fmt.Println("primes[4] =", primes[4])

	// Bounds: a constant index gives a compile error, a variable index a run-time error (panic)
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Error:", r)
			rest()
		}
	}()
	i := 5
	primes[i] = 13 // panic: index out of range
}

func rest() {
	primes := [5]int{1, 3, 5, 7, 11}

	// Traversal
	sum := 0
	for _, p := range primes {
		sum += p
	}
	fmt.Println("sum =", sum)

	// An array is a VALUE: assignment copies it!
	cp := primes
	cp[1] = 100
	fmt.Println("primes[1] =", primes[1], ", cp[1] =", cp[1])

	// Slice: a dynamically sized "view" of a backing array
	s := []int{5, 2, 9, 1}
	s = append(s, 7) // extension
	fmt.Println("slice:", s, "len =", len(s), "cap =", cap(s))

	alias := s // assigning a slice does NOT copy the elements
	alias[0] = 0
	fmt.Println("after alias[0] = 0, s[0] =", s[0])

	dup := slices.Clone(s) // a real copy
	slices.Sort(dup)
	fmt.Println("sorted copy:", dup, ", original:", s)

	z := make([]int, 3, 10) // len 3, cap 10
	fmt.Println("make([]int, 3, 10):", z, len(z), cap(z))
}
