If I have a matrix defined as:
(def m1 [[1 2 3][4 5 6][7 8 9]])
How do I go about counting the vectors within the vector in clojure. I know that (count m1) will return 3 which is the number of vectors I have in the initial vector but I can't remember how to count the inner vectors (its been a very very long time since I've had to deal with any lisp dialect). Also I do not want to flatten the vector and then count it because I need to count the values separately (ie. I want to return 3, 3, 3 because each of the inner vectors have 3 elements. One last restriction I guess is that I want to do this without using map right away because I realized I can simply do (map count m1).
That's actually very simple, just call:
(map count m1)
Or if you want to have your result also in vector:
(mapv count m1)
You'll want to use map. It will apply count to each element in the vector and return a list of counts.
(def m1 [[1 2 3][4 5 6][7 8 9]])
(map count m1)
=> (3 3 3)
Your edit: "I want to do this without using map."
(defn counts [vs]
(loop [vs vs, cs []]
(if (empty? vs)
cs
(recur (rest vs), (conj cs (count (first vs)))))))
One answer quite good but use count. Assume not using count and also not use map
((fn [lst]
(loop [l lst, n 0]
(if (empty? l)
n
(recur (rest l) (inc n)))))'(1 2 3))
Related
I'm trying to get the lowest integer out of a vector only containing numbers. I know how to do it with lists. You compare the first two values of the list and depending on which is larger you either save your value to output it later or call the function again with the rest of the list (all elements except the first) using the cdr procedure.
But with vectors I'm completely lost. My guess would be that the way of thinking about the solution would be the same for lists and vectors. I've been reading on the racket-lang website but haven't been able to come up with a solution to the problem. The procedures I've been experimenting most with are vector-ref and vector-length as they seem to be the most useful in this problem (but this is my first time working with vectors so what do I know).
So my two questions are:
How can we get all values except the first from a vector? Is there a procedure like cdr but for vectors?
If you were working with lists you would use cons to save the values you would want to output. But is there a similar way of doing it when working with vectors?
Thanks!
The simplest solution is to use a variant of for called for/fold.
I thought there were an for/min but alas.
#lang racket
(define v (vector 11 12 13 4 15 16))
(for/fold ([m +inf.0]) ([x (in-vector v)])
(min m x))
If you like a more explicit approach:
(define (vector-min xs)
(define n (vector-length xs))
(let loop ([i 0] ; running index
[m +inf.0]) ; minimum value so far
(cond
[(= i n) ; if the end is reached
m] ; return the minimum
[else ; else
(define x (vector-ref v i)) ; get new element in vector
(loop (+ i 1) ; increment index
(min m x))]))) ; new minimum
UPDATE
(let loop ([x 1] [y 10])
(loop (+ x 1) (- y 1))
is the same as:
(let ()
(define (loop (x y)
(loop (+ x 1) (- y 1)))
(loop 1 10))
Vectors are O(1) access and indexed so it is a completely different data structure, however you have SEFI-43 which is like the SRFI-1 List library, but for vectors.
#lang racket
(require srfi/43)
(define (min-element lst)
(vector-fold min (vector-ref lst 0) lst))
(max-element #(7 8 1 2 3 4 5 12))
; ==> 1
The racket/vector module has vector-argmin for finding the minimum element of a vector (Well, the minimum after feeding the elements through a transformation function). Combine that with a function like identity from racket/function and it's trivial:
(vector-argmin identity '#(5 4 3 2 1 6))
I solved Project Euler's 8th problem using SBCL and the iterate package from quicklisp. In my code I defined a function that turns a number into a list of it's digits. Here's the source code:
(defun number-to-list (n)
(iter (for c in-string (write-to-string n)) (collect (digit-char-p c))))
The collect clause both in iter and in loop make a list out of the values. Is it possible to instead generate a vector (one dimensional array)?
Would my only option be to convert the list generated by number-to-list to a vector? Because that seems inefficient (although probably not that inefficient)
Usually there is one big problem: how large will the result vector be? It would be best to know that upfront, then we can allocate the vector once with the correct size. Otherwise we would have find ways to deal with that: use a resizable vector, allocate a list first and copy into a result vector later, allocate a larger vector with a fill pointer, ...
If you have a sequence, then one can use the Common Lisp function MAP: if the source object is a vector, here a string, its length is cheap to get.
CL-USER 1 > (map 'vector
#'digit-char-p
(write-to-string 5837457324534))
#(5 8 3 7 4 5 7 3 2 4 5 3 4)
You can use ITERATE and collect a vector:
FOO 32 > (defun number-to-vector (n)
(iter (for c in-string (write-to-string n))
(collect (digit-char-p c) result-type vector)))
NUMBER-TO-VECTOR
FOO 33 > (number-to-vector 8573475934)
#(8 5 7 3 4 7 5 9 3 4)
If you look at the macro expansion, it actually collects into a list and then calls COERCE to create the vector. So: no win in efficiency.
Note that this is another example where ITERATE is more powerful than LOOP: the standard LOOP can't directly return vectors from collect.
The proposed solutions are correct and elegant, but they first create a list, or trasform the number in string. I would like to propose a direct transformation from integers to arrays, without transforming first the number in a list or a string:
(defun digits(n)
"Transform a positive integer n in array of digits"
(let* ((logn (floor (log n 10)))
(result (make-array (1+ logn) :element-type '(integer 0 9))))
(loop for i downfrom logn to 0
do (setf (values n (aref result i)) (floor n 10)))
result))
The problem of allocating an array of the correct dimension is solved with the formula that gives the number of decimal digits of an integer n: ⌊log10 n⌋+1.
Maybe not a direct answer to your question but here are my num-to-list and list-to-num functions I frequently use.
(defun num-to-list-helper (n liste)
(cond ((< n 1) liste)
(t (num-to-list-helper (truncate (/ n 10)) (cons (rem n 10) liste))))))
(defun num-to-list (n)
(num-to-list-helper n nil))
(defun list-to-num-helper (liste n)
(if (null liste)
n
(list-to-num-helper (cdr liste)
(+ n (* (car liste) (expt 10 (1- (length liste))))))))
(defun list-to-num (liste)
(list-to-num-helper liste 0))
You could try these and see if there's an improvement over converting the number to string. Personally I don't prefer strings for numbers as I consider them as an ugly trick I was forced to do in my Java days.
You could also convert these functions to a version using vectors and see how they do.
> (conj [0] 1 2 3)
[0 1 2 3]
> (conj {:a "ei"} {:b "bi"})
{:b "bi", :a "ei"}
>
See, when it acts on vector, it puts 1,2,3 at end of it.
Whereas it put :b "bi" in front of :a map k-v pair
Why is this?
thanks
As with many hashed maps implementations, Clojure's hashed maps do not sort their entries, not retain the order in which they were inserted. This allows for better performance.
Note that conj does not have general ordering semantics either (it has ordering semantics for some concrete types, such as vectors).
You don't have to go as far as maps to get inconsistent behaviour from conj:
(conj [1] 2) ; [1 2]
(conj (list 1) 2) ; (2 1)
Hash maps have no defined order. But, for any map,
the seq of entries will always be the same
the vals and keys will be in consistent order.
Thus, for map m,
(= (keys m) (map key m))
(= (vals m) (map val m))
(= m (zipmap (keys m) (vals m)))
Currently, this sequence seems to be independent of insertion order. I tested this on sets by randomly shuffling random integers.
Iam another Clojure-newbi!
How can i assign a vector containing some values to another one?
I want to do:
[a b] >>> [b (+ a b)]
so that afterwards b has the value of (a+b) and a that of b.
It looks like you're trying to do a fibonacci sequence.
user=> (def fibseq (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1])))
#'user/fibseq
user=> (take 10 fibseq)
(1 1 2 3 5 8 13 21 34 55)
What you've got to remember in clojure is immutability, so you don't change a and b to be the new values. So something like:
user=> (defn next-fib [[a b]]
(let [na b
nb (+ a b)]
[na nb]))
user=> (next-fib [1 2])
[2 3]
would produce a function next-fib that would return the next 2 values from your input. During the function, a and b cannot be changed, they are immutable, hence assignment to new values.
Here, i'm using destructuring to immediately break the elements of the input vector into values a and b, which are then used to calculate the next element, and is the same as how the 1 liner at the top of my answer works.
Or if you're doing looping, you can recur with values that get substitute over their previous iteration, this is not changing a and b (during any iteration their values are fixed and still immutable), but redoing the entire stack with new values in their place, subtle difference. See articles on tail recursion.
user=> (loop [a 1 b 1]
(if (< a 20)
(recur b (+ a b))
[a b]))
[21 34]
Here's a simple version of the Fibonacci Sequence using recur, it returns the first n numbers.
(defn fib-recur [n]
(loop [fib [] x n a 0 b 1]
(if (zero? x)
fib
(recur (conj fib b) (dec x) b (+ a b)))))
It works by starting with an empty array of numbers it's building, then recurs by decrementing the counter (x) from n to 0, each iteration changes a and b to be new values as part of the recursion, and it adds the latest number to the array fib returning that when the counter gets to zero.
I am practicing for my programming paradigms exam and working through problem sets I come to this problem. This is the first problem after reversing and joining lists recursively, so I suppose there is an elegant recursive solution.
I am given a list of lists and a permutation. I should permute every list including a list of lists with that specified permutation.
I am given an example:
->(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
->((1 3 2) (5 7 6) (a c b))
I have no idea even how to start. I need to formulate the problem in recursive interpretation to be able to solve it, but I can not figure out how.
Well, let's see how we can break this problem down. We are given a list of lists, and a list of numbers, and we want to order each list according to the order specified by the list of numbers:
=>(permute '((1 2 3) (4 5 6)) '(3 2 1))
'((3 2 1) (6 5 4))
We can see that each list in the list of lists can be handled separately, their solutions are unrelated to each other. So we can have a helper permute1 that handles the case of one list, then use map to apply this function to each of the lists (with the same ordering each time):
(define (permute lists ordering)
(map (lambda (xs) (permute1 xs ordering))
lists))
(define (permute1 items ordering)
...)
Now, to calculate (permute1 '(4 5 6) '(3 2 1)), what we mean is:
The first item of the new list will be the 3rd item of items, because the first number in ordering is 3.
The rest of the items of the new list will be determined by using the rest of the numbers in the ordering.
If the ordering is the empty list, return the empty list.
This forms the base case (3), the recursive case (1), and the steps to recur deeper (2). So a sketch of our solution would look like:
(define (permute1 items ordering)
(if (empty? ordering)
'()
(let ([next-item ???])
(??? next-item
(permute1 items (rest ordering))))))
Where the ???s represent getting the item based on the first number in ordering and combining this item with the remainder of the calculation, respectively.
Here's another option, using higher-order functions. This is the idiomatic way to think about a solution in a functional language - we split the problem in sub-problems, solve each one using existing procedures and finally we compose the answer:
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define (perm lst order)
(foldr (lambda (idx acc)
(cons (list-ref lst (sub1 idx)) acc))
'()
order))
(define (permute lst order)
(if (atom? lst)
lst
(perm (map (lambda (x) (permute x order)) lst)
order)))
We start by defining atom?, a generic predicate and perm, a helper that will reorder any given list according to the ordering specified in one of its parameters. It uses foldr to build the output list and list-ref to access elements in a list, given its 0-based indexes (that's why we subtract one from each index).
The main permute function takes care of (recursively) mapping perm on each element of an arbitrarily nested input list, so we can obtain the desired result:
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
=> '((1 3 2) (5 7 6) (a c b))
I am given an example:
(permute ('(1 2 3) '(a b c) '(5 6 7)) '(1 3 2))
((1 3 2) (5 7 6) (a c b))
The syntax you've given isn't correct, and will cause an error, but it's fairly clear what you mean. You want that
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
;=> ((1 3 2) (5 7 6) (a c b))
Now, it's not clear how you're indicating the permutation. Is '(1 3 2) a permutation because it has some (1-based) indices, and indicates the way to rearrange elements, or is it because it is actually a permutation of the elements of the first list of the first list? E.g., would
(permute '((x y z) (a b c) (5 6 7)) '(1 3 2))
;=> ((x z y) (5 7 6) (a c b))
work too? I'm going to assume that it would, because it will make the problem much easier.
I have no idea even how to start. I need to formulate the problem in
recursive interpretation to be able to solve it, but I can not figure
out how.
You need to write a function that can take a list of indices, and that returns a function that will perform the permutation. E.g,.
(define (make-permutation indices)
…)
such that
((make-permutation '(3 1 2)) '(a b c))
;=> (c a b)
One you have that, it sounds like your permute function is pretty simple:
(define (permute lists indices)
(let ((p (make-permutation indices)))
(p (map p lists))))
That would handle the case you've given in your example, since (map p lists) will return ((1 3 2) (a b c) (5 7 6)), and then calling p with that will return ((1 3 2) (5 7 6) (a c b)). If you need to be able to handle more deeply nested lists, you'll need to implement a recursive mapping function.
Here's my take, which seems to be shorter than the previous examples:
(define (permute lst ord)
(define ord-1 (map sub1 ord)) ; change from 1-based to 0-based indexes
(define (perm elts) ; recursive sub-procedure
(if (list? elts)
(map perm (map (curry list-ref elts) ord-1)) ; list -> recurse
elts)) ; else return unchanged
(perm lst)) ; initial call
testing
> (permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
'((1 3 2) (5 7 6) (a c b))
> (permute '((1 (i permute did) 3) (a b (scheme cool is)) (5 6 7)) '(1 3 2))
'((1 3 (i did permute)) (5 7 6) (a (scheme is cool) b))