package main

// MinStackOld ...
type MinStackOld struct {
	val []int
	min []int
	top int
}

// ConstructorOld /** initialize your data structure here. */
func ConstructorOld() MinStackOld {
	s := MinStackOld{make([]int, 0), make([]int, 0), -1}
	return s
}

// Push ...
func (stack *MinStackOld) Push(x int) {
	stack.val = append(stack.val, x)
	stack.top++
	idx := 0
	for ; idx < stack.top; idx++ {
		if x > stack.val[idx] {
			break
		}
	}
	stack.min = append(stack.min, 0)
	copy(stack.min[idx+1:stack.top+1], stack.min[idx:stack.top])
	stack.min[idx] = x
}

// Pop ...
func (stack *MinStackOld) Pop() {
	if stack.top != -1 {
		idx := 0
		for ; idx < stack.top+1; idx++ {
			if stack.min[idx] == stack.val[stack.top] {
				break
			}
		}
		stack.min = append(stack.min[:idx], stack.min[idx+1:]...)
		stack.val = stack.val[:stack.top]
		stack.top--
	}
}

// Top ...
func (stack *MinStackOld) Top() int {
	return stack.val[stack.top]
}

// GetMin ...
func (stack *MinStackOld) GetMin() int {
	return stack.min[stack.top]
}

/**
 * Your MinStack object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(x);
 * obj.Pop();
 * param_3 := obj.Top();
 * param_4 := obj.GetMin();
 */

// MinStack ...
type MinStack struct {
	val []int
	min []int
}

// Constructor /** initialize your data structure here. */
func Constructor() MinStack {
	return MinStack{}
}

// Push important! min []int stores the "current miximum"
func (stack *MinStack) Push(x int) {
	stack.val = append(stack.val, x)
	if len(stack.min) == 0 {
		stack.min = append(stack.min, x)
		return
	}
	m := stack.min[len(stack.min)-1]
	if x < m {
		stack.min = append(stack.min, x)
		return
	}
	stack.min = append(stack.min, m)
}

// Pop ...
func (stack *MinStack) Pop() {
	n := len(stack.val) - 1
	stack.val = stack.val[:n]
	stack.min = stack.min[:n]
}

// Top ...
func (stack *MinStack) Top() int {
	return stack.val[len(stack.val)-1]
}

// GetMin ...
func (stack *MinStack) GetMin() int {
	return stack.min[len(stack.min)-1]
}

// func main() {
// 	stack := Constructor()
// 	stack.Push(1)
// 	fmt.Println(stack.Top())
// 	fmt.Println(stack.GetMin())
// }