leetcode

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

commit b4d2c1ef78bb9e9455e01153d2f80c0fa5e7d64c
parent 1258a96b176cfdd3c84abe1eb6a06ed5e3dadd9f
Author: Jack Sangdahl <jack@pngu.org>
Date:   Fri,  5 Jun 2026 21:03:25 -0600

3573. total waviness of numbers in range 2

Diffstat:
Atotal_waviness_nums_range2.c | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atotal_waviness_nums_range2.py | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 156 insertions(+), 0 deletions(-)

diff --git a/total_waviness_nums_range2.c b/total_waviness_nums_range2.c @@ -0,0 +1,83 @@ +// 3753. Total Waviness of Numbers in Range II +#include "leetcode.h" + +/* + * 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. + */ + +struct state { + int prev, curr, tight, lead; + long long cnt, sum; +}; + +long long solve(long long num) { + if (num < 100) + return 0; + char s[20]; + sprintf(s, "%lld", num); + int n = strlen(s), curr_size = 0; + struct state curr_states[500]; + curr_states[curr_size++] = (struct state){10, 10, 1, 1, 1, 0}; + for (int pos = 0; pos < n; ++pos) { + int limit = s[pos] - '0'; + long long cnt[2][2][11][11] = {0}; + long long sum[2][2][11][11] = {0}; + for (int i = 0; i < curr_size; ++i) { + struct state st = curr_states[i]; + int max_digit = st.tight ? limit : 9; + for (int digit = 0; digit <= max_digit; ++digit) { + int new_lead = (st.lead && digit == 0) ? 1 : 0; + int new_prev = st.curr; + int new_curr = new_lead ? 10 : digit; + int new_tight = (st.tight && digit == max_digit) ? 1 : 0; + long long add = 0; + if (!new_lead && st.prev != 10 && st.curr != 10) + if ((st.prev < st.curr && st.curr > digit) || + (st.prev > st.curr && st.curr < digit)) + add = st.cnt; + cnt[new_tight][new_lead][new_prev][new_curr] += st.cnt; + sum[new_tight][new_lead][new_prev][new_curr] += st.sum + add; + } + } + struct state next_states[500]; + int next_size = 0; + for (int tight = 0; tight < 2; ++tight) + for (int lead = 0; lead < 2; ++lead) + for (int prev = 0; prev <= 10; ++prev) + for (int curr = 0; curr <= 10; ++curr) { + long long c = cnt[tight][lead][prev][curr]; + long long s_val = sum[tight][lead][prev][curr]; + if (c) + next_states[next_size++] = + (struct state){prev, curr, tight, lead, c, s_val}; + } + memcpy(curr_states, next_states, next_size * sizeof(struct state)); + curr_size = next_size; + } + long long res = 0; + for (int i = 0; i < curr_size; ++i) + res += curr_states[i].sum; + return res; +} + +long long totalWaviness(long long num1, long long num2) { + return solve(num2) - solve(num1 - 1); +} + +int main() { + long long r1 = totalWaviness(120, 130); + long long r2 = totalWaviness(198, 202); + long long r3 = totalWaviness(4848, 4848); + printf("%lld\n", r1); + assert(r1 == 3); + printf("%lld\n", r2); + assert(r2 == 3); + printf("%lld\n", r3); + assert(r3 == 2); +} diff --git a/total_waviness_nums_range2.py b/total_waviness_nums_range2.py @@ -0,0 +1,73 @@ +# 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))