1#![feature(test)]
4
5extern crate test;
6
7struct Sol38;
9
10impl Sol38 {
11 pub fn count_and_say(n: i32) -> String {
13 let mut s = "1".to_string();
14 for _ in 0..n - 1 {
15 let mut enc = vec![];
16
17 let (mut count, mut prv) = (0, '^');
18 for chr in s.chars().chain("$".chars()) {
19 if chr == prv {
20 count += 1;
21 } else {
22 enc.push((count, prv));
23 (count, prv) = (1, chr);
24 }
25 }
26
27 println!("-> {:?}", enc);
28
29 let mut t = String::new();
30 for (count, chr) in enc.iter().skip(1) {
31 t += &format!("{}{}", count, chr);
32 }
33
34 s = t;
35 }
36
37 println!("** {}", s);
38
39 s
40 }
41}
42
43struct Sol65;
45
46impl Sol65 {
47 pub fn is_number(s: String) -> bool {
48 let stt = [
51 [0, 0, 0, 0, 0], [3, 2, 4, 0, 1], [3, 0, 4, 0, 0], [3, 0, 5, 6, 9], [5, 0, 0, 0, 0], [5, 0, 0, 6, 9], [8, 7, 0, 0, 0], [8, 0, 0, 0, 0], [8, 0, 0, 0, 9], [0, 0, 0, 0, 9], ];
62
63 let mut cstate = 1; for chr in s.chars() {
66 cstate = match chr {
67 '0'..='9' => stt[cstate][0],
68 '+' | '-' => stt[cstate][1],
69 '.' => stt[cstate][2],
70 'e' | 'E' => stt[cstate][3],
71 ' ' => stt[cstate][4],
72 _ => return false, }
74 }
75
76 matches!(cstate, 3 | 5 | 8 | 9)
77 }
78
79 fn is_number_enum(s: String) -> bool {
80 #[derive(Debug)]
81 enum State {
82 Start,
83 Sign,
84 Dot,
85 Int,
86 IntDot,
87 Decimal,
88 E,
89 ESign,
90 Exp,
91 }
92
93 use State::*;
94
95 let mut cstate = Start;
96 for chr in s.chars() {
97 cstate = match (&cstate, chr) {
98 (Start, '+' | '-') => Sign,
99 (Start | Sign, '.') => Dot,
100 (Start | Sign, '0'..='9') => Int,
101 (Dot | IntDot, '0'..='9') => Decimal,
102 (Int | Decimal | Exp, '0'..='9') => cstate, (Int, '.') => IntDot,
104 (Int | Decimal | IntDot, 'e' | 'E') => E,
105 (E, '+' | '-') => ESign,
106 (E | ESign, '0'..='9') => Exp,
107
108 _ => return false,
109 }
110 }
111
112 matches!(cstate, Int | IntDot | Decimal | Exp)
113 }
114}
115
116struct Sol165 {}
118
119impl Sol165 {
120 pub fn compare_version(version1: String, version2: String) -> i32 {
121 let version1: Vec<_> = version1
122 .split('.')
123 .flat_map(|rv| rv.parse::<i32>())
124 .collect();
125 let version2: Vec<_> = version2
126 .split('.')
127 .flat_map(|rv| rv.parse::<i32>())
128 .collect();
129
130 println!("-> {version1:?} {version2:?}");
131
132 version1
133 .iter()
134 .chain(std::iter::repeat(&0))
135 .zip(version2.iter().chain(std::iter::repeat(&0)))
136 .take(version1.len().max(version2.len()))
137 .inspect(|z| println!("-> {z:?}"))
138 .filter(|&(rv1, rv2)| rv1 != rv2)
139 .nth(0)
140 .map_or(0, |(rv1, rv2)| if rv1 > rv2 { 1 } else { -1 })
141 }
142}
143
144struct Sol466 {}
146
147impl Sol466 {
148 pub fn get_max_repetitions(s1: String, n1: i32, s2: String, n2: i32) -> i32 {
150 let (mut counts, mut marks) = (vec![0; s2.len() + 1], vec![0; s2.len() + 1]);
151
152 let s2: Vec<_> = s2.chars().collect();
153
154 let (mut count, mut mark) = (0, 0);
155 for i in 0..n1 as usize {
156 for chr in s1.chars() {
157 if chr == s2[mark] {
158 mark += 1;
159 }
160 if mark == s2.len() {
161 mark = 0;
162 count += 1;
163 }
164 }
165
166 (counts[i], marks[i]) = (count, mark);
167 println!("-> {i} {counts:?} {marks:?}");
168
169 for k in 0..i {
170 if marks[k] == mark {
171 let prv = counts[k];
172 let pattern = (counts[i] - counts[k]) * ((n1 - 1 - k as i32) / (i - k) as i32);
173 let rest = counts[k + (n1 as usize - 1 - k) % (i - k)] - counts[k];
174
175 return (prv + pattern + rest) / n2;
176 }
177 }
178 }
179
180 counts[n1 as usize - 1] / n2
181 }
182}
183
184struct Sol804 {}
186
187impl Sol804 {
188 pub fn unique_morse_representations(words: Vec<String>) -> i32 {
189 use std::collections::HashSet;
190
191 const MORSE: [&str; 26] = [
192 ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..",
193 "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-",
194 "-.--", "--..",
195 ];
196
197 let mut codes: HashSet<String> = HashSet::new();
198 for word in words.iter() {
199 let mut code = String::new();
200 for chr in word.chars() {
201 if let Some(i) = ('a'..='z').position(|x| x == chr) {
202 code.push_str(MORSE[i]);
203 }
204 }
205
206 codes.insert(code);
207 }
208 println!("-> {codes:?}");
209
210 codes.len() as _
211 }
212}
213
214struct Sol917;
216
217impl Sol917 {
218 pub fn reverse_only_letters(s: String) -> String {
219 let mut ichr = s.chars().rev().filter(|c| c.is_alphabetic());
220
221 s.chars()
222 .flat_map(|c| (!c.is_alphabetic()).then_some(c).or_else(|| ichr.next()))
223 .collect()
224 }
225}
226
227struct Sol966 {}
229
230impl Sol966 {
231 pub fn spellchecker(wordlist: Vec<String>, queries: Vec<String>) -> Vec<String> {
232 use std::collections::HashMap;
233
234 let words: HashMap<String, Vec<_>> =
235 wordlist.iter().fold(HashMap::new(), |mut words, w| {
236 words
237 .entry(
238 w.to_string()
239 .to_lowercase()
240 .chars()
241 .map(|chr| match chr {
242 'a' | 'e' | 'i' | 'o' | 'u' => '*',
243 _ => chr,
244 })
245 .collect(),
246 )
247 .and_modify(|lst| lst.push(w))
248 .or_insert(vec![w]);
249
250 words
251 });
252 println!("-> {words:?}");
253
254 queries
255 .iter()
256 .map(|w| {
257 let key: String = w
258 .to_lowercase()
259 .chars()
260 .map(|chr| if "aeiou".contains(chr) { '*' } else { chr })
261 .collect();
262
263 if let Some(lst) = words.get(&key) {
264 if lst.contains(&w) {
265 w.to_string()
266 } else {
267 for lw in lst.iter() {
268 if lw.to_lowercase() == w.to_lowercase() {
269 return lw.to_string();
270 }
271 }
272 lst.first().unwrap().to_string()
273 }
274 } else {
275 "".to_string()
276 }
277 })
278 .collect()
279 }
280}
281
282struct Sol1061 {}
284
285impl Sol1061 {
286 pub fn smallest_equivalent_string(s1: String, s2: String, base_str: String) -> String {
287 let mut djset: Vec<_> = (0..26).collect();
288
289 let mut union = |v1, v2| {
290 let (v1, v2) = (find(v1, &mut djset), find(v2, &mut djset));
291 match v1.cmp(&v2) {
292 std::cmp::Ordering::Greater => djset[v1] = v2,
293 std::cmp::Ordering::Less => djset[v2] = v1,
294 _ => {}
295 }
296 };
297
298 fn find(v: usize, djset: &mut [usize]) -> usize {
299 if djset[v] != v {
300 djset[v] = find(djset[v], djset);
301 }
302 djset[v]
303 }
304
305 for (chr1, chr2) in s1.as_bytes().iter().zip(s2.as_bytes().iter()) {
306 union((chr1 - b'a') as usize, (chr2 - b'a') as usize);
307 }
308
309 println!("-> {djset:?}");
310
311 base_str
312 .as_bytes()
313 .iter()
314 .map(|&chr| (find((chr - b'a') as usize, &mut djset) as u8 + b'a') as char)
315 .collect()
316 }
317}
318
319struct Sol1078 {}
321
322impl Sol1078 {
323 pub fn find_ocurrences(text: String, first: String, second: String) -> Vec<String> {
324 println!(
325 ":? {:?}",
326 text.split(" ")
327 .collect::<Vec<_>>()
328 .windows(3)
329 .filter(|w| w[0] == first && w[1] == second)
330 .map(|w| w[2].to_string())
331 .collect::<Vec<_>>()
332 );
333
334 text.split(" ")
335 .collect::<Vec<_>>()
336 .windows(3)
337 .fold(vec![], |mut v, w| {
338 if w[0] == first && w[1] == second {
339 v.push(w[2].to_string());
340 }
341 v
342 })
343 }
344}
345
346struct Sol1154;
348
349impl Sol1154 {
350 pub fn day_of_year(date: String) -> i32 {
351 let mut days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
352
353 let mut vs = vec![];
354 for w in date.split('-') {
355 vs.push(w.parse::<i32>());
356 }
357
358 println!(" -> {:?}", vs);
359
360 let mut dy = 0;
361 if let (Ok(year), Ok(month), Ok(day)) = (&vs[0], &vs[1], &vs[2]) {
362 dy += day;
363 if year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) {
364 days[1] += 1;
365 }
366
367 for m in 0..month - 1 {
368 dy += days[m as usize];
369 }
370 }
371
372 dy
373 }
374}
375
376struct Sol1163 {}
378
379impl Sol1163 {
380 pub fn last_substring(s: String) -> String {
381 let s: Vec<_> = s.chars().collect();
382 let n = s.len();
383
384 let (mut i, mut j) = (0, 1);
385 while j < n {
386 let mut k = 0;
387 while j + k < n && s[i + k] == s[j + k] {
388 k += 1;
389 }
390
391 if j + k < n && s[i + k] < s[j + k] {
392 (i, j) = (j, (j + 1).max(i + k + 1));
393 } else {
394 j += k + 1;
395 }
396 }
397
398 s.iter().skip(i).collect()
399 }
400}
401
402struct Sol1513 {}
404
405impl Sol1513 {
406 pub fn num_sub(s: String) -> i32 {
407 const M: usize = 1e9 as usize + 7;
408
409 s.chars()
410 .collect::<Vec<char>>()
411 .chunk_by(|c, c_next| c == c_next)
412 .filter(|chk| chk[0] == '1')
413 .inspect(|e| println!("-> {e:?}"))
414 .map(|chk| (chk.len() * (chk.len() + 1) / 2) % M)
415 .fold(0, |total, n| (total + n) % M) as _
416 }
417}
418
419struct Sol1876 {}
421
422impl Sol1876 {
423 pub fn count_good_substrings(s: String) -> i32 {
424 s.chars()
425 .collect::<Vec<_>>()
426 .windows(3)
427 .fold(0, |count, w| {
428 if w[0] == w[1] || w[1] == w[2] || w[2] == w[0] {
429 count
430 } else {
431 count + 1
432 }
433 }) as _
434 }
435}
436
437struct Sol1957 {}
439
440impl Sol1957 {
441 pub fn make_fancy_string(s: String) -> String {
442 if s.len() < 3 {
443 return s;
444 }
445
446 println!(
447 ":? {:?}",
448 s.chars()
449 .collect::<Vec<_>>()
450 .chunk_by(|&a, &b| a == b)
451 .flat_map(|chunk| chunk.iter().take(2.min(chunk.len())).collect::<Vec<_>>())
452 .collect::<Vec<_>>()
453 );
454
455 let mut chars: Vec<_> = s.chars().collect();
456
457 let mut p = 2;
458 for x in 2..chars.len() {
459 if chars[x] != chars[p - 1] || chars[x] != chars[p - 2] {
460 chars[p] = chars[x];
461 p += 1;
462 }
463 }
464
465 chars[..p].iter().collect()
466 }
467}
468
469struct Sol2138 {}
471
472impl Sol2138 {
473 pub fn divide_string(s: String, k: i32, fill: char) -> Vec<String> {
474 let mut divs = vec![];
475
476 let k = k as usize;
477 for start in (0..=s.len() - k).step_by(k) {
478 divs.push(s[start..start + k].to_string());
479 }
480
481 if !s.len().is_multiple_of(k) {
482 let mut last = s[s.len() / k * k..].to_string();
483 for _ in 0..k - s.len() % k {
484 last.push(fill);
485 }
486 divs.push(last);
487 }
488
489 divs
490 }
491}
492
493struct Sol2269 {}
495
496impl Sol2269 {
497 pub fn divisor_substrings(num: i32, k: i32) -> i32 {
498 let k = k as usize;
499
500 let mut count = 0;
501 let s = num.to_string();
502 for start in 0..=s.len() - k {
503 let n = s[start..start + k].parse::<i32>().unwrap();
504 if n != 0 && num % n == 0 {
505 count += 1;
506 }
507 }
508
509 count as _
510 }
511}
512
513struct Sol2273 {}
515
516impl Sol2273 {
517 pub fn remove_anagrams(words: Vec<String>) -> Vec<String> {
518 let mut fs_prv = [0; 26];
519 println!("-> {:p} {fs_prv:?}", &fs_prv);
520
521 words.into_iter().fold(vec![], |mut ls, word| {
522 let mut fs = [0; 26];
523 word.chars()
524 .for_each(|chr| fs[chr.to_digit(36).unwrap() as usize - 10] += 1);
525
526 println!("-> {:p} {fs:?}", &fs);
527
528 if fs_prv != fs {
529 ls.push(word);
530 }
531 fs_prv = fs;
532 println!("-> {:p}", &fs_prv);
533
534 ls
535 })
536 }
537}
538
539struct Sol2315 {}
541
542impl Sol2315 {
543 pub fn count_asterisks(s: String) -> i32 {
544 println!(
545 ":? {}",
546 s.split('|').step_by(2).fold(0, |count, pair| {
547 count + pair.chars().filter(|&chr| chr == '*').count()
548 })
549 );
550
551 s.split('|')
552 .enumerate()
553 .filter(|(i, _)| i & 1 == 0)
554 .map(|(_, pair)| pair)
555 .fold(0, |count, pair| {
556 count + pair.chars().filter(|&chr| chr == '*').count()
557 }) as _
558 }
559}
560
561struct Sol2785 {}
563
564impl Sol2785 {
565 pub fn sort_vowels(s: String) -> String {
566 let mut vws: Vec<_> = s
567 .chars()
568 .filter(|&chr| "aAeEiIoOuU".contains(chr))
569 .collect();
570 vws.sort();
571 println!("-> {vws:?}");
572
573 let s: Vec<_> = s
574 .chars()
575 .map(|chr| if "aAeEiIoOuU".contains(chr) { '*' } else { chr })
576 .collect();
577 println!("-> {s:?}");
578
579 s.iter()
580 .scan(0, |i, &chr| {
581 if chr == '*' {
582 *i += 1;
583 Some(vws[*i - 1])
584 } else {
585 Some(chr)
586 }
587 })
588 .collect()
589 }
590}
591
592struct Sol3330;
594
595impl Sol3330 {
596 pub fn possible_string_count(word: String) -> i32 {
597 word.as_bytes()
598 .windows(2)
599 .fold(1, |count, w| if w[0] == w[1] { count + 1 } else { count })
600 }
601}
602
603struct Sol3403 {}
605
606impl Sol3403 {
607 pub fn answer_string(word: String, num_friends: i32) -> String {
608 if num_friends == 1 {
609 return word;
610 }
611
612 let n = word.len();
613 let mut answer = String::new();
614 for i in 0..n {
615 let s = &word[i..n.min(i + n - (num_friends as usize - 1))];
616 if &answer[..] < s {
617 answer = s.to_string();
618 }
619 }
620
621 answer
622 }
623}
624
625struct Sol3442 {}
627
628impl Sol3442 {
629 pub fn max_difference(s: String) -> i32 {
630 use std::collections::HashMap;
631
632 let mut freqs = HashMap::new();
633 for chr in s.chars() {
634 freqs.entry(chr).and_modify(|f| *f += 1).or_insert(1);
635 }
636
637 println!("-> {freqs:?}");
638
639 if let (Some(omax), Some(emin)) = (
640 freqs.values().filter(|&f| f & 1 == 1).max(),
641 freqs.values().filter(|&f| f & 1 == 0).min(),
642 ) {
643 return omax - emin;
644 }
645
646 0
647 }
648}
649
650#[cfg(test)]
651mod tests;