Generate random number within specified range without REDUNDANCY in TCL - random

hi I need to generate 30 random numbers without any repeatations of numbers in TCL.
Here is the code to generate random number which works fine, but will generate redundant numbers.
proc myRand { min max } {
set maxFactor [expr [expr $max + 1] - $min]
set value [expr int([expr rand() * 100])]
set value [expr [expr $value % $maxFactor] + $min]
return $value
}
for {set i 1} {$i < 31} {incr i} {
upvar 0 fnode($i) fnod($i)
set fnod($i) [myRand 1 20] ;# random number is generated between 1 to 20
}
Anyone please help out.

To generate a list of random numbers without repetitions, you've got to put in code to explicitly prevent them. In general, random sequences most certainly can contain repetitions, just as if you toss a coin, it will sometimes come up heads twice (or more) in a row.
set r -1; # Some value that definitely isn't in the sequence
for {set i 1} {$i < 31} {incr i} {
upvar 0 fnode($i) fnod($i)
while {$r == [set r [myRand 1 20]]} {
# Empty body
}
set fnod($i) $r; # Random number is generated between 1 to 20
}
Note that if you're picking 30 values from a collection of 20 numbers, you'll necessarily (by the pigeonhole principle) get some repetitions. But we can prevent values from occurring twice in a row.
Your random number generator is slightly horrifying too. This is the idiomatic version:
proc myRand {min max} {
set range [expr {$max - $min + 1}]
return [expr {$min + int(rand() * $range)}]
}

Code to generate a sequence of unique random numbers could be written like this, but it won't work unless $nnums is less than or equal to $rmax.
set nnums 30
set rmax 20
set nums {}
if {$nnums > $rmax} {
puts "You can't get $nnums unique values from a range of 1 to $rmax!"
} else {
while {[llength $nums] < $nnums} {
set n [myRand 1 $rmax]
if {$n ni $nums} {lappend nums $n}
}
set nums [linsert $nums 0 {}]
for {set i 1} {$i <= $nnums} {incr i} {
set fnod($i) [lindex $nums $i]
}
}
(When I started writing this answer, I was to preoccupied to notice that you were trying to get 30 unique numbers from a 1-20 range, which is impossible, as others have pointed out.)
There are some other problems with your code. You don't need to do nested calls to expr:
expr [expr $max + 1] - $min
# is the same as
expr {$max + 1 - $min}
so your random number generator can be written like this:
proc myRand {min max} {
expr {int(rand() * 100) % ($max + 1 - $min) + $min}
}
but that is still more calculations than necessary. This version is better:
proc myRand {min max} {
expr {int(rand() * ($max + 1 - $min)) + $min}
}
You can also use this:
package require math
::math::random 1 21
(Note 21, not 20!)

Related

last iteration gets skipped and not printed in a for loop

Im trying to build a code that when the user inputs a sequence of numbers it will go through the sequence comparing each numbers and for every new biggest number in the sequence it will sum all the previous ones
func main() {
var numeri []int
numeri = GetInputSlice()
fmt.Println(numeri)
var sum int
num := len(numeri)
for i := 0; i < num - 1 ; i++ {
sum += numeri[i]
if numeri[i] > numeri[i+1] || numeri[i] == num - 1 {
fmt.Println(sum)
sum = 0
}
}
}
full code over here: https://go.dev/play/p/13ljQPmKaRA
if I input this sequence of numbers [1 2 13 0 7 8 9 -1 0 2] I would like to get 16, 24 and 1.
But in my code I only get 16 and 24 without getting the last 1 and I can't figure out a way to fix this.
Only numeri[i] is ever added to sum, and your loop never visits the last item (i < num - 1), so how could the last item be ever added?
Range through the whole slice, perform the addition, but only compare to the next element if you're not at the last one. If we're at the last one, we also want to print, so we may use a single condition
i == max || numeri[i] > numeri[i+1]
Where the comparison to the next element will not be executed if i == max (short circuit evaluation).
For example:
max := len(numeri) - 1
for i, v := range numeri {
sum += v
if i == max || v > numeri[i+1] {
fmt.Println(sum)
sum = 0
}
}
This will output (try it on the Go Playground):
[1 2 13 0 7 8 9 -1 0 2]
16
24
1

Expect Script - For Loop - How to use more than 1 variable

