List of prime numbers from 2 to n (scheme) - list

I am trying to create a procedure which builds a list of prime numbers from 2 to any number n. Of course, this needs to be done iteratively, but I do not exactly know what I'm doing wrong.
(define (list-2-to-n n)
(define (iter n result)
(if (= n 0)
result
(if (< n 2)
'()
(if (= (remainder n 3) 0)
(list-2-to-n (- n 1))
(if (even? n)
(list-2-to-n (- n 1))
(iter (- n 1) (cons n result)))))))
(iter n '()))
Whenever test cases are passed through the procedure, it always returns ()

what I'm doing wrong.
Let's see. First of all, your indentation is woefully misleading. It really should correctly reflect the code's structure:
(define (list-2-to-n-0 n) ; a global function
(define (iter n result) ; an internal function
(if (= n 0)
result
(if (< n 2) ; **else**
'()
(if (= (remainder n 3) 0)
(list-2-to-n (- n 1))
(if (even? n) ; **else**
(list-2-to-n (- n 1))
(iter (- n 1) (cons n result)))))))
(iter n '()))
If not, at least you should've clearly marked the alternative clauses with some comments.
Now, you test whether the input number is divisible by 2 or 3, and respond in exactly the same manner. The two cases should really be joined then into one. Also, we can use cond here instead of so many nested ifs:
(define (list-2-to-n-1 n) ; a global function
(define (iter n result) ; an internal function
(cond
((= n 0) result)
((< n 2) '())
((or (= (remainder n 2) 0) (= (remainder n 3) 0))
(list-2-to-n (- n 1)) ; calling a global function, and
(else ; returning its result
(iter (- n 1) ; calling internal function, and
(cons n result))))) ; returning its result
(iter n '()))
Calling the global function there means starting the whole process anew - it will call its iter with the initial accumulator argument of (). Your supposedly result-returning case of n==0 is actually unreachable, for any initial value of n above 0, because the case n < 2 will be encountered first, and () will be returned (exactly the observed behaviour).
You shouldn't start anew i.e. you should always call the internal function. You should fix your base case. Last but not least, checking for divisibility by 2 or 3 only won't be enough, already for 5. So let's write isPrime there, and implement it later on:
(define (list-2-to-n-1 n) ; a global function
(define (iter n result) ; an internal function
(cond
((< n 2) result)
((not (isPrime n))
(iter (- n 1) result)) ; calling internal function, without
(else ; altering the accumulator
(iter (- n 1) ; calling internal function,
(cons n result))))) ; altering the accumulator
(iter n '()))
isPrime needs to try dividing n by 2,3,... Doesn't need to try dividing by any evens above 2, just odds will be enough. Doesn't need to try out any potential divisor d such that d * d > n, because if n = f * d, f <= d then f*d <= d*d i.e. n <= d*d.
Of course trying dividing by any composite like 9, 15, 77, is superfluous too - if any of those divide n then one of their prime factors 3, 5, 7, 11 divide it too, and we would detect them earlier. So actually, trying dividing by primes only is enough. To be able to do that, you need to restructure your code so that it builds its resulting list of primes in ascending order, and uses its prefix portion not greater than sqrt(k) to test each candidate k.
This is known as trial division algorithm. Then there's a much faster sieve of Eratosthenes.

Related

Find the longest integer in a vector using while loops

Working on this program that's supposed to take a vector of integers as input and return the one with the longest integer. Example (vector 20 738 5942 125) and would return 4 as its the longest one. I'm pretty sure I have most of this done the only issue I have is in the conditional as I have to call an outside function (count-integers), this is what I have so far:
(require while)
(define (empty-VINT? low high) (> low high))
(define (count-integers n)
(cond [(< n 10) 1]
(else(+ 1 (count-integers [/ n 10])))))
(define (count-digits V)
(local [
(define x (void))
(define accum (void))
(define largest 0)]
(begin
(set! x (vector-length V))
(set! accum 0)
(while (< accum (vector-length V))
(cond [(empty-VINT? x accum) accum]
[(> (count-integers (vector-ref V accum) largest)
(add1 x) accum(vector-ref V accum))]
[else add1 accum])))))
Right now when its run, I get this message: cond: expected a clause with a question and an answer, but found a clause with only one part. Any suggestions would be great, thanks
First of all, it's not clear what do you want to return. 4 isn't the longest integer (that's 5942), 4 is a maximal digit count among integers in given vector.
Secondly, your code isn't idiomatic and without your comment, it's very hard to say what's going on. Programming in functional languages requies functional way of thinking. Forget about while, set!, void, local and nested define and instead spend some time learning about apply, map, filter and foldl.
I would solve this problem like this:
(define (digits number)
(string-length (number->string number)))
(define (max-digit-count vec)
(apply max (map digits (vector->list vec))))
(max-digit-count (vector 20 738 5942 125))
=> 4
From comments:
Design and implement a function to find the number of digits in the longest integer in a (vectorof integer) ...
use ... while loops
So a plan (design) might be:
count-digits: integer -> natural
max-digit-count: (vectorof integer) -> natural
..something while something max count-digits something ???
Implementing count-digits seems straightforward (but
integers can be negative, and in Racket (integer? 123.000) is true).
#lang racket
(define (count-digits int) ;; Integer -> Natural
;; produce count of digits in int
(string-length (number->string (abs (exact-truncate int)))))
As #Gwang-Jin Kim mentions, while could be defined:
(define-syntax-rule (while condition body ...)
;; From: https://stackoverflow.com/questions/10968212/while-loop-macro-in-drracket
(let loop ()
(when condition
body ...
(loop))))
and then one could use it:
(define (max-digit-count vec) ;; VectorOfInteger -> Natural
;; produce maximum of digit counts of vec elements
(define vx 0)
(define acc 0)
(while (< vx (vector-length vec))
(set! acc (max accum (count-digits (vector-ref vec vx))))
(set! vx (add1 vx)))
acc)
(max-digit-count (vector 20 -738.00 5942 125)) ;=> 4
One of the problems with while is that it can't produce a value (where would it come
from if the condition is false on entry?)
If one "enhanced" while a bit:
(define-syntax-rule (while< x-id limit a-id a-init update)
;; "while loop" incrementing x-id from 0 to limit-1, updating a-id
(let loop ([x-id 0] [a-id a-init])
(if (< x-id limit)
(loop (add1 x-id) update)
a-id)))
max-digit-count could be neater:
(define (max-digit-count vec) ;; VectorOfInteger -> Natural
;; produce maximum of digit counts of vec elements
(while< vx (vector-length vec)
acc 0 (max acc (count-digits (vector-ref vec vx)))))
#MartinPuda's answer is quite good.
I would have defined:
(define (digits n (acc 0))
(if (< n 1)
acc
(digits (/ n 10) (+ acc 1))))
(define (max-digits lst)
(digits (car (sort lst >))))
To apply it:
(max-digits (vector->list (vector 20 738 5942 125)))
Why you should not use while
Using while would force you to mutate variable values. It is much more "natural" for lisp languages to follow the functional style (recursive functions instead of while loops or other loops) rather than the imperative style with mutation of variables.
That is why while is not in the lisp languages.
But if you want to use it:
(define-syntax-rule (while condition body ...)
;; From: https://stackoverflow.com/questions/10968212/while-loop-macro-in-drracket
(let loop ()
(when condition
body ...
(loop))))
(define (digits n (acc 0))
(cond ((< n 1) acc)
(else (digits (/ n 10) (+ acc 1)))))
(define (max-digits lst)
(let ((max-digit 0))
(while (not (null? lst))
(let ((digit (digits (car lst))))
(when (< max-digit digit)
(set! max-digit digit))
(set! lst (cdr lst))))
max-digit))
Then you can try:
> (max-digits (vector->list v))
4
> (max-digits '(1111 123456 2345 34))
6
Prefer let over define
Why? Because if you use let, you can control the scope of the to-be-mutated variable very precisely. You can define in your definition, from where on your variable canNOT have any effect on your code (since its scope ended at some point). While with define you don't have this fine-grained control. (Or this control is implicit not explicite like with let). You could delete/unbind the variable explicitely but that is rarely done in real life.
Therefore, in Lisp, for variable declarations use whenever possible let, especially whenever you deal with mutated variables.
All imperative = declarations should be in Lisp languages let expressions!
You can use function arguments instead of let-definitions, because they are anyway implemented using lets
Just you save syntactically some lines - and the fewer lines you occupy the cleaner the code.
#lang racket
(define (digits n)
(string-length (number->string n)))
(define (max-digit a b)
(if (< (digits a) (digits b)) b a))
(define (max-digits lst (res ""))
(while (not (null? lst))
(set! res (max-digit res (car lst)))
(set! lst (cdr lst)))
(digits res))

Creating a list of n elements in Scheme/lisp?

I am trying to create a list of n elements. It must produce this output:
(my-list 5)
>> 0 1 2 3 4
I have the function below:
(define (my-list n)
(cond
((<= n 0) '())
(else (reverse-list (cons (- n 1)
(my-list(- n 1)))))
)
)
and this is producing
(my-list 10)
>>(8 6 4 2 0 1 3 5 7 9)
I understand this is due to reversing the list at every recursive call, but I am not sure what is the correct way. Also my reverse-list is working fine.
Thanks in advance!
A standard idiom in Scheme 'build-and-reverse' suggests you only reverse the list once, at the very end, when its reverse has been completely built (thus reducing the complexity down to O(N) from quadratic.)
So yes, you end up in a tail call to reverse but the list should be built without doing it. Scheme has plenty of local recursive binding constructs.
But.
If you build a range starting with the largest value (that should be one greater than the last element to the list) you don't need to reverse it in the end, at each iteration step you decrease a counter and prepend its new value to those already accumulated:
(define (range n)
(let rng ((m (- n 1)) (ret-val '())) ; named-let is very useful for small local recursive closures
(if (< m 0) ; that original (<= n 0) check is also handled here
ret-val ; here, the result is returned; note we don't need to reverse it
(rng (- m 1) (cons m ret-val))))))
(display (range 10))
(newline)
prints
(0 1 2 3 4 5 6 7 8 9)
Or, to demonstrate the build-and-reverse, we can start with the lowest value:
(define (range-asc n)
(let rng ((m 0) (ret-val '()))
(if (= m n)
(reverse ret-val) ; since we started from zero, we need to reverse it
(rng (+ m 1) (cons m ret-val)))))
(Looks like I still remember/can recover some Scheme. :-O)
First of all, your code. Properly formatted it should look something like:
(define (my-list n)
(cond ((<= n 0) '())
(else (reverse-list (cons (- n 1)
(my-list (- n 1)))))))
Problem you have, is reverse-list call. It happens every time you add new element to the list. You can fix it in many ways, but simple solution is to wrap your recursive code into local function, and do some additional operations (reverse in your case) when it returns.
(define (my-list n)
(define (build-list m)
(cond ((<= m 0) '())
(else (cons (- m 1)
(build-list (- m 1))))))
(reverse-list (build-list n)))
So, inside my-list function, first we define recursive part as a local function build-list. This is exactly your code, but with call to reverse-list removed. This part will build your list, but as you know, in reverse order. But that is no longer a problem, since we can reverse it when local function returns.

infinite sequence scheme to make infinite sequence

I have a project in scheme in which I need to implement an infinite sequence of numbers. I can't use any scheme-built-in complex functions, and I just do not know how to make my sequence infinite without program crashing in infinite loop. I don't have to really output it, but I need to be able to use it.
(seq n) ;;output: n,n+1,n+2,n+3.... to infinity (seq 5) ->5,6,7,8,9...
Right now I did a sequence until n+7, but I need this to infinity:
(define (seq n)
(define (asc-order LIST counter)
(cond ((= counter (+ n 7)) LIST)
(else (asc-order (append LIST (cons (+ counter 1) '()))
(+ counter 1)))))
(asc-order '() (- n 1))
)
IO example (It works, but I need it infinite sequence):
>(define s (seq 3))
>(car s)
3
You can represent an infinite sequence as a function that produces one element at a time. The user (consumer) can then call the function each a new element of the sequence is needed.
An example:
(define (f x) (* x x))
(define seq
(let ()
(define n 0) ; current index
(lambda () ; the function that is to be called repeatedly
(define a (f n)) ; compute the new element
(set! n (+ n 1)) ; compute new index
a))) ; return the new element
(seq) ; compute element 0
(seq) ; compute element 1
(seq) ; ...
(seq)
(seq)
(seq)
This evaluates to:
0
1
4
9
16
25
In order to write (sequence->list s n) which computes the first n elements of the sequence s, make a loop that calls s in total n times - and collect the results in a list.
The key is to delay evaluation of the list by wrapping a procedure around it.
Here's the simplest implementation I can think of.
It's only "lazy" in the tail.
(define (seq n)
(cons n (lambda () (seq (+ n 1)))))
(define (seq-car s)
(car s))
(define (seq-cdr s)
((cdr s)))
Example use:
; Get the 'n' first elements of 's'.
(define (seq-take n s)
(if (<= n 0)
'()
(cons (seq-car s) (seq-take (- n 1) (seq-cdr s)))))
> (define s (seq 10))
> s
'(10 . #<procedure>)
> (seq-take 5 s)
'(10 11 12 13 14)
Here is another solution using delayed evaluation:
(use-modules (ice-9 receive))
(define (seq f)
(let loop ((n 0))
(lambda ()
(values (f n) (loop (1+ n))))))
(define squares (seq (lambda (x) (* x x))))
(receive (square next) (squares)
(pk square) ;; => 0
(receive (square next) (next)
(pk square) ;; => 1
(receive (square next) (next)
(pk square) ;; => 4
(receive (square next) (next)
(pk square))))) ;; => 9

Decimal to Binary in Lisp - make a non-nested 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.

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.