LinuxQuestions.org
Support LQ: Use code LQCO20 and save 20% on CrossOver Office
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 05-16-2009, 03:08 AM   #1
genderbender
Member
 
Registered: Jan 2005
Location: US
Distribution: Centos, Ubuntu, Solaris, Redhat
Posts: 377

Rep: Reputation: 31
Add together everything in an array


Hi, I have an array of eight, single digit numbers, whats the easiest way (ideally without expr) to add all the numbers together?

I also need to figure out a way of generating a number which will round the total up to the nearest 10. So basically if the total of all the numbers in my array is 8 I need to get a 2 from somewhere and add it to the complete list of numbers, so the final list will be 11111112. I can think of complicated slow ways to do this (setup numbers 10-80 as variables and then work out what the smallest positive difference between the total and the variable), however this just seems crap and innefficient. I can probably work this out myself, just haven't got started yet and could do with some pointers.

Thanks for your help
 
Old 05-16-2009, 03:59 AM   #2
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,695
Blog Entries: 5

Rep: Reputation: 237Reputation: 237Reputation: 237
how are you getting those arrays? hardcoded into the script? or parsed from somewhere.. number of tools such as awk, bc can be used to sum them up. Even bash itself can be used by going over the arrays and doing the addition. As for the second part, don't understand what you are saying. better to give more clearer example.
 
Old 05-16-2009, 08:41 AM   #3
bgeddy
Senior Member
 
Registered: Sep 2006
Location: Liverpool - England
Distribution: slackware64 13.37 and -current, Dragonfly BSD
Posts: 1,810

