1pub mod dp {
2 use itertools::structs::Combinations;
5 use std::sync::RwLock;
6 use field_accessor::FieldAccessor;
7
8 struct MultiCombination<I: Iterator> {
9 combs: Vec<Combinations<I>>,
10 }
11
12 impl<I> Iterator for MultiCombination<I>
13 where
14 I: Iterator,
15 I::Item: Clone,
16 {
17 type Item = Vec<I::Item>;
18 fn next(&mut self) -> Option<Self::Item> {
19 for comb in &mut self.combs {
20 if let Some(elt) = comb.next() {
21 return Some(elt);
22 } else {
23 continue;
24 }
25 }
26 None
27 }
28 }
29 use rayon::prelude::*;
30 use std::collections::HashMap;
31 use std::sync::Arc;
32
33 #[derive(Clone, Debug, FieldAccessor)]
34 pub struct AnswerElement {
35 pub answer_arr: Vec<(Vec<i32>, Vec<i32>)>,
36 pub keys_remainder: Vec<i32>,
37 pub targets_remainder: Vec<i32>,
38 }
39
40 impl Eq for AnswerElement {}
41
42 impl PartialEq for AnswerElement {
43 fn eq(&self, other: &Self) -> bool {
44 self.answer_arr == other.answer_arr
45 }
46 }
47
48 use std::cmp::Ordering;
49
50 impl Ord for AnswerElement {
51 fn cmp(&self, other: &Self) -> Ordering {
52 self.answer_arr.cmp(&other.answer_arr)
53 }
54 }
55
56 impl PartialOrd for AnswerElement {
57 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
58 Some(self.cmp(other))
59 }
60 }
61
62 #[derive(Clone, Debug)]
63 struct DpTable {
64 dp: Vec<bool>,
65 max_value: usize,
66 }
67
68 pub fn sequence_matcher_formatter(result: Vec<AnswerElement>) -> String {
69 let mut s: Vec<String> = vec![];
70 for (i, r) in result.iter().enumerate() {
71 let mut t: Vec<String> = vec![];
72 for elem in r.answer_arr.clone() {
73 let key_str: String = elem
74 .0
75 .iter()
76 .map(|k| k.to_string())
77 .collect::<Vec<String>>()
78 .join(" + ");
79 let target_str: String = elem
80 .1
81 .iter()
82 .map(|k| k.to_string())
83 .collect::<Vec<String>>()
84 .join(" + ");
85 t.push(format!(
86 "(Sum({}) -> keys:[{}] == targets:[{}])",
87 elem.0.iter().sum::<i32>(),
88 key_str,
89 target_str
90 ));
91 }
92 s.push(format!(
93 "pattern{number:^width$}=> [{v}],\n keys remainder : {k}\n targets remainder : {t}\n",
94 number = i + 1,
95 width = 4,
96 v = t.join("\n "),
97 k = r.keys_remainder.iter().map(|k| k.to_string()).collect::<Vec<String>>().join(", "),
98 t = r.targets_remainder.iter().map(|k| k.to_string()).collect::<Vec<String>>().join(", "),
99 ))
100 }
101 s.join("\n")
102 }
103
104 pub fn find_subset(arr: Vec<i32>, value: i32, max_length: usize) -> Vec<Vec<i32>> {
130 _find_subset(&arr, value, max_length, None, None, None)
131 }
132
133 fn _find_subset(
134 arr: &Vec<i32>,
135 value: i32,
136 max_length: usize,
137 dptable: Option<&DpTable>,
138 arr_pos: Option<&Vec<u32>>,
139 offset: Option<i32>,
140 ) -> Vec<Vec<i32>> {
141 use std::cmp::max;
142 use std::cmp::min;
143 let offset: i32 = match offset {
146 Some(x) => x,
147 None => {
148 (max(arr.iter().min().unwrap().abs() + 1, min(value, 0).abs() + 1)) as i32
149 }
150 };
151 let answer: Arc<RwLock<Vec<Vec<i32>>>> = Arc::new(RwLock::new(vec![]));
152 if offset == 0 && arr.iter().min().unwrap() >= &0 && value >= 0 {
153 let arr_pos = arr.iter().map(|e| *e as u32).collect::<Vec<u32>>();
154 let _dp: DpTable;
155 let dptable = match dptable {
156 Some(x) => x,
157 None => {
158 _dp = _make_dp_table(&arr_pos, value as usize);
159 &_dp
160 }
161 };
162 let result =
163 _find_subsetsfast_only_positive(&arr_pos, value as usize, max_length, dptable);
164 result.iter().for_each(|i| {
165 answer
166 .write()
167 .unwrap()
168 .push(i.iter().map(|e| *e as i32).collect::<Vec<i32>>())
169 });
170 return vector_sorter(answer.read().unwrap().to_vec());
171 } else {
172 let length = arr.len();
173
174 let max_value = value + min(length, max_length) as i32 * offset;
178 let _arr_pos: &Vec<u32>;
179 let temp;
180 _arr_pos = match arr_pos {
181 None => {
182 temp = arr
183 .iter()
184 .map(|e| (e + offset) as u32)
185 .collect::<Vec<u32>>();
186 &temp
187 }
188 Some(x) => x,
189 };
190 let temp2;
191 let dptable = match dptable {
192 Some(x) => x,
193 None => {
194 temp2 = _make_dp_table(&_arr_pos, max_value as usize);
195 &temp2
196 }
197 };
198 let c = |i| {
199 let result = _find_subsetsfast_only_positive(
200 &_arr_pos,
201 (value + (i as i32 * offset)) as usize,
202 max_length,
203 dptable,
204 );
205 result.iter().for_each(|res| {
206 let mut tempsum: i32 = 0;
207 let mut new_res: Vec<i32> = Vec::with_capacity(res.len());
208 for j in res {
209 let v = *j as i32 - offset;
210 tempsum += v;
211 new_res.push(v);
212 }
213 if tempsum == value {
214 answer.write().unwrap().push(new_res);
215 }
216 })
217 };
218 if cfg!(feature = "wasm") {
219 (1..min(length, max_length) + 1).into_iter().for_each(c);
220 } else {
221 (1..min(length, max_length) + 1).into_par_iter().for_each(c);
222 }
223 return vector_sorter(answer.read().unwrap().to_vec());
224 };
225 }
226
227 fn rec(
228 dp: &Vec<bool>,
229 arr: &Vec<u32>,
230 i: usize,
231 j: usize,
232 route: &mut Vec<u32>,
233 answer: &mut Vec<Vec<u32>>,
234 max_length: usize,
235 collen: usize,
236 ) {
237 if i == 0 {
241 if j == 0 {
242 if route.len() <= max_length {
244 answer.push(route.clone());
245 }
246 }
247 return;
248 }
249
250 if route.len() > max_length {
251 return;
252 }
253 let i_minus_one = i - 1;
254 let one_step_up = i_minus_one * collen + j;
255 let v = { *arr.get(i_minus_one).unwrap() };
256
257 if *dp.get(one_step_up).unwrap() == true {
258 rec(dp, arr, i_minus_one, j, route, answer, max_length, collen);
259 }
260
261 let j_v: usize = match j.checked_sub(v as usize) {
262 Some(x) => x,
263 None => return,
264 };
265 match dp.get(one_step_up - v as usize) {
266 Some(x) => {
267 if x == &true {
268 route.push(v);
269 rec(dp, arr, i_minus_one, j_v, route, answer, max_length, collen);
270 route.pop();
271 }
272 }
273 None => (),
274 }
275 }
276
277 #[test]
278
279 fn test_vector_sorter() {
280 for _i in 0..1 {
281 let v = vec![vec![1, 3, 4], vec![4, 5]];
282 let r = vector_sorter(v);
283 assert_eq!(r, vec![vec![4, 5], vec![1, 3, 4]]);
284
285 let v = vec![vec![4, 2, 1], vec![4, 2]];
286 let r = vector_sorter(v);
287 assert_eq!(r, vec![vec![2, 4], vec![1, 2, 4]]);
288
289 let v = vec![vec![3, 0], vec![3], vec![2, 1], vec![1, 0, 2]];
290 let r = vector_sorter(v);
291 assert_eq!(r, vec![vec![3], vec![1, 2], vec![0, 3], vec![0, 1, 2]]);
292 }
293 }
294
295 fn vector_sorter<T: std::cmp::Ord + std::iter::Sum + std::clone::Clone + Copy>(
296 mut vec: Vec<Vec<T>>,
297 ) -> Vec<Vec<T>> {
298 if vec.len() == 0 {
299 return vec;
300 }
301 vec.sort_unstable();
302 vec.sort_unstable_by_key(|x| x.len());
303 vec.iter_mut().for_each(|x| x.sort_unstable());
304 vec
305 }
306
307 fn _make_dp_table(arr: &Vec<u32>, value: usize) -> DpTable {
308 let collen = value + 1;
309 let mut dp: Vec<bool> = vec![false; (value + 1) * (arr.len() + 1)];
310 dp[0] = true;
311 let mut current_address = 0;
312 arr.iter().for_each(|v_u32| {
313 let v_usize = *v_u32 as usize;
314 (0..value + 1).for_each(|_j| {
315 let current_value = *dp.get(current_address).unwrap();
316 if current_value == false {
317 current_address += 1;
318 return;
319 };
320 let address_onestep_down = current_address + collen;
321 dp[address_onestep_down] = true;
322
323 match dp.get_mut(address_onestep_down + v_usize) {
324 Some(x) => {
325 *x = true;
326 }
327 None => {}
328 }
329 current_address += 1;
330 });
331 });
332 DpTable {
333 dp: dp,
334 max_value: value,
335 }
336 }
337
338 fn _find_subsetsfast_only_positive(
339 arr: &Vec<u32>,
340 value: usize,
341 max_length: usize,
342 dptable: &DpTable,
343 ) -> Vec<Vec<u32>> {
344 let answer_exist: bool = *dptable
349 .dp
350 .get(dptable.dp.len() - 1 - (dptable.max_value - value))
351 .unwrap();
352 if answer_exist == false {
353 return vec![];
354 }
355 let collen = dptable.max_value + 1;
356 let a_length: usize = arr.len();
357 let mut route: Vec<u32> = vec![];
358 let mut answer: Vec<Vec<u32>> = vec![];
359 rec(
360 &dptable.dp,
361 &arr,
362 a_length,
363 value,
364 &mut route,
365 &mut answer,
366 max_length,
367 collen,
368 );
369 answer
370 }
371
372 fn vec_remove(arr: &mut Vec<i32>, v: i32) {
373 let index = arr.binary_search(&v).unwrap();
374 arr.remove(index);
375 }
376
377 pub fn sequence_matcher(
438 keys: &mut Vec<i32>,
439 targets: &mut Vec<i32>,
440 max_key_length: usize,
441 max_target_length: usize,
442 n_candidates: usize,
443 use_all_keys: bool,
444 use_all_targets: bool,
445 ) -> Result<Vec<AnswerElement>, String> {
446 let mut group: Vec<(Vec<i32>, Vec<i32>)> = vec![];
447 let mut answer: Arc<RwLock<Vec<AnswerElement>>> = Arc::new(RwLock::new(vec![]));
448 if use_all_keys && use_all_targets {
449 let ks = keys.iter().sum::<i32>();
450 let ts = targets.iter().sum::<i32>();
451 if ks != ts {
452 return Err(format!("The sums of two arrays must be the same values. key's sum is {}. target's sum is {}. The difference is {}.", ks, ts, ks - ts));
453 }
454 }
455 let mut hashmap_fs: Arc<RwLock<HashMap<(Vec<i32>, i32), Vec<Vec<i32>>>>> =
456 Arc::new(RwLock::new(HashMap::new()));
457 keys.sort_unstable();
458 targets.sort_unstable();
459 let swap: bool;
460 let (keys, targets, max_key_length, max_target_length, use_all_keys, use_all_targets) =
461 if keys.len() > targets.len() {
462 swap = true;
463 (
464 targets,
465 keys,
466 max_target_length,
467 max_key_length,
468 use_all_targets,
469 use_all_keys,
470 )
471 } else {
472 swap = false;
473 (
474 keys,
475 targets,
476 max_key_length,
477 max_target_length,
478 use_all_keys,
479 use_all_targets,
480 )
481 };
482 use std::cmp::min;
483 (0..min(keys.len(), targets.len())).for_each(|i| {
484 sequence_matcher_core(
485 keys,
486 targets,
487 &mut group,
488 &mut answer,
489 max_key_length,
490 max_target_length,
491 &mut hashmap_fs,
492 n_candidates,
493 use_all_keys,
494 use_all_targets,
495 i,
496 vec![],
497 )
498 });
499 let mut answer_vec: Vec<AnswerElement> = answer.read().unwrap().to_vec();
500 if swap {
501 answer_vec.iter_mut().for_each(|x| {
502 x.answer_arr.iter_mut().for_each(|y| {
503 std::mem::swap(&mut y.0, &mut y.1);
504 });
505 match x.swap(&"keys_remainder".to_string(), &"targets_remainder".to_string()) {
506 Ok(_) => {},
507 Err(e) => {
508 panic!("{}", e);
509 }
510 }
511 });
512 }
513 for i in 0..answer_vec.len() {
514 answer_vec[i]
515 .answer_arr
516 .sort_unstable_by_key(|k| k.0.iter().sum::<i32>());
517 answer_vec[i].answer_arr.sort_unstable_by_key(|k| k.0.len());
518 }
519 answer_vec.sort_unstable();
520 answer_vec.dedup();
521 if answer_vec.len() == 0 {
522 println!("Can't find any combination.");
523 }
524 Ok(answer_vec[..min(n_candidates, answer_vec.len())].to_vec())
525 }
526
527 fn sequence_matcher_core(
528 keys: &mut Vec<i32>,
529 targets: &mut Vec<i32>,
530 group: &mut Vec<(Vec<i32>, Vec<i32>)>,
531 answer: &mut Arc<RwLock<Vec<AnswerElement>>>,
532 max_key_length: usize,
533 max_target_length: usize,
534 hashmap_fs: &mut Arc<RwLock<HashMap<(Vec<i32>, i32), Vec<Vec<i32>>>>>,
535 n_candidates: usize,
536 use_all_keys: bool,
537 use_all_targets: bool,
538 max_depth: usize,
539 last_key: Vec<i32>,
540 ) -> () {
541 use itertools::Itertools;
542 use std::cmp::max;
543 use std::cmp::min;
544
545 if answer.read().unwrap().len() >= n_candidates {
546 return;
547 }
548
549 let add: bool = match (use_all_keys, use_all_targets) {
550 (true, true) => {
551 let add = match (keys.len() == 0, targets.len() == 0) {
552 (true, true) => true,
553 _ => false,
554 };
555 add
556 }
557 (true, false) => {
558 let add = match (keys.len() == 0, targets.len() == 0) {
559 (true, true) => true,
560 (true, false) => true,
561 _ => false,
562 };
563 add
564 }
565 (false, true) => {
566 let add = match (keys.len() == 0, targets.len() == 0) {
567 (true, true) => true,
568 (false, true) => true,
569 _ => false,
570 };
571 add
572 }
573 (false, false) => {
574 let add = match (keys.len() == 0, targets.len() == 0) {
575 (true, true) => true,
576 (false, true) => true,
577 (true, false) => true,
578 _ => false,
579 };
580 add
581 }
582 };
583
584 if add {
585 group.sort_unstable_by_key(|k| k.0.iter().sum::<i32>());
586 group.sort_unstable_by_key(|k| k.0.len());
587 let elem = AnswerElement {
588 answer_arr: group.clone(),
589 keys_remainder: keys.clone(),
590 targets_remainder: targets.clone(),
591 };
592 if answer.read().unwrap().contains(&elem) {
593 return;
594 } else {
595 answer.write().unwrap().push(elem.clone());
596 return;
597 }
598 }
599 if keys.len() == 0 || targets.len() == 0 {
600 return;
601 }
602 if group.len() > max_depth {
603 return;
604 }
605 targets.sort_unstable();
606 keys.sort_unstable();
607 keys.reverse();
608 let dp: DpTable;
609 let mut offset: i32 = 0;
610 let arr_pos: Vec<u32>;
611 let dp2: Option<&DpTable> =
612 if targets.iter().min().unwrap() >= &0 && keys.iter().min().unwrap() >= &0 {
613 arr_pos = targets.iter().map(|e| *e as u32).collect::<Vec<u32>>();
614 let max_value = keys[..min(max_key_length, keys.len())].iter().sum::<i32>();
615 dp = _make_dp_table(&arr_pos, max_value as usize);
616 Some(&dp)
617 } else {
618 offset = max(
619 targets.iter().min().unwrap().abs() + 1,
620 keys.iter().fold(0, |sum, x| min(sum, x + sum)).abs() + 1,
621 );
622 arr_pos = targets
623 .iter()
624 .map(|e| (e + offset) as u32)
625 .collect::<Vec<u32>>();
626 let _max_value = keys[..min(max_key_length, keys.len())]
627 .iter()
628 .map(|x| max(0, *x))
629 .sum::<i32>();
630 let max_value = _max_value + min(targets.len(), max_target_length) as i32 * offset;
631 dp = _make_dp_table(&arr_pos, max_value as usize);
632 Some(&dp)
633 };
634 keys.reverse();
635 let mut combs = vec![];
636 for i in 1..min(max_key_length, keys.len()) + 1 {
637 combs.push(keys.clone().into_iter().enumerate().combinations(i))
638 }
639 let mc = MultiCombination { combs: combs };
640 if cfg!(feature = "wasm") {
641 mc.for_each(|i| {
642 let sum_key: i32 = i.iter().map(|j| j.1).sum();
643 if sum_key < last_key.iter().sum() && i.len() == last_key.len() {
644 return;
645 }
646 let mut sets = {
647 match hashmap_fs.try_write() {
648 Ok(mut v) => v
649 .entry((targets.clone(), sum_key))
650 .or_insert(_find_subset(
651 &targets,
652 sum_key,
653 max_target_length,
654 dp2,
655 Some(&arr_pos),
656 Some(offset),
657 ))
658 .clone(),
659 Err(_) => _find_subset(
660 &targets,
661 sum_key,
662 max_target_length,
663 dp2,
664 Some(&arr_pos),
665 Some(offset),
666 ),
667 }
668 };
669 if sets.len() == 0 {
670 return;
671 }
672 sets.dedup();
673 let mut keys_removed: Vec<i32> = keys.clone();
674 let vec_key: Vec<i32> = i
675 .iter()
676 .enumerate()
677 .map(|(j2, j)| keys_removed.remove(j.0 - j2))
678 .collect();
679 sets.iter().for_each(|set| {
680 if set.len() == 0 {
681 return;
682 }
683 let mut keys_for_next = keys_removed.clone();
684 let mut targets_for_next = targets.clone();
685 let mut group_for_next = group.clone();
686 group_for_next.push((vec_key.clone(), set.clone()));
687 set.iter().for_each(|j| {
688 vec_remove(&mut targets_for_next, *j);
689 });
690 sequence_matcher_core(
691 &mut keys_for_next,
692 &mut targets_for_next,
693 &mut group_for_next,
694 &mut answer.clone(),
695 max_key_length,
696 max_target_length,
697 &mut hashmap_fs.clone(),
698 n_candidates,
699 use_all_keys,
700 use_all_targets,
701 max_depth,
702 vec_key.clone(),
703 );
704 });
705 });
706 } else {
707 mc.par_bridge().for_each(|i| {
708 let sum_key: i32 = i.par_iter().map(|j| j.1).sum();
709 if sum_key < last_key.iter().sum() && i.len() == last_key.len() {
710 return;
711 }
712 let mut sets = {
713 match hashmap_fs.try_write() {
714 Ok(mut v) => v
715 .entry((targets.clone(), sum_key))
716 .or_insert(_find_subset(
717 &targets,
718 sum_key,
719 max_target_length,
720 dp2,
721 Some(&arr_pos),
722 Some(offset),
723 ))
724 .clone(),
725 Err(_) => _find_subset(
726 &targets,
727 sum_key,
728 max_target_length,
729 dp2,
730 Some(&arr_pos),
731 Some(offset),
732 ),
733 }
734 };
735 if sets.len() == 0 {
736 return;
737 }
738 sets.dedup();
739 let mut keys_removed: Vec<i32> = keys.clone();
740 let vec_key: Vec<i32> = i
741 .iter()
742 .enumerate()
743 .map(|(j2, j)| keys_removed.remove(j.0 - j2))
744 .collect();
745 sets.par_iter().for_each(|set| {
746 if set.len() == 0 {
747 return;
748 }
749 let mut keys_for_next = keys_removed.clone();
750 let mut targets_for_next = targets.clone();
751 let mut group_for_next = group.clone();
752 group_for_next.push((vec_key.clone(), set.clone()));
753 set.iter().for_each(|j| {
754 vec_remove(&mut targets_for_next, *j);
755 });
756 sequence_matcher_core(
757 &mut keys_for_next,
758 &mut targets_for_next,
759 &mut group_for_next,
760 &mut answer.clone(),
761 max_key_length,
762 max_target_length,
763 &mut hashmap_fs.clone(),
764 n_candidates,
765 use_all_keys,
766 use_all_targets,
767 max_depth,
768 vec_key.clone(),
769 );
770 });
771 });
772 }
773 if use_all_keys == false && use_all_targets == false {
774 if group.len() == 0 {
775 return;
776 }
777 let elem = AnswerElement {
778 answer_arr: group.clone(),
779 keys_remainder: keys.clone(),
780 targets_remainder: targets.clone(),
781 };
782 answer.write().unwrap().push(elem.clone());
783 }
784 ()
785 }
786
787 #[test]
788 fn test_sequence_matcher() {
789 let answer = sequence_matcher(
790 &mut vec![-950, 10000],
791 &mut vec![5000, 4000, 50],
792 10,
793 10,
794 2,
795 true,
796 true,
797 )
798 .unwrap();
799 assert_eq!(
800 answer[0].answer_arr,
801 vec![(vec![-950, 10000], vec![50, 4000, 5000]),]
802 );
803
804 let answer = sequence_matcher(
805 &mut vec![6, 7, 3, 2, -9, -3, 8, 3, 6, -10],
806 &mut vec![3, 2, -6, -8, 2, -9, 0, -5, -3, 37],
807 7,
808 6,
809 30,
810 true,
811 true,
812 )
813 .unwrap();
814 assert!(answer.len() >= 29 && answer.len() <= 31);
815 let answer = sequence_matcher(
818 &mut vec![100, 200, 300, 400, 500, 600, -700, 800, 900, 1000],
819 &mut vec![300, 700, 500, 600, -700, 2700],
820 3,
821 2,
822 200,
823 true,
824 true,
825 )
826 .unwrap();
827 assert_eq!(answer.len(), 195);
828 assert_eq!(
829 answer[0].answer_arr,
830 vec![
831 (vec![-700], vec![-700]),
832 (vec![100, 200], vec![300]),
833 (vec![300, 400], vec![700]),
834 (vec![500, 600], vec![500, 600]),
835 (vec![800, 900, 1000], vec![2700]),
836 ]
837 );
838
839 let answer = sequence_matcher(
840 &mut vec![9, 0, 1, 7, 1],
841 &mut vec![7, 2, 8, 0, 1],
842 3,
843 2,
844 100,
845 true,
846 true,
847 )
848 .unwrap();
849 assert_eq!(answer.len(), 24);
850 assert_eq!(
851 answer[0].answer_arr,
852 vec![
853 (vec![0], vec![0]),
854 (vec![1], vec![1]),
855 (vec![7], vec![7]),
856 (vec![1, 9], vec![2, 8]),
857 ]
858 );
859
860 let answer = sequence_matcher(
861 &mut vec![1000, 1100, 150, 123, 5, 10],
862 &mut vec![2100, 273, 4, 11],
863 6,
864 4,
865 200,
866 true,
867 true,
868 )
869 .unwrap();
870 assert_eq!(answer.len(), 5);
871 assert_eq!(
872 answer[0].answer_arr,
873 vec![
874 (vec![5, 10], vec![4, 11]),
875 (vec![123, 150], vec![273]),
876 (vec![1000, 1100], vec![2100]),
877 ]
878 );
879 assert_eq!(
880 answer[2].answer_arr,
881 vec![(vec![5, 10, 123, 150, 1000, 1100], vec![4, 11, 273, 2100]),]
882 );
883
884 let answer = sequence_matcher(
885 &mut vec![1, 2, 3],
886 &mut vec![1000, 1200],
887 10,
888 10,
889 2,
890 true,
891 true,
892 );
893 let expected = Err(format!("The sums of two arrays must be the same values. key's sum is {}. target's sum is {}. The difference is {}.", 6, 2200, -2194));
894 assert_eq!(answer, expected);
895
896 let answer = sequence_matcher(
897 &mut vec![1, 2, 3, 4],
898 &mut vec![1, 5],
899 10,
900 10,
901 2,
902 true,
903 true,
904 );
905 let expected = Err(format!("The sums of two arrays must be the same values. key's sum is {}. target's sum is {}. The difference is {}.", 10, 6, 4));
906
907 assert_eq!(answer, expected);
908
909 let answer = sequence_matcher(
910 &mut vec![183, 36, 231, 128, 137],
911 &mut vec![8, 9, 15, 15, 33, 36, 39, 45, 46, 60, 68, 73, 80, 92, 96],
912 1,
913 15,
914 20,
915 true,
916 true,
917 )
918 .unwrap();
919
920 assert_eq!(answer.len(), 13);
921 assert_eq!(
922 answer[0].answer_arr,
923 vec![
924 (vec![36], vec![36]),
925 (vec![128], vec![9, 39, 80]),
926 (vec![137], vec![8, 33, 96]),
927 (vec![183], vec![45, 46, 92]),
928 (vec![231], vec![15, 15, 60, 68, 73]),
929 ]
930 );
931 }
932 #[test]
933
934 fn test_sequence_matcher_allowing_imcomplete_answer() {
935 let answer = sequence_matcher(
936 &mut vec![1, 2, -3, 4, 5],
937 &mut vec![1, 2],
938 6,
939 4,
940 200,
941 true,
942 false,
943 )
944 .unwrap();
945 assert_eq!(answer.len(), 0);
946
947 let answer = sequence_matcher(
948 &mut vec![1, 2, -3, 4, 5],
949 &mut vec![1, 2],
950 6,
951 4,
952 200,
953 false,
954 true,
955 )
956 .unwrap();
957 assert_eq!(answer.len(), 6);
958 assert_eq!(answer[0].answer_arr, vec![(vec![-3, 1, 5], vec![1, 2]),]);
959 }
960
961 #[test]
962 fn test_sequence_matcher_allowing_imcomplete_answer_complicated() {
963 let answer = sequence_matcher(
964 &mut vec![-755, 222, 851, 291, -511, -567, 958, 939, -28],
965 &mut vec![-590, 785, -597, -184, -968, -555, -221, -28],
966 30,
967 30,
968 200,
969 false,
970 true,
971 )
972 .unwrap();
973 assert_eq!(answer.len(), 0);
974
975 let answer = sequence_matcher(
976 &mut vec![-755, 222, 851, 291, -511, -567, 958, 939, -28],
977 &mut vec![-590, 785, -597, -184, -968, -555, -221, -28],
978 30,
979 30,
980 100,
981 false,
982 false,
983 )
984 .unwrap();
985 assert_eq!(
986 answer[0].answer_arr,
987 vec![(
988 vec![-755, -567, -511, -28, 939],
989 vec![-968, -555, -184, 785]
990 ),]
991 );
992 }
993}
994
995#[cfg(test)]
996mod tests {
997
998 use super::*;
999
1000 #[test]
1001 fn test_find_subset() {
1002 let result = dp::find_subset(vec![1, 2, 3], 3, 2);
1003 let route1: Vec<i32> = vec![3];
1004 let route2: Vec<i32> = vec![1, 2];
1005 let answer: Vec<Vec<i32>> = vec![route1, route2];
1006 assert_eq!(result, answer);
1007
1008 let result = dp::find_subset(vec![0, 3, 5, 10], 3, 2);
1009 let route1: Vec<i32> = vec![3];
1010 let route2: Vec<i32> = vec![0, 3];
1011 let answer: Vec<Vec<i32>> = vec![route1, route2];
1012 assert_eq!(result, answer);
1013
1014 let result = dp::find_subset(vec![1, 2, 3, 0], 3, 3);
1015 let route1: Vec<i32> = vec![3];
1016 let route2: Vec<i32> = vec![0, 3];
1017 let route3: Vec<i32> = vec![1, 2];
1018 let route4: Vec<i32> = vec![0, 1, 2];
1019 let answer: Vec<Vec<i32>> = vec![route1, route2, route3, route4];
1020 assert_eq!(result, answer);
1021
1022 let result = dp::find_subset(vec![1, 2, 3], 3, 2);
1023 let route1: Vec<i32> = vec![3];
1024 let route2: Vec<i32> = vec![1, 2];
1025 let answer: Vec<Vec<i32>> = vec![route1, route2];
1026 assert_eq!(result, answer);
1027
1028 let result = dp::find_subset(vec![1, 2, 3, 4, 5], 10, 4);
1029 let route1: Vec<i32> = vec![2, 3, 5];
1030 let route2: Vec<i32> = vec![1, 4, 5];
1031 let route3: Vec<i32> = vec![1, 2, 3, 4];
1032 let answer: Vec<Vec<i32>> = vec![route1, route2, route3];
1033 assert_eq!(result, answer);
1034
1035 let result = dp::find_subset(vec![1, 2, 3, 4, 5], 10, 3);
1036 let route2: Vec<i32> = vec![2, 3, 5];
1037 let route3: Vec<i32> = vec![1, 4, 5];
1038 let answer: Vec<Vec<i32>> = vec![route2, route3];
1039 assert_eq!(result, answer);
1040
1041 let arr = vec![75, 467, 512, -835, 770, -69, 10];
1042 let result = dp::find_subset(arr, 711, 3);
1043 let route1: Vec<i32> = vec![-69, 10, 770];
1044 let answer: Vec<Vec<i32>> = vec![route1];
1045 assert_eq!(result, answer);
1046
1047 let arr = vec![-3, 10, 56, -33, 65, -9, 8, 72, 63, 35];
1048 let result = dp::find_subset(arr, 7, 4);
1049 let route1: Vec<i32> = vec![-3, 10];
1050 let route2: Vec<i32> = vec![-33, -3, 8, 35];
1051 let answer: Vec<Vec<i32>> = vec![route1, route2];
1052 assert_eq!(result, answer);
1053
1054 let arr = vec![
1055 73209, 95597, 84735, 40496, 83553, 95595, -628, 201, 27597, 7904, 98445, 6241, 33002,
1056 -776, -711, 45552, 86746, 84248, 66278, 37475,
1057 ];
1058 let result = dp::find_subset(arr, 72782, 3);
1059 let route1: Vec<i32> = vec![-628, 201, 73209];
1060 let answer: Vec<Vec<i32>> = vec![route1];
1061 assert_eq!(result, answer);
1062
1063 let arr = vec![-1, 2, 3];
1064 let result = dp::find_subset(arr, -1, 1);
1065 let route1: Vec<i32> = vec![-1];
1066 let answer: Vec<Vec<i32>> = vec![route1];
1067 assert_eq!(result, answer);
1068
1069 let arr = vec![-10, 5, -2];
1070 let result = dp::find_subset(arr, -5, 2);
1071 let route1: Vec<i32> = vec![-10, 5];
1072 let answer: Vec<Vec<i32>> = vec![route1];
1073 assert_eq!(result, answer);
1074
1075 let arr = vec![-3, -5, -7];
1076 let result = dp::find_subset(arr, -15, 3);
1077 let route1: Vec<i32> = vec![-7, -5, -3];
1078 let answer: Vec<Vec<i32>> = vec![route1];
1079 assert_eq!(result, answer);
1080
1081 let arr = vec![-100, 10, 20];
1082 let result = dp::find_subset(arr, -70, 3);
1083 let route1: Vec<i32> = vec![-100, 10, 20];
1084 let answer: Vec<Vec<i32>> = vec![route1];
1085 assert_eq!(result, answer);
1086 }
1087}