// 3. hét – Tömbműveletek: beszúrás, törlés, megfordítás, forgatás
// Futtatás: go run ./h03/arrayops
package main

import "fmt"

// insert a pos indexre szúr be; a tömbben n elem van. Hátulról toljuk jobbra – O(n).
func insert(a []int, n, pos, x int) int {
	if n == len(a) {
		panic("a tömb megtelt")
	}
	for i := n - 1; i >= pos; i-- {
		a[i+1] = a[i]
	}
	a[pos] = x
	return n + 1
}

// deleteAt a pos indexről töröl: elölről toljuk balra – O(n).
func deleteAt(a []int, n, pos int) int {
	for i := pos; i < n-1; i++ {
		a[i] = a[i+1]
	}
	a[n-1] = 0
	return n - 1
}

// reverse helyben, két mutatóval – O(n).
func reverse(a []int) {
	for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
		a[i], a[j] = a[j], a[i]
	}
}

// rotateLeft k hellyel, három megfordítással – O(n), O(1) tárigény.
func rotateLeft(a []int, k int) {
	k %= len(a)
	reverse(a[:k])
	reverse(a[k:])
	reverse(a)
}

func main() {
	a := make([]int, 6)
	n := copy(a, []int{5, 8, 13, 21, 34})
	fmt.Println("kezdetben:     ", a, "n =", n)

	n = insert(a, n, 2, 99)
	fmt.Println("insert(2, 99): ", a, "n =", n)

	n = deleteAt(a, n, 1)
	fmt.Println("delete(1):     ", a, "n =", n)

	r := []int{1, 2, 3, 4, 5}
	reverse(r)
	fmt.Println("reverse:       ", r)

	q := []int{1, 2, 3, 4, 5}
	rotateLeft(q, 2)
	fmt.Println("rotateLeft(2): ", q)

	// Szeletekkel ugyanez tömörebben (a háttérben ugyanúgy O(n) mozgatás történik)
	s := []int{5, 8, 13, 21, 34}
	s = append(s[:2], append([]int{99}, s[2:]...)...) // beszúrás
	s = append(s[:1], s[2:]...)                       // törlés
	fmt.Println("szeletekkel:   ", s)
}
