patternjavaMinor
Splitting an array in 2 parts such that one part sums to a multiple of 10 and other sums to an odd number
Viewed 0 times
oddsuchnumberarraypartsplittingonethatmultiplesums
Problem
Given an array of ints, is it possible to divide the ints into two
groups, so that the sum of one group is a multiple of 10, and the sum
of the other group is odd. Every int must be in one group or the
other. Write a recursive helper method that takes whatever arguments
you like, and make the initial call to your recursive helper from
splitOdd10(). (No loops needed.)
groups, so that the sum of one group is a multiple of 10, and the sum
of the other group is odd. Every int must be in one group or the
other. Write a recursive helper method that takes whatever arguments
you like, and make the initial call to your recursive helper from
splitOdd10(). (No loops needed.)
splitOdd10({5, 5, 5}) → true
splitOdd10({5, 5, 6}) → false
splitOdd10({5, 5, 6, 1}) → truepublic boolean splitOdd10(int[] nums) {
int total=findSum(0, nums, 0);
if((total%10)%2==0||total==0)
{
return false;
}
return ifGroupExistsThatSumsToValue(0, nums, total%10);
}
public int findSum(int n, int[] nums, int sum)
{
if(nums.length==0)
return 0;
if(n==nums.length-1)
{
return sum+nums[n];
}
return findSum(n+1, nums, sum+nums[n]);
}
public boolean ifGroupExistsThatSumsToValue(int start, int[]nums, int target)
{
if(start==nums.length-1)
{
return target-nums[start]==0;
}
if(target==0)
{
return true;
}
if(ifGroupExistsThatSumsToValue(start+1, nums, target-nums[start]))
return ifGroupExistsThatSumsToValue(start+1, nums, target-nums[start]);
return ifGroupExistsThatSumsToValue(start+1, nums, target+nums[start]);
}Solution
You could simplify
The end part of the
When logic is kind of tricky, like in this problem, it's good to add the examples in the problem statement as proper unit tests:
And then keep adding some more to try to cover all corner cases, for example:
As others have pointed out, your formatting is awful. Please reformat nicely next time,
To be honest, I don't really understand why
I'm wondering if I'm missing something. Both your and my solutions are passing all my unit tests.
findSum. I would also rename the variables and reorder the parameters:private int findSum(int[] nums, int i, int accum) {
if (i == nums.length) {
return accum;
}
return findSum(nums, i + 1, nums[i] + accum);
}The end part of the
ifGroupExistsThatSumsToValue method can also be simplified:public boolean ifGroupExistsThatSumsToValue(int start, int[] nums, int target) {
if (start == nums.length - 1) {
return target - nums[start] == 0;
}
if (target == 0) {
return true;
}
return ifGroupExistsThatSumsToValue(start + 1, nums, target - nums[start])
|| ifGroupExistsThatSumsToValue(start + 1, nums, target + nums[start]);
}When logic is kind of tricky, like in this problem, it's good to add the examples in the problem statement as proper unit tests:
@Test
public void test_5_5_5() {
assertTrue(splitOdd10(new int[]{5, 5, 5}));
}
@Test
public void test_5_5_6() {
assertFalse(splitOdd10(new int[]{5, 5, 6}));
}
@Test
public void test_5_5_6_1() {
assertTrue(splitOdd10(new int[]{5, 5, 6, 1}));
}And then keep adding some more to try to cover all corner cases, for example:
@Test
public void testEmpty() {
assertFalse(splitOdd10(new int[0]));
}
@Test
public void testSingleNum() {
assertTrue(splitOdd10(new int[]{1}));
assertFalse(splitOdd10(new int[]{2}));
assertFalse(splitOdd10(new int[]{10}));
}As others have pointed out, your formatting is awful. Please reformat nicely next time,
Control Shift f in Eclipse does this easily, and any decent IDE has the equivalent.To be honest, I don't really understand why
splitOdd10 and ifGroupExistsThatSumsToValue have to be so complicated. If I simply follow the problem description in a straightforward way and just try to add up the numbers from left to right and check the conditions, I arrive at something that's much shorter and easier to understand:private boolean splitOdd10(int[] nums) {
return splitOdd10(nums, 0, 0, findSum(nums, 0, 0));
}
private boolean splitOdd10(int[] nums, int i, int left, int right) {
return left % 10 == 0 && right % 2 == 1
|| i < nums.length && splitOdd10(nums, i + 1, left + nums[i], right - nums[i]);
}I'm wondering if I'm missing something. Both your and my solutions are passing all my unit tests.
Code Snippets
private int findSum(int[] nums, int i, int accum) {
if (i == nums.length) {
return accum;
}
return findSum(nums, i + 1, nums[i] + accum);
}public boolean ifGroupExistsThatSumsToValue(int start, int[] nums, int target) {
if (start == nums.length - 1) {
return target - nums[start] == 0;
}
if (target == 0) {
return true;
}
return ifGroupExistsThatSumsToValue(start + 1, nums, target - nums[start])
|| ifGroupExistsThatSumsToValue(start + 1, nums, target + nums[start]);
}@Test
public void test_5_5_5() {
assertTrue(splitOdd10(new int[]{5, 5, 5}));
}
@Test
public void test_5_5_6() {
assertFalse(splitOdd10(new int[]{5, 5, 6}));
}
@Test
public void test_5_5_6_1() {
assertTrue(splitOdd10(new int[]{5, 5, 6, 1}));
}@Test
public void testEmpty() {
assertFalse(splitOdd10(new int[0]));
}
@Test
public void testSingleNum() {
assertTrue(splitOdd10(new int[]{1}));
assertFalse(splitOdd10(new int[]{2}));
assertFalse(splitOdd10(new int[]{10}));
}private boolean splitOdd10(int[] nums) {
return splitOdd10(nums, 0, 0, findSum(nums, 0, 0));
}
private boolean splitOdd10(int[] nums, int i, int left, int right) {
return left % 10 == 0 && right % 2 == 1
|| i < nums.length && splitOdd10(nums, i + 1, left + nums[i], right - nums[i]);
}Context
StackExchange Code Review Q#60982, answer score: 5
Revisions (0)
No revisions yet.