Asking for the idomatic way respectively for avoiding a duplicate in the code - common-lisp

(Just for fun) I figured out a way to represent this:
250 : 8 = 31 + 2
31 : 8 = 3 + 7
∴ (372)8
in the following procedure:
(defun dec->opns (n base)
(do* ((lst nil (append lst (list pos))) ; this is also not so nice
(m n (truncate m base))
(pos (rem m base) (rem m base)) ) ; <<<<<<
((< m base) (reverse (append lst (list m)))) ))
The procedure does what it is supposed to do until now.
CL-USER> (dec->opns 2500000 8)
(1 1 4 2 2 6 4 0)
At this point, I simply ask myself, how to avoid the two times
(rem m base).
First of all because of duplicates are looking daft. But also they may be a hint that the solution isn't the elegant way. Which also is not a problem. I am studying for becoming a primary school teacher (from 1st to 6nd class) and am considering examples for exploring math in a sense of Paperts Mindstorms. Therefore exploring all stages of creating and refining a solution are welcome.
But to get a glimpse of the professional solution, would you be so kind to suggest a more elegant way to implement the algorithm in an idiomatic way?
(Just to anticipate opposition to my "plan": I have no intentions to overwhelm the youngsters with Common Lisp. For now, I am using Common Lisp for reflecting about my study content and using the student content for practicing Common Lisp. My intention in the medium term is to write a "common (lisp) Logo setup" and a Logo environment with which the examples in Harveys Computer Science Logo style (vol. 1), Paperts Mindstorms, Solomons et. al LogoWorks, and of course in Abelsons et. al Turtle Geometry can be implemented uncompromisingly. If I will not cave in, the library will be found with quickload in the still more distant future under the name "c-logo-s" and be called cλogos ;-) )

The closest to your code
You can reduce the reversing of the reversing and append -> by using cons only. The duplication of (rem m base) is only an optical issue, since the first (rem m base) gets executed only the first time the loop runs and the second (rem m base) in all other cases. Thus they are actually not a duplication. One cannot use a let here, because of the required syntax within the macro. (<variable> <initial-value> <progression-for-each-round>)
(defun dec->ops (n base)
(do* ((acc nil (cons r acc))
(m n (truncate m base))
(r (rem m base) (rem m base)))
((zerop m) acc)))
The most Common Lispy version
The rosetta solutions for Common Lisp seems to give the most Common Lisp-like ways - either using write-to-string/parse-integer or even some format quircks.
(defun decimal->base-n (n base)
(write-to-string n :base base))
(defun base-n->decimal (base-n base)
(parse-integer (format nil "~a" base-n) :radix base))
(defun decimal-to-base-n (number &key (base 16))
(format nil (format nil "~~~dr" base) number))
(defun base-n-to-decimal (number &key (base 16))
(read-from-string (format nil "#~dr~d" base number)))
;; or:
(defun change-base (number input-base output-base)
(format nil "~vr" output-base (parse-integer number :radix input-base)))
Source: https://rosettacode.org/wiki/Non-decimal_radices/Convert#Common_Lisp
(decimal-to-base-n 2500000 :base 8)
;;=> "11422640"
Solution without format or write-to-string/parse-integer
Use tail call recursion:
(defun dec->ops (n base &optional (acc nil))
(if (< n base)
(cons n acc)
(multiple-value-bind (m r) (truncate n base)
(dec->ops m base (cons r acc)))))
Try it:
[41]> (dec->ops 250 8)
(3 7 2)
[42]> (dec->ops 250000 8)
(7 5 0 2 2 0)
[43]> (dec->ops 2500000 8)
(1 1 4 2 2 6 4 0)
The do/do* macros are in this case not so nice, because one cannot capture the multiple values returned by truncate nicely (truncate is mod and rem in one function - one should use this fact).
If you really wants to use do*
(defun dec->ops (n base)
(do* ((acc nil (cons (second values) acc))
(values (list n) (multiple-value-list (truncate (first values) base))))
((< (first values) base) (nbutlast (cons (first values) (cons (second values) acc))))))
This works
[69]> (dec->ops 250 8)
(3 7 2)
[70]> (dec->ops 2500000 8)
(1 1 4 2 2 6 4 0)

I would go with the following implementation when trying to avoid recursion:
(defun digits-in-base (number base)
(check-type number (integer 0))
(check-type base (integer 2))
(loop
:with remainder
:do (multiple-value-setq (number remainder) (truncate number base))
:collect remainder
:until (= number 0)))
Multiple values are not directly handled by LOOP so instead of converting the values to a list I prefer using MULTIPLE-VALUE-SETQ to update multiple values at once.
The code first does some type checks because otherwise it can loop infinitely: the inputs are expected to be respectively positive or null, and greater than 1.
I put the :until condition at the end so that 0 gives (0).
Note that the digits are sorted from the smallest to the highest rank:
(digits-in-base 4 2)
=> (0 0 1)
(digits-in-base 250 8)
=> (2 7 3)
Alternatively, for the reverse order:
(defun digits-in-base (number base)
(check-type number (integer 0))
(check-type base (integer 2))
(loop
:with remainder :and digits
:do (multiple-value-setq (number remainder) (truncate number base))
:do (push remainder digits)
:until (= number 0)
:finally (return digits)))
(digits-in-base 4 2)
=> (1 0 0)
(digits-in-base 250 8)
=> (3 7 2)
In a previous version of this answer I said the first one (from low to high digits) is better for further manipulation of the digits, but I am not so sure.
Converting back to a number is quite easy with number arranged from high to low digits (all the code below use the second version):
(defun digits-to-number (digits base)
(reduce (lambda (n d) (+ d (* n base)))
digits
:initial-value 0))
So is formatting to a string:
(defun number-string-base (number base)
(format nil
(if (<= base 10)
"(~{~d~})~d"
"(~{~d~^'~})~d")
(digits-in-base number base)
base))
(number-string-base 250 8)
=> "(372)8"
(number-string-base 250 16)
=> "(15'10)16"

