1use std::cmp::Ordering;
6use std::cmp::Reverse;
7use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};
8use std::error::Error as StdError;
9use std::fmt;
10
11#[derive(Debug, Clone, PartialEq)]
13pub enum Error {
14 NotFound,
15 InvalidInput,
16 InvalidGraph,
17 NegativeCycle,
18}
19
20impl fmt::Display for Error {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 match self {
23 Error::NotFound => write!(f, "not found"),
24 Error::InvalidInput => write!(f, "invalid input"),
25 Error::InvalidGraph => write!(f, "invalid graph"),
26 Error::NegativeCycle => write!(f, "negative-weight cycle detected"),
27 }
28 }
29}
30
31impl StdError for Error {}
32
33pub fn quick_sort<T: Ord + Clone>(items: &[T]) -> Vec<T> {
37 if items.len() <= 1 {
38 return items.to_vec();
39 }
40 let pivot = items[items.len() / 2].clone();
41 let mut left = Vec::new();
42 let mut middle = Vec::new();
43 let mut right = Vec::new();
44 for x in items {
45 if *x < pivot {
46 left.push(x.clone());
47 } else if *x > pivot {
48 right.push(x.clone());
49 } else {
50 middle.push(x.clone());
51 }
52 }
53 let mut result = quick_sort(&left);
54 result.extend(middle);
55 result.extend(quick_sort(&right));
56 result
57}
58
59pub fn merge_sort<T: Ord + Clone>(items: &[T]) -> Vec<T> {
61 if items.len() <= 1 {
62 return items.to_vec();
63 }
64 let mid = items.len() / 2;
65 let left = merge_sort(&items[..mid]);
66 let right = merge_sort(&items[mid..]);
67 merge(&left, &right)
68}
69
70fn merge<T: Ord>(left: &[T], right: &[T]) -> Vec<T>
71where
72 T: Clone,
73{
74 let mut merged = Vec::with_capacity(left.len() + right.len());
75 let mut i = 0;
76 let mut j = 0;
77 while i < left.len() && j < right.len() {
78 if left[i] <= right[j] {
79 merged.push(left[i].clone());
80 i += 1;
81 } else {
82 merged.push(right[j].clone());
83 j += 1;
84 }
85 }
86 merged.extend_from_slice(&left[i..]);
87 merged.extend_from_slice(&right[j..]);
88 merged
89}
90
91pub fn heap_sort<T: Ord + Clone>(items: &[T]) -> Vec<T> {
93 let mut arr = items.to_vec();
94 let n = arr.len();
95 if n <= 1 {
96 return arr;
97 }
98 for i in (0..n / 2).rev() {
99 sift_down(&mut arr, n, i);
100 }
101 for end in (1..n).rev() {
102 arr.swap(0, end);
103 sift_down(&mut arr, end, 0);
104 }
105 arr
106}
107
108fn sift_down<T: Ord>(arr: &mut [T], n: usize, i: usize) {
109 let mut largest = i;
110 let left = 2 * i + 1;
111 let right = 2 * i + 2;
112 if left < n && arr[left] > arr[largest] {
113 largest = left;
114 }
115 if right < n && arr[right] > arr[largest] {
116 largest = right;
117 }
118 if largest != i {
119 arr.swap(i, largest);
120 sift_down(arr, n, largest);
121 }
122}
123
124pub fn radix_sort(items: &[i64]) -> Result<Vec<i64>, Error> {
126 if items.is_empty() {
127 return Ok(Vec::new());
128 }
129 for &v in items {
130 if v < 0 {
131 return Err(Error::InvalidInput);
132 }
133 }
134 let mut arr = items.to_vec();
135 let mut max_val = arr[0];
136 for &v in &arr {
137 if v > max_val {
138 max_val = v;
139 }
140 }
141 let mut exp = 1;
142 while max_val / exp > 0 {
143 counting_sort_by_digit(&mut arr, exp);
144 exp *= 10;
145 }
146 Ok(arr)
147}
148
149fn counting_sort_by_digit(arr: &mut [i64], exp: i64) {
150 let n = arr.len();
151 let mut output = vec![0; n];
152 let mut count = vec![0; 10];
153 for &num in arr.iter() {
154 count[((num / exp) % 10) as usize] += 1;
155 }
156 for i in 1..10 {
157 count[i] += count[i - 1];
158 }
159 for i in (0..n).rev() {
160 let index = ((arr[i] / exp) % 10) as usize;
161 output[count[index] - 1] = arr[i];
162 count[index] -= 1;
163 }
164 arr.copy_from_slice(&output);
165}
166
167pub fn tim_sort<T: Ord + Clone>(items: &[T]) -> Vec<T> {
169 let mut arr = items.to_vec();
170 arr.sort();
171 arr
172}
173
174fn check_sorted<T: Ord>(arr: &[T]) -> Result<(), Error> {
177 for i in 1..arr.len() {
178 if arr[i] < arr[i - 1] {
179 return Err(Error::InvalidInput);
180 }
181 }
182 Ok(())
183}
184
185pub fn binary_search<T: Ord>(arr: &[T], target: &T) -> Result<usize, Error> {
187 check_sorted(arr)?;
188 let mut lo = 0;
189 let mut hi = arr.len() as isize - 1;
190 while lo <= hi {
191 let mid = (lo + hi) / 2;
192 let mid_usize = mid as usize;
193 if &arr[mid_usize] == target {
194 return Ok(mid_usize);
195 }
196 if &arr[mid_usize] < target {
197 lo = mid + 1;
198 } else {
199 hi = mid - 1;
200 }
201 }
202 Err(Error::NotFound)
203}
204
205pub fn interpolation_search(arr: &[i64], target: i64) -> Result<usize, Error> {
207 check_sorted(arr)?;
208 let mut lo = 0;
209 let mut hi = arr.len() as isize - 1;
210 while lo <= hi && target >= arr[lo as usize] && target <= arr[hi as usize] {
211 if arr[hi as usize] == arr[lo as usize] {
212 if arr[lo as usize] == target {
213 return Ok(lo as usize);
214 }
215 break;
216 }
217 let lo_usize = lo as usize;
218 let hi_usize = hi as usize;
219 let pos = lo_usize
220 + ((target - arr[lo_usize]) as f64 / (arr[hi_usize] - arr[lo_usize]) as f64
221 * (hi_usize - lo_usize) as f64) as usize;
222 if pos < lo_usize || pos > hi_usize {
223 break;
224 }
225 if arr[pos] == target {
226 return Ok(pos);
227 }
228 if arr[pos] < target {
229 lo = pos as isize + 1;
230 } else {
231 hi = pos as isize - 1;
232 }
233 }
234 Err(Error::NotFound)
235}
236
237pub fn jump_search<T: Ord>(arr: &[T], target: &T) -> Result<usize, Error> {
239 check_sorted(arr)?;
240 let n = arr.len();
241 if n == 0 {
242 return Err(Error::NotFound);
243 }
244 let mut step = (n as f64).sqrt() as usize;
245 if step == 0 {
246 step = 1;
247 }
248 let mut prev = 0;
249 while arr[step.min(n) - 1] < *target {
250 prev = step;
251 step += (n as f64).sqrt() as usize;
252 if prev >= n {
253 return Err(Error::NotFound);
254 }
255 }
256 while arr[prev] < *target {
257 prev += 1;
258 if prev == step.min(n) {
259 return Err(Error::NotFound);
260 }
261 }
262 if &arr[prev] == target {
263 return Ok(prev);
264 }
265 Err(Error::NotFound)
266}
267
268#[derive(Debug, Clone, PartialEq)]
272pub struct Edge {
273 pub to: String,
274 pub weight: f64,
275}
276
277impl Edge {
278 pub fn new(to: &str, weight: f64) -> Self {
279 Edge {
280 to: to.to_string(),
281 weight,
282 }
283 }
284}
285
286pub fn bfs(graph: &HashMap<String, Vec<String>>, start: &str) -> Result<Vec<String>, Error> {
288 if !graph.contains_key(start) {
289 return Err(Error::InvalidGraph);
290 }
291 let mut visited = HashSet::new();
292 visited.insert(start.to_string());
293 let mut queue = VecDeque::new();
294 queue.push_back(start.to_string());
295 let mut result = Vec::new();
296 while let Some(current) = queue.pop_front() {
297 result.push(current.clone());
298 if let Some(neighbors) = graph.get(¤t) {
299 for nbr in neighbors {
300 if visited.insert(nbr.clone()) {
301 queue.push_back(nbr.clone());
302 }
303 }
304 }
305 }
306 Ok(result)
307}
308
309pub fn dfs(graph: &HashMap<String, Vec<String>>, start: &str) -> Result<Vec<String>, Error> {
311 if !graph.contains_key(start) {
312 return Err(Error::InvalidGraph);
313 }
314 let mut visited = HashSet::new();
315 visited.insert(start.to_string());
316 let mut stack = vec![start.to_string()];
317 let mut result = Vec::new();
318 while let Some(current) = stack.pop() {
319 result.push(current.clone());
320 if let Some(neighbors) = graph.get(¤t) {
321 for nbr in neighbors.iter().rev() {
322 if visited.insert(nbr.clone()) {
323 stack.push(nbr.clone());
324 }
325 }
326 }
327 }
328 Ok(result)
329}
330
331#[derive(Clone)]
332struct State {
333 cost: f64,
334 node: String,
335}
336
337impl PartialEq for State {
338 fn eq(&self, other: &Self) -> bool {
339 self.cost.total_cmp(&other.cost) == Ordering::Equal && self.node == other.node
340 }
341}
342
343impl Eq for State {}
344
345impl PartialOrd for State {
346 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
347 Some(self.cmp(other))
348 }
349}
350
351impl Ord for State {
352 fn cmp(&self, other: &Self) -> Ordering {
353 other
354 .cost
355 .total_cmp(&self.cost)
356 .then_with(|| self.node.cmp(&other.node))
357 }
358}
359
360pub fn dijkstra(
362 graph: &HashMap<String, Vec<Edge>>,
363 start: &str,
364) -> Result<(HashMap<String, f64>, HashMap<String, String>), Error> {
365 if !graph.contains_key(start) {
366 return Err(Error::InvalidGraph);
367 }
368 let mut distances: HashMap<String, f64> =
369 graph.keys().map(|k| (k.clone(), f64::INFINITY)).collect();
370 distances.insert(start.to_string(), 0.0);
371 let mut predecessors = HashMap::new();
372
373 let mut pq = BinaryHeap::new();
374 pq.push(State {
375 cost: 0.0,
376 node: start.to_string(),
377 });
378
379 while let Some(State { cost, node }) = pq.pop() {
380 if cost != distances[&node] {
381 continue;
382 }
383 for e in graph.get(&node).unwrap_or(&Vec::new()) {
384 if e.weight < 0.0 {
385 return Err(Error::InvalidGraph);
386 }
387 let nd = cost + e.weight;
388 let current = distances.get(&e.to).copied().unwrap_or(f64::INFINITY);
389 if nd < current {
390 distances.insert(e.to.clone(), nd);
391 predecessors.insert(e.to.clone(), node.clone());
392 pq.push(State {
393 cost: nd,
394 node: e.to.clone(),
395 });
396 }
397 }
398 }
399 Ok((distances, predecessors))
400}
401
402pub fn a_star<F>(
404 graph: &HashMap<String, Vec<Edge>>,
405 start: &str,
406 goal: &str,
407 heuristic: F,
408) -> Result<(Vec<String>, f64), Error>
409where
410 F: Fn(&str, &str) -> f64,
411{
412 if !graph.contains_key(start) || !graph.contains_key(goal) {
413 return Err(Error::InvalidGraph);
414 }
415 let mut g_score = HashMap::new();
416 g_score.insert(start.to_string(), 0.0);
417 let mut came_from = HashMap::new();
418 let mut pq = BinaryHeap::new();
419 pq.push(State {
420 cost: heuristic(start, goal),
421 node: start.to_string(),
422 });
423
424 while let Some(State { cost: _, node }) = pq.pop() {
425 if node == goal {
426 return Ok((reconstruct_path(&came_from, &node), g_score[goal]));
427 }
428 for e in graph.get(&node).unwrap_or(&Vec::new()) {
429 let tentative = g_score[&node] + e.weight;
430 let current = g_score.get(&e.to).copied().unwrap_or(f64::INFINITY);
431 if tentative < current {
432 came_from.insert(e.to.clone(), node.clone());
433 g_score.insert(e.to.clone(), tentative);
434 pq.push(State {
435 cost: tentative + heuristic(&e.to, goal),
436 node: e.to.clone(),
437 });
438 }
439 }
440 }
441 Err(Error::NotFound)
442}
443
444fn reconstruct_path(came_from: &HashMap<String, String>, start: &str) -> Vec<String> {
445 let mut current = start.to_string();
446 let mut path = vec![current.clone()];
447 while let Some(prev) = came_from.get(¤t) {
448 path.push(prev.clone());
449 current = prev.clone();
450 }
451 path.reverse();
452 path
453}
454
455struct Edge3 {
456 from: String,
457 to: String,
458 weight: f64,
459}
460
461pub fn bellman_ford(
463 graph: &HashMap<String, Vec<Edge>>,
464 start: &str,
465) -> Result<(HashMap<String, f64>, HashMap<String, String>), Error> {
466 if !graph.contains_key(start) {
467 return Err(Error::InvalidGraph);
468 }
469 let mut vertices = HashSet::new();
470 let mut edges = Vec::new();
471 for (u, list) in graph {
472 vertices.insert(u.clone());
473 for e in list {
474 vertices.insert(e.to.clone());
475 edges.push(Edge3 {
476 from: u.clone(),
477 to: e.to.clone(),
478 weight: e.weight,
479 });
480 }
481 }
482 let mut distances = HashMap::new();
483 distances.insert(start.to_string(), 0.0);
484 let mut predecessors = HashMap::new();
485
486 for _ in 0..vertices.len().saturating_sub(1) {
487 let mut updated = false;
488 for e in &edges {
489 if let Some(&du) = distances.get(&e.from) {
490 let dv = distances.get(&e.to).copied().unwrap_or(f64::INFINITY);
491 if du + e.weight < dv {
492 distances.insert(e.to.clone(), du + e.weight);
493 predecessors.insert(e.to.clone(), e.from.clone());
494 updated = true;
495 }
496 }
497 }
498 if !updated {
499 break;
500 }
501 }
502
503 for e in &edges {
504 if let Some(&du) = distances.get(&e.from) {
505 let dv = distances.get(&e.to).copied().unwrap_or(f64::INFINITY);
506 if du + e.weight < dv {
507 return Err(Error::NegativeCycle);
508 }
509 }
510 }
511 Ok((distances, predecessors))
512}
513
514pub fn knapsack_01(weights: &[i64], values: &[i64], capacity: i64) -> Result<i64, Error> {
518 if weights.len() != values.len() {
519 return Err(Error::InvalidInput);
520 }
521 if capacity < 0 {
522 return Err(Error::InvalidInput);
523 }
524 let cap = capacity as usize;
525 let mut dp = vec![0; cap + 1];
526 for i in 0..weights.len() {
527 let w = weights[i] as usize;
528 if weights[i] < 0 {
529 return Err(Error::InvalidInput);
530 }
531 let v = values[i];
532 for c in (w..=cap).rev() {
533 if dp[c - w] + v > dp[c] {
534 dp[c] = dp[c - w] + v;
535 }
536 }
537 }
538 Ok(dp[cap])
539}
540
541pub fn longest_common_subsequence<T: PartialEq>(a: &[T], b: &[T]) -> usize {
543 let (m, n) = (a.len(), b.len());
544 let mut prev = vec![0; n + 1];
545 for i in 1..=m {
546 let mut curr = vec![0; n + 1];
547 for j in 1..=n {
548 if a[i - 1] == b[j - 1] {
549 curr[j] = prev[j - 1] + 1;
550 } else {
551 curr[j] = prev[j].max(curr[j - 1]);
552 }
553 }
554 prev = curr;
555 }
556 prev[n]
557}
558
559pub fn edit_distance<T: PartialEq>(a: &[T], b: &[T]) -> usize {
561 let (m, n) = (a.len(), b.len());
562 let mut prev: Vec<usize> = (0..=n).collect();
563 for i in 1..=m {
564 let mut curr = vec![0; n + 1];
565 curr[0] = i;
566 for j in 1..=n {
567 let cost = if a[i - 1] == b[j - 1] { 0 } else { 1 };
568 let insertion = curr[j - 1] + 1;
569 let deletion = prev[j] + 1;
570 let substitution = prev[j - 1] + cost;
571 curr[j] = insertion.min(deletion).min(substitution);
572 }
573 prev = curr;
574 }
575 prev[n]
576}
577
578pub fn kmp_search(text: &str, pattern: &str) -> Result<Vec<usize>, Error> {
582 if pattern.is_empty() {
583 return Err(Error::InvalidInput);
584 }
585 let t = text.as_bytes();
586 let p = pattern.as_bytes();
587 let failure = compute_kmp_failure(p);
588 let mut matches = Vec::new();
589 let mut j = 0;
590 for i in 0..t.len() {
591 while j > 0 && t[i] != p[j] {
592 j = failure[j - 1];
593 }
594 if t[i] == p[j] {
595 j += 1;
596 }
597 if j == p.len() {
598 matches.push(i - p.len() + 1);
599 j = failure[j - 1];
600 }
601 }
602 Ok(matches)
603}
604
605fn compute_kmp_failure(pattern: &[u8]) -> Vec<usize> {
606 let mut failure = vec![0; pattern.len()];
607 let mut j = 0;
608 for i in 1..pattern.len() {
609 while j > 0 && pattern[i] != pattern[j] {
610 j = failure[j - 1];
611 }
612 if pattern[i] == pattern[j] {
613 j += 1;
614 failure[i] = j;
615 }
616 }
617 failure
618}
619
620pub fn rabin_karp_search(
622 text: &str,
623 pattern: &str,
624 base: i64,
625 modulus: i64,
626) -> Result<Vec<usize>, Error> {
627 if pattern.is_empty() {
628 return Err(Error::InvalidInput);
629 }
630 let t = text.as_bytes();
631 let p = pattern.as_bytes();
632 let (n, m) = (t.len(), p.len());
633 if m > n {
634 return Ok(Vec::new());
635 }
636 let mut h = 1i64;
637 for _ in 0..m - 1 {
638 h = (h * base) % modulus;
639 }
640 let mut pattern_hash = 0i64;
641 let mut text_hash = 0i64;
642 for i in 0..m {
643 pattern_hash = (pattern_hash * base + p[i] as i64) % modulus;
644 text_hash = (text_hash * base + t[i] as i64) % modulus;
645 }
646 let mut matches = Vec::new();
647 for i in 0..=n - m {
648 if text_hash == pattern_hash && &t[i..i + m] == p {
649 matches.push(i);
650 }
651 if i < n - m {
652 text_hash = (text_hash - t[i] as i64 * h) % modulus;
653 text_hash = (text_hash * base + t[i + m] as i64) % modulus;
654 text_hash = ((text_hash % modulus) + modulus) % modulus;
655 }
656 }
657 Ok(matches)
658}
659
660pub fn boyer_moore_search(text: &str, pattern: &str) -> Result<Vec<usize>, Error> {
662 if pattern.is_empty() {
663 return Err(Error::InvalidInput);
664 }
665 let t = text.as_bytes();
666 let p = pattern.as_bytes();
667 let (n, m) = (t.len(), p.len());
668 if m > n {
669 return Ok(Vec::new());
670 }
671 let mut bad_char = HashMap::new();
672 for (i, &b) in p.iter().enumerate() {
673 bad_char.insert(b, i);
674 }
675 let mut matches = Vec::new();
676 let mut i = 0usize;
677 while i <= n - m {
678 let mut j = (m - 1) as isize;
679 while j >= 0 && t[i + j as usize] == p[j as usize] {
680 j -= 1;
681 }
682 if j < 0 {
683 matches.push(i);
684 i += m;
685 } else {
686 let ju = j as usize;
687 let last = bad_char.get(&t[i + ju]).copied().unwrap_or(usize::MAX);
688 let mut shift = if ju > last { ju - last } else { 1 };
689 if shift < 1 {
690 shift = 1;
691 }
692 i += shift;
693 }
694 }
695 Ok(matches)
696}
697
698pub fn activity_selection(activities: &[(i64, i64)]) -> Result<Vec<usize>, Error> {
702 if activities.is_empty() {
703 return Ok(Vec::new());
704 }
705 #[derive(Clone, Copy)]
706 struct Indexed {
707 index: usize,
708 start: i64,
709 end: i64,
710 }
711 let mut list = Vec::with_capacity(activities.len());
712 for (i, &(start, end)) in activities.iter().enumerate() {
713 if start > end {
714 return Err(Error::InvalidInput);
715 }
716 list.push(Indexed { index: i, start, end });
717 }
718 list.sort_by(|a, b| a.end.cmp(&b.end));
719 let mut selected = vec![list[0].index];
720 let mut last_end = list[0].end;
721 for item in list.iter().skip(1) {
722 if item.start >= last_end {
723 selected.push(item.index);
724 last_end = item.end;
725 }
726 }
727 Ok(selected)
728}
729
730pub fn fractional_knapsack(
732 weights: &[f64],
733 values: &[f64],
734 capacity: f64,
735) -> Result<f64, Error> {
736 if weights.len() != values.len() {
737 return Err(Error::InvalidInput);
738 }
739 if capacity < 0.0 {
740 return Err(Error::InvalidInput);
741 }
742 #[derive(Clone, Copy)]
743 struct Item {
744 ratio: f64,
745 weight: f64,
746 }
747 let mut items = Vec::with_capacity(weights.len());
748 for i in 0..weights.len() {
749 if weights[i] > 0.0 {
750 items.push(Item {
751 ratio: values[i] / weights[i],
752 weight: weights[i],
753 });
754 }
755 }
756 items.sort_by(|a, b| {
757 b.ratio
758 .partial_cmp(&a.ratio)
759 .unwrap_or(Ordering::Equal)
760 });
761 let mut total = 0.0;
762 let mut remaining = capacity;
763 for it in items {
764 let take = it.weight.min(remaining);
765 total += take * it.ratio;
766 remaining -= take;
767 if remaining <= 0.0 {
768 break;
769 }
770 }
771 Ok(total)
772}
773
774struct HuffmanNode {
775 freq: i64,
776 char: String,
777 left: Option<Box<HuffmanNode>>,
778 right: Option<Box<HuffmanNode>>,
779}
780
781impl PartialEq for HuffmanNode {
782 fn eq(&self, other: &Self) -> bool {
783 self.freq == other.freq && self.char == other.char
784 }
785}
786
787impl Eq for HuffmanNode {}
788
789impl PartialOrd for HuffmanNode {
790 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
791 Some(self.cmp(other))
792 }
793}
794
795impl Ord for HuffmanNode {
796 fn cmp(&self, other: &Self) -> Ordering {
797 self.freq
798 .cmp(&other.freq)
799 .then_with(|| self.char.cmp(&other.char))
800 }
801}
802
803pub fn huffman_coding(frequencies: &HashMap<String, i64>) -> Result<HashMap<String, String>, Error> {
805 if frequencies.is_empty() {
806 return Err(Error::InvalidInput);
807 }
808 let mut pq = BinaryHeap::new();
809 for (ch, &freq) in frequencies {
810 pq.push(Reverse(HuffmanNode {
811 freq,
812 char: ch.clone(),
813 left: None,
814 right: None,
815 }));
816 }
817 if pq.len() == 1 {
818 let node = pq.pop().unwrap().0;
819 let mut codes = HashMap::new();
820 codes.insert(node.char, "0".to_string());
821 return Ok(codes);
822 }
823 while pq.len() > 1 {
824 let left = pq.pop().unwrap().0;
825 let right = pq.pop().unwrap().0;
826 let parent = HuffmanNode {
827 freq: left.freq + right.freq,
828 char: String::new(),
829 left: Some(Box::new(left)),
830 right: Some(Box::new(right)),
831 };
832 pq.push(Reverse(parent));
833 }
834 let root = pq.pop().unwrap().0;
835 let mut codes = HashMap::new();
836 assign_huffman_codes(&root, "", &mut codes);
837 Ok(codes)
838}
839
840fn assign_huffman_codes(node: &HuffmanNode, prefix: &str, codes: &mut HashMap<String, String>) {
841 if !node.char.is_empty() {
842 if prefix.is_empty() {
843 codes.insert(node.char.clone(), "0".to_string());
844 } else {
845 codes.insert(node.char.clone(), prefix.to_string());
846 }
847 return;
848 }
849 if let Some(ref left) = node.left {
850 assign_huffman_codes(left, &format!("{}0", prefix), codes);
851 }
852 if let Some(ref right) = node.right {
853 assign_huffman_codes(right, &format!("{}1", prefix), codes);
854 }
855}
856
857pub fn max_subarray(arr: &[i64]) -> Result<i64, Error> {
861 if arr.is_empty() {
862 return Err(Error::InvalidInput);
863 }
864 Ok(max_subarray_dc(arr, 0, arr.len() - 1))
865}
866
867fn max_subarray_dc(arr: &[i64], left: usize, right: usize) -> i64 {
868 if left == right {
869 return arr[left];
870 }
871 let mid = (left + right) / 2;
872 let left_sum = max_subarray_dc(arr, left, mid);
873 let right_sum = max_subarray_dc(arr, mid + 1, right);
874 let cross_sum = max_crossing_sum(arr, left, mid, right);
875 left_sum.max(right_sum).max(cross_sum)
876}
877
878fn max_crossing_sum(arr: &[i64], left: usize, mid: usize, right: usize) -> i64 {
879 let mut sum = arr[mid];
880 let mut left_max = arr[mid];
881 for i in (left..mid).rev() {
882 sum += arr[i];
883 if sum > left_max {
884 left_max = sum;
885 }
886 }
887 sum = arr[mid + 1];
888 let mut right_max = arr[mid + 1];
889 for i in mid + 2..=right {
890 sum += arr[i];
891 if sum > right_max {
892 right_max = sum;
893 }
894 }
895 left_max + right_max
896}
897
898pub fn count_inversions<T: Ord + Clone>(arr: &[T]) -> usize {
900 let (_, count) = sort_and_count(arr);
901 count
902}
903
904fn sort_and_count<T: Ord + Clone>(arr: &[T]) -> (Vec<T>, usize) {
905 let n = arr.len();
906 if n <= 1 {
907 return (arr.to_vec(), 0);
908 }
909 let mid = n / 2;
910 let (left, lcount) = sort_and_count(&arr[..mid]);
911 let (right, rcount) = sort_and_count(&arr[mid..]);
912 let (merged, scount) = merge_and_count(&left, &right);
913 (merged, lcount + rcount + scount)
914}
915
916fn merge_and_count<T: Ord + Clone>(left: &[T], right: &[T]) -> (Vec<T>, usize) {
917 let mut merged = Vec::with_capacity(left.len() + right.len());
918 let mut count = 0;
919 let mut i = 0;
920 let mut j = 0;
921 while i < left.len() && j < right.len() {
922 if left[i] <= right[j] {
923 merged.push(left[i].clone());
924 i += 1;
925 } else {
926 merged.push(right[j].clone());
927 j += 1;
928 count += left.len() - i;
929 }
930 }
931 merged.extend_from_slice(&left[i..]);
932 merged.extend_from_slice(&right[j..]);
933 (merged, count)
934}
935
936pub fn fast_power(base: f64, exponent: i64) -> f64 {
938 if exponent < 0 {
939 return 1.0 / fast_power(base, -exponent);
940 }
941 if exponent == 0 {
942 return 1.0;
943 }
944 if exponent == 1 {
945 return base;
946 }
947 let half = fast_power(base, exponent / 2);
948 if exponent % 2 == 0 {
949 half * half
950 } else {
951 base * half * half
952 }
953}