PDA

View Full Version : summing the Digits of a Number



zak
05-05-2011, 11:16
in this article (http://blog.wolfram.com/2011/05/03/mathematica-qa-four-ways-to-sum-integer-digit-blocks/) the main issue is to sum the digits of a number, in mathematica IntegerDigits function job is to partition a number to its digits and assign it to a List, and Total finction to sum the List items.
summing number digits used in recreational mathematics, and in the pseudoscience numerology (http://www.thinbasic.com/community/showthread.php?10554-semi-random-walk-(pictorial-numerology)



Uses "console"
Dim num ,sumnum As Ext
num = 718981134123456789
sumnum = SumIntegerDigits(num)
PrintL sumnum
WaitKey

Function SumIntegerDigits(num As Ext)
Dim sumnum As Ext

While num
sumnum = sumnum + Mod(num, 10)
num = Int(num / 10)
Wend

Return sumnum
End Function

danbaron
09-05-2011, 01:15
It's interesting, both the problem, and (as always), Mathematica.

Here is one way to do it in Racket (Scheme (Lisp)).

:idea:


; code -----------------------------------------------------------------------------------------------------------

#lang racket

(define (sum-digits n)
(define ns (number->string n))
(define sl (string->list ns))
(define ci (map (lambda (n) (- (char->integer n) 48))sl))
(define sum 0)
(define (sum-list-of-numbers l)
(cond
((null? l) sum)
(else
(set! sum (+ sum (car l)))
(sum-list-of-numbers (cdr l)))))
(sum-list-of-numbers ci))

(define (time-sum-digits n)
(let ((t1 (current-milliseconds)))
(let ((total (sum-digits n)))
(let ((t2 (current-milliseconds)))
(let ((tt (/ (- t2 t1) 1000.0)))
(values total tt))))))

; REPL interactions ----------------------------------------------------------------------------------------------

> (sum-digits 0)
0
> (sum-digits 1)
1
> (sum-digits 12)
3
> (sum-digits 123)
6
> (sum-digits 1234)
10
> (define num 718981134123456789)
> (sum-digits num)
87
> (define big-num (expt 1498 1498))
> big-num
82546073234432505256450890252641261393332245255084608707963709273701788845112576531126557076857786317192366112237223036552991833801271356025417150273452078458939348996952671497630932227826230671072070338890275138596196027493215196221982248029922197017490759099122526102648557403164903291616738874388358025471764841749291193118408812120662280679870121235136111236388344975142765365091494616248417811907153542434658011151638430000899830164055443173322664612707554004207522620694159111348996320959939343633932203669660654122507505047804853792714077665323871057136835211877816471086903082020083511822597248006139631331782887842780047540057873174607018707861082239697329517108922855065789005646643809836045788499857447420188960245510708254673692831511727690595537484046231499794782745982727466866782089229860605465418274848815905358185926107238877570798325732334839186301670264399170873072524207754871392654455780314860706740914693427040535286718662136977230340486118354426256618731221914268019917936775998803644489438979871446446878436725885353328319368794614390493147824821401362903293643719180683179321056484478044673351198545675095924510949395893305406732944690443275253629063410884362893713479041529379087583982011844676373639514115466718004179596926663113779742939026650448790990799378160313542499685669508696656272184702384881235239142978003027021039203900031931531371216473532986393655662936209618266173864319182965188544514222825004184693671930955907291499956788965689878373326938410106102822570117394429977703796599873947508726379082127953635964976410667571950165908587512771162749961691331829638919214514734387280143203683068348910771089915516591070634723479003733004537241405193562801019354506931283111365518385622586982225394300018010937418942750158097139638185778821545461769116614792185531867399613060666798206005584975673990469326846774518046259011267992889220918382151215167031907461188247701174274294115668845628146605098681218957175377435851171205626999598344050360062045099785568369439958143119257258191662332590219780348646230705988892200557109112778687145461122567434720125984982455460409550861717804923921704801730867662419738439185344646037363848470308992044248299604776559104040638906620166484519415092959733362097453567514159178081771922338575979468768699395068305972626658965774826018663770284484116377970824477470198708296612809962345332505161753427313337127941563345434734144552647161627171592730560838663949988263159570711390474805166183242190643795777497397314335872414019085221283938753732115127873100096242681519718293735554529575048082153368629749668661525813534826313770290368841966168417950482562828031503950251112760387019108176589703881812041107569020493433523683409616033101799305988040066339401024068832153402740093939487670912025207656978306822524687772475561423692730649278816884262692609756907077822408010332868392519981751131743846016834825696738803337597220699003857193385582193224049470687418830073684730667726898853750872903787456285123422032313451745579590514595931721561076413672171533378247338734194522911211348282671784981753309796796485385895420594262680393965112310232548654149284745448217479399559062079662410650788189159618640584239722062657653004751799729928620756812383006171701028151932724614189295544331449899593129446114831121280733806453740997261543057288642608778723334576005635948048991846198257954505995494260451241146553607133835253174275690469883451340187980621727003355911377005360394419643112963701675759402502247539071850032836830792264699396634202490334810430634251041561299557237379575652145543830133788232450201018038238883862176304363885408146513485706469077027775132572098167220512073621868683936826454991654619394418574071835453678896938733091982768302336771304559142838596421956389375184902162126924922434625501390643454052375113041343508577614409652137839116754188527358277959901734135371350345409616109113478613795582899692762602377638907327631431501565975812335057256412128993613895974624488648326434889119936097494579510325620896227588813983158673974406053480947418424187236913321422363482632203931963438177553019325324105186761627391589356552288615381553523462034649659493928681526675324502550602591030418201474457802877673110149304898915822363839519533894149658198314350157737503175439663524010131966976804175022410324831818364764240552064904130547180982960655417019519927043238868348445808263602107213407358292655904110473941052348891481169975601406518390767505002992665710489784506959955245040604504942555509918522180848066959414643028915564879433737631030698716361945719920877048117054306292941583437120124854348950738756850027914795369841694667308597300590519101392065172488190258534289764780812386586514732540199634273124236191320861374548879593325175553639086779141764153344
> (time-sum-digits big-num)
21307
0.016
>

zak
09-05-2011, 06:02
thanks Dan , you persuade me to give Racket a try , sometimes what is more important for a language is how much wisdom it contains , the human brain have more wisdom than the computer with A.I capabilities even he is slow compared to the electronic computer. i see from the introduction that Racket have plotting capabilities on the same IDE, i have tried this to plot a sine to the ide and to a sine.png file:

#lang Racket
(require plot)
(plot
(line sin)
#:out-file "sine.png")
i will discover if it has GUI such as button textbox etc.

danbaron
09-05-2011, 06:32
Now, you showed me something, zak.

Previously, I never looked at anything in the Help, except for the Guide and the Reference.

I ran your example, and was shocked.

7200

Now that I look, I see that it does have buttons, etc. Just look in the Help, under, "GUI --> 2 Windowing Classes".

danbaron
10-05-2011, 07:48
I decided to see which way is faster to sum digits in Racket, "zak's", "math" way, or "my", "list" way.

(At least for me, it's hard to guess. Rather than speculating, the easiest way I know, is just to do an experiment.)

Below, I implemented zak's way as, "sum-digits-1", and my way as, "sum-digits-2".

I defined a big number, "big-num", as, 24789^24789.

You can see in the REPL interactions, that it has 108,930 digits.

Then I timed both functions (in seconds), and you can see the results below.

Both functions gave the same answer for the digit sum, 489,384.

(Interestingly, that number, 489,384 is likely to be correct. How do I know? Probably, we can assume that the 108,930 digits of the number are approximately random. So, on average, for every 10 digits, each of the digits 0-9 should be represented. That means that the average digit value is, (0+1+2+3+4+5+6+7+8+9)/10, = 4.5. In that case, an estimate of the sum of the digits would be, 4.5 * 108930, = 490,185.)

I guess the moral of the story is, "In Racket, avoid integer divisions when you can.".

:oops: :neutral: :twisted:


; code ---------------------------------------------------------------------------------------------------

#lang racket

(define (sum-digits-1 n)
(define sum 0)
(define (loop n1)
(cond
((= n1 0) sum)
(else
(set! sum (+ sum (modulo n1 10)))
(loop (floor (/ n1 10))))))
(loop n))

(define (sum-digits-2 n)
(define ns (number->string n))
(define sl (string->list ns))
(define ci (map (lambda (n) (- (char->integer n) 48))sl))
(define sum 0)
(define (sum-list-of-numbers l)
(cond
((null? l) sum)
(else
(set! sum (+ sum (car l)))
(sum-list-of-numbers (cdr l)))))
(sum-list-of-numbers ci))

(define (num-digits n)
(define ns (number->string n))
(define sl (string->list ns))
(length sl))

(define (time-function f n)
(let ((t1 (current-milliseconds)))
(let ((total (f n)))
(let ((t2 (current-milliseconds)))
(let ((tt (/ (- t2 t1) 1000.0)))
(values total tt))))))

: REPL interactions --------------------------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.
> (define a 24789)
> (define big-num (expt a a))
> (num-digits big-num)
108930
> (time-function sum-digits-1 big-num)
489384
183.403
> (time-function sum-digits-2 big-num)
489384
0.448
>

John Spikowski
10-05-2011, 08:01
Dan,

Just curious, have you ever tried using thinBasic for any of your experiments?

It seems you have posted your adventures with every obscure language you can dig up but I have never seen a thinBasic post by you.

Strange since this IS the thinBasic forum.

John

zak
10-05-2011, 08:35
you are genius in infering why number 489,384. indeed i have made a Bus tour over territories of Racket and i think it is great, i begins to read its book "How to Design Programs" http://www.htdp.org/ also the second edition of it. http://www.ccs.neu.edu/home/matthias/HtDP2e/index.html
my bigest probem is that i have a limited neurotrasmiters in my brain due to an old severe influenza so my learning is too slow. but i can't resist the fun Toys everywhere.

danbaron
10-05-2011, 09:02
I have, John.

Look here.

http://www.thinbasic.com/community/forumdisplay.php?347-Math-all-about

Look at the threads, "Project Lovecraft Problem 1", "Project Lovecraft Problem 2", "Project Lovecraft Problem 3", "Project Lovecraft Problem 4", "Project Lovecraft Problem 5", "Project Lovecraft Problem 6", "Project Lovecraft Problem 7".

(I guess you must be worried that Thinbasic users will be seduced away by the hypnotic powers of, "every obscure language I can dig up". I wonder if most people who are happy with Basic have much interest in "obscure" languages. I doubt it. I don't think my posting in other languages hurts anything here. I am not depriving someone else of the opportunity to post about Thinbasic. It isn't like there is a limit on the number of threads or posts, and my submitting something in an "obscure" language prevents someone else from submitting something in Thinbasic, is it? All I am doing is increasing the number of posts. I also guess that you think there is a competition between languages - that one language is threatened by the mention of another. I don't think that. To me, it is all computer science. And that, is what interests me.)

John Spikowski
10-05-2011, 19:09
my bigest probem is that i have a limited neurotrasmiters in my brain due to an old severe influenza so my learning is too slow.My daughter (31) was one of the first H1N1 patients to end up in an ICU. She had 5 near death experiences. An experimental anti-viral and chest tubes was the only thing that ended up saving her life. She lost her right lung in the battle. She is in a skilled nursing / physical rehab facility trying to bring her body back online after being on a ventilator for over 6 months and in a bed. She has suffered anoxic brain damage that makes it very difficult for her with motor control. Oct. will be two years of dealing with this nightmare. At least she is alive when everyone said there was no hope left.

danbaron
11-05-2011, 06:22
My wife and I were married in May of 1978. She was diagnosed with multiple sclerosis in March of 1978. As of August 16th, 2011, she will have been at a sub-acute nursing facility for 12 years. It is 60 miles from my house. For the first 10 years, I drove to and from there every day. Since then, I have taken the train there 5 days per week. During the entire time she has been there, she has had a tracheostomy. For at least the last 10 years, she has also had a feeding tube, and has been on a ventilator. (She has been lying flat on her back, "in a bed", since, June of 1994.)

zak
11-05-2011, 08:10
you deserve a noble prize Dan for sincerity and dedication.
this is really the final frontier from a human to tolerate.
30 years are too much and very long time.

zak

danbaron
11-05-2011, 08:29
Don't feel sorry for me.

Now I realize, that what I have endured, is nothing compared to what another member here has gone through!

What human has ever carried so much?!?!!

And with such grace, and good humor?!?!!

Oh, cruel world! Oh, cruel, cruel world!!

I can't continue now, I'm too emotional ...

:oops: :cry: :unguee:

John Spikowski
11-05-2011, 10:02
I experienced the ultimate challenge when the attending resident of the ICU brought me into a family conference and ask me how I wanted my daughter to die? (on or off the ventilator)

My response was failure on her part wasn't an option I was willing to accept and took over the management of Athena's care from that point on. The brief moments Athena was awake during that period, she begged me to let her go.

Is this love or an unwillingness to accept loss?

danbaron
11-05-2011, 21:18
In my opinion, it is not a matter of, "either-or".

I have found it impossible to disentangle concerns for me from concerns for my wife.

A person just has an overall feeling that, usually, at some point pushes him in one direction or another. On the other hand, sometimes a person can vacillate back and forth, or be so overwhelmed by the unpleasant options, that he becomes emotionally paralyzed.

I think that intellectually analyzing such a feeling, doesn't do much good. I think the conclusions of every such analysis we do is primarily determined by our feelings at that particular time.

In my opinion, our primary involuntary internal wiring is for our own personal survival (including our emotional survival). You or I can become angry at ourselves for experiencing what seem to be selfish feelings, but, I think we will have them anyway, they are out of our control. If you think about it, you are the only person who is not an abstraction to yourself. No matter who the other person is, for instance, your wife or your child, that person becomes just an idea, an abstract image in your head, whenever they are out of your presence, whenever you cannot experience them directly with one or more of your senses. You, yourself, are the only one who you always have to live with, who is always real to you. We can't do anything to change that.

Many many people in these situations struggle with obsessive internal ruminations, that is part of caring about someone else. The more you care, the more you may be internally tortured. And conversely, a person who cares only about himself, may go through life happy as can be.

On the other hand, don't ever put much faith in doctors. To me, most of them are narcissists, and, are not very bright. Often their recommendations are what is easiest for them personally, or are what they have been programmed to say. Sometimes I look at certain doctors, and I think that they are acting - they are trying to fool people into believing that they know more than the people know themselves. If you think about it, medicine can cure hardly anything at all. Usually, time, and the body, do the curing, when there is curing (or improvement). I think that is the main reason that the primary rule of the Hippocratic Oath is, "Do no harm.". I guess, Hippocrates, or whoever came up with the oath, was wise enough to realize, that, it's not a good idea to use a "hammer", to try to fix the amazingly intricate and delicate human body. (Would a doctor heed his own advice, if the patient was his own child?)

To me, the intricacy and delicacy of the human body, and the lack of understanding of it by medicine, is shown by the prescription drugs advertised today. They advertise a drug to treat something very minor, say, bladder control. And then, they have to use 500 words detailing all of the awful side effects the drug can produce.

Many people in situations where family members have life threatening illnesses or traumas, find comfort in religion. I think, part of that comfort comes from being part of a community. The members comfort each other. Also, then, the person realizes that whatever feelings he is having, have been had by other people for thousands of years. Also, then, there is the hope that Someone above, will ultimately fix what we cannot fix here and now. (Other people find no help at all in religion, which causes me to suspect that the strength of the religious drive (instinct) in a particular person, is at least partially genetic.)

If humans were independent, then, there would be no relationships, correct? Reproduction would only be accidental, and, Homo Sapiens would not exist. (How many babies would survive past infancy? Why would a truly independent person care about anyone else, even his own baby? Doesn't caring imply emotional dependence? And, who can separate emotional dependence from love? Is there a difference?) What relationship contains zero co-dependence? In fact, personalities which seem to be the most independent, are classified as, "schizoid".

http://en.wikipedia.org/wiki/Schizoid_personality_disorder

The various personality disorders, including schizoid, are more severe forms of emotional illness, than any type of neurosis.

John Spikowski
12-05-2011, 08:32
There is a reason they call it practicing medicine.

I'm just thankful Athena doesn't remember anything of what she went through. I guess it's a way for the brain to protect itself when dealing with extreme trauma.

Athena hasn't lost her personality, wit or will to survive. Her body took a beating and H1N1 almost won the fight but she never gave up nor did I.

I agree with you that our bodies are amazing vessels.

REDEBOLT
19-05-2011, 07:05
Last Modified = 05-18-2011 at 21:07:52

Program = SumOfDigits

Sum the digits of the number 24789^24789.

hi_Version 205

Base = 24789
Exponent = 24789
Num-digits = 108930

Example 1:
Val(Mid$(snum,i,1)) To Len(sNum)
Sum-digits = 489384
1.853 secs.

Example 2:
Val(Mid$(snum,i,1)) To lNumDigits
Sum-digits = 489384
1.707 secs.

Example 3:
Val(Chr$(Peek(Byte,sPtr))) To lNumDigits
Sum-digits = 489384
0.235 secs.

Example 4:
Val(Chr$(hi_GetRegByte(lReg_Large, i))) To lNumDigits
Sum-digits = 489384
0.288 secs.

28.529 secs.

Done...

Press any key to end program.


The Example 1 is the slowest method. Compared to Example 2, it shows that there is a slight overhead when the "TO" limit of a "FOR" loop is a function call.

Example 3 is the fasted method. It shows the power of using PEEK$ with a pointer.

Example 4 is nearly as fast, and it shows the efficiency of extracting bytes from a HIME register.

Attached is a zip file containing the source code.

Be sure to download the freeware HIME package from here (http://www.thinbasic.com/community/showthread.php?11156-H.i.m.e.&highlight=hime).

Regards,
Bob

danbaron
19-05-2011, 09:10
I don't think I can beat it.

:cry:


' code ------------------------------------------------------------------------------------

#lang racket

(define (sum-digits-3 n)
(define L (map char->integer (string->list (number->string n))))
(define sum (foldl + 0 L))
(set! sum (- sum (* (length L) 48)))
sum)

(define (time-function f n)
(let ((t1 (current-milliseconds)))
(let ((total (f n)))
(let ((t2 (current-milliseconds)))
(let ((tt (/ (- t2 t1) 1000.0)))
(values total tt))))))

' REPL interactions -----------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.
> (define a (expt 24789 24789))
> (time-function sum-digits-3 a)
489384
0.418
> (time-function sum-digits-3 a)
489384
0.409
> (time-function sum-digits-3 a)
489384
0.409
> (time-function sum-digits-3 a)
489384
0.416
>

REDEBOLT
19-05-2011, 20:06
Eddy Van Esch has proposed two more examples.

Thank you. Eddy! :cool:

Last Modified = 05-19-2011 at 13:40:39

Program = SumOfDigits

Sum the digits of the number 24789^24789.

hi_Version 205

Base = 24789
Exponent = 24789
Num-digits = 108930

Example 1:
Val(Mid$(snum,i,1)) To Len(sNum)
Sum-digits = 489384
4.586 secs.

Example 2:
Val(Mid$(snum,i,1)) To lNumDigits
Sum-digits = 489384
4.173 secs.

Example 3:
Val(Chr$(Peek(Byte,sPtr))) To lNumDigits
Sum-digits = 489384
0.513 secs.

Example 4:
Val(Chr$(hi_GetRegByte(lReg_Large, i))) To lNumDigits
Sum-digits = 489384
0.676 secs.

Example 5:
hi_GetRegByte(lReg_Large, i) - 48 To lNumDigits
Sum-digits = 489384
0.202 secs.

Example 6:
hi_GetRegByte(lReg_Large, i) To lNumDigits
Sum-digits = 489384
0.173 secs.

35.076 secs.

Done...

Press any key to end program.

ErosOlmi
19-05-2011, 21:30
As you may know, breaking a string using MID$ or LEFT$ or RIGHT$ or whatever method that moves memory areas is very cpu consuming.

I would suggest a SUPER SUPER fast method of summing strings of one byte all in thinBasic using the power of "logical variables (http://www.thinbasic.com/community/showthread.php?11143-Do-you-know-Logical-variables)"



Uses "Console"
Alias Console_WriteLine As SysOut

Dim T1, T2 As Quad
Dim sNum As String = Repeat$(10000, "1234567890")
Dim lSumDigits As Long
Dim i As Long

HiResTimer_Init


T1 = HiResTimer_Get
For i =1 To Len(snum)
lSumDigits += Val(Mid$(sNum,i,1))
Next
T2 = HiResTimer_Delta
SysOut "Slow method summing using MID$ a string of " & Len(sNum) & " bytes"
SysOut Using$("###.###",T2/1000000) + " secs."
SysOut "Sum is " & lSumDigits

SysOut "----------------------------------------------------"

'---Define a logical array of fixed strings of 1 byte each at the same
'---memory location of the string buffer
Dim MyNums(Len(sNum)) As String * 1 At StrPtr(sNum)
T1 = HiResTimer_Get
lSumDigits = Array Sum MyNums() '---thinBasic automatically detect is string
'---is a number and sum each elements
T2 = HiResTimer_Delta
SysOut "Super fast method summing using a logical array 1 byte fixed string of " & ubound(MyNums) & " elements"
SysOut Using$("###.###",T2/1000000) + " secs."
SysOut "Sum is " & lSumDigits

WaitKey


Here the standard method using val(mid$(...)) and my suggested method compared:


Slow method summing using MID$ a string of 100000 bytes
1.823 secs.
Sum is 450000
----------------------------------------------------
Super fast method summing using a logical array 1 byte fixed string of 100000 elements
0.017 secs.
Sum is 450000


My method is a ... little bit faster !!!!!

ErosOlmi
19-05-2011, 21:53
And this is the comparison if summing up digits of 1 million bytes string using the above two methods:

Slow method summing using MID$ a string of 1000000 bytes
723.878 secs.
Sum is 4500000
----------------------------------------------------
Super fast method summing using a logical array 1 byte fixed string of 1000000 elements
0.156 secs.
Sum is 4500000

danbaron
20-05-2011, 05:17
Eros' way is very good if you begin with a number that is stored as a string.

The other fast ways (for 24789^24789) range in time from about 0.17 seconds, to about 0.5 seconds.

I think the times for those are too close to preclude the possibility, that the particular machine is the deciding factor.

:o


' code -----------------------------------------------------------------------------------------------------

#lang racket

(define (n^n n)
(expt n n))

(define (num-digits n)
(define x (/ (log n) (log 10)))
(define y (ceiling x))
(when (= x y) (set! y (+ y 1)))
(inexact->exact y))

(define (sum-digits-1 n)
(define sum 0)
(define (loop n1)
(cond
((= n1 0) sum)
(else
(set! sum (+ sum (modulo n1 10)))
(loop (floor (/ n1 10))))))
(loop n))

(define (sum-digits-2 n)
(define ns (number->string n))
(define sl (string->list ns))
(define ci (map (lambda (n) (- (char->integer n) 48))sl))
(define sum 0)
(define (sum-list-of-numbers l)
(cond
((null? l) sum)
(else
(set! sum (+ sum (car l)))
(sum-list-of-numbers (cdr l)))))
(sum-list-of-numbers ci))

(define (sum-digits-3 n)
(define L (map char->integer (string->list (number->string n))))
(define sum (foldl + 0 L))
(set! sum (- sum (* (length L) 48)))
sum)

(define (sum-digits-4 n)
(define s (number->string n))
(define l (string-length s))
(define sum 0)
(define count 0)
(define (loop)
(cond
((= count l) sum)
(else
(set! sum (+ sum (char->integer (string-ref s count))))
(set! count (add1 count))
(loop))))
(loop)
(set! sum (- sum (* l 48)))
sum)

(define (time-function f n)
(let ((t1 (current-milliseconds)))
(let ((total (f n)))
(let ((t2 (current-milliseconds)))
(let ((tt (/ (- t2 t1) 1000.0)))
(values total tt))))))

' REPL interactions ----------------------------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.

' Sum 108,930 digits.

> (define a 24789)
> (define b (n^n a))
> (time-function sum-digits-1 b)
489384
198.283
> (time-function sum-digits-2 b)
489384
0.46
> (time-function sum-digits-3 b)
489384
0.486
> (time-function sum-digits-4 b)
489384
0.418
> (time-function sum-digits-2 b)
489384
0.442
> (time-function sum-digits-3 b)
489384
0.537
> (time-function sum-digits-4 b)
489384
0.411

' Sum 1,000,005 digits.

> (define a 189482)
> (define b (n^n a))
> (num-digits b)
1000005
> (time-function sum-digits-4 b)
4499836
11.605
>

ErosOlmi
20-05-2011, 06:35
Yes you are right but ...

I was not comparing a programming language with another programming language.

I was comparing a method with another method inside the same programming language (thinBasic) on the same machine. And the difference is astronomically different.

My script was created to demonstrate that whenever possible long runs of "VAL(MID$(...))" are to avoid because very inefficient especially in an interpreted language like thinBasic that does not have a intermediate optimization level (pCode)

Ciao
Eros

REDEBOLT
20-05-2011, 08:21
Wow, Eros, that's Aweome!

Last Modified = 05-19-2011 at 21:57:07

Program = SumOfDigits

Sum the digits of the number 24789^24789.

hi_Version 205

Base = 24789
Exponent = 24789
Num-digits = 108930

Example 1:
Val(Mid$(snum,i,1)) To Len(sNum)
Sum-digits = 489384
4.396 secs.

Example 2:
Val(Mid$(snum,i,1)) To lNumDigits
Sum-digits = 489384
4.319 secs.

Example 3:
Val(Chr$(Peek(Byte,sPtr))) To lNumDigits
Sum-digits = 489384
0.358 secs.

Example 4:
Val(Chr$(hi_GetRegByte(lReg_Large, i))) To lNumDigits
Sum-digits = 489384
0.506 secs.

Example 5:
hi_GetRegByte(lReg_Large, i) - 48 To lNumDigits
Sum-digits = 489384
0.216 secs.

Example 6:
hi_GetRegByte(lReg_Large, i) To lNumDigits
lSumDigits = lSumDigits - (lNumDigits * 4
Sum-digits = 489384
0.174 secs.

Example 7: by Eros Olmi
Array Sum MyNums()
Sum-digits = 489384
0.037 secs.

35.125 secs.

Done...

Press any key to end program.

You guys have done a magnificient job with the BASIC language! :o

I have got to learn more here! :D

Regards,
Bob

REDEBOLT
20-05-2011, 13:10
Last Modified = 05-20-2011 at 03:35:34

Program = SumOfDigits

Sum the digits of the number 189482^189482.

hi_Version 205

Array Sum MyNums()
Time to calculate the large number string,
208.935 secs.

Base = 189482
Exponent = 189482
Num-digits = 1000005

Example 7: by Eros Olmi
Array Sum MyNums()
Sum-digits = 4499836
0.590 secs.

209.532 secs.

Done...

Press any key to end program.

danbaron
20-05-2011, 20:49
I do notice that I can get a little more speed, if I close as many applications as I have control over, before I run the tests.

Also, below, I would expect the time for 1,000,005 digits to be approximately equal to 1,000,005 / 108,930 times the time for 108,930 digits, i.e., a linear increase.

That would be approximately 3.43 seconds.

But, the actual time is 10.671 seconds.

I don't know why.


' REPL interactions ---------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.
> (define a 24789)
> (define b (n^n a))
> (num-digits b)
108930
> (time-function sum-digits-2 b)
489384
0.406
> (time-function sum-digits-3 b)
489384
0.515
> (time-function sum-digits-4 b)
489384
0.374
> (define a 189482)
> (define b (n^n a))
> (num-digits b)
1000005
> (time-function sum-digits-4 b)
4499836
10.671
>

danbaron
21-05-2011, 08:11
' code -------------------------------------------------------------------------------------------------------------

#lang racket

(define big-int 0)
(define big-int-string "")

(define (n^n n)
(expt n n))

(define (num-digits n)
(add1 (order-of-magnitude n)))

(define (make-big-integer n)
(set! big-int (n^n n)))

(define (make-big-integer-string n)
(set! big-int-string (number->string n)))

(define (sum-digits-of-integer n)
(define s (number->string n))
(define l (string-length s))
(define sum 0)
(define count 0)
(define (loop)
(cond
((= count l) sum)
(else
(set! sum (+ sum (char->integer (string-ref s count))))
(set! count (add1 count))
(loop))))
(loop)
(set! sum (- sum (* l 48)))
sum)

(define (sum-digits-of-integer-string s)
(define l (string-length s))
(define sum 0)
(define count 0)
(define (loop)
(cond
((= count l) sum)
(else
(set! sum (+ sum (char->integer (string-ref s count))))
(set! count (add1 count))
(loop))))
(loop)
(set! sum (- sum (* l 48)))
sum)

(define (time-function f n)
(let ((t1 (current-milliseconds)))
(let ((total (f n)))
(let ((t2 (current-milliseconds)))
(let ((tt (/ (- t2 t1) 1000.0)))
(values total tt))))))

' REPL interactions ------------------------------------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.

> (time-function make-big-integer 24789)
0.062
> (num-digits big-int)
108930
> (time-function sum-digits-of-integer big-int)
489384
0.374
> (time-function make-big-integer-string big-int)
0.374
> (time-function sum-digits-of-integer-string big-int-string)
489384
0.032

> (time-function make-big-integer 189482)
1.685
> (num-digits big-int)
1000005
> (time-function sum-digits-of-integer big-int)
4499836
10.764
> (time-function make-big-integer-string big-int)
10.312
> (time-function sum-digits-of-integer-string big-int-string)
4499836
0.25
>

danbaron
22-05-2011, 05:17
' REPL interactions ------------------------------------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.

> (time make-big-integer 1611056)
39.25
> (time num-digits big-int)
10000003
129.527
> (time sum-digits-of-integer big-int)
44997718
355.665
> (time make-big-integer-string big-int)
354.026
> (time sum-digits-of-integer-string big-int-string)
44997718
2.496
>

danbaron
22-05-2011, 08:12
' REPL interactions ------------------------------------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.

> (time make-big-integer 3082205)
146.156
> (time num-digits big-int)
20000002
1273.475
> (time sum-digits-of-integer big-int)
90002651
974.828
> (time make-big-integer-string big-int)
969.525
> (time sum-digits-of-integer-string big-int-string)
90002651
5.164
>

danbaron
22-05-2011, 23:46
' REPL interactions ------------------------------------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.

> (time make-big-integer 4508542)
270.145
> (time num-digits big-int)
30000002
679.115
> (time sum-digits-of-integer big-int)
134994313
1723.004
> (time make-big-integer-string big-int)
1665.081
> (time sum-digits-of-integer-string big-int-string)
134994313
11.232
>

danbaron
23-05-2011, 07:05
' code -------------------------------------------------------------------------------------------------------------

#lang racket

[define big-integer 0]
[define big-integer-string ""]

[define [m-such-that-num-digits-of-m^m->= n]
[define target [* n [log 10]]]
[define m 1]
[define [loop]
[cond
[[>= [* m [log m]] target] m]
[else
[set! m [add1 m]]
[loop]]]]
[loop]]

[define [n^n n]
[expt n n]]

[define [num-digits n]
[add1 [order-of-magnitude n]]]

[define [set-big-integer n]
[set! big-integer [n^n n]]]

[define [set-big-integer-string-and-sum-digits-of-integer n]
[set! big-integer-string [number->string n]]
[define l [string-length big-integer-string]]
[define sum 0]
[define count 0]
[define [loop]
[cond
[[= count l] sum]
[else
[set! sum [+ sum [char->integer [string-ref big-integer-string count]]]]
[set! count [add1 count]]
[loop]]]]
[loop]
[set! sum [- sum [* l 48]]]
sum]

[define [sum-digits-of-integer-string s]
[define l [string-length s]]
[define sum 0]
[define count 0]
[define [loop]
[cond
[[= count l] sum]
[else
[set! sum [+ sum [char->integer [string-ref s count]]]]
[set! count [add1 count]]
[loop]]]]
[loop]
[set! sum [- sum [* l 48]]]
sum]

[define [time f n]
[let [[t1 [current-milliseconds]]]
[let [[total [f n]]]
[let [[t2 [current-milliseconds]]]
[let [[tt [/ [- t2 t1] 1000.0]]]
[values total tt]]]]]]

' REPL interactions ------------------------------------------------------------------------------------------------

Welcome to DrRacket, version 5.1 [3m].
Language: racket.

> [define a 40000000]
> [define b [m-such-that-num-digits-of-m^m->= a]]
> b
5907214
> [time set-big-integer b]
385.523
> [time num-digits big-integer]
40000007
1031.348
> [time set-big-integer-string-and-sum-digits-of-integer big-integer]
179994916
2698.995
> [time sum-digits-of-integer-string big-integer-string]
179994916
16.692
>