Since you expressed interest in various approaches, one thing worth remembering is that Lisp's great strength is creating and extending languages. Indeed all the iteration constructs in Common Lisp are such extensions: CL has no primitive iteration constructs at all.
So there is nothing preventing anyone writing their own, which will be just as good as the ones the language provides. For instance Tim Bradshaw's simple loops provides an 'applicative looping construct', looping, which makes this quite simple to implement:
(defun dec->ops (n base)
(looping ((m n)
(a '()))
(when (< (abs m) base)
(return (cons m a)))
(multiple-value-bind (q r) (truncate m base)
(values q (cons r a)))))
Using looping, the variables bound in the loop are updated by the values of the last form in the loop's body.
Of course this is rather close to the classic tail-recursive implementation (here using iterate):
(defun dec->ops (n base)
(iterate next ((m n)
(a '()))
(if (< (abs m) base)
(cons m a)
(multiple-value-bind (q r) (truncate m base)
(next q (cons r a))))))
People tend not to like things like this because they are 'not idiomatic CL' of course.

Related

Prime number check in Lisp

Can someone point out my mistake here. I am trying to check if a number is a prime number or not.
It works to an extent but I have a semantics error. For example it is telling me that 9 is a prime number but at the same time it is telling me 4 and 6 are not prime numbers and I am confused.
(defvar *prime* nil)
(defun primeCheck (x y)
(if (and (>= x y) (not (= (mod x y) 0)))
(progn
(setf y (+ y 1))
(primeCheck x y)
(setf *prime* 'yes))
(setf *prime* 'no))
)
(primeCheck 9 2)
(if (equal *prime* 'yes) (print "Number is prime") (print "Number is not prime"))
Many things are wrong.
How about using primarity test e.g. from SICP (structure and interpretation of computer programs)?
;; from SICP (here in clojure)
;; http://www.sicpdistilled.com/section/1.2.6/
(defun smallest-divisor (n)
(find-divisor n 2))
(defun square (n)
(* n n))
(defun find-divisor (n test-divisor)
(cond ((> (square test-divisor) n) n)
((dividesp test-divisor n) test-divisor)
(t (find-divisor n (1+ test-divisor)))))
(defun dividesp (a b)
(zerop (mod b a)))
(defun primep (n)
(= n (smallest-divisor n)))
primep tests for primarity.
I suggest you to download some IDE (for example LispWorks Personal Edition) or find online REPL for Common Lisp and run your codes in it. Your mistakes:
("prime number") is badly formed list. Replace that with (print "prime number")
primeCheck calls some (yet) undefined function modulus
(*prime-Check* nil) is badly formed list. Replace with (setf *prime-Check* nil)
badly formed cond and and
with all these corrections, it doesn't work for 2,3,5 etc.

Lisp recursive function missing base case on first call

I started programming with lisp yesterday so please excuse if I am making some really newbie mistake. I am trying to create a function which calculates the bell numbers using the bell triangle and my recursive triangle function is not working properly. I am also sure if I got my recursive triangle function working that my recursive bell function is somehow also broken.
When I test my triangle function I get the output:
(defun bell(l n)
(if(< n 1)(list 1))
(if (= n 1)(last l))
(bell (triangle (reverse l) (last l) (list-length l)) (- n 1))
)
(defun triangle(pL nL i)
(if(<= i 0)
(write "equals zero!")
(reverse nL)
)
(triangle pL (append (list (+ (nth i pL) (nth i nL))) nL) (- i 1))
)
(write (triangle '(1) '(1) 0))
=>
"equals zero!""equals zero!"
*** - NTH: -1 is not a non-negative integer
For some reason, it is printing my debug code twice even though the function should be meeting my base case on the first call.
For some reason, it is printing my debug code twice even though the function should be meeting my base case on the first call.
It is printed twice because if is not doing what you think it does. The first if test is true, therefore equals zero! is printed. After that, a recursive call to triangle function is invoked. The test is again true (-1 <= 0), so equals zero! is again printed. Finally, you get an error because nthcdr function is called with -1. I strongly recommend you a good lisp debugger. The one from Lispworks is pretty good.
I honestly don't get the logic of what you were trying to achieve with your code. so I wrote mine:
(defun generate-level (l &optional (result))
"given a list l that represents a triangle level, it generates the next level"
(if (null l) result
(if (null result)
(generate-level l (list (car (last l))))
(generate-level (cdr l) (append result
(list (+ (car l)
(car (last result)))))))))
(defun bell (levels &optional (l))
"generate a bell triangle with the number of labels given by the first parameter"
(unless (zerop levels)
(let ((to-print (if (null l) (list 1) (generate-level l))))
(print to-print)
(bell (1- levels) to-print))))
Things to understand the implementation:
&optional (parameter): this parameter is optional and nil by default.
append concatenates two lists. I'm using it to insert in the back of the list.
let ((to-print x)) creates a new variable binding (local variable) called to-print and initialized to x.
I almost forgot to mention how if works in common lisp:
(if (= x 1) y z) means if x is equal to 1 then return y, otherwise z.
Now if you call the function to create a Bell triangle of 7 levels:
CL-USER 9 > (bell 7)
(1)
(1 2)
(2 3 5)
(5 7 10 15)
(15 20 27 37 52)
(52 67 87 114 151 203)
(203 255 322 409 523 674 877)
NIL
It would be nicer to print it with the appropiate padding, like this:
1
1 2
2 3 5
5 7 10 15
15 20 27 37 52
52 67 87 114 151 203
203 255 322 409 523 674 877
but I left that as an exercise to the reader.
Your ifs don't have any effect. They're evaluated, and produce results, but then you discard them. Just like
(defun abc ()
'a
'b
'c)
would evaluate 'a and 'b to produce the symbols a and b, and then would evaluate 'c to produce the symbol c, which would then be returned. In the case of
(if(<= i 0)
(write "equals zero!") ; then
(reverse nL) ; else
)
you're comparing whether i is less than or equal to zero, and if it is, you print equals zero, and if it's not, you (non-destructively) reverse nL and discard the result. Then you finish the function by making a call to triangle. It seems like you probably want to return the reversed nL when i is less than or equal to zero. Use cond instead, since you can have multiple body forms, as in:
(cond
((<= i 0) (write ...) (reverse nL))
(t (triangle ...)))
You could also use if with progn to group the forms:
(if (<= i 0)
(progn
(write ...)
(reverse nL))
(triangle ...))
Your other function has the same problem. If you want to return values in those first cases, you need to use a form that actually returns them. For instance:
(if (< n 1)
(list 1)
(if (= n 1)
(last l)
(bell #| ... |#)))
More idiomatic would be cond, and using list rather than l, which looks a lot like 1:
(cond
((< n 1) (list 1))
((= n 1) (last list))
(t (bell #| ... |#)))
Thank you all for the explanations. I eventually arrived at the code below. I realized that the if block worked something like..
(if (condition) (execute statement) (else execute this statement))
(defun bell(l n)
(if (< n 2)(last l)
(bell (triangle l (last l) 0) (- n 1))
)
)
(defun triangle(pL nL i)
(if(= i (list-length pL)) nL
(triangle pL (append nL (list (+ (nth i pL) (nth i nL)))) (+ i 1))
)
)
(write (bell (list 1) 10))

Scheme Tail Recursion (BitsOn count)

I need some help to implement a function that receives a number and returns the number of bits that would have been required to be “on” in order to represent the input number in binary base.
For example, the number 5 is represented as 101 in binary and therefore requires two bits to be “on”.
Example:
(numOfBitsOn 5) will return 2 because 5 in binary is 101
(numOfBitsOn 101) will return 4 because 101 in binary is 1100101
The function must be written as tail recursion.
This is m first time learning Scheme. Up to now this is all I wrote:
(define (numOfBitsOn number)
(define (numOfBitsOn-2 number acc)
(cond ((eq? number 0)acc)
(not(eq? (modulo number 2)0) (+ acc 1))
(numOfBitsOn-2 (/ number 2) acc))))
And it gives me that:
begin (possibly implicit): no expression after a sequence of internal definitions in: (begin (define (numofbitson-2 number acc) (cond ((eq? number 0) acc) (not (eq? (modulo number 2) 0) (+ acc 1)) (numofbitson-2 (number) acc))))
I'm sure it doesn't even close to the solution =\
Can you help me please?
Thanks!
(define (slow-popcount n)
(do ((n n (quotient n 2))
(count 0 (+ count (modulo n 2))))
((zero? n) count)))

Digits of a number in Racket are in random order

I decided to write a function that given a number will return a list containing the digits in that number, my attempt is:
(define (rev-digits n)
(if (= n 0)
'()
(cons (modulo n 10) (digits (quotient n 10)))))
(define (digits n)
(reverse (rev-digits n)))
The fact is, I need the digits to be in proper order, but the function returns, for example:
> (digits 1234567890)
'(9 7 5 3 1 2 4 6 8 0)
In seemingly random order... can you help me getting a more ordinated output?
rev-digits needs to call itself, not digits.
(define (rev-digits n)
(if (= n 0)
'()
(cons (modulo n 10) (rev-digits (quotient n 10)))))
(define (digits n)
(reverse (rev-digits n)))
should work.
It's worth noting that your "random" output was not in fact random; rather the digits were "bouncing" back and forth from the start to the end of the list. Which makes sense, because you were effectively switching back and forth between a "normal" and reversed version of your digits function.
The answer given by #JayKominek is spot-on and fixes the error in your code. To complement it, here's an alternative implementation:
(define (rev-digits n)
(let loop ((n n) (acc '()))
(if (< n 10)
(cons n acc)
(loop (quotient n 10) (cons (modulo n 10) acc)))))
The advantages of the above code are:
It's tail recursive and hence more efficient
It correctly handles the edge case when n is zero (your code returns an empty list)
It doesn't require a helper procedure, thanks to the use of a named let
It builds the list in the correct order, there's no need to reverse it at the end
A simple solution:
#lang racket
(define (digits n)
(for/list ([c (number->string n)])
(- (char->integer c) (char->integer #\0))))

Reverse the order of a given integer - Scheme

ive been given a task in Scheme (Dr Racket) to reverse to order of a given digit. The solution should be recursive, and this is what i got this far..
The truth is, im not quite sure if the given algorithm even works because i get:
" application: not a procedure;
expected a procedure that can be applied to arguments"
error every time i run it..
Any thoughts or help on the issue?
(define reverse-digits
(lambda (n) (if (> n 9)
(+ (* 10 (modulo n 10)) (reverse-digits (quotient n 10)))
(n))))
(reverse-digits 1234)
This is a HW assignment so I won't give you code.
Your problem is that multiplying (modulo n 10) by 10 doesn't get you to the position you need to be in. Consider (reverse-digits 123):
(reverse-digits 123)
(+ 30 (reverse-digits 12))
(+ 30 (+ 20 (reverse-digits 1)))
(+ 30 (+ 20 1))
51
What you want is to multiply it by a different power of 10 every time depending on the length of the number. You could either make a function that calculates the length of the number (possibly by repeatedly dividing the number by 10 and keeping track of how many times it did that) or passing along the length of the number (possibly by creating another function that takes the number n as an argument and calculates the length, then passes it along to your function which will then subtract 1 from length every recursive call.
What you would then get is something like this:
(reverse-digits 123)
(+ 300 (reverse-digits 12))
(+ 300 (+ 20 (reverse-digits 1)))
(+ 300 (+ 20 1))
321
The error you're getting is because in your else-case, you do (n). As n is not a procedure, you get an error. You just want n instead.
Are you bound to using specific procedures ? If not, there's an alternative to using modulo and adding numbers. It's about using list procedures such as
number->string
take
list->string
and so on.
This is my solution, it is not very efficient!
(define
invert-number-aux (λ (n res)
(if (empty? n) res
(invert-number-aux
(take n (-(length n) 1)) ;new n
(append res (list (last n))) ;new res
)
)))
(define
invert-number (λ (n)
(string->number (list->string (invert-number-aux (string->list(number->string n)) '())))
))
It will be helpful to use smaller helper functions.
Here is one way to split the task in smaller parts:
; number->digits : natural -> list-of-digits
(define (number->digits n)
...)
; digits->number : list-of-digits -> natural
(define (number->digits n)
...)
With these helpers you can write:
(define (reverse-number x)
(digits->number
(reverse
(number->digits x))))
Also - if you want to the error " application: not a procedure; expected a procedure that can be applied to arguments" replace (n) with n.
If you run your program in DrRacket, the application (n) ought to be colored red. The problem is that (42) means evaluate 42 and then call the result as if is a function. Since 42 is a number, you get the error.
Its important to understand that fixnums don't have just one representation and what the different digits are of a number might change with the base of its representation. Here is my take on it.
(define (number->digits number (base 10))
(let loop ((n number) (acc '()))
(if (zero? n)
acc
(let-values (((res rem) (quotient/remainder n base)))
(loop res (cons rem acc))))))
(define (list->number lst (base 10))
(foldl (lambda (x acc)
(+ (* acc base) x))
0
lst))
(define (reverse-digits number (base 10))
(list->number (reverse (number->digits number base))
base))
(number->string (reverse-digits #b100111 #b10) #b10) ; ==> "111001" (or 39 => 57 in base 10)
(number->string (reverse-digits #xebabefac #x10) #x10) ; ==> "cafebabe" (or 3953913772 => 3405691582 in base 10)
(number->string (reverse-digits 1234)) ; ==> 4321

Resources