Rep: Reputation: 223Reputation: 223Reputation: 223
Quote:
I also need to figure out a way of generating a number which will round the total up to the nearest 10. So basically if the total of all the numbers in my array is 8 I need to get a 2 from somewhere and add it to the complete list of numbers, so the final list will be 11111112. I can think of complicated slow ways to do this (setup numbers 10-80 as variables and then work out what the smallest positive difference between the total and the variable), however this just seems crap and innefficient. I can probably work this out myself, just haven't got started yet and could do with some pointers.
Here's an idea for using bc to round up to the nearest 10. I set TOT to some test amounts to demonstrate and get the result in RES:
Code:
#!/bin/bash
#
TOT=33
RES=$(echo "if ($TOT % 10) (($TOT / 10)+1)  * 10 else ($TOT /10 ) * 10
" | bc)
echo "Tried $TOT result was $RES"
TOT=102
RES=$(echo "if ($TOT % 10) (($TOT / 10)+1)  * 10 else ($TOT /10 ) * 10
" | bc)
echo "Tried $TOT result was $RES"
RES=$(echo "if ($TOT % 10) (($TOT / 10)+1)  * 10 else ($TOT /10 ) * 10
" | bc)
TOT=70
RES=$(echo "if ($TOT % 10) (($TOT / 10)+1)  * 10 else ($TOT /10 ) * 10
" | bc)
echo "Tried $TOT result was $RES"
Save it to a file and make executable to test. Just look at the "bc" bit to get an idea what's going on.
 
Old 05-16-2009, 11:10 AM   #4
genderbender
Member
 
Registered: Jan 2005
Location: US
Distribution: Centos, Ubuntu, Solaris, Redhat
Posts: 377

Original Poster
Rep: Reputation: 31
The numbers are randomly generated, they go through a bit of a complex formular and then get changed into other numbers. Theres no predicting what the numbers will be, except they'll be less than 10 and there will be 8 of them.

bgeddy, thanks for your help with the last bit, it's a good starting point for me .

P.S did not know awk had arithmatic functions!

The last part is basically the difference between the total and the nearest 10 (rounded up). I'll try to explain the maths a bit better:

random numbers: 5, 1, 6, 3, 2, 8, 9, 1
total = 35
rounded total = 5 (rounded up to 40)

final number = 5, 1, 6, 3, 2, 8, 9, 1, (5 my final number)

Last edited by genderbender; 05-16-2009 at 11:25 AM.
 
Old 05-16-2009, 12:13 PM   #5
genderbender
Member
 
Registered: Jan 2005
Location: US
Distribution: Centos, Ubuntu, Solaris, Redhat
Posts: 377

Original Poster
Rep: Reputation: 31
Just thought of a clever way of doing the second bit!!

If the numbers greater than 10, e.g 18, take off the second digit (the 8), add 1 to the first and put a 0 on the end. Psuedo code coming up, looks tricky...
Code:
 if totals bigger than 10 (e.g 18)
 take off the second digit to leave the first digit (the 1)
 add 1 to that number = 2
 stick a zero on the end of that = 20
 calculate total (18) - the number weve just got(20).
 
 if the totals smaller than 10 (e.g 8)
 do 10 - the total (10 - 8)
 
Old 05-16-2009, 01:04 PM   #6
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,123

Rep: Reputation: 407Reputation: 407Reputation: 407Reputation: 407Reputation: 407
Why 'bash' + 'bc' + 'awk' + what else instead of Perl/Python/Ruby - of the latter just one language is needed.
 
Old 05-16-2009, 01:53 PM   #7
genderbender
Member
 
Registered: Jan 2005
Location: US
Distribution: Centos, Ubuntu, Solaris, Redhat
Posts: 377

Original Poster
Rep: Reputation: 31
Because I don't know perl, python or ruby and the 70+ lines I've wrote so far are in bash, I can't see this being massively more simpler in any other programming language anyway.
 
Old 05-16-2009, 02:26 PM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,123

Rep: Reputation: 407Reputation: 407Reputation: 407Reputation: 407Reputation: 407
Quote:
Originally Posted by genderbender View Post
Because I don't know perl, python or ruby and the 70+ lines I've wrote so far are in bash, I can't see this being massively more simpler in any other programming language anyway.
I do not quite understand the algorithm you ant to implement, but here is random numbers generation and summation:



Code:
sergei@amdam2:~/junk> cat -n gen_and_add_random_number.pl
     1  #!/usr/bin/perl -w
     2
     3  use strict;
     4
     5  my $number_of_random_numbers = 15;
     6  my $max_random_number = 10;
     7
     8  my @random_numbers = map{int(rand($max_random_number + 1))} (1 .. $number_of_random_numbers); # this is random numbers generation
     9
    10  my $sum_of_random_numbers = 0;
    11  map {$sum_of_random_numbers += $_;} @random_numbers; # actual summation
    12
    13  warn "\@random_numbers=@random_numbers";
    14  warn "\$sum_of_random_numbers=$sum_of_random_numbers";
    15
sergei@amdam2:~/junk> ./gen_and_add_random_number.pl
@random_numbers=2 2 1 1 9 6 2 8 5 3 0 2 7 1 0 at ./gen_and_add_random_number.pl line 13.
$sum_of_random_numbers=49 at ./gen_and_add_random_number.pl line 14.
 
Old 05-16-2009, 04:19 PM   #9
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 1,421

Rep: Reputation: 360Reputation: 360Reputation: 360Reputation: 360
Quote:
Originally Posted by genderbender View Post
Just thought of a clever way of doing the second bit!!

If the numbers greater than 10, e.g 18, take off the second digit (the 8), add 1 to the first and put a 0 on the end. Psuedo code coming up, looks tricky...
Code:
 if totals bigger than 10 (e.g 18)
 take off the second digit to leave the first digit (the 1)
 add 1 to that number = 2
 stick a zero on the end of that = 20
 calculate total (18) - the number weve just got(20).
 
 if the totals smaller than 10 (e.g 8)
 do 10 - the total (10 - 8)
Your if condition is wrong, this algorithm would round 30 up to 40. How about
Code:
Take only the first digit (e.g. 18 mod 10 = 8)
if it's not 0 then
  (10 - digit) is the number you want (10 - 8 = 2)
else
  You don't need another number
 
Old 05-16-2009, 05:00 PM   #10
genderbender
Member
 
Registered: Jan 2005
Location: US
Distribution: Centos, Ubuntu, Solaris, Redhat
Posts: 377

Original Poster
Rep: Reputation: 31
I realised that about 8 minutes after I started typing, got the total working (ending up using expr) and this is the beginning of my if statement:
Code:
if [ "$total" -lt "10" ];
 then let "chkbit = 10"
elif [ "$total" == "10" || "$total" == "20" || $total" == "30" || "$total" == "40" || "$total" == "50" || $total" == "60" || "$total" == "70" ];
 then let "chkbit = 0"
else
 #this is jut in for testing purposes.
 let "chkbit = 500"
fi
It's not working right not, probably some syntax error. I'll explain the algorithm as best I can:
Quote:
1. take a random 13 digit number
2. double every other digit (1, 3, 5 etc)
3. if the doubled total is more than 10, take 9 from the number, otherwise leave it alone.
4. Add all the doubled digits together
5. Add a 14th digit which will make the total perfectly divisible by 10

1. 4 5 4 6 8 3 2 8 1 9 0 2 3
2. 8 8 16 4 2 0 6
3. 7
4. 8 + 8 + 7 + 4 + 2 + 0 + 6 = 35
5a. 35 rounded up to nearest 10 = 40, then difference between 40 and 35
5b. 4 5 4 6 8 3 2 8 1 9 0 2 3 5 <--final number
I've almost finished it though, the name of the algorithm is Luhn, I don't plan to 'use it' and it was more of an experiment with how efficient bash was and how easy this would be. In retrospect something like perl would be easier and I'm sure there are LOTS of other scripts to do the same thing.

Last edited by genderbender; 05-16-2009 at 07:18 PM.
 
Old 05-16-2009, 07:05 PM   #11
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,695
Blog Entries: 5

Rep: Reputation: 237Reputation: 237Reputation: 237
Quote:
Originally Posted by genderbender View Post
In retrospect something like perl would be easier and I'm sure there are LOTS of other scripts to do the same thing.
and Python
Code:
import random
numrand = 15
maxrand = 10
rand = [ random.randint(1,maxrand) for i in range(1,numrand)]
summation = sum(rand)
print "random numbers: ", rand
print "sum of them: ",summation
output:
Code:
# ./test.py
random numbers:  [7, 2, 9, 6, 3, 2, 4, 10, 1, 8, 9, 8, 1, 1]
sum of them:  71
#
 
Old 06-08-2009, 07:32 AM   #12
genderbender
Member
 
Registered: Jan 2005
Location: US
Distribution: Centos, Ubuntu, Solaris, Redhat
Posts: 377

Original Poster
Rep: Reputation: 31
Heres the finished script, it's a little messy as the variables have inconsistant names and such, but it seems to function at a basic level, algorithm can be tested at the following site http://www.ee.unb.ca/cgi-bin/tervo/luhn.pl
If anyone wants to make this more interesting or use parts of it feel free. Just so people are aware, I got the algorithm wrong originally and didn't include the other digits in the total.

Code:
#code below was nicked and heavily modified from a dice random number generator
#
PIPS=10         #generate numbers from 0 - 9
MAXTHROWS=13 #This is the number of single digit numbers
throw=0         # Throw count.

#generate 13 one digit numbers...
number2=`while [ "$throw" -lt "$MAXTHROWS" ]
do
  let "die1 = RANDOM % $PIPS"
  echo $die1
  let "throw += 1"
done`
#
#thats all the stolen code...

#select only the even digits (2, 4, 6 etc)
array2=($number2)
for (( i = 0 ; i < ${#array2[@]} ; i++ ))
do
  let "i += 1"
  addevens=`echo ${array2[$i]}`
  ADDEVE=( "${ADDEVE[@]}" "$addevens" )
done

array=($number2)
for (( i = -1 ; i < ${#array[@]} ; i++ ))
do
  do let "i += 1"
  #echo out the other digits, if the numbers are greater than 10 double them and then subtract 9
  NUMB=`echo ${array[$i]}`
  let MULT=`expr $NUMB*2`
    if [ "$MULT" -gt "9" ];
      then let "MULT -= 9"
    fi
  #write numbers into an array
  addodds=`echo $MULT`
  ADDAR=( "${ADDAR[@]}" "$addodds" )
done

let totaleve=`expr ${ADDEVE[0]}+${ADDEVE[1]}+${ADDEVE[2]}+${ADDEVE[3]}+${ADDEVE[4]}+${ADDEVE[5]}`

#add all the numbers contained in the array together
let totalodd=`expr ${ADDAR[0]}+${ADDAR[1]}+${ADDAR[2]}+${ADDAR[3]}+${ADDAR[4]}+${ADDAR[5]}+${ADDAR[6]}`
let total=`expr $totalodd+$totaleve`

#the following was just for testing purposes, it was done in the early stages so arrays may be invalid now.
#
#echo the odd total is $totalodd
#echo the even total is $totaleve
#echo the grand total is $total
#echo "list of odd (doubled) elements : ${ADDAR[@]}"
#echo "list of even array elements    : ${ADDEVE[@]}"
#echo "total of all elements in the array: $total"

#if the total is 10 the checkbit will be zero as the totals already divisible by 10

if [ "$total" -lt "10" ];then
  let "chkbit = 10"
  let LAST=`expr $chkbit - $total`

#if the totals already a possible multiple of 10 the checkbit will be zero
elif [[ "$total" -eq "10" || "$total" -eq "20" || "$total" -eq "30" || "$total" -eq "40" || "$total" -eq "50"  || "$total" -eq "60"  || "$total" -eq "70"|| "$
total" -eq "80" || "$total" -eq "90" || "$total" -eq "100" || "$total" -eq "110"  || "$total" -eq "120"  || "$total" -eq "130"  ]]; then
  let "chkbit = 0"
  let LAST=$chkbit
#if the total is a number not divisible by 10 take the first digit of the total, add one to it and then multiply it by 10 and assign it a variable called chkbit, subtract the total from the checkbit to give a grand total divisible by 10.
else
  totalup=`echo $total | cut -c1`
  let chkbit=`expr $totalup+1`
  let chkbit=`expr $chkbit*10`
  let LAST=`expr $chkbit - $total`
fi
echo -n $number2 $LAST
echo

exit 0

Last edited by genderbender; 06-08-2009 at 07:41 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can I add a raid0 array to an existing install leaving the OS on the original drive? jvn Linux - Hardware 4 03-26-2009 05:05 AM
Bash Variable Array, Trying to add another value into the array helptonewbie Linux - Newbie 6 03-02-2009 11:18 PM
How can I add new device(disk or partition) into a raid0 array xqkp77 Linux - Hardware 0 06-18-2007 01:37 AM
add a new disk to raid1 array retrev Linux - General 1 04-08-2007 01:57 AM
Add drives to existing array Adaptec 2400A kentc Linux - Hardware 1 01-23-2007 10:54 AM


All times are GMT -5. The time now is 02:50 PM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration