// 8. hét – Kétvégű sor (deque) ciklikus tömbbel
// Futtatás: go run ./h08/deque
package main

import "fmt"

type Deque struct {
	data         []int
	front, count int
}

func NewDeque(capacity int) *Deque { return &Deque{data: make([]int, capacity)} }

func (d *Deque) index(i int) int { return (d.front + i) % len(d.data) }

func (d *Deque) AddFirst(x int) {
	if d.count == len(d.data) {
		panic("tele")
	}
	d.front = (d.front - 1 + len(d.data)) % len(d.data) // Go-ban is: -1 % n negatív lenne!
	d.data[d.front] = x
	d.count++
}

func (d *Deque) AddLast(x int) {
	if d.count == len(d.data) {
		panic("tele")
	}
	d.data[d.index(d.count)] = x
	d.count++
}

func (d *Deque) RemoveFirst() int {
	x := d.data[d.front]
	d.front = (d.front + 1) % len(d.data)
	d.count--
	return x
}

func (d *Deque) RemoveLast() int {
	x := d.data[d.index(d.count-1)]
	d.count--
	return x
}

func (d *Deque) Items() []int {
	r := make([]int, d.count)
	for i := range r {
		r[i] = d.data[d.index(i)]
	}
	return r
}

func main() {
	d := NewDeque(6)
	d.AddLast(3)
	d.AddLast(4)
	d.AddFirst(2)
	d.AddFirst(1)
	d.AddLast(5)
	fmt.Println("deque:", d.Items())
	f := d.RemoveFirst()
	l := d.RemoveLast()
	fmt.Println("RemoveFirst =", f, ", RemoveLast =", l, "->", d.Items())

	// Palindrom-ellenőrzés deque-vel
	p := NewDeque(16)
	for _, c := range "racecar" {
		p.AddLast(int(c))
	}
	pal := true
	for p.count > 1 {
		if p.RemoveFirst() != p.RemoveLast() {
			pal = false
		}
	}
	fmt.Println(`"racecar" palindrom (deque-vel)?`, pal)
}
