Risolvendo i problemi del progetto Eulero, ottengo che è necessario effettuare le operazioni con le cifre di un numero lungo normalmente come stringa. Lavoro in linux, emacs, melma con sbcl.Numero intero lungo per stringa e viceversa, operazione con cifre
Ad esempio, per ottenere la somma delle cifre di questo potere 2¹⁰⁰⁰, io lavoro in questo modo,
1) Ottenere il potere
CL-USER> (defparameter *answer-as-integer* (expt 2 1000))
*ANSWER-AS-INTEGER*
CL-USER> *ANSWER-AS-INTEGER*
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
Grazie a Common Lisp questo è molto facile. Ora credo che un buon modo dovrebbe essere quello di applicare ridurre a questa sequenza di cifre.
2) Ottenere la stringa
CL-USER> (defparameter *answer-as-string* (write-to-string *ANSWER-AS-INTEGER*))
*ANSWER-AS-STRING*
CL-USER> *ANSWER-AS-STRING*
"10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376"
ora ho la sequenza, in modo da applicare ridurre, ma ho cose sbagliate: Questo è un char quindi applico un char di conversione a intero:
CL-USER> (reduce #'(lambda (x y) (+ (digit-char-p x) (digit-char-p y))) *ANSWER-AS-string*)
ma ottengo un errore:
The value 1 is not of type CHARACTER.
[Condition of type TYPE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort thread (#<THREAD "repl-thread" RUNNING {1005DE80B3}>)
Backtrace:
0: (DIGIT-CHAR-P 1) [optional]
1: ((LAMBDA (X Y)) 1 #\7)
2: (REDUCE #<FUNCTION (LAMBDA (X Y)) {100523C79B}> "1071508607186267320948425049060001810561404811705533607443750388370351051124936122493198378815695858127594672917553146825187145285692314043598457757469..
3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (REDUCE (FUNCTION (LAMBDA # #)) *ANSWER-AS-STRING*) #<NULL-LEXENV>)
4: (EVAL (REDUCE (FUNCTION (LAMBDA # #)) *ANSWER-AS-STRING*))
5: (SWANK::EVAL-REGION "(reduce #'(lambda (x y) (+ (digit-char-p x) (digit-char-p y))) *ANSWER-AS-string*) ..)
Locals:
SB-DEBUG::ARG-0 = "(reduce #'(lambda (x y) (+ (digit-char-p x) (digit-char-p y))) *ANSWER-AS-string*)\n"
6: ((LAMBDA NIL :IN SWANK-REPL::REPL-EVAL))
7: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {10051F065B}>)
8: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {10051F059B}>)
9: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {10051F057B}>)
10: (SWANK-REPL::REPL-EVAL "(reduce #'(lambda (x y) (+ (digit-char-p x) (digit-char-p y))) *ANSWER-AS-string*) ..)
11: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(reduce #'(lambda (x y) (+ (digit-char-p x) (digit-char-p y))) *ANSWER-AS-string*) ..)
12: (EVAL (SWANK-REPL:LISTENER-EVAL "(reduce #'(lambda (x y) (+ (digit-char-p x) (digit-char-p y))) *ANSWER-AS-string*) ..)
13: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(reduce #'(lambda (x y) (+ (digit-char-p x) (digit-char-p y))) *ANSWER-AS-string*) ..)
14: (SWANK::PROCESS-REQUESTS NIL)
15: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
16: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
17: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {1005DF00DB}>)
18: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/home/anquegi/quicklisp/dists/quicklisp/software/slime-2.13/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::H..
19: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-OUTPUT* . #1=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1005DCF343}>) (*STANDARD-INPUT* . #2=#<SWANK/GRAY::SLIME-INPUT-STREAM {1006160003}>) (*TRACE-OUTPUT* . #1#) (*ERR..
20: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {1005078BE3}> NIL)
21: ((FLET #:WITHOUT-INTERRUPTS-BODY-1226 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
22: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
23: ((FLET #:WITHOUT-INTERRUPTS-BODY-647 :IN SB-THREAD::CALL-WITH-MUTEX))
24: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {7FFFEA81ED1B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THR..
25: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1005DE80B3}> #S(SB-THREAD:SEMAPHORE :NAME "Thread setup semaphore" :%COUNT 0 :WAITCOUNT 0 :MUTEX #<SB-THREAD:MU..
26: ("foreign function: call_into_lisp")
27: ("foreign function: new_thread_trampoline")
e se provo ad usare questo come cifre senza conversione del inteerpreter dice che questa Non è un numero intero, quindi sto diventando pazzo, perché questo è giusto, ma il non codice di cui sopra:
(reduce #'+ *ANSWER-AS-string*)
The value #\1 is not of type NUMBER.
[Condition of type TYPE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort thread (#<THREAD "repl-thread" RUNNING {1005DE80B3}>)
Backtrace:
0: (+ #\1 #\0)
1: (REDUCE #<FUNCTION +> "107150860718626732094842504906000181056140481170553360744375038837035105112493612249319837881569585812759467291755314682518714528569231404359845775746985748039345677748242309854..
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (REDUCE (FUNCTION +) *ANSWER-AS-STRING*) #<NULL-LEXENV>)
3: (EVAL (REDUCE (FUNCTION +) *ANSWER-AS-STRING*))
4: (SWANK::EVAL-REGION "(reduce #'+ *ANSWER-AS-string*) ..)
Locals:
SB-DEBUG::ARG-0 = "(reduce #'+ *ANSWER-AS-string*)\n"
5: ((LAMBDA NIL :IN SWANK-REPL::REPL-EVAL))
6: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {100566384B}>)
7: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {100566378B}>)
8: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {100566376B}>)
9: (SWANK-REPL::REPL-EVAL "(reduce #'+ *ANSWER-AS-string*) ..)
10: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(reduce #'+ *ANSWER-AS-string*) ..)
11: (EVAL (SWANK-REPL:LISTENER-EVAL "(reduce #'+ *ANSWER-AS-string*) ..)
12: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(reduce #'+ *ANSWER-AS-string*) ..)
13: (SWANK::PROCESS-REQUESTS NIL)
14: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
15: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
16: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {1005DF00DB}>)
17: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/home/anquegi/quicklisp/dists/quicklisp/software/slime-2.13/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::H..
18: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-OUTPUT* . #1=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1005DCF343}>) (*STANDARD-INPUT* . #2=#<SWANK/GRAY::SLIME-INPUT-STREAM {1006160003}>) (*TRACE-OUTPUT* . #1#) (*ERR..
19: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {1005078BE3}> NIL)
20: ((FLET #:WITHOUT-INTERRUPTS-BODY-1226 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
21: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
22: ((FLET #:WITHOUT-INTERRUPTS-BODY-647 :IN SB-THREAD::CALL-WITH-MUTEX))
23: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {7FFFEA81ED1B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THR..
24: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1005DE80B3}> #S(SB-THREAD:SEMAPHORE :NAME "Thread setup semaphore" :%COUNT 0 :WAITCOUNT 0 :MUTEX #<SB-THREAD:MU..
25: ("foreign function: call_into_lisp")
26: ("foreign function: new_thread_trampoline")
ho risolto questo in questo modo:
CL-USER> (defun sum-digits-in-a-string (str)
(reduce #'+ (map 'list #'digit-char-p str)))
SUM-DIGITS-IN-A-STRING
CL-USER> (sum-digits-in-a-string *ANSWER-AS-STRING*)
1366
Quindi la mia domanda è di questo che ho ottieni questo errore prima un numero intero e dopo un carattere, e qual è il modo migliore di lavorare con le cifre di un intero lungo. Se la mia aproximation è buona: long-integer -> string -> lista di interi -> applica riduci.
Non hai nemmeno bisogno di output di debug in più, si può vedere nel backtrace (linea 1). – Svante
@Svante Certo, è anche lì, ma la * pratica * dell'output di debug è utile. (Non sconto i debugger, ecc., Ma un po 'di output di log può fare miracoli.) Inoltre, non è sempre chiaro come un debugger stamperà un valore. Ma hai ragione, in questo caso, l'output era già visibile, ma solo su quella iterazione. Aggiungendo un po 'di output, abbiamo visto anche il primo, dove erano entrambi i personaggi. –