I'm new to scheme and having difficulty understanding vectors in scheme. I need to create a function that calculates the number of non-zero inputs in
a vector. I need to do this by not converting the vector into a list.
For exampl3.
(non-zero-dim #(3 0 2 4 0 2))
returns 4
My code so far is
(define non-zero-input
(lambda (vector)
(let ((size (vector-length vector)))
do ((position 0 (+ position 1))
(total 0
(if ((not (zero? vector-ref vector position)))
(+ total 1))
(((= position size) total)))))))
However I'm getting this error :do: bad syntax in: (do ((position 0 (+ position 1)) (total 0 (if ((not (zero? vector-ref vector position))) (+ total 1)) (((= position size) total))
How do i fix this error ?
Using the built-in procedures vector-length and vector-filter-not, you can simplify your function as:
(define (non-zero-dim vec)
(vector-length (vector-filter-not zero? vec)))
For example,
> (non-zero-dim #(3 0 2 4 0 2))
4
Some things to consider:
Keep track of your brackets. For example, (zero? vector-ref vector position) should be (zero? (vector-ref vector position)), whereby arity of zero? is one, and arity of vector-ref is two. Similarly with do ... vs. (do ... etc.
if statements must have an else clause (ie. (if condition then else)). For example, (if true 1) would fail, but (if true 1 2) would pass. Hence, (if ((not (zero? vector-ref vector position))) (+ total 1)) would fail.
The racket/vector package has vector-count, which returns the number of elements of a vector that satisfy a given predicate. This makes counting the non-zero values trivial:
#lang racket/base
(require racket/function racket/vector)
(define (non-zero-dim vec)
(vector-count (negate zero?) vec))
(println (non-zero-dim #(3 0 2 4 0 2)) ; 4
Related
I'm still pretty fresh to Racket so a bit confused about this, i've created a drop-divisible and sieve-with function as shown below with some help but now need to use both to create a single function that finds all prime numbers with a given length of a list.
(define (drop-divisible x lst)
(cond
[(empty? lst) empty]
[(or (= x (first lst)) (< 0 (remainder (first lst) x)))
(cons (first lst) (drop-divisible x (rest lst)))]
[else (drop-divisible x (rest lst))]))
(define (sieve-with divisors lst)
(foldl (lambda (e acc) (drop-divisible e acc))
lst divisors))
this is one of the test cases i need to pass
(module+ test
(check-equal? (sieve 10) (list 2 3 5 7)))
so far ive tried to create a list using the parameter given with sieve to create a list of that size.
(define (sieve lst)
((sieve-with () (build-list (sub1 lst) (+ values 2)))))
getting stuck on how to get the divisors from just 10 in the test case. Thanks
So your code has to pass the test
(check-equal? (sieve 10) (list 2 3 5 7))
This means, first, that (sieve 10) must be a valid call, and second, that it must return (list 2 3 5 7), the list of primes up to 10. 10 is a number,
(define (sieve n)
... so what do we have at our disposal? We have a number, n which can be e.g. 10; we also have (sieve-with divisors lst), which removes from lst all numbers divisible by any of the numbers in divisors. So we can use that:
(sieve-with (divisors-to n)
(list-from-to 2 n)))
list-from-to is easy to write, but what about divisors-to? Before we can try implementing it, we need to see how this all works together, to better get the picture of what's going on. In pseudocode,
(sieve n)
=
(sieve-with (divisors-to n)
(list-from-to 2 n))
=
(sieve-with [d1 d2 ... dk]
[2 3 ... n])
=
(foldl (lambda (d acc) (drop-divisible d acc))
[2 3 ... n] [d1 d2 ... dk])
=
(drop-divisible dk
(...
(drop-divisible d2
(drop-divisible d1 [2 3 ... n]))...))
So evidently, we can just
(define (divisors-to n)
(list-from-to 2 (- n 1)))
and be done with it.
But it won't be as efficient as it can be. Only the prime numbers being used as the divisors should be enough. And how can we get a list of prime numbers? Why, the function sieve is doing exactly that:
(define (divisors-to n)
(sieve (- n 1)))
Would this really be more efficient though, as we've intended, or less efficient? Much, much, much less efficient?......
But is (- n 1) the right limit to use here? Do we really need to test 100 by 97, or is testing just by 7 enough (because 11 * 11 > 100)?
And will fixing this issue also make it efficient indeed, as we've intended?......
So then, we must really have
(define (divisors-to n)
(sieve (the-right-limit n)))
;; and, again,
(define (sieve n)
(sieve-with (divisors-to n)
(list-from-to 2 n)))
So sieve calls divisors-to which calls sieve ... we have a vicious circle on our hands. The way to break it is to add some base case. The lists with upper limit below 4 already contain no composite numbers, namely, it's either (), (2), or (2 3), so no divisors are needed to handle those lists, and (sieve-with '() lst) correctly returns lst anyway:
(define (divisors-to n)
(if (< n 4)
'()
(sieve (the-right-limit n))))
And defining the-right-limit and list-from-to should be straightforward enough.
So then, as requested, the test case of 10 proceeds as follows:
(divisors-to 10)
=
(sieve 3) ; 3*3 <= 10, 4*4 > 10
=
(sieve-with (divisors-to 3)
(list-from-to 2 3))
=
(sieve-with '() ; 3 < 4
(list 2 3))
=
(list 2 3)
and, further,
(sieve 100)
=
(sieve-with (divisors-to 100)
(list-from-to 2 100))
=
(sieve-with (sieve 10) ; 10*10 <= 10, 11*11 > 10
(list-from-to 2 100))
=
(sieve-with (sieve-with (divisors-to 10)
(list-from-to 2 10))
(list-from-to 2 100))
=
(sieve-with (sieve-with (list 2 3)
(list-from-to 2 10))
(list-from-to 2 100))
=
(sieve-with (drop-divisible 3
(drop-divisible 2
(list-from-to 2 10)))
(list-from-to 2 100))
=
(sieve-with (drop-divisible 3
(list 2 3 5 7 9))
(list-from-to 2 100))
=
(sieve-with (list 2 3 5 7)
(list-from-to 2 100))
just as we wanted.
I guess this is an assignment 1 from CS2613. It would be helpful to add an exact description of your problems:
Q1: drop-divisible
Using (one or more) higher order functions filter,
map, foldl, foldr (i.e. no explicit recursion), write a function
drop-divisible that takes a number and a list of numbers, and returns
a new list containing only those numbers not "non-trivially
divisible". In particular every number trivially divides itself, but
we don't drop 3 in the example below.
You are required to write drop-divisible using higher order functions (map, filter, foldl and so on), with no explicit recursion. Your drop-divisible is definitely recursive (and probably copied from this question).
Q2: sieve-with
Using drop-divisible and explicit recursion write a
function that takes a list of divisors, a list of numbers to test, and
applies drop-divisible for each element of the list of divisors.
Q3: sieve
Impliment a function sieve that uses sieve-with to find all
prime numbers and most n. This should be a relatively simple wrapper
function that just sets up the right arguments to sieve-with. Note
that not all potential divisors need to be checked, you can speed up
your code a lot by stopping at the square root of the number you are
testing.
Function sieve will call sieve-with with two arguments: a list of divisors and a list of all numbers to be sieved. You will need function range to create these lists and also sqrt to get the square root of the given number.
How can I check if a relation represented as a matrix (list of lists) is antisymmetric?
For example, the function should return true for;
(antisymm ((1 1 0) (0 0 1) (0 0 0)))
Example:
(antisymm ((1 1 0) (0 0 1) (0 0 0))) returns #t
(antisymm ((1 1 0) (0 0 1) (0 1 0))) returns #f
If you are going to be dealing with matrices (or any data type) the first thing to do is to write some abstractions. Matrices are not lists of lists: they might be represented as lists of lists, but they're matrices.
So let's assume some abstractions which I will not write:
matrix-rows tells you how many rows a matrix has;
matrix-cols tells you how many columns a matrix has;
matrix-ref retrieves an element of a matrix.
I will also assume zero-based indexing (which is not what mathematicians assume).
You might also want a make-matrix function.
Then it is relatively easy to write a symmetry checker:
(define (symmetry-test? m symmetry-predicate?)
;; Zero-based indexing assumed
(define max-row (- (matrix-rows m) 1))
(define max-col (- (matrix-cols m) 1))
(cond
((not (= max-row max-col))
(error "not square"))
((= max-row 0)
;; 1x1 is symmetric by definition
#t)
(else
(let check ((row 1)
(col 0))
;; Note we need to check diagonal elts for skew case
(cond
((> col max-col)
#t)
((> col row)
(check (+ row 1) 0))
((symmetry-predicate? (matrix-ref m row col)
(matrix-ref m col row))
(check row (+ col 1)))
(else
#f))))))
And now
(define (matrix-symmetric? m)
;; a matrix is symmetric if a[r,c] = a[c,r] for all r, c
(symmetry-test? m =))
(define (matrix-skew? m)
;; a matrix is skew is a[r,c] = - a[c,r] for all r, c
(symmetry-test? m (λ (a b) (= a (- b)))))
For additional bonus points: why does this show that a list of lists is an absolutely terrible representation for a matrix?
I need some help :D.
I have written this procedure that turns a string into a list of numbers:
(define (string->encodeable string)
(map convert-to-base-four (map string->int (explode string))))
I need a function that does the exact opposite. In other words, takes a list of a list of numbers in base 4, turn it into base 10, and then creates a string. Is there a "creative" way to reverse my function or do I have to write every opposite step again. Thank you so much for your help.
A standard Scheme implementation using SRFI-1 List library
#!r6rs
(import (rnrs base)
(only (srfi :1) fold))
(define (base4-list->number b4l)
(fold (lambda (digit acc)
(+ digit (* acc 4)))
0
b4l))
(base4-list->number '(1 2 3))
; ==> 27
It works the same in #lang racket but then you (require srfi/1)
PS: I'm not entirely sure if your conversion from base 10 to base 4 is the best solution. Imagine the number 95 which should turn into (1 1 3 3). I would have done it with unfold-right in SRFI-1.
Depends on how you define "creative". In Racket you could do something like this:
(define (f lst)
(number->string
(for/fold ([r 0]) ([i (in-list lst)])
(+ i (* r 4)))))
then
> (f '(1 0 0))
"16"
> (f '(1 3 2 0 2 1 0 0 0))
"123456"
The relationship you're looking for is called an isomorphism
The other answers here demonstrate this using folds but at your level I think you should be doing this on your own – or at least until you're more familiar with the language
#lang racket
(define (base10 ns)
(let loop ((ns ns) (acc 0))
(if (empty? ns)
acc
(loop (cdr ns) (+ (car ns)
(* 4 acc))))))
(displayln (base10 '(3 0))) ; 12
(displayln (base10 '(3 1))) ; 13
(displayln (base10 '(3 2))) ; 14
(displayln (base10 '(3 3))) ; 15
(displayln (base10 '(1 0 0))) ; 16
(displayln (base10 '(1 3 2 0 2 1 0 0 0))) ; 123456
#naomik's answer mentioned isomorphisms. When you construct an isomorphism, you're constructing a function and its inverse together. By composing and joining isomorphisms together, you can construct both directions "at once."
;; Converts between a base 4 list of digits (least significant first, most
;; significant last) and a number.
(define iso-base4->number
(iso-lazy
(iso-cond
;; an iso-cond clause has an A-side question, an A-to-B isomorphism,
;; and a B-side question. Here the A-side is empty and the B-side is
;; zero.
[empty? (iso-const '() 0) zero?]
;; Here the A-side is a cons, and the B-side is a positive number.
[cons?
(iso-join
cons
(λ (r q) (+ (* 4 q) r))
[first iso-identity (curryr remainder 4)]
[rest iso-base4->number (curryr quotient 4)])
positive?])))
This code contains all the information needed to convert a base 4 list into a number and back again. (The base 4 lists here are ordered from least-significant digit to most-significant digit. This is reversed from the normal direction, but that's okay, that can be fixed outside.)
The first cond case maps empty to zero and back again.
The second cond case maps (cons r q) to (+ (* 4 q) r) and back again, but with q converted between lists and numbers recursively.
Just as a cons cell can be split using first and rest, a positivive number can be split into its "remainder-wrt-4" and its "quotient-wrt-4". Since the remainder is a fixed size and the quotient is an arbitrary size, the remainder is analogous to first and the quotient is analogous to rest.
The first and remainder don't need to be converted into each other, so the first iso-join clause uses iso-identity, the isomorphism that does nothing.
[first iso-identity (curryr remainder 4)]
The rest and quotient do need to be converted though. The rest is a list of base 4 digits in least-to-most-significant order, and the quotient is the number corresponding to it. The conversion between them is iso-base4->number.
[rest iso-base4->number (curryr quotient 4)]
If you're interested in how these isomorphism forms like iso-const, iso-cond, and iso-join are defined, this gist contains everything needed for this example.
Example
(trace '((1 2 3) (4 5 6) (7 8 9))) should evaluate to 15 (1+5+9).
Hint: use map to obtain the smaller matrix on which trace can be applied recursively. The Matrix should be squared.
i tried to do it but i cant seem to do it, i tried to get the diagonals first.
define (diagonals m n)
(append
(for/list ([slice (in-range 1 (- (* 2 n) 2))])
(let ((z (if (< slice n) 0 (add1 (- slice n)))))
(for/list ([j (in-range z (add1 (- slice z)))])
(vector-ref (vector-ref m (sub1 (- n j))) (- slice j))))
is there any way to solve that question in a very simple recursive way using map.
i tried to solve it like that.
define (nth n l)
(if (or (> n (length l)) (< n 0))
(if (eq? n 0) (car l)
(nth (- n 1) (cdr l)))))
(+ (nth 3 '(3 4 5)) (nth 2 '(3 4 5)) (nth 3 '(3 4 5)))
but it didnt work too.
Although I don't think answering homework questions is a good idea in general, I can't resist this because it is an example of both what is so beautiful about Lisp programs and what can be so horrible.
What is so beautiful:
the recursive algorithm is almost identical to a mathematical proof by induction and it's just so pretty and clever;
What is so horrible:
matrices are not semantically nested lists and it's just this terrible pun to pretend they are (I'm not sure if my use of first & rest makes it better or worse);
it just conses like mad for no good reason at all;
I'm pretty sure its time complexity is n^2 when it could be n.
Of course Lisp programs do not have to be horrible in this way.
To compute the trace of a matrix:
if the matrix is null, then the trace is 0;
otherwise add the top left element to the trace of the matrix you get by removing the first row and column.
Or:
(define (awful-trace m)
(if (null? m)
;; the trace of the null matrix is 0
0
;; otherwise the trace is the top left element added to ...
(+ (first (first m))
;; the trace of the matrix without its first row and column which
;; we get by mapping rest over the rest of the matrix
(awful-trace (map rest (rest m))))))
And you may be tempted to think the following function is better, but it is just as awful in all the ways described above, while being harder to read for anyone not versed in the auxiliary-tail-recursive-function-with-an-accumulator trick:
(define (awful-trace/not-actually-better m)
(define (awful-loop mm tr)
(if (null? mm)
tr
(awful-loop (map rest (rest mm))
(+ tr (first (first mm))))))
(awful-loop m 0))
Try:
(apply + (map (lambda (index row) (list-ref row index))
'(0 1 2)
'((1 2 3) (4 5 6) (7 8 9))))
Of course, turn that into a function.
To handle matrices larger than 3x3, we need more indices.
Since map stops when it traverses the shortest of the lists, the (0 1 2) list can just be padded out by hand as large as ... your best guess at the the largest matrix you think you would ever represent with nested lists in Scheme before you graduate and never see this stuff again.
I am new at scheme and at this site.. I interrupt with this question. please give me a way to write a scheme function to calculate how many non-zero values are there in a list of numbers..
(non-zero '(4 1 0 2 0 1 3)) - 5
You have to consider three cases:
(define (non-zero numbers)
(cond ((null? numbers) 0) ; is the list empty? return zero
((not (= (car numbers) 0)) ; is the current element non-zero?
(+ 1 (non-zero (cdr numbers)))) ; add 1 to the counter and recur
(else ; otherwise
(non-zero (cdr numbers))))) ; skip to the next element
Or if your interpreter supports it, a more idiomatic solution would be to use higher-order procedures:
(define (non-zero numbers)
(count (lambda (n) (not (zero? n)))
numbers))
Either way, it works as expected:
(non-zero '(4 1 0 2 0 1 3))
=> 5
I am not familiar with scheme at all. But this can easily be implemented using recursion. Imagine a list [0,1,2,2,0,1]. You would need to walk down the list, looking at each element in turn and increasing a counter by one each time you find a 0 in the list.
(define (count_zeroes numbers)
(if (null? numbers) 0
(+ 1 (count_zeroes (cdr numbers))))