Hills And Valleys
You are given a sequence of $$$n$$$ integers $$$a_1$$$, $$$a_2$$$, ..., $$$a_n$$$. Let us call an index $$$j$$$ ($$$2 \le j \le {{n-1}}$$$) a hill if $$$a_j > a_{{j+1}}$$$ and $$$a_j > a_{{j-1}}$$$; and let us call it a valley if $$$a_j < a_{{j+1}}$$$ and $$$a_j < a_{{j-1}}$$$.Let us define the intimidation value of a sequence as the sum of the number of hills and the number of valleys in the sequence. You can change exactly one integer in the sequence to any number that you want, or let the sequence remain unchanged. What is the minimum intimidation value that you can achieve?
In the first test case, changing $$$a_2$$$ to $$$2$$$ results in no hills and no valleys.In the second test case, the best answer is just to leave the array as it is.In the third test case, changing $$$a_3$$$ to $$$6$$$ results in only one valley (at the index $$$5$$$).In the fourth test case, changing $$$a_3$$$ to $$$6$$$ results in no hills and no valleys.
The first line of the input contains a single integer $$$t$$$ ($$$1 \le t \le 10000$$$) — the number of test cases. The description of the test cases follows.The first line of each test case contains a single integer $$$n$$$ ($$$1 \le n \le 3\cdot10^5$$$).The second line of each test case contains $$$n$$$ space-separated integers $$$a_1$$$, $$$a_2$$$, ..., $$$a_n$$$ ($$$1 \le a_i \le 10^9$$$).It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$3\cdot10^5$$$.
For each test case, print a single integer — the minimum intimidation value that you can achieve.
def one(i, left, right):
    if i > left and i > right or (i < left and i < right):
        return True
    return False

def hill_valley(n, new_nums):
    ans = 0
    for i in range(1, n - 1):
        if one(new_nums[i], new_nums[i - 1], new_nums[i + 1]):
            ans += 1
    return ans

def min_hill_valley(n, nums):
    if n <= 3:
        return 0
    ans = hill_valley(n, nums)
    if ans <= 1:
        return 0
    minus = 0
    i = 1
    if one(nums[i], nums[i - 1], nums[i + 1]):
        minus += 1
    if one(nums[i + 1], nums[i], nums[i + 2]):
        minus += 1
    i = n - 2
    new_minus = 0
    if one(nums[i], nums[i - 1], nums[i + 1]):
        new_minus += 1
    if one(nums[i - 1], nums[i - 2], nums[i]):
        new_minus += 1
    minus = max(minus, new_minus)
    for i in range(2, n - 2):
        if one(nums[i], nums[i - 1], nums[i + 1]):
            new_minus = 1
            if one(nums[i - 1], nums[i - 2], nums[i]) and one(nums[i + 1], nums[i], nums[i + 2]):
                return ans - 3
            if one(nums[i - 1], nums[i - 2], nums[i]) and (not one(nums[i + 1], nums[i - 1], nums[i + 2])):
                new_minus += 1
            if one(nums[i + 1], nums[i], nums[i + 2]) and (not one(nums[i - 1], nums[i - 2], nums[i + 1])):
                new_minus += 1
            minus = max(minus, new_minus)
    return ans - minus
for _ in range(int(input())):
    n = int(input())
    nums = list(map(int, input().split()))
    print(min_hill_valley(n, nums))
import queue
from math import inf, gcd, floor, sqrt, ceil, log, log2, log10, factorial
import sys
from collections import *
from random import *
import itertools
sys.setrecursionlimit(99999)
eps = sys.float_info.epsilon
P = 2
INF = 1000000000.0 + 1
MOD = 10 ** 9 + 7

def is_prime(n):
    if n == 0 or n == 1:
        return False
    d = 2
    while d * d <= n:
        if n % d == 0:
            return False
        d += 1
    return True

def div_up(n, k):
    if n % k == 0:
        return n // k
    else:
        return n // k + 1

def num_len(n, base=10):
    if n == 0:
        return 1
    return int(floor(log(n, base) + 1))

def dfs_sample(graph, cl, p, v):
    cl[v] = 1
    for to in graph[v]:
        if cl[to] == 1 and p[v] != to:
            pass
        elif cl[to] == 0:
            p[to] = v
            dfs_sample(graph, cl, p, to)
    cl[v] = 2

