Coercing numbers to lists in common lisp - common-lisp

I'd like to turn integers into lists. For example, 2245 => (2 2 4 5).
I dislike (coerce (write-to-string 2245) 'list) because it yields (#\2 #\2 #\4 #\5).
Help please?

(map 'list #'digit-char-p (prin1-to-string n))
works well.

(defun number-to-list (n)
(loop for c across (write-to-string n) collect (digit-char-p c)))
An alternative loop based solution.

Same as jon_darkstar but in common lisp. This fails for negative numbers, but trivial to amend.
(defun number-to-list (number)
(assert (and (integerp number)
(>= number 0)))
(labels ((number-to-list/recursive (number) (print number)
(cond
((zerop number)
nil)
(t
(cons (mod number 10)
(number-to-list/recursive (truncate (/ number 10))))))))
(nreverse (number-to-list/recursive number))))

Common Lisp implementation for non-negative integers:
(defun number-to-list (n &optional tail)
(if (zerop n)
(or tail '(0))
(multiple-value-bind (val rem)
(floor n 10)
(number-to-list val (cons rem tail)))))

I don't really use common lisp, but I'd do it like this in Scheme. hopefully that can help?
(define (number-to-list x)
(define (mod-cons x l)
(if (zero? x)
l
(mod-cons (quotient x 10) (cons (remainder x 10) l))))
(mod-cons x '()))
(number-to-list 1234)

A variation on #Mark Cox's solution that also includes the '-' sign in case of negative integers. Inspired by #Terje Norderhaug's amendment to #rhombidodecahedron's solution, where negative numbers are represented by including a negative sign before the digits.
(defun number-to-numlist (number)
"Converts an integer to a list of its digits. Negative numbers
are represented by a '-' sign prepended to the digits of its absolute value."
(assert (integerp number))
(labels ((collect-digits (number number-components list-of-numbers)
(setf number-components (multiple-value-list (floor number 10)))
(if (zerop number)
(or list-of-numbers '(0))
(collect-digits (first number-components) nil
(cons (second number-components) list-of-numbers)))))
(let ((number-list (collect-digits (abs number) nil nil)))
(if (< number 0)
(append '(-) number-list)
number-list))))

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.

How can I make my average function tail recursive in Lisp

I am simply trying to make this average function to be tail recursive. I have managed to get my function to work and that took some considerable effort. Afterwards I went to ask my professor if my work was satisfactory and he informed me that
my avg function was not tail recursive
avg did not produce the correct output for lists with more than one element
I have been playing around with this code for the past 2 hours and have hit a bit of a wall. Can anyone help me to identify what I am not understanding here.
Spoke to my professor he was != helpful
(defun avg (aList)
(defun sumup (aList)
(if (equal aList nil) 0
; if aList equals nil nothing to sum
(+ (car aList) (sumup (cdr aList)) )
)
)
(if
(equal aList nil) 0
; if aList equals nil length dosent matter
(/ (sumup aList) (list-length aList) )
)
)
(print (avg '(2 4 6 8 19))) ;39/5
my expected results for my test are commented right after it 39/5
So this is what I have now
(defun avg (aList &optional (sum 0) (length 0))
(if aList
(avg (cdr aList) (+ sum (car aList))
(+ length 1))
(/ sum length)))
(print (avg '(2 4 6 8 19))) ;39/5
(defun avg (list &optional (sum 0) (n 0))
(cond ((null list) (/ sum n))
(t (avg (cdr list)
(+ sum (car list))
(+ 1 n)))))
which is the same like:
(defun avg (list &optional (sum 0) (n 0))
(if (null list)
(/ sum n)
(avg (cdr list)
(+ sum (car list))
(+ 1 n))))
or more similar for your writing:
(defun avg (list &optional (sum 0) (n 0))
(if list
(avg (cdr list)
(+ sum (car list))
(+ 1 n))
(/ sum n)))
(defun avg (lst &optional (sum 0) (len 0))
(if (null lst)
(/ sum len)
(avg (cdr lst) (incf sum (car lst)) (1+ len))))
You could improve your indentation here by putting the entire if-then/if-else statement on the same line, because in your code when you call the avg function recursively the indentation bleeds into the next line. In the first function you could say that if the list if null (which is the base case of the recursive function) you can divide the sum by the length of the list. If it is not null, you can obviously pass the cdr of the list, the sum so far by incrementing it by the car of the list, and then increment the length of the list by one. Normally it would not be wise to use the incf or 1+ functions because they are destructive, but in this case they will only have a localized effect because they only impact the optional sum and len parameters for this particular function, and not the structure of the original list (or else I would have passed a copy of the list).
Another option would be to use a recursive local function, and avoid the optional parameters and not have to compute the length of the list on each recursive call. In your original code it looks like you were attempting to use a local function within the context of your avg function, but you should use the "labels" Special operator to do that, and not "defun":
(defun avg (lst)
(if (null lst)
0
(labels ((find-avg (lst sum len)
(if (null lst)
(/ sum len)
(find-avg (cdr lst) (incf sum (car lst)) len))))
(find-avg lst 0 (length lst))))
I'm not 100% sure if your professor would want the local function to be tail-recursive or if he was referring to the global function (avg), but that is how you could also make the local function tail-recursive if that is an acceptable remedy as well. It's actually more efficient in some ways, although it requires more lines of code. In this case a lambda expression could also work, BUT since they do not have a name tail-recursion is not possibly, which makes the labels Special operator is useful for local functions if tail-recursion is mandatory.

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))))

Arithmetic Recursion

I'm a beginner to scheme and I'm trying to learn some arithmetic recursion. I can't seem to wrap my head around doing this using scheme and producing the correct results. For my example, I'm trying to produce a integer key for a string by doing arithmetic on each character in the string. In this case the string is a list such as: '(h e l l o). The arithmetic I need to perform is to:
For each character in the string do --> (33 * constant + position of letter in alphabet)
Where the constant is an input and the string is input as a list.
So far I have this:
(define alphaTest
(lambda (x)
(cond ((eq? x 'a) 1)
((eq? x 'b) 2))))
(define test
(lambda (string constant)
(if (null? string) 1
(* (+ (* 33 constant) (alphaTest (car string))) (test (cdr string)))
I am trying to test a simple string (test '( a b ) 2) but I cannot produce the correct result. I realize my recursion must be wrong but I've been toying with it for hours and hitting a wall each time. Can anyone provide any help towards achieving this arithmetic recursion? Please and thank you. Keep in mind I'm an amateur at Scheme language :)
EDIT
I would like to constant that's inputted to change through each iteration of the string by making the new constant = (+ (* 33 constant) (alphaTest (car string))). The output that I'm expecting for input string '(a b) and constant 2 should be as follows:
1st Iteration '(a): (+ (* 33 2) (1)) = 67 sum = 67, constant becomes 67
2nd Iteration '(b): (+ (* 33 67) (2)) = 2213 sum = 2213, constant becomes 2213
(test '(a b) 2) => 2280
Is this what you're looking for?
(define position-in-alphabet
(let ([A (- (char->integer #\A) 1)])
(λ (ch)
(- (char->integer (char-upcase ch)) A))))
(define make-key
(λ (s constant)
(let loop ([s s] [constant constant] [sum 0])
(cond
[(null? s)
sum]
[else
(let ([delta (+ (* 33 constant) (position-in-alphabet (car s)))])
(loop (cdr s) delta (+ sum delta)))]))))
(make-key (string->list ) 2) => 0
(make-key (string->list ab) 2) => 2280
BTW, is the procedure supposed to work on strings containing characters other than letters—like numerals or spaces? In that case, position-in-alphabet might yield some surprising results. To make a decent key, you might just call char->integer and not bother with position-in-alphabet. char->integer will give you a different number for each character, not just each letter in the alphabet.
(define position-in-alphabet
(let ([A (- (char->integer #\A) 1)])
(lambda (ch)
(- (char->integer (char-upcase ch)) A))))
(define (test chars constant)
(define (loop chars result)
(if (null? chars)
result
(let ((r (+ (* 33 result) (position-in-alphabet (car chars)))))
(loop (rest chars) (+ r result)))))
(loop chars constant))
(test (list #\a #\b) 2)
Here's a solution (in MIT-Gnu Scheme):
(define (alphaTest x)
(cond ((eq? x 'a) 1)
((eq? x 'b) 2)))
(define (test string constant)
(if (null? string)
constant
(test (cdr string)
(+ (* 33 constant) (alphaTest (car string))))))
Sample outputs:
(test '(a) 2)
;Value: 67
(test '(a b) 2)
;Value: 2213
I simply transform the constant in each recursive call and return it as the value when the string runs out.
I got rid of the lambda expressions to make it easier to see what's happening. (Also, in this case the lambda forms are not really needed.)
Your test procedure definition appears to be broken:
(define test
(lambda (string constant)
(if (null? string)
1
(* (+ (* 33 constant)
(alphaTest (car string)))
(test (cdr string)))
Your code reads as:
Create a procedure test that accepts two arguments; string and constant.
If string is null, pass value 1, to end the recursion. Otherwise, multiply the following values:
some term x that is = (33 * constant) + (alphaTest (car string)), and
some term y that is the output of recursively passing (cdr string) to the test procedure
I don't see how term y will evaluate, as 'test' needs two arguments. My interpreter threw an error. Also, the parentheses are unbalanced. And there's something weird about the computation that I can't put my finger on -- try to do a paper evaluation to see what might be getting computed in each recursive call.

Resources