How can I use more than 1 variable in expect script "for loop"? Please help.
Thanks in advance.
With one variable:
for {set i 1} {$i < 256} {incr i 1} {
}
How can 2 or 3 variables, say init , condition, increment of i, j, k ?
comma, semicolon is not working.
Thanks,
Krishna
Keep in mind that expect is an extension of Tcl. Documentation of Tcl is available.
The syntax of for is:
for start test next body
"start" and "next" are both evaluated as scripts. "test" is an expression
You can do:
for {set i 1; set j 10; set k "x"} {$i < 5 && $j > 0} {incr i; incr j -2; append k x} {
puts "$i\t$j\t$k"
}
outputs
1 10 x
2 8 xx
3 6 xxx
4 4 xxxx
This is equivalent to the following, so use whatever is most readable.
set i 1
set j 10
set k "x"
while {$i < 5 && $j > 0} {
puts "$i\t$j\t$k"
incr i
incr j -2
append k x
}
In fact, you can make liberal use of newlines in a for command too
for {
set i 1
set j 10
set k "x"
} {
$i < 5 && $j > 0
} {
incr i
incr j -2
append k x
} {
puts "$i\t$j\t$k"
}

not able to sort list in tcl

I have below code in NS2 which calculates distance between two nodes and put it in a list "nbr". I want to sort out that list in ascending order as per value "d" and again store it in a list for further use for that I used lsort command but it is giving me same list that is unsorted.
please help
code:.
proc distance { n1 n2 nd1 nd2} {
set x1 [expr int([$n1 set X_])]
set y1 [expr int([$n1 set Y_])]
set x2 [expr int([$n2 set X_])]
set y2 [expr int([$n2 set Y_])]
set d [expr int(sqrt(pow(($x2-$x1),2)+pow(($y2-$y1),2)))]
if {$d<300} {
if {$nd2!=$nd1 && $nd2 == 11} {
set nbr "{$nd1 $nd2 $x1 $y1 $d}"
set m [lsort -increasing -index 4 $nbr]
puts $m
}
}
}
for {set i 1} {$i < $val(nn)} {incr i} {
for {set j 1} {$j < $val(nn)} {incr j} {
$ns at 5.5 "distance $node_($i) $node_($j) $i $j"
}
}
output:
{1 11 305 455 273}
{4 11 308 386 208}
{5 11 378 426 274}
{7 11 403 377 249}
{8 11 244 405 215}
{9 11 256 343 154}
{10 11 342 328 172}
{12 11 319 192 81}
{13 11 395 196 157}
{14 11 469 191 231}
{15 11 443 140 211}
{16 11 363 115 145}
{17 11 290 135 75}
{18 11 234 121 69}
{19 11 263 60 132}
{20 11 347 60 169}
Right now, you're calculating each of the distances separately, but aren't actually collecting them all into a list that can be sorted.
Let's fix this by first rewriting distance to just do the distance calculations themselves:
proc distance {n1 n2 nd1 nd2} {
set x1 [expr int([$n1 set X_])]
set y1 [expr int([$n1 set Y_])]
set x2 [expr int([$n2 set X_])]
set y2 [expr int([$n2 set Y_])]
set d [expr int(sqrt(pow(($x2-$x1),2)+pow(($y2-$y1),2)))]
# Why not: set d [expr hypot($x2-$x1,$y2-$y1)]
# I'm keeping *everything* we know at this point
return [list $nd1 $nd2 $n1 $n2 $d $x1 $y1 $x2 $y2]
}
Then, we need another procedure that will process the whole collection (at the time the simulator calls it) and do the sorting. It will call distance to get the individual record, since we've factored that information out.
proc processDistances {count threshold {filter ""}} {
global node_
set distances {}
for {set i 1} {$i < $count} {incr i} {
for {set j 1} {$j < $count} {incr j} {
# Skip self comparisons
if {$i == $j} continue
# Apply target filter
if {$filter ne "" && $j != $filter} continue
# Get the distance information
set thisDistance [distance $node_($i) $node_($j) $i $j]
# Check that the nodes are close enough
if {[lindex $thisDistance 4] < $threshold} {
lappend distances $thisDistance
}
}
}
# Sort the pairs, by distances
set distances [lsort -real -increasing -index 4 $distances]
# Print the sorted list
foreach tuple $distances {
puts "{$tuple}"
}
}
Then we arrange for that whole procedure to be called at the right time:
# We recommend building callbacks using [list], not double quotes
$ns at 5.5 [list processDistances $val(nn) 300 11]

What way is faster to populate a list with unique values in Tcl?

