#lang racket
(define(rectangleList list rectangle1)(recursion list rectangle1'()))
;(define rectangleList(list '(2 4 6 1)'(1 8 4 4)'(0 5 4 0)))
;(define rectangle1 '(1 3 5 2))
(define(recursion rectangleList rectangle1 returnedList)
(if(<(length rectangleList)1)
returnedList
(recursion(cdr rectangleList) rectangle1
(if(Intersect(car rectangleList)rectangle1)
(cons (car rectangleList) returnedList)
returnedList
)
)
)
)
(define(Intersect rectangleList rectangle1)
(and(and(<(car rectangleList) (cadr rectangle1)))
(and(> (cadr rectangleList) (car rectangle1)))
(and(< (cdr rectangleList)(caddr rectangle1)))
(and(> (caddr rectangleList) (cdr rectangle1)))))
I am having a problem with calling my racket code. I am unsure how to proceed. The code is taking a list of rectangles and then also taking a rectangle and seeing if the singular rectangle intersects with any of the other rectangles in the list. Then it should output the list of rectangles that it intersects with i.e Test Cases.
Problem Statement: Given a rectangle, R, and a list of rectangles, L, return the list containing the elements in L that intersect with R.
Any help on this matter would be greatly appreciated! :)
#lang racket
(define(rectangleList list rectangle1)(recursion list rectangle1'()))
;(define rectangleList(list '(2 4 6 1)'(1 8 4 4)'(0 5 4 0)))
;(define rectangle1 '(1 3 5 2))
;Recusion function
(define(recursion rectangleList rectangle1 returnedList)
(if(<(length rectangleList)1)
returnedList
(recursion(cdr rectangleList) rectangle1
(if(Intersect(car rectangleList)rectangle1)
(cons (car rectangleList) returnedList)
returnedList
)
)
)
)
;Intersect function
(define(Intersect rectangleList rectangle1)
;R1.topx<R2.bottomx
(and(and(< (list-ref rectangleList 0) (list-ref rectangle1 2)))
;R1.bottomx>R2.topx
(and(> (list-ref rectangleList 2) (list-ref rectangle1 0)))
;R1.bottomy<R2.topy
(and(< (list-ref rectangleList 3)(list-ref rectangle1 1)))
;R1.topy>R2.bottomy
(and(> (list-ref rectangleList 1) (list-ref rectangle1 3)))))
You call it by:
(rectangleList ('(1 1 4 5) '(1 3 5 6)) '( 1 3 5 7))
Related
Trying to write a function that returns every third element in a list
including the first element in racket. All I get now is my code blowing up with a first: contract violation
expected: (and/c list? (not/c empty?))
given: 4
(define l (list 1 2 3 4 5 6 7 8 9))
(define (skipper lst)
(if (null? lst)
'()
(cons (first lst)
(skipper (car (cdr (cdr (cdr lst))))))))
(skipper l)
The problem was just the car around cdddr.
(define l (list 1 2 3 4 5 6 7 8 9))
(define (skipper lst)
(if (null? lst)
'()
(cons (first lst)
(skipper (if (< (length lst) 3)
'()
(cdddr lst))))))
(skipper l) ;; '(1 4 7)
Generalized Solution
(define (my-cdr lst) ;; `cdr` behaving like in common-lisp: (cdr '()) -> '()
(cond ((null? lst) '())
(else (cdr lst))))
(define (multi-cdr lst k) ;; apply `my-cdr` k-times on `lst`
(cond ((zero? k) lst)
(else (multi-cdr (my-cdr lst) (- k 1)))))
(define (skipper lst k)
(if (null? lst)
'()
(cons (first lst)
(skipper (multi-cdr lst k) k))))
Test it:
(skipper l 3) ;; '(1 4 7)
(skipper l 4) ;; '(1 5 9)
(skipper l 2) ;; '(1 3 5 7 9)
(skipper l 1) ;; '(1 2 3 4 5 6 7 8 9)
The issue is that you cannot call (cdr (cdr (cdr lst))) when lst has less than 3 elements.
You tagged this with racket, so I'm going to show you a solution using match
(define (skipper l)
(match l
;; some element and at least 3 more
((list a rest ..3)
(cons a (skipper (cddr rest))))
;; at least one element
((cons a _)
(list a))
;; otherwise
(else
empty)))
(skipper '())
;; '()
(skipper '(0))
;; '(0)
(skipper '(0 1 2 3 4 5 6 7))
;; '(0 3 6)
(skipper '(0 1 2 3 4 5 6 7 8 9))
;; '(0 3 6 9)
This solution doesn't use length which unnecessarily computes the length of the list
I have this homework in LISP where I need to sort out atoms and then sublists from a list. I'm sure this is supposed to be easy task but as I'm not much of a programmer then this is really taking quite a while for me to understand.
I have this list of numbers:
(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6)
And if I understand correctly my task then I should get something like this:
(5 -1 -6 (2 6 1) (8 7 -3) (0 (9 4)))
So far all I found out is how to count atoms and/or sublists but I don't need that.
(DEFUN ATOMNUMBER (L) (COND ((NULL L) 0)
((ATOM (CAR L)) (+ 1 (ATOMNUMBER (CDR L))))
(T (ATOMNUMBER (CDR L))) ))
Also that function should work correctly even when there are only sublists, only atoms or just empty list.
Maybe someone can give me any examples?
Thanks in advance!
There are several possible approaches in Common Lisp:
use REMOVE-IF to remove the unwanted items. (Alternatively use REMOVE-IF-NOT to keep the wanted items.) You'll need two lists. Append them.
use DOLIST and iterate over the list, collect the items into two lists and append them
write a recursive procedure where you need to keep two result lists.
it should also be possible to use SORT with a special sort predicate.
Example:
> (sort '(1 (2 6 1) 4 (8 7 -3) 4 1 (0 (9 4)) -6 10 1)
(lambda (a b)
(atom a)))
(1 10 -6 1 4 4 1 (2 6 1) (8 7 -3) (0 (9 4)))
As stable version:
(stable-sort '(1 (2 6 1) 4 (8 7 -3) 4 1 (0 (9 4)) -6 10 1)
(lambda (a b)
(and (atom a)
(not (atom b)))))
(1 4 4 1 -6 10 1 (2 6 1) (8 7 -3) (0 (9 4)))
I am more used to Scheme but here's a solution that works in Lisp:
(defun f (lst)
(labels
((loop (lst atoms lists)
(cond
((null lst)
(append (reverse atoms) (reverse lists)))
((atom (car lst))
(loop (cdr lst) (cons (car lst) atoms) lists))
(T
(loop (cdr lst) atoms (cons (car lst) lists))))))
(loop lst '() '())))
(f '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6))
Basically you iterate over the list, and each element is either appended to the atoms list or the lists lists. In the end you join both to get your result.
EDIT
The remove-if version is way shorter, of course:
(let ((l '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6)))
(append
(remove-if-not #'atom l)
(remove-if #'atom l)))
Just in case you will want to exercise more, and you will find that the examples provided here are not enough :P
(defun sort-atoms-first-recursive (x &optional y)
(cond
((null x) y)
((consp (car x))
(sort-atoms-first-recursive (cdr x) (cons (car x) y)))
(t (cons (car x) (sort-atoms-first-recursive (cdr x) y)))))
(defun sort-atoms-first-loop (x)
(do ((a x (cdr a))
(b) (c) (d) (e))
(nil)
(if (consp (car a))
(if b (setf (cdr b) a b (cdr b)) (setf b a d a))
(if c (setf (cdr c) a c (cdr c)) (setf c a e a)))
(when (null (cdr a))
(cond
((null d) (return e))
((null c) (return d))
(t (setf (cdr b) nil (cdr c) d) (return e))))))
(sort-atoms-first-recursive '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6))
(sort-atoms-first-loop '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6))
The second one is destructive (but doesn't create any new conses).
Here's an iterative code, constructing its output in a top-down manner (the comment is in Haskell syntax):
;atomsFirst xs = separate xs id id where
; separate [] f g = f (g [])
; separate (x:xs) f g
; | atom x = separate xs (f.(x:)) g
; | True = separate xs f (g.(x:))
(defmacro app (l v)
`(progn (rplacd ,l (list ,v)) (setq ,l (cdr ,l))))
(defun atoms-first (xs)
(let* ((f (list nil)) (g (list nil)) (p f) (q g))
(dolist (x xs)
(if (atom x) (app p x) (app q x)))
(rplacd p (cdr g))
(cdr f)))
The two intermediate lists that are being constructed in a top-down manner are maintained as open-ended lists (i.e. with explicit ending pointer), essentially following the difference-lists paradigm.
You can do this recursive way:
(defun f (lst)
(cond
((null lst) nil)
((atom (car lst))
(append (list (car lst)) (f (cdr lst))))
(T
(append (f (cdr lst)) (list (f (car lst))))
)
)
)
(step (f '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6)))
Output:
step 1 --> (F '(5 -1 (2 6 1) (8 7 -3) ...))
step 1 ==> value: (5 -1 -6 (0 (9 4)) (8 7 -3) (2 6 1))
How to get the intersection of multiple lists using elisp? I'm a elisp newbie but I'm imagining there is some builtin function or a nicer solution using reduce. I cobbled this together, but it seems overly complicated.
;; get the intersection of these lists
;; result should be (3 4 5)
(setq test '((0 1 2 3 4 5) (2 3 4 5 6) (3 4 5 6 7)))
(require 'cl-lib)
(cl-remove-if-not
(lambda (x) (cl-every
(lambda (y) (> (length (memq x y) ) 0 ) )
(cdr test) ) )
(car test) )
;; ( 3 4 5)
There is a cl-intersection that takes only two operands:
(cl-intersection '(0 1 2 3 4 5) '(2 3 4 5 6))
You can use it do define your own intersection:
(defun my-intersection(l)
(cond ((null l) nil)
((null (cdr l)) (car l))
(t (cl-intersection (car l) (my-intersection (cdr l))))))
(my-intersection '((0 1 2 3 4 5) (2 3 4 5 6) (3 4 5 6 7)))
Updated
Thanks to the #Tobias comment below, you could have in the new function the same keyword parameters of cl-intersection, that is (:test :test-not :key) and propagate them to all the calls to it inside the recursion.
Here is the extended version:
(defun my-intersection(l &rest cl-keys)
(cond ((null l) nil)
((null (cdr l)) (car l))
(t (apply 'cl-intersection (car l) (apply 'my-intersection (cdr l) cl-keys) cl-keys))))
Install dash third-party list manipulation library (follow instructions to install it). Then you need:
(-reduce '-intersection '((1 2 3 4) (2 3 4 5) (3 4 5 6))) ; => (3 4)
If you need a function that accepts variable number of lists, instead of a single list of lists, wrap it in a function using &rest keyword, like that:
(defun -intersection* (&rest list-of-lists)
(-reduce '-intersection list-of-lists))
;; (-intersection* '(1 2 3 4) '(2 3 4 5) '(3 4 5 6)) ; => (3 4)
If it's the first time you use -reduce, it's a “fold” function: it takes a binary function, a list of elements, and reduces them to a final result one list element at a time. This answer explains the concept behind the fold.
Is there a way to do this:
(defvar long-list ((1 1 1 1) (2 2 2 2) (3 3 3 3)
(4 4 4 4) (5 5 5 5) (6 6 6 6))
(format t "magic" long-list)
To output something like:
(1 1 1 1) (2 2 2 2) (3 3 3 3)
(4 4 4 4) (5 5 5 5) (6 6 6 6)
Where I would define the number of columns to print?
I know about (format t "~/my-function/" long-list) option, but maybe there's something built-in?
The reference is being highly unhelpful on this particular topic.
OK, sorry, I actually found it: http://www.lispworks.com/documentation/lw51/CLHS/Body/f_ppr_fi.htm#pprint-tabular but before I found it, I wrote this:
(defun pplist-as-string (stream fmt colon at)
(declare (ignore colon at))
(dolist (i fmt)
(princ i stream)))
(defun ppcolumns (stream fmt colon at cols)
(declare (ignore at colon))
(when (or (not cols) (< cols 1)) (setq cols 1))
(let* ((fmt-length (length fmt))
(column-height (floor fmt-length cols))
(remainder (mod fmt-length cols))
(printed 0)
columns
column-sizes)
(do ((c fmt (cdr c))
(j 0 (1+ j))
(r (if (zerop remainder) 0 1) (if (zerop remainder) 0 1))
(i 0 (1+ i)))
((null c))
(when (or (= j (+ r column-height)) (zerop i))
(setq columns (cons c columns)
column-sizes
(cons
(+ r column-height) column-sizes))
(unless (zerop remainder)
(unless (zerop i) (decf remainder)))
(setq j 0)))
(setq columns (reverse columns)
column-sizes (reverse column-sizes))
(when (/= fmt-length (* column-height cols))
(incf column-height))
(dotimes (i column-height)
(do ((c columns (cdr c))
(size column-sizes (cdr size)))
((or (null c)))
(when (> printed (1- fmt-length))
(return-from ppcolumns))
(when (< 0 (car size))
(pplist-as-string stream (caar c) nil nil)
(when (caar c) (incf printed))
(unless (null c) (princ #\ ))
(rplaca c (cdar c))))
(princ #\newline))))
which prints it in another direction. In case you would need it.
I have this homework in LISP where I need to sort out atoms and then sublists from a list. I'm sure this is supposed to be easy task but as I'm not much of a programmer then this is really taking quite a while for me to understand.
I have this list of numbers:
(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6)
And if I understand correctly my task then I should get something like this:
(5 -1 -6 (2 6 1) (8 7 -3) (0 (9 4)))
So far all I found out is how to count atoms and/or sublists but I don't need that.
(DEFUN ATOMNUMBER (L) (COND ((NULL L) 0)
((ATOM (CAR L)) (+ 1 (ATOMNUMBER (CDR L))))
(T (ATOMNUMBER (CDR L))) ))
Also that function should work correctly even when there are only sublists, only atoms or just empty list.
Maybe someone can give me any examples?
Thanks in advance!
There are several possible approaches in Common Lisp:
use REMOVE-IF to remove the unwanted items. (Alternatively use REMOVE-IF-NOT to keep the wanted items.) You'll need two lists. Append them.
use DOLIST and iterate over the list, collect the items into two lists and append them
write a recursive procedure where you need to keep two result lists.
it should also be possible to use SORT with a special sort predicate.
Example:
> (sort '(1 (2 6 1) 4 (8 7 -3) 4 1 (0 (9 4)) -6 10 1)
(lambda (a b)
(atom a)))
(1 10 -6 1 4 4 1 (2 6 1) (8 7 -3) (0 (9 4)))
As stable version:
(stable-sort '(1 (2 6 1) 4 (8 7 -3) 4 1 (0 (9 4)) -6 10 1)
(lambda (a b)
(and (atom a)
(not (atom b)))))
(1 4 4 1 -6 10 1 (2 6 1) (8 7 -3) (0 (9 4)))
I am more used to Scheme but here's a solution that works in Lisp:
(defun f (lst)
(labels
((loop (lst atoms lists)
(cond
((null lst)
(append (reverse atoms) (reverse lists)))
((atom (car lst))
(loop (cdr lst) (cons (car lst) atoms) lists))
(T
(loop (cdr lst) atoms (cons (car lst) lists))))))
(loop lst '() '())))
(f '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6))
Basically you iterate over the list, and each element is either appended to the atoms list or the lists lists. In the end you join both to get your result.
EDIT
The remove-if version is way shorter, of course:
(let ((l '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6)))
(append
(remove-if-not #'atom l)
(remove-if #'atom l)))
Just in case you will want to exercise more, and you will find that the examples provided here are not enough :P
(defun sort-atoms-first-recursive (x &optional y)
(cond
((null x) y)
((consp (car x))
(sort-atoms-first-recursive (cdr x) (cons (car x) y)))
(t (cons (car x) (sort-atoms-first-recursive (cdr x) y)))))
(defun sort-atoms-first-loop (x)
(do ((a x (cdr a))
(b) (c) (d) (e))
(nil)
(if (consp (car a))
(if b (setf (cdr b) a b (cdr b)) (setf b a d a))
(if c (setf (cdr c) a c (cdr c)) (setf c a e a)))
(when (null (cdr a))
(cond
((null d) (return e))
((null c) (return d))
(t (setf (cdr b) nil (cdr c) d) (return e))))))
(sort-atoms-first-recursive '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6))
(sort-atoms-first-loop '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6))
The second one is destructive (but doesn't create any new conses).
Here's an iterative code, constructing its output in a top-down manner (the comment is in Haskell syntax):
;atomsFirst xs = separate xs id id where
; separate [] f g = f (g [])
; separate (x:xs) f g
; | atom x = separate xs (f.(x:)) g
; | True = separate xs f (g.(x:))
(defmacro app (l v)
`(progn (rplacd ,l (list ,v)) (setq ,l (cdr ,l))))
(defun atoms-first (xs)
(let* ((f (list nil)) (g (list nil)) (p f) (q g))
(dolist (x xs)
(if (atom x) (app p x) (app q x)))
(rplacd p (cdr g))
(cdr f)))
The two intermediate lists that are being constructed in a top-down manner are maintained as open-ended lists (i.e. with explicit ending pointer), essentially following the difference-lists paradigm.
You can do this recursive way:
(defun f (lst)
(cond
((null lst) nil)
((atom (car lst))
(append (list (car lst)) (f (cdr lst))))
(T
(append (f (cdr lst)) (list (f (car lst))))
)
)
)
(step (f '(5 -1 (2 6 1) (8 7 -3) (0 (9 4)) -6)))
Output:
step 1 --> (F '(5 -1 (2 6 1) (8 7 -3) ...))
step 1 ==> value: (5 -1 -6 (0 (9 4)) (8 7 -3) (2 6 1))