Skip to main content

math/
lib.rs

1//! # Math (Core) :: Rusty
2
3/// 29m Divide Two Integers
4struct Sol29;
5
6impl Sol29 {
7    /// Divide two integers
8    ///
9    /// Examples
10    ///
11    /// ```
12    /// use rustacean::math::Sol29;
13    ///
14    /// assert_eq!(Sol29::divide(10, 3), 3);
15    /// ```
16    ///
17    pub fn divide(dividend: i32, divisor: i32) -> i32 {
18        if dividend == divisor {
19            return 1;
20        }
21
22        let psign = (dividend < 0) == (divisor < 0);
23        let (mut n, d) = (dividend.unsigned_abs(), divisor.unsigned_abs());
24
25        let mut r: u32 = 0;
26        while n >= d {
27            let mut p = 0;
28            while n > (d << (p + 1)) {
29                p += 1;
30            }
31
32            r += 1 << p;
33            n -= d << p;
34        }
35
36        if r == 1 << 31 && psign {
37            return i32::MAX; // (1<<31) -1
38        }
39
40        match psign {
41            true => r as i32,
42            _ => -(r as i32),
43        }
44    }
45}
46
47/// 166m Fraction to Recurring Decimal
48struct Sol166 {}
49
50impl Sol166 {
51    /// -2^31 <= N, D <= 2^31-1
52    pub fn fraction_to_decimal(numerator: i32, denominator: i32) -> String {
53        use std::collections::HashMap;
54
55        if numerator == 0 {
56            return "0".to_string();
57        }
58
59        let mut parts = vec![];
60        if (numerator < 0) ^ (denominator < 0) {
61            parts.push("-".to_string());
62        }
63
64        let mut numerator = (numerator as i64).abs();
65        let denominator = (denominator as i64).abs();
66
67        parts.push((numerator / denominator).to_string());
68
69        if numerator % denominator == 0 {
70            return parts.join("");
71        }
72
73        parts.push(".".to_string());
74
75        let mut rs = HashMap::new();
76
77        numerator %= denominator;
78        while numerator != 0 {
79            if let Some(&p) = rs.get(&numerator) {
80                parts.insert(p, "(".to_string());
81                parts.push(")".to_string());
82                break;
83            }
84
85            rs.insert(numerator, parts.len());
86
87            numerator *= 10;
88            parts.push((numerator / denominator).to_string());
89
90            numerator %= denominator;
91        }
92
93        println!("-> {rs:?} {parts:?}");
94
95        parts.join("")
96    }
97}
98
99/// 335h Self Crossing
100struct Sol335 {}
101
102impl Sol335 {
103    pub fn is_self_crossing(distance: Vec<i32>) -> bool {
104        if distance.windows(4).any(|w| w[0] >= w[2] && w[3] >= w[1]) {
105            return true;
106        }
107
108        if distance
109            .windows(5)
110            .any(|w| w[1] == w[3] && w[0] + w[4] >= w[2])
111        {
112            return true;
113        }
114
115        if distance
116            .windows(6)
117            .any(|w| w[3] >= w[1] && w[2] > w[4] && w[0] + w[4] >= w[2] && w[1] + w[5] >= w[3])
118        {
119            return true;
120        }
121
122        false
123    }
124}
125
126/// 587h Erect the Fence
127struct Sol587 {}
128
129impl Sol587 {
130    /// 1 <= N <= 3000
131    /// 0 <= x_i, y_i <= 100
132    pub fn outer_trees(mut trees: Vec<[i32; 2]>) -> Vec<[i32; 2]> {
133        if trees.len() <= 3 {
134            return trees;
135        }
136
137        trees.sort_unstable();
138
139        // Cross-Product
140        // OA-> X OB->
141        fn cross_prd(o: &[i32; 2], a: &[i32; 2], b: &[i32; 2]) -> i32 {
142            (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])
143        }
144
145        let mut lower = vec![];
146        for p in trees.iter() {
147            while lower.len() >= 2
148                && cross_prd(lower[lower.len() - 2], lower[lower.len() - 1], p) < 0
149            {
150                lower.pop();
151            }
152            lower.push(p);
153        }
154
155        let mut upper = vec![];
156        for p in trees.iter().rev() {
157            while upper.len() >= 2
158                && cross_prd(upper[upper.len() - 2], upper[upper.len() - 1], p) < 0
159            {
160                upper.pop();
161            }
162            upper.push(p);
163        }
164
165        let mut convex_hull: Vec<_> = lower[..lower.len() - 1]
166            .iter()
167            .chain(upper[..upper.len() - 1].iter())
168            .map(|&&p| p)
169            .collect();
170
171        convex_hull.sort();
172        convex_hull.dedup();
173        convex_hull
174    }
175}
176
177/// 837m New 21 Game
178struct Sol837 {}
179
180impl Sol837 {
181    pub fn new21_game(n: i32, k: i32, max_pts: i32) -> f64 {
182        let (n, k) = (n as usize, k as usize);
183
184        let max_pts = max_pts as usize;
185        let mut probs = vec![0.0; n + 1];
186        probs[0] = 1.0;
187
188        for pts in 1..=n {
189            for draw in 1..=max_pts {
190                if pts >= draw && pts < k + draw {
191                    probs[pts] += probs[pts - draw] / max_pts as f64;
192                }
193            }
194        }
195        println!("-> {probs:?}");
196
197        let mut probs = vec![0.0; n + 1];
198        probs[0] = 1.0;
199
200        let mut w_sum = if k > 0 { 1.0 } else { 0.0 };
201        for pts in 1..=n {
202            probs[pts] = w_sum / max_pts as f64;
203
204            if pts < k {
205                w_sum += probs[pts];
206            }
207            if pts >= max_pts && pts < max_pts + k {
208                w_sum -= probs[pts - max_pts];
209            }
210        }
211        println!("-> {probs:?}");
212
213        probs.iter().skip(k).sum()
214    }
215}
216
217/// 838m Push Dominoes
218struct Sol838;
219
220impl Sol838 {
221    pub fn push_dominoes(dominoes: String) -> String {
222        let n = dominoes.len();
223        let mut force = vec![0; n];
224
225        let mut r = 0;
226        for (i, chr) in dominoes.chars().enumerate() {
227            r = match chr {
228                'R' => n as i32,
229                'L' => 0,
230                _ => (r - 1).max(0),
231            };
232
233            force[i] += r;
234        }
235
236        let mut l = 0;
237        for (i, chr) in dominoes.chars().rev().enumerate() {
238            l = match chr {
239                'R' => 0,
240                'L' => n as i32,
241                _ => (l - 1).max(0),
242            };
243
244            force[n - 1 - i] -= l;
245        }
246
247        println!("-> {:?}", force);
248
249        force
250            .iter()
251            .map(|&f| match f {
252                ..=-1 => 'L',
253                1.. => 'R',
254                _ => '.',
255            })
256            .collect()
257    }
258}
259
260/// 892 Surface Area of 3D Shapes
261struct Sol892 {}
262
263impl Sol892 {
264    pub fn surface_area(grid: Vec<Vec<i32>>) -> i32 {
265        let mut area = 0;
266
267        for (x, row) in grid.iter().enumerate() {
268            for (y, &height) in row.iter().enumerate() {
269                if height > 0 {
270                    area += 2; // Top & Bottom
271
272                    // Sides
273                    for (dx, dy) in [(0, 1), (0, -1), (1, 0), (-1, 0)] {
274                        let x = x.wrapping_add_signed(dx);
275                        let y = y.wrapping_add_signed(dy);
276                        if x < grid.len() && y < grid.len() {
277                            area += 0.max(height - grid[x][y]);
278                        } else {
279                            area += height;
280                        }
281                    }
282                }
283            }
284        }
285
286        area
287    }
288}
289
290/// 908 Smallest Range I
291struct Sol908;
292
293impl Sol908 {
294    pub fn smallest_range_i(nums: Vec<i32>, k: i32) -> i32 {
295        let mx = nums.iter().max();
296        let mn = nums.iter().min();
297
298        println!(" -> {:?} {:?}", mx, mn);
299
300        match (nums.iter().max(), nums.iter().min()) {
301            (Some(x), Some(n)) => 0.max(x - n - 2 * k),
302            _ => 0,
303        }
304    }
305}
306
307/// 970m Powerful Integers
308struct Sol970;
309
310impl Sol970 {
311    /// 1 <= x,y <= 100
312    /// 0 <= bound <= 10^6
313    pub fn powerful_integers(x: i32, y: i32, bound: i32) -> Vec<i32> {
314        use std::collections::HashSet;
315
316        let mut p_x = vec![1];
317        let mut p_y = vec![1];
318
319        if x > 1 {
320            let mut p = x;
321            while p < bound {
322                p_x.push(p);
323                p *= x;
324            }
325        }
326        if y > 1 {
327            let mut p = y;
328            while p < bound {
329                p_y.push(p);
330                p *= y;
331            }
332        }
333
334        let mut set = HashSet::new();
335        for x in &p_x {
336            for y in &p_y {
337                if x + y <= bound {
338                    set.insert(x + y);
339                }
340            }
341        }
342
343        set.drain().collect()
344    }
345}
346
347/// 989 Add to Array-Form of Integer
348struct Sol989;
349
350impl Sol989 {
351    pub fn add_to_array_form(num: Vec<i32>, k: i32) -> Vec<i32> {
352        println!(
353            "-> {:?}",
354            std::iter::successors(Some((k, 0, num.len())), |&(mut carry, _, mut p)| {
355                match carry > 0 || p > 0 {
356                    true => {
357                        if p > 0 {
358                            p -= 1;
359                            carry += num[p];
360                        }
361                        Some((carry / 10, carry % 10, p))
362                    }
363                    _ => None,
364                }
365            })
366            .map(|(_, d, _)| d)
367            .skip(1)
368            .fold(vec![], |mut rst, d| {
369                rst.push(d);
370                rst
371            })
372        );
373
374        let mut rst = vec![];
375
376        let (mut carry, mut p) = (k, num.len());
377        while carry > 0 || p > 0 {
378            if p > 0 {
379                p -= 1;
380                carry += num[p]
381            }
382            rst.push(carry % 10);
383            carry /= 10;
384        }
385
386        rst.reverse();
387        rst
388    }
389}
390
391/// 1295 Find Numbers with Even Number of Digits
392struct Sol1295;
393
394impl Sol1295 {
395    pub fn find_numbers(nums: Vec<i32>) -> i32 {
396        println!(
397            ":: {}",
398            nums.iter()
399                .filter(|&&n| {
400                    let mut digits = 0;
401                    let mut n = n;
402                    while n > 0 {
403                        n /= 10;
404                        digits += 1;
405                    }
406
407                    digits & 1 == 0
408                })
409                .count()
410        );
411
412        nums.iter()
413            .map(|&n| {
414                let mut digits = 0;
415                let mut n = n;
416                while n > 0 {
417                    n /= 10;
418                    digits += 1;
419                }
420
421                (digits + 1) & 1
422            })
423            .sum()
424    }
425}
426
427/// 1432m Max Difference You Can Get From Changing an Integer
428struct Sol1432 {}
429
430impl Sol1432 {
431    pub fn max_diff(num: i32) -> i32 {
432        let darr: Vec<_> = num
433            .to_string()
434            .as_bytes()
435            .iter()
436            .map(|&chr| (chr - b'0') as i32)
437            .collect();
438
439        let mut vmin = num;
440        match darr[0] {
441            1 => {
442                if let Some(&m) = darr[1..].iter().find(|&&d| d != 1 && d != 0) {
443                    vmin = 1;
444                    for &d in &darr[1..] {
445                        vmin = 10 * vmin + if d == m { 0 } else { d };
446                    }
447                }
448            }
449            _ => {
450                vmin = 0;
451                for &d in &darr {
452                    vmin = 10 * vmin + if d == darr[0] { 1 } else { d };
453                }
454            }
455        }
456
457        let mut vmax = num;
458        if let Some(&x) = darr.iter().find(|&d| d != &9) {
459            vmax = 0;
460            for &d in &darr {
461                vmax = 10 * vmax + if d == x { 9 } else { d };
462            }
463        }
464
465        println!("-> {vmin} {vmax}");
466
467        vmax - vmin
468    }
469}
470
471/// 1780m Check if Number is a Sum of Powers of Three
472struct Sol1780;
473
474impl Sol1780 {
475    /// 1 <= N <= 10^7
476    pub fn check_powers_of_three(n: i32) -> bool {
477        use std::iter::successors;
478
479        let mut powers: Vec<_> = successors(Some(1), |p| {
480            if 3 * p <= 1e7 as i32 {
481                Some(3 * p)
482            } else {
483                None
484            }
485        })
486        .collect();
487        powers.reverse();
488
489        println!("-> {:?}", powers);
490
491        let mut n = n;
492        for p in powers {
493            if n >= p {
494                n -= p;
495                if n == 0 {
496                    return true;
497                }
498            }
499        }
500
501        false
502    }
503
504    /// O(2^log3(N))
505    fn check_powers_of_three_recursive(n: i32) -> bool {
506        fn search(n: i32, power: i32) -> bool {
507            if n == 0 {
508                return true;
509            }
510            if n < power {
511                return false;
512            }
513
514            search(n, 3 * power) || search(n - power, 3 * power)
515        }
516
517        search(n, 1)
518    }
519}
520
521/// 1980m Find Unique Binary String
522struct Sol1980;
523
524impl Sol1980 {
525    pub fn find_different_binary_string(nums: Vec<String>) -> String {
526        nums.iter()
527            .enumerate()
528            .filter_map(|(i, s)| s.chars().nth(i))
529            .map(|chr| match chr {
530                '1' => '0',
531                _ => '1',
532            })
533            .collect()
534    }
535}
536
537/// 2081h Count of k-Mirror Numbers
538struct Sol2081 {}
539
540impl Sol2081 {
541    /// 2 <= k <= 9
542    /// 1 <= n <= 30
543    pub fn k_mirror(k: i32, mut n: i32) -> i64 {
544        let k = k as i64;
545
546        let k_palindrome = |mut p| {
547            let mut digits = vec![];
548            while p > 0 {
549                digits.push(p % k);
550                p /= k;
551            }
552
553            let (mut l, mut r) = (0, digits.len() - 1);
554            while l < r {
555                if digits[l] != digits[r] {
556                    return false;
557                }
558                l += 1;
559                r -= 1;
560            }
561
562            println!("-> + {digits:?}");
563            true
564        };
565
566        let mut total = 0;
567
568        let mut start = 1;
569        loop {
570            for mut p in start..start * 10 {
571                let mut t = p / 10;
572                while t > 0 {
573                    p *= 10;
574                    p += t % 10;
575                    t /= 10;
576                }
577                println!("-> (O) {p}");
578
579                if k_palindrome(p) {
580                    total += p;
581                    n -= 1;
582                    if n == 0 {
583                        return total;
584                    }
585                }
586            }
587
588            for mut p in start..start * 10 {
589                let mut t = p;
590                while t > 0 {
591                    p *= 10;
592                    p += t % 10;
593                    t /= 10;
594                }
595                println!("-> (E) {p}");
596
597                if k_palindrome(p) {
598                    total += p;
599                    n -= 1;
600                    if n == 0 {
601                        return total;
602                    }
603                }
604            }
605
606            start *= 10;
607        }
608    }
609}
610
611/// 2197h Replace Non-Coprime Numbers in Array
612struct Sol2197 {}
613
614impl Sol2197 {
615    pub fn replace_non_coprimes(nums: Vec<i32>) -> Vec<i32> {
616        fn gcd(mut a: i32, mut b: i32) -> i32 {
617            while b > 0 {
618                (a, b) = (b, a % b);
619            }
620            a
621        }
622
623        let mut stack = vec![];
624        for mut n in nums {
625            while let Some(&last) = stack.last() {
626                if gcd(last, n) > 1 {
627                    stack.pop();
628                    n *= last / gcd(last, n); // lcm(a,b) * gcd(a,b) = a * b
629                } else {
630                    break;
631                }
632            }
633
634            stack.push(n);
635        }
636
637        stack
638    }
639}
640
641/// 2338h Count the Number of Ideal Arrays
642struct Sol2338;
643
644impl Sol2338 {
645    /// 2 <= N <= 10^4, 1 <= Max <= 10^4
646    /// Choose & Multi-Choose :: C((n/k)) = C(n+k-1/k)
647    pub fn ideal_arrays(n: i32, max_value: i32) -> i32 {
648        const P: usize = 15;
649
650        let mut sieve: Vec<usize> = (0..=max_value as usize).collect();
651        for p in 2..sieve.len() {
652            if sieve[p] == p {
653                for m in (p * p..sieve.len()).step_by(p) {
654                    sieve[m] = p;
655                }
656            }
657        }
658        println!("-> Sieve :: {sieve:?}");
659
660        let mut factors = vec![vec![]; max_value as usize + 1];
661        for (n, _) in sieve
662            .iter()
663            .enumerate()
664            .take(max_value as usize + 1)
665            .skip(2)
666        {
667            let mut x = n;
668            while x > 1 {
669                let factor = sieve[x];
670                let mut count = 0;
671                while x.is_multiple_of(factor) {
672                    x /= factor;
673                    count += 1;
674                }
675                factors[n].push(count);
676            }
677        }
678        println!("-> Factors Counts: {factors:?}");
679
680        let mut c = vec![vec![0; P + 1]; n as usize + P + 1];
681        c[0][0] = 1;
682
683        const M: i64 = 1_000_000_007;
684        for n in 1..c.len() {
685            c[n][0] = 1;
686            for k in 1..=n.min(P) {
687                c[n][k] = (c[n - 1][k] + c[n - 1][k - 1]) % M
688            }
689        }
690
691        (1..=max_value as usize).fold(0, |count, v| {
692            let mut total = 1;
693            for &k in &factors[v] {
694                total = total * c[n as usize + k - 1][k] % M;
695            }
696
697            (count + total) % M
698        }) as i32
699    }
700}
701
702/// 2523m Closest Prime Numbers in Range
703struct Sol2523;
704
705impl Sol2523 {
706    pub fn closest_primes(left: i32, right: i32) -> Vec<i32> {
707        let mut sieve = vec![0; 1 + right as usize];
708
709        for (i, n) in sieve
710            .iter_mut()
711            .enumerate()
712            .take(right as usize + 1)
713            .skip(2)
714        {
715            *n = i;
716        }
717
718        for p in 2..=right as usize {
719            if sieve[p] == p {
720                for m in (p * p..=right as usize).step_by(p) {
721                    sieve[m] = p;
722                }
723            }
724        }
725
726        println!("-> {:?}", sieve);
727
728        let primes: Vec<_> = sieve
729            .into_iter()
730            .enumerate()
731            .skip(1)
732            .filter(|(i, p)| i == p && *p as i32 >= left)
733            .map(|(_, p)| p as i32)
734            .collect();
735
736        println!("-> {:?}", primes);
737
738        primes.windows(2).fold(vec![-1, -1], |rst, v| {
739            if rst == vec![-1, -1] || v[1] - v[0] < rst[1] - rst[0] {
740                vec![v[0], v[1]]
741            } else {
742                rst
743            }
744        })
745    }
746}
747
748/// 2566 Maximum Difference by Remapping a Digit
749struct Sol2566 {}
750
751impl Sol2566 {
752    /// 1 <= N <= 10^8
753    pub fn min_max_difference(num: i32) -> i32 {
754        let nstr: Vec<_> = num.to_string().chars().collect();
755
756        if let Some(p) = num.to_string().chars().position(|chr| chr != '9') {
757            let vmax = nstr
758                .iter()
759                .map(|&chr| {
760                    if chr == nstr[p] {
761                        9
762                    } else {
763                        chr.to_digit(10).unwrap_or(0)
764                    }
765                })
766                .fold(0, |r, d| r * 10 + d);
767
768            let vmin = nstr
769                .iter()
770                .map(|&chr| {
771                    if chr == nstr[0] {
772                        0
773                    } else {
774                        chr.to_digit(10).unwrap_or_default()
775                    }
776                })
777                .fold(0, |r, d| r * 10 + d);
778
779            println!("-> {vmin} ~ {vmax}");
780
781            return (vmax - vmin) as i32;
782        }
783
784        num
785    }
786}
787
788/// 2579m Count Total Number of Colored Cells
789struct Sol2578;
790
791impl Sol2578 {
792    pub fn colored_cells(n: i32) -> i64 {
793        let mut rst = 1;
794        for n in 2..=n as i64 {
795            rst += 4 * (n - 1);
796        }
797
798        rst
799    }
800}
801
802/// 2818h Apply Operations to Maximize Score
803struct Sol2818;
804
805impl Sol2818 {
806    /// 1 <= N, N_i <= 10^5
807    pub fn maximum_score(nums: Vec<i32>, k: i32) -> i32 {
808        let mut omega = vec![0; 1 + 1e5 as usize];
809        for p in 2..omega.len() {
810            if omega[p] == 0 {
811                for m in (p..omega.len()).step_by(p) {
812                    omega[m] += 1;
813                }
814            }
815        }
816
817        const M: i64 = 7 + 1e9 as i64;
818        fn mpower(mut b: i64, mut e: i64) -> i64 {
819            let mut r = 1;
820            while e > 0 {
821                if e & 1 == 1 {
822                    r = (r * b) % M;
823                }
824                b = (b * b) % M;
825                e >>= 1;
826            }
827
828            r
829        }
830
831        let n = nums.len();
832        let (mut left, mut right) = (vec![-1; n], vec![n as i32; n]);
833
834        let mut stack: Vec<usize> = vec![];
835
836        for (i, &v) in nums.iter().enumerate() {
837            while !stack.is_empty()
838                && omega[nums[stack[stack.len() - 1]] as usize] < omega[v as usize]
839            {
840                right[stack.pop().unwrap()] = i as i32;
841            }
842
843            if !stack.is_empty() {
844                left[i] = *stack.last().unwrap() as i32;
845            }
846
847            stack.push(i);
848        }
849
850        let mut set = vec![];
851        for e in nums
852            .iter()
853            .map(|&v| v as i64)
854            .zip((0..n as i32).zip(left.iter().zip(right.iter())))
855        {
856            set.push(e);
857        }
858        set.sort_by_key(|e| -e.0);
859
860        println!("-> {:?}", set);
861
862        let mut score = 1i64;
863        let mut k = k;
864        for (v, (i, (l, r))) in set {
865            let total = (i - l) as i64 * (r - i) as i64;
866            if total >= k as i64 {
867                score = score * mpower(v, k as i64) % M;
868                break;
869            }
870            score = score * mpower(v, total) % M;
871            k -= total as i32;
872        }
873
874        score as i32
875    }
876}
877
878/// 2843 Count Symmetric Integers
879struct Sol2843;
880
881impl Sol2843 {
882    pub fn count_symmetric_integers(low: i32, high: i32) -> i32 {
883        let mut count = 0;
884
885        for n in low..=high {
886            let n = n.to_string();
887            let n = n.as_bytes();
888            let w = n.len();
889            if w & 1 == 0 {
890                let (mut left, mut right) = (0, 0);
891                for i in 0..w / 2 {
892                    left += n[i];
893                    right += n[w / 2 + i];
894                }
895                if left == right {
896                    count += 1;
897                }
898            }
899        }
900
901        // 1 <= N_i <= 10^4
902        println!(
903            "-> {}",
904            (low..=high).fold(0, |r, n| {
905                match n {
906                    1..100 if n % 11 == 0 => r + 1,
907                    1000..10000 => {
908                        if n / 1000 + (n % 1000) / 100 == (n % 100) / 10 + (n % 10) {
909                            r + 1
910                        } else {
911                            r
912                        }
913                    }
914                    _ => r,
915                }
916            })
917        );
918
919        count
920    }
921}
922
923/// 2929m Distribute Candies Among Children II
924struct Sol2929 {}
925
926impl Sol2929 {
927    /// 1 <= N, L <= 10^6
928    pub fn distribute_candies(n: i32, limit: i32) -> i64 {
929        let mut ways = 0;
930        for candy1 in 0..=limit.min(n) {
931            if n - candy1 <= 2 * limit {
932                println!(
933                    "-> Candy1: {candy1} | Candy2: {} ~ {}",
934                    (n - candy1).min(limit),
935                    0.max(n - candy1 - limit)
936                );
937
938                ways += ((n - candy1).min(limit) - (n - candy1 - limit).max(0) + 1) as i64
939            }
940        }
941
942        ways
943    }
944}
945
946/// 3021m Alice and Bob Playing Flower Game
947struct Sol3021 {}
948
949impl Sol3021 {
950    pub fn flower_game(n: i32, m: i32) -> i64 {
951        n as i64 * m as i64 / 2
952    }
953}
954
955/// 3024 Type of Triangle
956struct Sol3024;
957
958impl Sol3024 {
959    pub fn triangle_type(nums: Vec<i32>) -> String {
960        let mut nums = nums;
961        nums.sort();
962
963        let (a, b, c) = (nums[0], nums[1], nums[2]);
964        if a + b <= c {
965            "none"
966        } else if a == c {
967            "equilateral"
968        } else if a == b || b == c {
969            "isosceles"
970        } else {
971            "scalene"
972        }
973        .to_string()
974    }
975}
976
977/// 3272h Find the Count of Good Integers
978struct Sol3272;
979
980impl Sol3272 {
981    /// 1 <= n <= 10, 1 <= k <= 9
982    pub fn count_good_integers(n: i32, k: i32) -> i64 {
983        use std::collections::HashSet;
984
985        let mut set: HashSet<String> = HashSet::new();
986
987        let start = 10u32.pow((n - 1) as u32 / 2);
988        for v in start..10 * start {
989            let left = v.to_string();
990            let right: String = left.chars().rev().skip((n & 1) as usize).collect();
991
992            let palindrome = format!("{}{}", left, right);
993            match palindrome.parse::<u64>() {
994                Ok(v) if v.is_multiple_of(k as u64) => {
995                    let mut chrs: Vec<char> = palindrome.chars().collect();
996                    chrs.sort_unstable();
997                    set.insert(chrs.iter().collect());
998                }
999                _ => {}
1000            }
1001        }
1002
1003        println!("-> {:?}", set);
1004
1005        let mut facts = vec![1; (n + 1) as usize];
1006        for n in 2..=n as usize {
1007            facts[n] = facts[n - 1] * n;
1008        }
1009
1010        let mut count = 0;
1011        for chrs in set {
1012            let mut counter = [0; 10];
1013            for chr in chrs.as_bytes() {
1014                counter[(chr - b'0') as usize] += 1;
1015            }
1016
1017            let mut perms = (n as usize - counter[0]) * facts[n as usize - 1];
1018            for &count in counter.iter() {
1019                perms /= facts[count];
1020            }
1021
1022            count += perms;
1023        }
1024
1025        count as i64
1026    }
1027}
1028
1029/// 3304 Find the K-th Character in a String Game I
1030struct Sol3304 {}
1031
1032impl Sol3304 {
1033    pub fn kth_character(mut k: i32) -> char {
1034        let mut offset = 0;
1035
1036        k -= 1;
1037        for p in (0..32 - k.leading_zeros()).rev() {
1038            if (k >> p) & 1 == 1 {
1039                offset += 1;
1040            }
1041        }
1042
1043        ('a'..='z')
1044            .skip(offset as usize % 26)
1045            .take(1)
1046            .next()
1047            .unwrap_or('a')
1048    }
1049}
1050
1051/// 3307h Find the K-th Character in a String Game II
1052struct Sol3307 {}
1053
1054impl Sol3307 {
1055    pub fn kth_character(mut k: i64, operations: Vec<i32>) -> char {
1056        println!(
1057            ":? {:?}",
1058            ('a'..='z')
1059                .skip((k - 1).count_ones() as usize - 1)
1060                .take(1)
1061                .next()
1062                .unwrap_or('a')
1063        );
1064
1065        let mut offset = 0;
1066
1067        k -= 1;
1068        for p in (0..64 - k.leading_zeros()).rev() {
1069            if (k >> p) & 1 == 1 {
1070                offset += operations[p as usize];
1071            }
1072        }
1073
1074        ('a'..='z')
1075            .skip((offset % 26) as usize)
1076            .take(1)
1077            .next()
1078            .unwrap_or('a')
1079    }
1080}
1081
1082/// 3405h Count the Number of Arrays with K Matching Adjacent Elements
1083struct Sol3405 {}
1084
1085impl Sol3405 {
1086    pub fn count_good_arrays(n: i32, m: i32, k: i32) -> i32 {
1087        const M: i64 = 1e9 as i64 + 7;
1088
1089        let mut facts = vec![0; n as usize];
1090        let mut ifacts = vec![0; n as usize];
1091
1092        let power = |mut b, mut e| {
1093            let mut power = 1;
1094            while e > 0 {
1095                if e & 1 == 1 {
1096                    power = power * b % M;
1097                }
1098                b = b * b % M;
1099                e >>= 1;
1100            }
1101
1102            power
1103        };
1104
1105        facts[0] = 1;
1106        for i in 1..facts.len() {
1107            facts[i] = facts[i - 1] * i as i64 % M;
1108        }
1109
1110        ifacts[n as usize - 1] = power(facts[n as usize - 1], M - 2);
1111        for i in (1..ifacts.len()).rev() {
1112            ifacts[i - 1] = ifacts[i] * i as i64 % M;
1113        }
1114
1115        let n_choose_k = |n, k| facts[n] * ifacts[k] % M * ifacts[n - k] % M;
1116
1117        (m as i64 * n_choose_k(n as usize - 1, k as usize) % M
1118            * power(m as i64 - 1, (n - k - 1) as i64)
1119            % M) as _
1120    }
1121}
1122
1123/// 3443m Maximum Manhattan Distance After K Changes
1124struct Sol3443 {}
1125
1126impl Sol3443 {
1127    pub fn max_distance(s: String, k: i32) -> i32 {
1128        let (mut lat, mut long) = (0i32, 0i32);
1129        s.chars().enumerate().fold(0, |xdist, (i, dir)| {
1130            match dir {
1131                'N' => lat += 1,
1132                'S' => lat -= 1,
1133                'W' => long += 1,
1134                'E' => long -= 1,
1135                _ => (),
1136            }
1137
1138            xdist.max((i as i32 + 1).min(lat.abs() + long.abs() + 2 * k))
1139        })
1140    }
1141}
1142
1143#[cfg(test)]
1144mod tests;