Decimal to Binary in Lisp - make a non-nested list - list

When reaching my recursion cases, I use list to append the future result with the current one, but I end up with a nested list because of recursion. This causes an error when I have a number that causes recursion for more than five times.
Any ideas how I can get results in a single plain non-nested list, e.g.:
CL-USER 100 : 8 > (BINARY_LIST 4)
(1 0 0)
Code & Example output:
CL-USER 99 : 8 > (defun binary_list (i)
(COND
((= i 0) 0)
((= i 1) 1)
((= (mod i 2) 0) (list (binary_list (truncate i 2)) 0))
(t (list (binary_list (truncate i 2)) 1))
)
)
BINARY_LIST
CL-USER 100 : 8 > (BINARY_LIST 4)
((1 0) 0)
CL-USER 101 : 8 > (BINARY_LIST 104)
((((# 1) 0) 0) 0)

You are almost there. All you need to do is to replace list with nconc:
(defun binary-list (n)
(cond ((= n 0) (list 0))
((= n 1) (list 1))
(t (nconc (binary-list (truncate n 2)) (list (mod n 2))))))
You can avoid calling both truncate and mod by collecting both values in integer division:
(defun binary-list (n)
(assert (>= n 0))
(multiple-value-bind (q r) (floor n 2)
(if (zerop q)
(list r)
(nconc (binary-list q) (list r)))))
Note that this algorithm is quadratic because nconc has to traverse the result on each iteration. This can be avoided by passing an accumulator:
(defun binary-list (n &optional acc)
(assert (>= n 0))
(multiple-value-bind (q r) (floor n 2)
(if (zerop q)
(cons r acc)
(binary-list q (cons r acc)))))
Now we have a tail-recursive function which can be compiled to iteration by a modern compiler.
One more optimization trick you could use (which, in fact, should be done by the compiler - try disassemble to check!) is using ash and logand instead of the much more general and expensive floor:
(defun binary-list (n &optional acc)
(cond ((zerop n) (or acc (list 0)))
((plusp n)
(binary-list (ash n -1) (cons (logand 1 n) acc)))
(t (error "~S: non-negative argument required, got ~s" 'binary-list n))))
Incidentally, lispers usually use dash instead of underscores in symbols, so your binary_list should be binary-list if you do not want to offend our tender aesthetics.

this seems to me to be the most direct, least roundabout manner to achieve the desired results every time:
(defun mvp-binary-from-decimal (n r)
(if (zerop n)
r
(multiple-value-bind (a b)
(floor n 2)
(mvp-binary-from-decimal a (cons b r)))))
(defun binary-from-decimal (n)
(if (and (numberp n) (plusp n))
(mvp-binary-from-decimal n '())
(if (eql n 0) '(0) nil)))
tested in slime, sbcl, clisp - used as follows:
CL-USER> (binary-from-decimal 100)
(1 1 0 0 1 0 0)
CL-USER> (binary-from-decimal 10)
(1 0 1 0)
CL-USER> (binary-from-decimal 0)
(0)
there are some advanced reasons as to why this might be the most desirable manner in which to implement such functionality, but for now, suffice to say that it is clean, polite, readable and always works.

Related

how to make a recursive racket list that, from the input list, outputs its decreasing to 1 for every element in the list (e.g. ('3 2) outputs ('32121)

****What I tried****
(define(help num)
(if(= num 1)
num
(cons(num (help( - num 1))))))
;i called this defination in the bottom one
(define (list-expand L)
(cond
[(empty? L)'()]
[(=(car L)1)(cons(car L)(list-expand (cdr L)))]
[(>(car L)1) (cons(help(car L)(list-expand(cdr L))))]))
In the help procedure, the base case is incorrect - if the output is a list then you must return a list. And in the recursive step, num is not a procedure, so it must not be surrounded by brackets:
(define (help num)
(if (<= num 0)
'()
(cons num (help (- num 1)))))
And in list-expand, both recursive steps are incorrect. You just need to test whether the list is empty or not, calling help with the correct number of parameters; use append to combine the results, because we're concatenating sublists together:
(define (list-expand L)
(if (empty? L)
'()
(append (help (car L)) (list-expand (cdr L)))))
That should work as expected, but please spend some time studying Scheme's syntax, you still have trouble with the basics, for instance, when and where to use brackets...
(list-expand '(3 2))
=> '(3 2 1 2 1)
Just for fun - a non-recursive solution in Racket:
(append-map (lambda (n) (stream->list (in-range n 0 -1))) '(3 2))
;; or:
(append-map (lambda (n) (for/list ((x (in-range n 0 -1))) x)) '(3 2))
Returning:
'(3 2 1 2 1)

Concatenating list elements - Scheme

If i have a scheme code that generates the following result: (i'm using cons)
'((1 . 0) . 0)
How can i take this, and just simply display 100 as if it were just one integer number and not a list presented with those dots and parenthesis?
Thanks!
EDIT:
my full code:
(define (func X)
(if ( <= X 3 )
X
(cons (modulo X 4) (func(floor(/ X 4)) ))
))
If I understand correctly, you're trying to convert a number from base 10 to base 4, and then display it as a number, but there are several problems with your implementation.
You're building a list as output - but that's not what you want, you want a number. Also, you're traversing the input in the wrong order, and that's not the correct way to find the quotient between two numbers. Perhaps this will help:
(define (func X)
(let loop ((n X) (acc 0) (mult 1))
(if (< n 4)
(+ (* mult n) acc)
(loop (quotient n 4)
(+ (* mult (modulo n 4)) acc)
(* mult 10)))))
Alternatively, you could output a string to stress the fact that the output is not in base 10:
(define (func X)
(let loop ((n X) (acc ""))
(if (< n 4)
(string-append (number->string n) acc)
(loop (quotient n 4)
(string-append (number->string (modulo n 4)) acc)))))
It'll work as expected:
(func 16)
=> 100
Oscar Lopez's answer is excellent. I can't help adding that this problem doesn't need the "loop" construct:
;; translate a string to a base-4 string.
(define (func n)
(cond [(< n 4) (number->string n)]
[else (string-append (func (quotient n 4))
(number->string (modulo n 4)))]))

Curry-Skip Scheme

I have to write a scheme function called curry-skip that recursively that returns the nth element of a list such that
(((curry-skip 1) 'foo) 'bar) => bar
I can't seem to figure out how to do this recursively. I'm still fairly new to Scheme, so any help would be much appreciated!
Thanks
I wrote the following after looking at your example. It seemed fairly simple and as such I can't explain by what reasoning it came to be.
(define (curry-skip n)
(lambda (v) (if (= n 0)
v
(curry-skip (- n 1)))))
I think you have 3 cases here:
n>0 - you recurse down until n=0
n=0 - you memorize the argument, because that's the final value you need to return; memorization is done via a closure
else - ignore parameters until done, then finally return the memorized value
so
(define (res val) ; [procedure used for case 2 - n=0]
(define (res0 . x) (if (null? x) val res0)) ; [case 3]
res0)
(define (curry-skip n)
(cond
((< n 0) (error "n is negative"))
((= n 0) res) ; [case 2 - n = 0]
(else (lambda x (curry-skip (- n 1)))))) ; [case 1 - n > 0]
then
-> (((curry-skip 0) 'foo))
'foo
-> ((((curry-skip 0) 'foo) 'bar))
'foo
-> ((((curry-skip 1) 'foo) 'bar))
'bar
-> (((((curry-skip 0) 'foo) 'bar) 'baz))
'foo
-> (((((curry-skip 1) 'foo) 'bar) 'baz))
'bar
-> (((((curry-skip 2) 'foo) 'bar) 'baz))
'baz
Compared to your question my solution has got an extra pair of parentheses but that's as close as I could get.
(define (curry-skip n)
(if (zero? n)
(lambda (x) x)
(let ((rest (curry-skip (- n 1))))
(lambda (x) rest))))
You want to compute the (- n 1) cases outside of the returned lambda! So, in the above, when n is zero just return the one argument lambda; but, when n is positive, compute the (- n 1) case and return a lambda that ignores its argument and just returns the rest.
Note that, although not part of your question but related to a comment, if you needed a true curry, like in ML, you would need syntactic help as:
(define-syntax curry*
(syntax-rules ()
((_ (a) body ...) (lambda (a) body ...))
((_ (a b ...) body ...)
(lambda (a) (curry* (b ...) body ...)))))
Notice how the recursion creates lexical environments for each of a, b, … so that body can be properly evaluated. The curry-skip doesn't have such a need.
Here is some code addressing the comment about doing the 'curry-skip' inside the returned lambda. Doing the recursion outside of the lambda happens only once creating one closure; doing it inside the lambda creates closures on each invocation.
(define (curry-skip-o n)
(if (zero? n)
(lambda (x) x)
(let ((rest (curry-skip-o (- n 1))))
(lambda (x) rest))))
(define (curry-skip-i n)
(if (zero? n)
(lambda (x) x)
(lambda (x) (curry-skip-i (- n 1)))))
(define (run skipper r n)
(let ((f (skipper n)))
;; Repeat 'r' times with 'f'
(let rep ((r r))
(unless (zero? r)
;; Exhaust f
(let rep ((i 0) (f f))
(if (< i n)
(rep (+ i 1) (f i))
(f 0)))
(rep (- r 1))))))
> (time (run curry-skip-o 10000 10000)) ;; create ~10^4 closures
running stats for (run curry-skip-o 10000 10000):
no collections
376 ms elapsed cpu time, including 0 ms collecting
376 ms elapsed real time, including 0 ms collecting
160032 bytes allocated
> (time (run curry-skip-i 10000 10000)) ;; create ~10^8 closures
running stats for (run curry-skip-i 10000 10000):
191 collections
1587 ms elapsed cpu time, including 965 ms collecting
1588 ms elapsed real time, including 966 ms collecting
1599840048 bytes allocated

Create list from 2 numbers and 2 for loops

I have 2 numbers let's say number1=5 and number2=3 and I want to create a list in this form
((1(1 2 3)) (2(1 2 3)) (3(1 2 3)) (4(1 2 3)) (5(1 2 3)))
So the number1 indicates the number of the elements in the list and number2 indicates the total elements that will be as the second part of every element..
I have smth like this untill now
(define mylist '())
(define (pushlist item item2)
(do ((j 1 (+ j 1))) ((> j item2))
(set! mylist(list mylist (list item j)))))
(define (createlist number number2)
(do ((j 1 (+ j 1))) ((> j number))
(pushlist j number2)
))
(createlist 5 3)
Unfortunately it doesn't work.. It doesn't give the result I want.. It gives me this (((((((((((((((() (1 1)) (1 2)) (1 3)) (2 1)) (2 2)) (2 3)) (3 1)) (3 2)) (3 3)) (4 1)) (4 2)) (4 3)) (5 1)) (5 2)) (5 3))
There are many ways to solve this problem - for example, using explicit recursion, or using higher-order procedures. Your approach is not recommended, in Scheme you should try to avoid thinking about loops and mutation operations. Although it is possible to write such a solution, it won't be idiomatic. I'll try to explain how to write a more idiomatic solution, using explicit recursion first:
; create a list from i to n
(define (makelist i n)
(if (> i n)
'()
(cons i (makelist (add1 i) n))))
; create a list from i to m, together with
; a list returned by makelist from 1 to n
(define (makenumlist i m n)
(if (> i m)
'()
(cons (list i (makelist 1 n))
(makenumlist (add1 i) m n))))
; call previous functions
(define (createlist number1 number2)
(makenumlist 1 number1 number2))
Now, an even more idiomatic solution would be to use higher-order procedures. This will work in Racket:
; create a list from i to n
(define (makelist n)
(build-list n add1))
; create a list from i to m, together with
; a list returned by makelist from 1 to n
(define (makenumlist m n)
(build-list m
(lambda (i)
(list (add1 i) (makelist n)))))
; call previous functions
(define (createlist number1 number2)
(makenumlist number1 number2))
See how we can avoid explicit looping? that's the Scheme way of thinking, the way you're expected to solve problems - embrace it!
I don't think that your pushlist procedure is doing what you you expect it to.
(define (pushlist item item2)
(do ((j 1 (+ j 1)))
((> j item2))
(set! mylist (list mylist (list item j)))))
If you have a list (x y z) and you want to push a new value v into it, you'd do
(set! lst (cons v lst))
because (cons v (x y z)) == (v x y z). By doing
(set! mylist (list mylist (list item j)))
you're making mylist always have exactly two elements, where the first is a deeper and deeper nested list. Óscar López's answer gives a more idiomatic approach to this problem. Here's a similar idiomatic approach:
(define (range n)
; returns a list (1 ... n)
(let rng ((n n) (l '()))
(if (zero? n)
l
(rng (- n 1) (cons n l)))))
If the sublists (1 ... n) can all be the same list (i.e., the actual list object is the same), then you can create it just once:
(define (createlist m n)
(let ((sublist (range n)))
(map (lambda (main)
(list main sublist))
(range m))))
Otherwise, if they need to be distinct, you can generate one for each of 1 ... m:
(define (createlist m n)
(map (lambda (main)
(list main (range n)))
(range m)))

Scheme number to list

I need a subroutine for my program written in scheme that takes an integer, say 34109, and puts it into a list with elements 3, 4, 1, 0, 9. The integer can be any length. Does anyone have a trick for this? I've thought about using modulo for every place, but I don't think it should be that complicated.
The simplest way I can think of, is by using arithmetic operations and a named let for implementing a tail-recursion:
(define (number->list num)
(let loop ((num num)
(acc '()))
(if (< num 10)
(cons num acc)
(loop (quotient num 10)
(cons (remainder num 10) acc)))))
Alternatively, you can solve this problem using string operations:
(define char-zero (char->integer #\0))
(define (char->digit c)
(- (char->integer c) char-zero))
(define (number->list num)
(map char->digit
(string->list (number->string num))))
This can be compressed into a single function, but I believe it's easier to understand if we split the problem in subparts as above.
(define (number->list num)
(map (lambda (c) (- (char->integer c) (char->integer #\0)))
(string->list
(number->string num))))
Anyway, the results are as expected:
(number->list 34109)
> '(3 4 1 0 9)
Something like this:
(define (num2list-helper num lst)
(cond ((< num 10) (cons num lst))
(else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))
(define (num2list num)
(num2list-helper num '()))
(num2list 1432)
As itsbruce commented you can hide helper function inside main one:
(define (num2list num)
(define (num2list-helper num lst)
(cond ((< num 10) (cons num lst))
(else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))
(num2list-helper num '()))
(num2list 1432)
to be continued...
I'm not a fan of manual looping, so here's a solution based on unfold (load SRFI 1 and SRFI 26 first):
(define (digits n)
(unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))
This returns an empty list for 0, though. If you want it to return (0) instead, we add a special case:
(define (digits n)
(case n
((0) '(0))
(else (unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))))
Of course, you can generalise this for other bases. Here, I implement this using optional arguments, so if you don't specify the base, it defaults to 10:
(define (digits n (base 10))
(case n
((0) '(0))
(else (unfold-right zero? (cut modulo <> base) (cut quotient <> base) n))))
Different Scheme implementations use different syntaxes for optional arguments; the above uses Racket-style (and/or SRFI 89-style) syntax.