leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

total_waviness_nums_range2.py (3046B)


# 3753. Total Waviness of Numbers in Range II

"""
you are given two integers representing an inclusive range. the waviness of a
number is defined as the total count of its peaks and valleys. a digit is a
peak if it is strictly greater than both of its immediate neighbours. a digit
is a valley if it is strictly less than both of its immediate neighbours. the
first and last digits of a number cannot be peaks or valleys. any number with
fewer than 3 digits has a waviness of 0. return the total sum of waviness for
all numbers in the range.
"""


class Solution:
    def solve(self, num: int) -> int:
        if num < 100:
            return 0
        s = str(num)
        n = len(s)
        curr_states = [(10, 10, 1, 1, 1, 0)]
        for pos in range(n):
            limit = int(s[pos])
            cnt = [[[[0] * 11 for _ in range(11)] for _ in range(2)] for _ in range(2)]
            sum_arr = [
                [[[0] * 11 for _ in range(11)] for _ in range(2)] for _ in range(2)
            ]
            for prev, curr, tight, lead, c, s_val in curr_states:
                max_digit = limit if tight else 9
                for digit in range(max_digit + 1):
                    new_lead = 1 if (lead and digit == 0) else 0
                    new_prev = curr
                    new_curr = 10 if new_lead else digit
                    new_tight = 1 if (tight and digit == max_digit) else 0
                    add = 0
                    if not new_lead and prev != 10 and curr != 10:
                        if (prev < curr and curr > digit) or (
                            prev > curr and curr < digit
                        ):
                            add = c
                    cnt[new_tight][new_lead][new_prev][new_curr] += c
                    sum_arr[new_tight][new_lead][new_prev][new_curr] += s_val + add
            next_states = []
            for tight in range(2):
                for lead in range(2):
                    for prev in range(11):
                        for cur in range(11):
                            c = cnt[tight][lead][prev][cur]
                            if c != 0:
                                next_states.append(
                                    (
                                        prev,
                                        cur,
                                        tight,
                                        lead,
                                        c,
                                        sum_arr[tight][lead][prev][cur],
                                    )
                                )
            curr_states = next_states
        ans = 0
        for _, _, _, _, _, s_val in curr_states:
            ans += s_val
        return ans

    def totalWaviness(self, num1: int, num2: int) -> int:
        return self.solve(num2) - self.solve(num1 - 1)


if __name__ == "__main__":
    obj = Solution()
    print(obj.totalWaviness(num1=120, num2=130))
    print(obj.totalWaviness(num1=198, num2=202))
    print(obj.totalWaviness(num1=4848, num2=4848))