Scheme - takink list from lists - scheme

If I have list:((3 4 5) (2 1 4) (4 1 3)) and I want to get only the (3 4 5) list, How can I do it?
Thank you.

(car '((3 4 5) (2 1 4) (4 1 3)))
In Scheme given the example you have.

Related

Round robin distribution in Clojure

I was wondering if anyone has any resources regarding round robin distribution in Clojure?
I have a function which splits the passed data into separate maps, like so:
(defn round-robin
"Divides the dataset into distinct maps using
round robin distribution"
[data sets split]
(partition split data)
)
My problem is that I'm not certain how to distribute these maps into the amount of "sets" defined. I'm thinking I could create the maps before hand with something like this:
(defn create-map-set
"Creates a set of (count) maps"
[count set]
(if(= count 0) set (recur (- count 1) (conj set
'())))
)
but as I can't reference indexes it becomes harder to merge data with the specific map.
Here's what I'm expecting:
Input: ((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
Output: ((2 5 1 4) (3 2 3 7) (7 3 4 2))
I'm essentially going 1 2 3, 1 2 3 when adding data to maps.
I will indicate how I go about such a problem. Clojure is quite conducive to this sort of experimentation. (leetwinski effectively gave this answer in his comment.)
Start off with the data.
'((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
Drop that inside a thread macro
(->> '((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))) ===> ((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
Partition halfway
(->> '((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
(partition 3)) ===> (((2 5) (3 2) (7 3)) ((1 4) (3 7) (4 2)))
At this point, we get two elements (always). If we can pass these into map, and then concatenate each two elements, we are done. So,
(->> '((2 5) (3 2) (7 3) (1 4) (3 7) (4 2))
(partition 3)
(apply map concat)) ===> ((2 5 1 4) (3 2 3 7) (7 3 4 2))
Now, remove the hard-coded stuff:
(defn round-robin [s]
(let [half-len (quot (count s) 2)]
(->> s
(partition half-len)
(apply map concat))))
Note that if the input is odd-length, function disregards the last element.
My experience is that any time you want to do some transformations on some data, it pays to just push the data into a thread-last macro (->>) and keep whacking at it. This problem is quite simple, but the method works for complex transformations also.

how can i append to a list without creating a dotted pair

how do i append (1 2 3) to the end of () to make ((1 2 3))
how do i append (4 5 6) to the end of that to make ((1 2 3) (4 5 6))
how do i append "|" to the end of that to make ((1 2 3) (4 5 6) "|")
with NO dotted pairs.
I'm working with Chicken Scheme but I'll take an answer from any scheme at this point. Note that any of these lists could also be nested lists of who knows what... i'm just writing a trivial example.
note: #sjamaan shows a solution using append that involves wrapping everything in another list to compensate for append doing things OTHER than what the name says.
(append (list 1 2 3) "|" ) ;=> (1 2 3 . "|")
;^^ didn't actually append, created a dotted pair
(append '(1 2 3) (list 4 5 6)) ;=> (1 2 3 4 5 6) ; don't want unwrapped list
;^^ didn't actually append the list i gave it but appended the contents of the list.
Basically I'm hoping for an append method that actually appends what you give it, not appends the contents of it, or takes it and makes a dotted pair. Maybe i'm just a dreamer... I can write a "no really append" method that just takes whatever params you give it and wraps them in an outer list to compensate but that's just silly... Surely scheme has some way to append without this crazyness.
Here is how append is made:
(define (append2 lst1 lst2)
(if (null? lst1)
lst2 ; the second list is unaltered
(cons (car lst1)
(append2 (cdr lst1) lst2))))
makes a pair chain consisting of all the elements in lst1 and lst2. It does not make a pair where there is nont in lst2 so:
(append2 '(1 2 3) '(4 5)) ; ==> (1 2 3 4 5)
(append2 '(1 2 3) '()) ; ==> (1 2 3) and not (1 2 3 ())
(append2 '(1 2 3) '5) ; ==> (1 2 3 . 5)
Note that every list like (1 2 3) actually is (1 2 3 . ()) or even more correctly (1 . (2 . (3 . ())))
how do i append (1 2 3) to the end of () to make ((1 2 3))
(define (insert-last e lst)
(let helper ((lst lst))
(if (pair? lst)
(cons (car lst)
(helper (cdr lst)))
(cons e '()))))
(insert-last '(1 2 3) '())
; ==> ((1 2 3))
how do i append (4 5 6) to the end of that to make ((1 2 3) (4 5
6))
(insert-last '(4 5 6) '((1 2 3)))
; ==> ((1 2 3) (4 5 6))
how do i append "|" to the end of that to make ((1 2 3) (4 5 6)
"|")
(insert-last "|" '((1 2 3) (4 5 6)))
; ==> ((1 2 3) (4 5 6) "|")
Know that this is very much like append. These are the worst way to make that list since you are making a new list every time. It's O(n) for each insert and O(n^2) for n elements. If you could do this in reverse order you get something that do this O(1) instead of O(n) for each insert. Instead of insert-last you use cons:
(cons '"|" '()) ; ==> ("|")
(cons '(4 5 6) '("|")) ; ==> ((4 5 6) "|")
(cons '(1 2 3) '((4 5 6) "|") ; ==> ((1 2 3) (4 5 6) "|")
This is O(1), O(n) for n elements processed. If you need to do it in the original order you can accumulate, then reverse..
(cons '(1 2 3) '()) ; ==> ((1 2 3))
(cons '(4 5 6) '((1 2 3))) ; ==> ((4 5 6) (1 2 3))
(cons '"|" '((4 5 6) (1 2 3))) ; ==> ("|" (4 5 6) (1 2 3))
(reverse '("|" (4 5 6) (1 2 3)) ; ==> ((1 2 3) (4 5 6) "|")
This is O(1), then O(n) for the reverse but it still is O(1) amortized. O(n) for n elements you process.
append doesn't append atoms to lists. It concatenates lists. You have to lift the atom up to a list before concatenation makes sense.
(append xs (list y))
But it makes sense to point out (reverse (cons y (reverse xs))) which has the same result. reverse suggests that you might be building up your list backwards if you need to append atoms to the end.
The procedure you're looking for is unsurprisingly called append (from SRFI-1). It appends a list of things onto another list. This does mean that if you want to add just one item, you'll need to make a list out of it:
(append '() '((1 2 3))) => ((1 2 3))
(append '((1 2 3)) '((4 5 6))) => ((1 2 3) (4 5 6))
(append '((1 2 3) (4 5 6)) '("|") ) => ((1 2 3) (4 5 6) "|")
It accepts multiple arguments, which will all be appended to eachother in that order, so you can also do:
(append '() '((1 2 3)) '((4 5 6)) '("|")) => ((1 2 3) (4 5 6) "|")
Hope this helps!
Whether you want it or not, cons cells will be created, since lists consist of cons cells.
how do i append (1 2 3) to the end of () to make ((1 2 3))
CL-USER 24 > (list '(1 2 3))
((1 2 3))
how do i append (4 5 6) to the end of that to make ((1 2 3) (4 5 6))
CL-USER 25 > (append '((1 2 3)) (list '(4 5 6)))
((1 2 3) (4 5 6))
how do i append "|" to the end of that to make ((1 2 3) (4 5 6) "|")
CL-USER 26 > (append '((1 2 3) (4 5 6)) (list "|"))
((1 2 3) (4 5 6) "|")

Counting adjacent duplicates in scheme and prolog

I am new to scheme and prolog and have done only a few basic problems.
I need to write a function in scheme and prolog for counting adjacent recurrences in a list.
Example: (Count '(1, 1, 1, 2, 3, 3, 1)) gives ((3 1) (1 2) (2 3) (1 1))
I do not want the code as this is homework but any hints or how to think about this problem would be appreciated as I don't know where to start.
Let's look at a hypothetical function loop:
(loop todo done)
that rewrites the list in todo to you wanted format
and done contains the part already handled.
(loop '(1 1 1 2 3 3 1) '())
(loop '(1 1 2 3 3 1) '((1 1))
(loop '(1 2 3 3 1) '((1 2))
(loop '(2 3 3 1) '((1 3))
(loop '(3 3 1) '((2 1) (1 3))
(loop '(3 1) '((3 1) (2 1) (1 3))
(loop '(1) '((3 2) (2 1) (1 3))
(loop '() '((1 1) (3 2) (2 1) (1 3))
'((1 1) (3 2) (2 1) (1 3)
Given such a function loop you can write
(define (count xs)
(reverse loop xs '())
Now in order to implement loop you need to consider these cases:
1) todo is empty
2) done is empty
3) the first element of todo is different from the first element of done
3) the first element of todo is the same as the first element of done

Adding Elements In a List Scheme

In Scheme, I am trying to iterate through a list adding each element from a portion of the list.
For example, if I had ((1 2 5) (1 2) (1 5) (1) (2 5) (2) (5) ()) for a list, I am trying to add the first part ( 1 2 5 ) and then the second part ( 1 2 ) and so on in order to see if each element adds up to a specific number.
Hope this makes sense, tried my best to explain this.
If someone could help me figure this problem out, I would really appreciate it.
To add the numbers of a (small) list you can use apply:
> (apply + '(1 2 3))
6
which is the same as
> (+ 1 2 3)
6
In order to apply this to a list of sublists, use map:
(define (f lst)
(map (lambda (sublst) (apply + sublst))
lst))
> (f '((1 2 5) (1 2) (1 5) (1) (2 5) (2) (5) ()))
'(8 3 6 1 7 2 5 0)
For larger list you might want to replace apply by foldl or equivalent.

Lisp: How to get all possible combinations of the elements from lists contained on a list?

I need to write a function in Common-Lisp that takes a list of lists and returns a list containing all the possible combinations of the elements from the sublists.
So, for example calling the function on a list such as ((1 2) (1 2)) should return a list like ((1 1) (1 2) (2 1) (2 2)). The input list can be of any length and the sublists are not guaranted to have the same length.
I know how to get this with paired elements from the sublists ( inputtting ((1 2) (1 2)) returns ((1 1) (2 2)), but that's not good enough for the arc-consistency algorithm I'm trying to write, and I'm stuck.
Thank you.
If you don't want to use a library, here's code to do the same thing, and works with any number of lists:
(defun combinations (&rest lists)
(if (endp lists)
(list nil)
(mapcan (lambda (inner-val)
(mapcar (lambda (outer-val)
(cons outer-val
inner-val))
(car lists)))
(apply #'combinations (cdr lists)))))
[2]> (combinations '(1 2))
((1) (2))
[3]> (combinations '(1 2) '(3 4))
((1 3) (2 3) (1 4) (2 4))
[4]> (combinations '(1 2) '(3 4) '(5 6))
((1 3 5) (2 3 5) (1 4 5) (2 4 5) (1 3 6) (2 3 6) (1 4 6) (2 4 6))
wvxvw removed their answer that pointed to a function from Alexandria, but it does provide a very similarly named function that actually does what you want. Instead of alexandria:map-combinations, you need alexandria:map-product, e.g.
(apply #'alexandria:map-product #'list '((1 2) (1 2)))
evaluates to
((1 1) (1 2) (2 1) (2 2))

Resources