I want to create a list of unique values. The values are taken from different sources and. There are 2 ways to populate my final list.
Put all the values in and then perform lrmdups:
set finalList [list ]
foreach selcetion $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
lappend finalList $i
}
}
set finalList [lrmdups $finalList]
or check if a value exists in the list, and only if it doesn't add it:
set finalList [list ]
foreach selcetion $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
if {[lsearch $finalList $i] == -1} {
lappend finalList $i
}
}
}
Which of the two methods is faster?
Use the time command to test the performance of Tcl code. Ensure you place your code in a procedure to gain the benefit of having it byte-compiled then use the time command to run the test a number of times and get an average time per iteration. For instance, here is an example that shows why expr expressions should always be braced.
% proc a {} {expr 1 + 2 + 3}
% proc b {} {expr {1 + 2 + 3}}
% time a 1000
4.491 microseconds per iteration
% time b 1000
0.563 microseconds per iteration
To deal with the specific task - I would add each new value into an array and let that eat the duplicates and then just turn it into a list at the end.
proc getUniques {wantedSize} {
array set uniques {}
while {[array size uniques] != $wantedSize} {
set uniques([getNewValue]) {}
}
return [array names uniques]
}
I also use the time command to benchmark. Here is my code, which I added two more methods, one to use array and the other uses struct::set to eliminate duplicates.
#!/usr/bin/env tclsh
#http://stackoverflow.com/questions/18337534/what-way-is-faster-to-populate-a-list-with-unique-values-in-tcl
package require Tclx
package require struct::set
proc removeDupMethod {selectionList} {
set finalList [list ]
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
lappend finalList $i
}
}
set finalList [lrmdups $finalList]
return $finalList
}
proc searchBeforInsertMethod {selectionList} {
set finalList [list ]
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
if {[lsearch $finalList $i] == -1} {
lappend finalList $i
}
}
}
}
proc useArrayMethod {selectionList} {
array set tally {}
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
incr tally($i)
}
}
set finalList [array names tally]
return $finalList
}
proc useStructSetMethod {selectionList} {
set finalList {}
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
struct::set include finalList $i
}
}
return $finalList
}
# Performs the benchmark on a method
proc bench {methodName} {
set selectionList {1:10 5:20 10:30 4:30}
set timeInfo [time {$methodName $selectionList} 1000]
puts "$methodName - $timeInfo"
}
# main
bench removeDupMethod
bench searchBeforInsertMethod
bench useArrayMethod
bench useStructSetMethod
The result:
removeDupMethod - 281.961364 microseconds per iteration
searchBeforInsertMethod - 93.984991 microseconds per iteration
useArrayMethod - 122.354889 microseconds per iteration
useStructSetMethod - 576.293311 microseconds per iteration
Discussion
Your second method, searchBeforInsertMethod, is the fastest.
useArrayMethod, which uses an array to ensure uniqueness, comes in second. This is to say that the TCL's built-in list commands are very optimized.
To my surprise, the useStructSetMethod is the slowest. I thought a library command should be optimized, but I was wrong.
Update
I took Siyb's hint and replace:
regexp {(\d+):(\d+)} $selection -> start end
with:
set range [split $selection :]
set start [lindex $selection 0]
set end [lindex $selection 1]
And see a dramatic increase in speed:
removeDupMethod - 9.337442 microseconds per iteration
searchBeforInsertMethod - 5.528975999999999 microseconds per iteration
useArrayMethod - 6.8120519999999996 microseconds per iteration
useStructSetMethod - 5.774831 microseconds per iteration
useNative - 6.105141 microseconds per iteration
Notes
The fastest is still searchBeforInsertMethod, the speed increase is nearly 17 times.
useStructSetMethod now rises to take second place
Update 2
Per potrzebie's request, I added 5000:6000 to the beginning and the numbers do not change much:
removeDupMethod - 10.826106 microseconds per iteration
searchBeforInsertMethod - 6.296769 microseconds per iteration
useArrayMethod - 7.752042 microseconds per iteration
useStructSetMethod - 6.910305999999999 microseconds per iteration
useNative - 7.274724 microseconds per iteration
I have tried using lsort -unique $list instead of lrmdups. On my box, this is the fastest method:
proc useNative {selectionList} {
foreach selection $selectionList {
regexp {(\d+):(\d+)} $selection -> start end
for {set i $start} {$i <= $end} {incr i} {
lappend finalList $i
}
}
set finalList [lsort -unique $finalList]
return $finalList
}
removeDupMethod - 171.573 microseconds per iteration
searchBeforInsertMethod - 58.264 microseconds per iteration
useArrayMethod - 96.109 microseconds per iteration
useStructSetMethod - 386.889 microseconds per iteration
useNative - 41.556 microseconds per iteration
EDIT: using split instead of the regular expression speeds up things as well (if the regex is actually part of your problem):
useNative - 20.938 microseconds per iteration
EDIT2: try adding -integer as a lsort parameter, should speed up things a little as well, if your are planning on sorting integers that is

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