2^(15) = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^(1000)?
This is how I solved in python.
sum([int(x) for x in str(pow(2,1000))])
For lisp, I don't know how to implement that algorithm ...
This is my sketch on how to slove ...
(loop for x across "12345" summing (- (char-int x) 48))
Still I need to cast (expt 2 1000) into string from integer ...
How can I do that ?
It works ! Thanks ...
It would be slightly better to use CHAR-CODE. But you can also use
DIGIT-CHAR-P.
CL-USER 4 > (digit-char-p #\3)
3
CL-USER 5 > (reduce #'+ (write-to-string (expt 2 1000)) :key #'digit-
char-p)
1366
As an alternative,
(defun integer-digit-list (n &optional (radix 10))
"Returns a list of the digits (base radix) of an integer. Least
digit
is in position 0."
(check-type n integer)
(if (zerop n)
(list 0)
(labels
((digit-list (n)
(multiple-value-bind (upper digit)
(floor n radix)
(cons digit (when (> upper 0) (digit-list upper))))))
(digit-list (abs n)))))
CL-USER> (reduce '+ (integer-digit-list (expt 2 1000)))
1366
CL-USER> (reduce '+ (integer-digit-list (expt 2 1000) 16))
1
CL-USER>
Wade
Others have already provided solutions. I wanted to add mine because it
is important to realize that you do not need the intermediate list of
digits, and you can proceed from either end (+ is commutative). So
(defun sum-digits (i)
(declare ((integer 0) i)) ;; we want a nonnegative integer
(let ((sum 0))
(tagbody
top
(multiple-value-bind (quotient remainder) (truncate i 10)
(incf sum remainder)
(when (plusp quotient)
(setf i quotient)
(go top))))
sum))
(sum-digits (expt 2 1000))
Some consider tagbody ugly - it is their loss :-)
Tamas
If put in a library it might be worth to have recursion
replaced with iteration (-> stack size limit).
Here is a iterative solution.
(defun integer-digit-list (n &optional (radix 10))
"Returns a list of the digits base radix of an integer. Least digit
is in position 0."
(check-type n integer)
(setf n (abs n))
(loop collect
(multiple-value-bind (upper digit)
(floor n radix)
(setf n upper)
digit)
while (> n 0)))
Wade
Yep.
or using SETF instead of MULTIPLE-VALUE-BIND:
(defun integer-digit-list (n &optional (radix 10))
"Returns a list of the digits base radix of an integer. Least digit
is in position 0."
(check-type n integer)
(setf n (abs n))
(loop with digit
do (setf (values n digit) (floor n radix))
collect digit while (plusp n)))
I cheerfully use TAGBODY when it's appropriate, but I don't consider
the above to be such a case, especially given that there's a considerably
simpler way *without* it, viz.:
(defun sum-digits (i)
(assert (and (integerp i) (>= i 0)))
(loop while (plusp i)
summing (multiple-value-bind (quotient remainder)
(truncate i 10)
(setf i quotient)
remainder)))
-Rob
p.s. Note that I changed your DECLARE to an ASSERT, since DECLARE is
a promise *by* the programmer, not a check *of* the programmer/user!
I suppose I could have written (ASSERT (TYPEP I '(INTEGER 0 *))),
but the TYPEP is likely to be slower.
-----
Rob Warnock <rp...@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
| I cheerfully use TAGBODY when it's appropriate, but I don't consider
| the above to be such a case, especially given that there's a considerably
| simpler way *without* it, viz.:
|
| (defun sum-digits (i)
| (assert (and (integerp i) (>= i 0)))
| (loop while (plusp i)
| summing (multiple-value-bind (quotient remainder)
| (truncate i 10)
| (setf i quotient)
| remainder)))
|
|
| p.s. Note that I changed your DECLARE to an ASSERT, since DECLARE is
| a promise *by* the programmer, not a check *of* the programmer/user!
| I suppose I could have written (ASSERT (TYPEP I '(INTEGER 0 *))),
| but the TYPEP is likely to be slower.
Since we're picking nits anyway :-} you could use
(check-type i (integer 0))
instead of the assert
--
Madhu
No it doesn't work here (EBCDIC system).
Use: (loop :for x :across (prin1-to-string (expt 2 1000)) :summing (digit-char-p x))
Yes, DIGIT-CHAR-P returns what you want, despite of its name.
--
__Pascal Bourguignon__