How can I improve my Countdown Numbers Solver algorithm to find more solutions? - algorithm

As my school Project, I need to build a solver for Countdown Numbers & Letters rounds. I wanted to develop a structure which I can use to build both solvers, and I first developed a Numbers solver. However, before using this solution for Letters, I need to improve my current algorithm. I think I'm wrong somewhere, because I don't get the same results with other tools I am using to compare my program. Here is program for my solver;
/// numbers_game_solver.dart
import 'dart:collection';
import 'package:trotter/trotter.dart';
/* Import statements was package-based, I turned them into relative paths for question. */
import 'number_generator.dart';
import 'operation.dart';
import 'solution.dart';
import 'solutions.dart';
/* Will try to combine numbers with operations, as shown below;
* List<List<Operation>> operations = <Operations>[a, ,b, ,c, ,d, ,e, ,f
* + - + * / ]
* Then if last operations result is equal to target, will result it.
* If not will show closest result.
*/
const List<String> kOperators = const <String>[kOpAdd, kOpDiv, kOpMul, kOpSub];
class NumbersGameSolver {
NumbersGameSolver()
: this.solutions = Solutions(_expectedResult);
/* TODO: Do tests with smaller numbers and targets. */
final List<int> _numbers = const <int>[1, 2, 3, 4]; // NumberGenerator.numbers;
static final int _expectedResult = 15; //NumberGenerator.expectedResult;
final Solutions solutions;
void solve() {
/* All permutations of operators with replacement, which will be inserted between numbers. */
final Set<List<String>> amalgamsOperators = Amalgams<String>(_numbers.length - 1, kOperators)().toSet();
/* There may duplicates occur in numbers list, because of this, numbers will be mapped
using permutations of indices. */
final List<int> indices = List<int>.generate(_numbers.length, (int index) => index);
final Iterable<List<int>> permutationsIndices = Permutations<int>(indices.length, indices)();
final Set<List<int>>
permutationsNumbers = permutationsIndices.map(
(List<int> listPerm) => listPerm.map(
(int index) => _numbers[index]
).toList()
).toSet();
for (final List<int> numbers in permutationsNumbers) {
for (final List<String> operators in amalgamsOperators) {
Queue<int> stackNums = Queue<int>.from(numbers);
Queue<String> stackOprts = Queue<String>.from(operators);
Solution tempSolution = Solution(_expectedResult);
do {
int left = stackNums.removeFirst(), right = stackNums.removeFirst();
Operation tempOperation = Operation(stackOprts.removeFirst(), left, right);
/* Record solutions current state. */
SolutionState solutionState = tempSolution.addOperation(tempOperation);
if (solutionState == SolutionState.currentlyValid) {
/* If valid, add result to the current numbers stack. */
stackNums.addFirst(tempOperation.result);
} else if (solutionState == SolutionState.lastOperationRedundant) {
/* If operation is redundant, dispose it and continue. */
continue;
} else if (solutionState == SolutionState.lastResultInvalid) {
/* If results is invalid at any stage, dispose whole solution. */
break;
}
if (solutions.addSolution(tempSolution) == true) break;
} while (stackNums.length > 1);
}
}
/* Will show only accurate solutions.
* If there is no accurate solutions, will show solutions which results
* are closest to the expected result.
*/
solutions.showSolutions();
}
}
There are 5 classes, to shorten the question I added them in this Gist.
My algorithm is as follows;
Rules for this Project are; program must randomly generate 5 single digit number and 1 two digit number where twoDigitNumber % 10 == 0 and a three digit number as target.
I get permutations of 4 operators and numbers that will be used in operations (Using trotter package.)
For each permutation of numbers, I apply each permutation of operators; using Operation class and add them into a Solution instance for each permutation.
I pass some redundant operations in each iteration, and if there is an invalid result at any stage, I dispose that solution and continue. (I'm taking this DataGenetics blog about this topic as a reference.)
To test my algorithm I used numbers 1, 2, 3, 4 and set target as 15. The results from dcode.fr Solver are as is;
15 (2 op.)
4 + 1 = 5
5 x 3 = 15
15 (3 op.)
4 + 3 = 7
7 x 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
12 + 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
2 + 1 = 3
12 + 3 = 15
15 (3 op.)
3 + 2 = 5
4 - 1 = 3
5 x 3 = 15
15 (3 op.)
4 x 3 = 12
12 + 1 = 13
13 + 2 = 15
15 (3 op.)
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
15 (3 op.)
4 + 2 = 6
6 - 1 = 5
5 x 3 = 15
15 (3 op.)
2 + 1 = 3
4 x 3 = 12
12 + 3 = 15
15 (3 op.)
2 - 1 = 1
4 + 1 = 5
5 x 3 = 15
(A total of 10 solutions.)
and the solutions my program found are as is;
> SOLUTION 1 ~
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
> SOLUTION 2 ~
4 + 1 = 5
5 x 3 = 15
(A total of 2 solutions.)
Can you tell me what am I thinking wrongly; Why can't I find all solutions? What are alternative approaches I can take to solve this problem? Is there anything I'm missing?
TY for taking time.

Related

Gold Mine Problem - Sequence of for loops

Gold mine problem. Following sequence for loop is giving correct result.
//see link for other code
static int getMaxGold(int gold[][], int m, int n) {
//see link for other code
for (int col = n-1; col >= 0; col--) {
for (int row = 0; row < m; row++) {
int right = (col == n-1) ? 0 : goldTable[row][col+1];
int right_up = (row == 0 || col == n-1) ? 0 : goldTable[row-1][col+1];
int right_down = (row == m-1 || col == n-1) ? 0 : goldTable[row+1][col+1];
goldTable[row][col] = gold[row][col] + Math.max(right, Math.max(right_up, right_down));
}
}
}
//see link for other code
While other way round does not give the expected result. For example
for (int col = 0; col < n; col ++) {
for (int row = 0; row < m; row++) {
//same code to calculate right, rightUp and rightDown
}
}
Any explanation for this behaviour?
You don't need to store a whole matrix.
When you build the table, you just need to keep the last layer you processed.
In your recursion, there is diagonally right, or right, so the layer is a column because to compute the value of some cell, you need to know three values (on its right)
You conclude (as spotted by Damien already) that you start from the rightmost column, then to compute the value of every cells of the n-1 column, you only need to know the nth column (which you luckily computed already)
In below example. m_ij refers to i-th line, j-th column. (e.g m_01 == 2, m_10 = 5)
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 3
The last column is {4,8,3,3}
To compute the max value for m_02 you need to choose between 4 and 8
3 - 4
\
8
m_02 = 3 + 8 = 11
To compute the max value of m_12 you need to choose between 4, 8 and 3
4
/
7 - 8
\
3
m_12 = 7 + 8 = 15
Skipping stuff
m_22 = 2 + 8 = 10
m_32 = 6 + 3 = 9
Now you know the max value for each square of the third column
1 2 11 .
5 6 15 .
9 1 10 .
4 5 9 .
You do the same for m_10, m_11, ...
idem
m_01 = 2 + max(11, 15) = 17
m_11 = 6 + 15
m_21 = 1 + 15
m_31 = 5 + 10
Left to process is thus
1 17
5 21
9 16
4 15
Then
1+21
5+21
9+21
4+16
And finally score = max(22, 26, 30, 20)
As you have noticed you only need to keep track of the last processed column. Not a whole table of computation. And the last processed column must start from the right and always be the rightmost one...
I don't think an implem is relevant to help you understand but in case
const s = `
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 3`
const m = s.trim().split('\n').map(x => x.trim().split(' ').map(y => parseInt(y)))
let layer = [0, 0, 0, 0]
for (let j = 3; j >= 0; --j) {
const nextLayer = []
for (let i = 0; i < 4; ++i) {
nextLayer[i] = m[i][j] + Math.max(
layer[i-1] || 0, // we default undefined value as 0 supposing s only holds positive coefficient
layer[i],
layer[i+1] || 0
)
}
layer = nextLayer
}
console.log(Math.max(...layer))

How do we Construct LCP-LR array from LCP array?

To find the number of occurrences of a given string P ( length m ) in a text T ( length N )
We must use binary search against the suffix array of T.
The issue with using standard binary search ( without the LCP information ) is that in each of the O(log N) comparisons you need to make, you compare P to the current entry of the suffix array, which means a full string comparison of up to m characters. So the complexity is O(m*log N).
The LCP-LR array helps improve this to O(m+log N).
know more
How we precompute LCP-LR array from LCP array?
And How does LCP-LR help in finding the number of occurrences of a pattern?
Please Explain the Algorithm with Example
Thank you
// note that arrSize is O(n)
// int arrSize = 2 * 2 ^ (log(N) + 1) + 1; // start from 1
// LCP = new int[N];
// fill the LCP...
// LCP_LR = new int[arrSize];
// memset(LCP_LR, maxValueOfInteger, arrSize);
//
// init: buildLCP_LR(1, 1, N);
// LCP_LR[1] == [1..N]
// LCP_LR[2] == [1..N/2]
// LCP_LR[3] == [N/2+1 .. N]
// rangeI = LCP_LR[i]
// rangeILeft = LCP_LR[2 * i]
// rangeIRight = LCP_LR[2 * i + 1]
// ..etc
void buildLCP_LR(int index, int low, int high)
{
if(low == high)
{
LCP_LR[index] = LCP[low];
return;
}
int mid = (low + high) / 2;
buildLCP_LR(2*index, low, mid);
buildLCP_LR(2*index+1, mid + 1, high);
LCP_LR[index] = min(LCP_LR[2*index], LCP_LR[2*index + 1]);
}
Reference: https://stackoverflow.com/a/28385677/1428052
Not having enough reps to comment so posting. Is anybody able to create the LCP-LR using #Abhijeet Ashok Muneshwar solution. For ex for text- mississippi the Suffix array-
0 1 2 3 4 5 6 7 8 9 10
10 7 1 4 0 9 8 3 6 2 5
The LCP array will be
0 1 2 3 4 5 6 7 8 9 10
1 1 4 0 0 1 0 2 1 3 0
And LCP-LR will be
0 1 2 3 4 5 6 7 8 9 10
1 1 0 4 0 0 0 0 0 1 3
But the LCP-LR obtained using the code is not same as above.
To the method buildLCP_LR i am passing index=0, low=0, high=n

Selecting neighbours on a circle

Consider we have N points on a circle. To each point an index is assigned i = (1,2,...,N). Now, for a randomly selected point, I want to have a vector including the indices of 5 points, [two left neighbors, the point itself, two right neighbors].
See the figure below.
Some sxamples are as follows:
N = 18;
selectedPointIdx = 4;
sequence = [2 3 4 5 6];
selectedPointIdx = 1
sequence = [17 18 1 2 3]
selectedPointIdx = 17
sequence = [15 16 17 18 1];
The conventional way to code this is considering the exceptions as if-else statements, as I did:
if ii == 1
lseq = [N-1 N ii ii+1 ii+2];
elseif ii == 2
lseq = [N ii-1 ii ii+1 ii+2];
elseif ii == N-1
lseq=[ii-2 ii-1 ii N 1];
elseif ii == N
lseq=[ii-2 ii-1 ii 1 2];
else
lseq=[ii-2 ii-1 ii ii+1 ii+2];
end
where ii is selectedPointIdx.
It is not efficient if I consider for instance 7 points instead of 5. What is a more efficient way?
How about this -
off = -2:2
out = mod((off + selectedPointIdx) + 17,18) + 1
For a window size of 7, edit off to -3:3.
It uses the strategy of subtracting 1 + modding + adding back 1 as also discussed here.
Sample run -
>> off = -2:2;
for selectedPointIdx = 1:18
disp(['For selectedPointIdx =',num2str(selectedPointIdx),' :'])
disp(mod((off + selectedPointIdx) + 17,18) + 1)
end
For selectedPointIdx =1 :
17 18 1 2 3
For selectedPointIdx =2 :
18 1 2 3 4
For selectedPointIdx =3 :
1 2 3 4 5
For selectedPointIdx =4 :
2 3 4 5 6
For selectedPointIdx =5 :
3 4 5 6 7
For selectedPointIdx =6 :
4 5 6 7 8
....
For selectedPointIdx =11 :
9 10 11 12 13
For selectedPointIdx =12 :
10 11 12 13 14
For selectedPointIdx =13 :
11 12 13 14 15
For selectedPointIdx =14 :
12 13 14 15 16
For selectedPointIdx =15 :
13 14 15 16 17
For selectedPointIdx =16 :
14 15 16 17 18
For selectedPointIdx =17 :
15 16 17 18 1
For selectedPointIdx =18 :
16 17 18 1 2
You can use modular arithmetic instead: Let p be the point among N points numbered 1 to N. Say you want m neighbors on each side, you can get them as follows:
(p - m - 1) mod N + 1
...
(p - 4) mod N + 1
(p - 3) mod N + 1
(p - 2) mod N + 1
p
(p + 1) mod N + 1
(p + 2) mod N + 1
(p + 3) mod N + 1
...
(p + m - 1) mod N + 1
Code:
N = 18;
p = 2;
m = 3;
for i = p - m : p + m
nb = mod((i - 1) , N) + 1;
disp(nb);
end
Run code here
I would like you to note that you might not necessarily improve performance by avoiding a if statement. A benchmark might be necessary to figure this out. However, this will only be significant if you are treating tens of thousands of numbers.

Formula needed: Sort array to array-"snaked"

After the you guys helped me out so gracefully last time, here is another tricky array sorter for you.
I have the following array:
a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
I use it for some visual stuff and render it like this:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Now I want to sort the array to have a "snake" later:
// rearrange the array according to this schema
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
// the original array should look like this
a = [1,2,3,4,12,13,14,5,11,16,15,6,10,9,8,7]
Now I'm looking for a smart formula / smart loop to do that
ticker = 0;
rows = 4; // can be n
cols = 4; // can be n
originalArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
newArray = [];
while(ticker &#60 originalArray.length)
{
//do the magic here
ticker++;
}
Thanks again for the help.
I was bored, so I made a python version for you with 9 lines of code inside the loop.
ticker = 0
rows = 4
cols = 4
originalArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
newArray = [None] * (rows * cols)
row = 0
col = 0
dir_x = 1
dir_y = 0
taken = {}
while (ticker < len(originalArray)):
newArray[row * cols + col] = originalArray[ticker]
taken[row * cols + col] = True
if col + dir_x >= cols or row + dir_y >= rows or col + dir_x < 0:
dir_x, dir_y = -dir_y, dir_x
elif ((row + dir_y) * cols + col + dir_x) in taken:
dir_x, dir_y = -dir_y, dir_x
row += dir_y
col += dir_x
ticker += 1
print newArray
You can index into the snake coil directly if you recall that
1 + 2 + 3 + ... + n = n*(n+1)/2
m^2 + m - k = 0 => m - (-1+sqrt(1+4*k))/2
and look at the pattern of the coils. (I'll leave it as a hint for the time being--you could also use that n^2 = (n-1)^2 + (2*n+1) with reverse-indexing, or a variety of other things to solve the problem.)
When translating to code, it's not really any shorter than Tuomas' solution if all you want to do is fill the matrix, however.

algorithm to sum up a list of numbers for all combinations

I have a list of numbers and I want to add up all the different combinations.
For example:
number as 1,4,7 and 13
the output would be:
1+4=5
1+7=8
1+13=14
4+7=11
4+13=17
7+13=20
1+4+7=12
1+4+13=18
1+7+13=21
4+7+13=24
1+4+7+13=25
Is there a formula to calculate this with different numbers?
A simple way to do this is to create a bit set with as much bits as there are numbers.
In your example 4.
Then count from 0001 to 1111 and sum each number that has a 1 on the set:
Numbers 1,4,7,13:
0001 = 13=13
0010 = 7=7
0011 = 7+13 = 20
1111 = 1+4+7+13 = 25
Here's how a simple recursive solution would look like, in Java:
public static void main(String[] args)
{
f(new int[] {1,4,7,13}, 0, 0, "{");
}
static void f(int[] numbers, int index, int sum, String output)
{
if (index == numbers.length)
{
System.out.println(output + " } = " + sum);
return;
}
// include numbers[index]
f(numbers, index + 1, sum + numbers[index], output + " " + numbers[index]);
// exclude numbers[index]
f(numbers, index + 1, sum, output);
}
Output:
{ 1 4 7 13 } = 25
{ 1 4 7 } = 12
{ 1 4 13 } = 18
{ 1 4 } = 5
{ 1 7 13 } = 21
{ 1 7 } = 8
{ 1 13 } = 14
{ 1 } = 1
{ 4 7 13 } = 24
{ 4 7 } = 11
{ 4 13 } = 17
{ 4 } = 4
{ 7 13 } = 20
{ 7 } = 7
{ 13 } = 13
{ } = 0
The best-known algorithm requires exponential time. If there were a polynomial-time algorithm, then you would solve the subset sum problem, and thus the P=NP problem.
The algorithm here is to create bitvector of length that is equal to the cardinality of your set of numbers. Fix an enumeration (n_i) of your set of numbers. Then, enumerate over all possible values of the bitvector. For each enumeration (e_i) of the bitvector, compute the sum of e_i * n_i.
The intuition here is that you are representing the subsets of your set of numbers by a bitvector and generating all possible subsets of the set of numbers. When bit e_i is equal to one, n_i is in the subset, otherwise it is not.
The fourth volume of Knuth's TAOCP provides algorithms for generating all possible values of the bitvector.
C#:
I was trying to find something more elegant - but this should do the trick for now...
//Set up our array of integers
int[] items = { 1, 3, 5, 7 };
//Figure out how many bitmasks we need...
//4 bits have a maximum value of 15, so we need 15 masks.
//Calculated as:
// (2 ^ ItemCount) - 1
int len = items.Length;
int calcs = (int)Math.Pow(2, len) - 1;
//Create our array of bitmasks... each item in the array
//represents a unique combination from our items array
string[] masks = Enumerable.Range(1, calcs).Select(i => Convert.ToString(i, 2).PadLeft(len, '0')).ToArray();
//Spit out the corresponding calculation for each bitmask
foreach (string m in masks)
{
//Get the items from our array that correspond to
//the on bits in our mask
int[] incl = items.Where((c, i) => m[i] == '1').ToArray();
//Write out our mask, calculation and resulting sum
Console.WriteLine(
"[{0}] {1}={2}",
m,
String.Join("+", incl.Select(c => c.ToString()).ToArray()),
incl.Sum()
);
}
Outputs as:
[0001] 7=7
[0010] 5=5
[0011] 5+7=12
[0100] 3=3
[0101] 3+7=10
[0110] 3+5=8
[0111] 3+5+7=15
[1000] 1=1
[1001] 1+7=8
[1010] 1+5=6
[1011] 1+5+7=13
[1100] 1+3=4
[1101] 1+3+7=11
[1110] 1+3+5=9
[1111] 1+3+5+7=16
Here is a simple recursive Ruby implementation:
a = [1, 4, 7, 13]
def add(current, ary, idx, sum)
(idx...ary.length).each do |i|
add(current + [ary[i]], ary, i+1, sum + ary[i])
end
puts "#{current.join('+')} = #{sum}" if current.size > 1
end
add([], a, 0, 0)
Which prints
1+4+7+13 = 25
1+4+7 = 12
1+4+13 = 18
1+4 = 5
1+7+13 = 21
1+7 = 8
1+13 = 14
4+7+13 = 24
4+7 = 11
4+13 = 17
7+13 = 20
If you do not need to print the array at each step, the code can be made even simpler and much faster because no additional arrays are created:
def add(ary, idx, sum)
(idx...ary.length).each do |i|
add(ary, i+1, sum + ary[i])
end
puts sum
end
add(a, 0, 0)
I dont think you can have it much simpler than that.
Mathematica solution:
{#, Total##}& /# Subsets[{1, 4, 7, 13}] //MatrixForm
Output:
{} 0
{1} 1
{4} 4
{7} 7
{13} 13
{1,4} 5
{1,7} 8
{1,13} 14
{4,7} 11
{4,13} 17
{7,13} 20
{1,4,7} 12
{1,4,13} 18
{1,7,13} 21
{4,7,13} 24
{1,4,7,13} 25
This Perl program seems to do what you want. It goes through the different ways to choose n items from k items. It's easy to calculate how many combinations there are, but getting the sums of each combination means you have to add them eventually. I had a similar question on Perlmonks when I was asking How can I calculate the right combination of postage stamps?.
The Math::Combinatorics module can also handle many other cases. Even if you don't want to use it, the documentation has a lot of pointers to other information about the problem. Other people might be able to suggest the appropriate library for the language you'd like to you.
#!/usr/bin/perl
use List::Util qw(sum);
use Math::Combinatorics;
my #n = qw(1 4 7 13);
foreach my $count ( 2 .. #n ) {
my $c = Math::Combinatorics->new(
count => $count, # number to choose
data => [#n],
);
print "combinations of $count from: [" . join(" ",#n) . "]\n";
while( my #combo = $c->next_combination ){
print join( ' ', #combo ), " = ", sum( #combo ) , "\n";
}
}
You can enumerate all subsets using a bitvector.
In a for loop, go from 0 to 2 to the Nth power minus 1 (or start with 1 if you don't care about the empty set).
On each iteration, determine which bits are set. The Nth bit represents the Nth element of the set. For each set bit, dereference the appropriate element of the set and add to an accumulated value.
ETA: Because the nature of this problem involves exponential complexity, there's a practical limit to size of the set you can enumerate on. If it turns out you don't need all subsets, you can look up "n choose k" for ways of enumerating subsets of k elements.
PHP: Here's a non-recursive implementation. I'm not saying this is the most efficient way to do it (this is indeed exponential 2^N - see JasonTrue's response and comments), but it works for a small set of elements. I just wanted to write something quick to obtain results. I based the algorithm off Toon's answer.
$set = array(3, 5, 8, 13, 19);
$additions = array();
for($i = 0; $i < pow(2, count($set)); $i++){
$sum = 0;
$addends = array();
for($j = count($set)-1; $j >= 0; $j--) {
if(pow(2, $j) & $i) {
$sum += $set[$j];
$addends[] = $set[$j];
}
}
$additions[] = array($sum, $addends);
}
sort($additions);
foreach($additions as $addition){
printf("%d\t%s\n", $addition[0], implode('+', $addition[1]));
}
Which will output:
0
3 3
5 5
8 8
8 5+3
11 8+3
13 13
13 8+5
16 13+3
16 8+5+3
18 13+5
19 19
21 13+8
21 13+5+3
22 19+3
24 19+5
24 13+8+3
26 13+8+5
27 19+8
27 19+5+3
29 13+8+5+3
30 19+8+3
32 19+13
32 19+8+5
35 19+13+3
35 19+8+5+3
37 19+13+5
40 19+13+8
40 19+13+5+3
43 19+13+8+3
45 19+13+8+5
48 19+13+8+5+3
For example, a case for this could be a set of resistance bands for working out. Say you get 5 bands each having different resistances represented in pounds and you can combine bands to sum up the total resistance. The bands resistances are 3, 5, 8, 13 and 19 pounds. This set gives you 32 (2^5) possible configurations, minus the zero. In this example, the algorithm returns the data sorted by ascending total resistance favoring efficient band configurations first, and for each configuration the bands are sorted by descending resistance.
This is not the code to generate the sums, but it generates the permutations. In your case:
1; 1,4; 1,7; 4,7; 1,4,7; ...
If I have a moment over the weekend, and if it's interesting, I can modify this to come up with the sums.
It's just a fun chunk of LINQ code from Igor Ostrovsky's blog titled "7 tricks to simplify your programs with LINQ" (http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/).
T[] arr = …;
var subsets = from m in Enumerable.Range(0, 1 << arr.Length)
select
from i in Enumerable.Range(0, arr.Length)
where (m & (1 << i)) != 0
select arr[i];
You might be interested in checking out the GNU Scientific Library if you want to avoid maintenance costs. The actual process of summing longer sequences will become very expensive (more-so than generating a single permutation on a step basis), most architectures have SIMD/vector instructions that can provide rather impressive speed-up (I would provide examples of such implementations but I cannot post URLs yet).
Thanks Zach,
I am creating a Bank Reconciliation solution. I dropped your code into jsbin.com to do some quick testing and produced this in Javascript:
function f(numbers,ids, index, sum, output, outputid, find )
{
if (index == numbers.length){
var x ="";
if (find == sum) {
y= output + " } = " + sum + " " + outputid + " }<br/>" ;
}
return;
}
f(numbers,ids, index + 1, sum + numbers[index], output + " " + numbers[index], outputid + " " + ids[index], find);
f(numbers,ids, index + 1, sum, output, outputid,find);
}
var y;
f( [1.2,4,7,13,45,325,23,245,78,432,1,2,6],[1,2,3,4,5,6,7,8,9,10,11,12,13], 0, 0, '{','{', 24.2);
if (document.getElementById('hello')) {
document.getElementById('hello').innerHTML = y;
}
I need it to produce a list of ID's to exclude from the next matching number.
I will post back my final solution using vb.net
v=[1,2,3,4]#variables to sum
i=0
clis=[]#check list for solution excluding the variables itself
def iterate(lis,a,b):
global i
global clis
while len(b)!=0 and i<len(lis):
a=lis[i]
b=lis[i+1:]
if len(b)>1:
t=a+sum(b)
clis.append(t)
for j in b:
clis.append(a+j)
i+=1
iterate(lis,a,b)
iterate(v,0,v)
its written in python. the idea is to break the list in a single integer and a list for eg. [1,2,3,4] into 1,[2,3,4]. we append the total sum now by adding the integer and sum of remaining list.also we take each individual sum i.e 1,2;1,3;1,4. checklist shall now be [1+2+3+4,1+2,1+3,1+4] then we call the new list recursively i.e now int=2,list=[3,4]. checklist will now append [2+3+4,2+3,2+4] accordingly we append the checklist till list is empty.
set is the set of sums and list is the list of the original numbers.
Its Java.
public void subSums() {
Set<Long> resultSet = new HashSet<Long>();
for(long l: list) {
for(long s: set) {
resultSet.add(s);
resultSet.add(l + s);
}
resultSet.add(l);
set.addAll(resultSet);
resultSet.clear();
}
}
public static void main(String[] args) {
// this is an example number
long number = 245L;
int sum = 0;
if (number > 0) {
do {
int last = (int) (number % 10);
sum = (sum + last) % 9;
} while ((number /= 10) > 0);
System.err.println("s = " + (sum==0 ? 9:sum);
} else {
System.err.println("0");
}
}

Resources