def down(a):
    for i in range(1, len(a)):
        if a[i] > a[i - 1]:
            return False
    return True

def up(a):
    for i in range(1, len(a)):
        if a[i] < a[i - 1]:
            return False
    return True

def code(c):
    return ord(c) - 32

def _hash_(s):
    (res, p) = (0, 1)
    for i in range(len(s)):
        res += code(s[i]) * p
        res %= MOD
        p *= P
        p %= MOD
    return res % MOD

def remove_edge(v, u, graph):
    graph[v].remove(u)
    graph[u].remove(v)

def dfs_stack(start, graph, visited, flags):
    global b
    stack = []
    visited[start] = True
    stack.append(start)
    while len(stack) != 0:
        v = stack.pop()
        if not flags[v]:
            b = False
        for to in graph[v]:
            if not visited[to]:
                visited[to] = True
                stack.append(to)

def all_eq(a):
    for i in range(len(a) - 1):
        if a[i] != a[i + 1]:
            return False
    return True

def kmp(s, pr):
    n = len(s)
    pr[0] = 0
    for i in range(1, n):
        j = pr[i - 1]
        while j > 0 and s[i] != s[j]:
            j = pr[j - 1]
        if s[i] == s[j]:
            j += 1
        pr[i] = j

def lcm(a, b):
    return a * b // gcd(a, b)

def gcd_advanced(a, b):
    if a == 0:
        return (0, 1, b)
    (x1, y1, g) = gcd_advanced(b % a, a)
    return (y1 - x1 * (b // a), x1, g)

def check1(a, i):
    n = len(a)
    if i - 2 >= 0 and a[i + 1] < a[i - 1] > a[i - 2] and (i + 3 < n) and (a[i] > a[i + 2] < a[i + 3]):
        return False
    return True

def check2(a, i):
    n = len(a)
    if i - 2 >= 0 and a[i + 1] > a[i - 1] < a[i - 2] and (i + 3 < n) and (a[i] < a[i + 2] > a[i + 3]):
        return False
    return True

def solve():
    n = int(input())
    a = list(map(int, input().split()))
    res = 0
    holm = [False for i in range(n)]
    dolina = [False for i in range(n)]
    for i in range(1, n - 1):
        if a[i - 1] > a[i] < a[i + 1]:
            dolina[i] = True
            res += 1
        elif a[i - 1] < a[i] > a[i + 1]:
            holm[i] = True
            res += 1
    if res == 0:
        print(0)
        return
    for i in range(1, n - 1):
        if holm[i - 1] and holm[i + 1] and dolina[i]:
            print(res - 3)
            return
        if dolina[i - 1] and dolina[i + 1] and holm[i]:
            print(res - 3)
            return
    for i in range(1, n - 2):
        if holm[i] and dolina[i + 1] and check1(a, i) or (dolina[i] and holm[i + 1] and check2(a, i)):
            print(res - 2)
            return
    print(res - 1)
for _ in range(int(input())):
    solve()

def debug():
    pass
t = int(input())
for _ in range(t):
    n = int(input())
    a = list(map(int, input().split()))
    d = [(a[i] < a[i + 1]) - (a[i] > a[i + 1]) for i in range(n - 1)]
    z = [d[i] * d[i + 1] for i in range(n - 2)]
    D = z.count(-1)
    if D < 2:
        print(0)
        continue
    if any((z[i:i + 3] == [-1, -1, -1] for i in range(n - 4))):
        print(D - 3)
    else:
        x = [i for i in range(n - 3) if z[i:i + 2] == [-1, -1]]
        for i in x:
            if i == 0 or i == n - 4 or (i > 0 and a[i] == a[i - 1]) or (i < n - 4 and a[i + 3] == a[i + 4]) or (a[i] < a[i + 1] > a[i + 2] >= a[i]) or (a[i] > a[i + 1] < a[i + 2] <= a[i]) or (a[i + 1] < a[i + 2] > a[i + 3] <= a[i + 1]) or (a[i + 1] > a[i + 2] < a[i + 3] >= a[i + 1]):
                print(D - 2)
                break
        else:
            print(D - 1)