1use crate::Solution;
2
3impl Solution {
4 pub fn can_partition_naive(nums: Vec<i32>) -> bool {
6 let mut sum: i32 = nums.iter().sum();
7 let mut result: Vec<(i32, i32)> = Vec::new();
8 nums.iter().for_each(|&x| match result.len() {
9 0 => {
10 sum -= x;
11 result.push((x, 0))
12 }
13 _ => {
14 let right_result = result
15 .iter()
16 .map(|&(left, right)| (left, right + x))
17 .collect::<Vec<(i32, i32)>>();
18 let left_result = result
19 .iter()
20 .map(|&(left, right)| (left + x, right))
21 .collect::<Vec<(i32, i32)>>();
22 result.clear();
23 result.extend(left_result);
24 result.extend(right_result);
25 }
26 });
27 result
28 .iter()
29 .filter(|&&(left, right)| left == right)
30 .collect::<Vec<_>>()
31 .len()
32 != 0
33 }
34
35 pub fn can_partition_whats_left(nums: Vec<i32>) -> bool {
38 let mut sum: i32 = nums.iter().sum();
39 let mut result: Vec<(i32, i32)> = Vec::new();
40 nums.iter().for_each(|&x| match result.len() {
41 0 => {
42 sum -= x;
43 result.push((x, 0))
44 }
45 _ => {
46 let new_result = result
47 .iter()
48 .filter(|&&(left, right)| match left.cmp(&right) {
49 std::cmp::Ordering::Greater => left - right <= sum,
50 _ => right - left <= sum,
51 })
52 .map(|&(left, right)| vec![(left + x, right), (left, right + x)])
53 .flatten()
54 .collect::<Vec<(i32, i32)>>();
55 result = new_result;
56 sum -= x;
57 }
58 });
59 result
60 .iter()
61 .filter(|&&(left, right)| left == right)
62 .collect::<Vec<_>>()
63 .len()
64 != 0
65 }
66
67 pub fn can_partition_sort_and_try(mut nums: Vec<i32>) -> bool {
69 nums.sort_by(|x, y| y.cmp(x));
70 nums.iter().fold(0, |acc, &x| match acc > 0 {
71 true => acc - x,
72 false => acc + x,
73 }) == 0
74 }
75
76 pub fn can_partition_odd_even_counter(nums: Vec<i32>) -> bool {
78 let sum: i32 = nums.iter().sum();
80 let sanitize = nums.iter().fold(true, |acc, &x| acc && (sum - x) >= x);
81 if !sanitize {
82 return false;
83 }
84 let (mut twos, mut ones) = (0, 0);
86 nums.iter().for_each(|&x| match x % 2 == 0 {
87 true => {
88 twos += x / 2;
89 }
90 false => {
91 ones += 1;
92 twos += (x - 1) / 2;
93 }
94 });
95 if twos % 2 != 0 && ones >= 2 {
96 twos -= 1;
97 ones -= 2;
98 }
99 twos % 2 == 0 && ones % 2 == 0
100 }
101
102 pub fn can_partition_dp_top_down(
103 nums: &Vec<i32>,
104 start_from: usize,
105 whats_left: i32,
106 goal_amount: i32,
107 ) -> bool {
108 if start_from >= nums.len() {
110 return false;
111
112 } else if goal_amount > whats_left {
115 return false;
116
117 } else if goal_amount == whats_left {
120 return true;
121 } else {
122 let next_start_from = start_from + 1;
127 let current_value = nums[start_from];
128 let next_whats_left = whats_left - current_value;
129 match goal_amount.cmp(¤t_value) {
130 std::cmp::Ordering::Greater => {
131 return Solution::can_partition_dp_top_down(
132 &nums,
133 next_start_from,
134 next_whats_left,
135 goal_amount - current_value,
136 ) || Solution::can_partition_dp_top_down(
137 &nums,
138 next_start_from,
139 next_whats_left,
140 goal_amount,
141 );
142 }
143 std::cmp::Ordering::Equal => {
144 return true;
145 }
146 std::cmp::Ordering::Less => {
147 return Solution::can_partition_dp_top_down(
148 &nums,
149 next_start_from,
150 next_whats_left,
151 goal_amount,
152 );
153 }
154 }
155 }
156 }
157
158 pub fn can_partition(mut nums: Vec<i32>) -> bool {
159 let sum: i32 = nums.iter().sum();
160 if sum % 2 != 0 {
161 false
162 } else {
163 nums.sort_by(|x, y| y.cmp(x));
164 Solution::can_partition_dp_top_down(&nums, 0, sum, sum / 2)
165 }
166 }
167}
168
169#[test]
170fn problem_416_test() {
171 assert_eq!(Solution::can_partition(vec![1, 5, 11, 5]), true);
172 assert_eq!(Solution::can_partition(vec![5, 3, 4, 4]), true);
173 assert_eq!(Solution::can_partition(vec![3, 3, 1, 94]), false);
174 assert_eq!(Solution::can_partition(vec![5, 3, 1, 4]), false);
175 assert_eq!(Solution::can_partition(vec![3, 3, 3, 4, 5]), true);
176 assert_eq!(Solution::can_partition(vec![1, 2, 5]), false);
177 assert_eq!(
178 Solution::can_partition(vec![
179 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
180 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
181 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
182 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
183 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
184 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100
185 ]),
186 true
187 );
188 assert_eq!(Solution::can_partition(vec![2, 2, 3, 5]), false);
189 assert_eq!(
190 Solution::can_partition(vec![
191 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
192 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
193 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
194 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 100
195 ]),
196 false
197 );
198}
199
200#[test]
201pub fn problem_416_failing() {}