LISP Lists sublist - lisp

function that only deletes the first element of each sublist in the list. For example,
Test 1:
List is (10 (1 2 3) (90 100) 122 156)
Output should be: (10 (2 3) (100) 122 156)
I know how to delete an element from the list but i don't know which function is used to delete element from the sublist

(defun butfirst (lst)
(mapcar
(lambda (e) (if (consp e) (cdr e) e))
lst))
(butfirst '(10 (1 2 3) (90 100) 122 156))
=> (10 (2 3) (100) 122 156)

yet another offer: without iteration, with a recursive algorithm.
(defun butfirst (lst)
(cond
((null lst) '())
((consp (car lst))
(cons (cdr (car lst))
(butfirst (cdr lst))))
(t (cons (car lst)
(butfirst (cdr lst))))))

Related

Filter out any value other than a number

I am trying to come up with a procedure that filters out any value other than a number. For example:
'(1 2 (a) 3) => '(1 2 () 3) or '(1 2 (a 10 11 (b 2 (c))) 3) => '(1 2 (10 11 (2 ())) 3)
This is what I have so far but it doesn't really work because it replaces the non numbers with an empty list instead of nothing:
(define (filter-numbers lst)
(if (null? lst)
'()
(if (list? lst)
(cons
(filter-numbers (car lst))
(filter-numbers (cdr lst)))
(if (number? lst)
lst
'())))
)
The procedure outputs the following:
> (filter-numbers '(1 2 (a) 3))
'(1 2 (()) 3)
instead of: '(1 2 () 3)
You need to check if an element in a sublist is a number before deciding to cons it to the output or not. I think it's easier if we restructure the code a bit; also some tips: don't use list?, prefer pair? as it's faster (unlike list? it doesn't have to traverse the whole list). And prefer cond instead of nesting ifs, your code will be easier to read. This is what I mean:
(define (filter-numbers lst)
(cond ((null? lst) lst)
((not (pair? (car lst)))
; check the element while still in a list, if we wait
; until we reach an atom it's too late to filter it out
(if (number? (car lst))
; either add the element to the output or skip it
(cons (car lst) (filter-numbers (cdr lst)))
(filter-numbers (cdr lst))))
(else (cons
(filter-numbers (car lst))
(filter-numbers (cdr lst))))))
It works as expected:
(filter-numbers '(1 2 (a) 3))
=> (1 2 () 3)
(filter-numbers '(1 2 (a 10 11 (b 2 (c))) 3))
=> '(1 2 (10 11 (2 ())) 3)

Don't know how to solve this error [Racket]: "car: contract violation expected: pair? given: '()"

I'm trying to get a list with the average of the following n elements. I'm reading a csv file that has 7 columns im just using the 6th one that has number values in order to get the average.
This is the code
;Function that returns a list containing the values of the desired column
(define (get-column col)
(let loop
([file (cdr(all-rows csv-path read-csv))]
[result empty])
(if (empty? file)
result
(loop (cdr file)
(cond
[(equal? col 1) (append result (list (caar file)))]
[(equal? col 2) (append result (list (string->number(cadar file))))]
[(equal? col 3) (append result (list (string->number(caddar file))))]
[(equal? col 4) (append result (list (string->number(car (cdddar file)))))]
[(equal? col 5) (append result (list (string->number(cadr (cdddar file)))))]
[(equal? col 6) (append result (list (string->number(caddr (cdddar file)))))]
[(equal? col 7) (append result (list (string->number(car (cdddr (cdddar file))))))]
)))))
(define (suma-SMA col n)
(let loop
([n n]
[res 0]
[col col])
(if (zero? n)
res
(loop (sub1 n) (+ res (car col)) (cdr col)))))
(define (get-SMA days)
(let loop
([col (get-column 6)]
[result empty])
(if (empty? col)
result
(loop (cdr col)(append result (list (suma-SMA col days)))))))
Here's a function that does what you asked for in the comments, e.g. given (1 2 3 4) it produces ((1+2)/2 (2+3)/2 (3+4)/2).
(define (sum list)
(cond
((null? list)
'()) ;; error?
((null? (cdr list))
'())
(else
(cons (/ (+ (car list) (cadr list)) 2) (sum (cdr list))))))
I'm still a bit confused because even the combination of get-SMA and suma-SMA does nothing like this. It's completely unclear what the days variable is doing, as you can see I didn't need it in my code above.
So I may have misunderstood what you are trying to do, but the function above does what you actually asked for so hopefully it will be helpful.
Here is the answer that I found useful for my problem.
(define (sum list n)
(cond
((null? list)
'()) ;; error?
((null? (cdr list))
'())
(else
(cons (suma-SMA list n) (sum (cdr list) n)))))

How to fix contract violation for lists of list in racket?

I am learning Racket for understanding principles of programming languages. What I am doing is to add only second elements in pairs of a list. In my understanding, I think I am doing correctly. However, the error message shows up. Please provide me any advise to understand what I am doing wrong.
(define pairs
'((1 5)(6 4)(7 8)(15 10)))
(define (secondSum lst)
(if (null? lst) 0
(+ (cdr (car lst)) (secondSum (cdr lst)))
)
)
>(secondSum pairs)
+: contract violation
expected: number?
given: '()
argument position: 2nd
other arguments...:
10
What I am looking for is
(5 + 4 + 8 + 10)
(cdr (car lst)) should be (car (cdr (car lst))) also (cadr (car lst)) or in racket preferred (second (first lst)) that is if lst is '((1 5)) the result should be 5.
I had to be sure this was right so I ran the program with the fix and verified the result:
(define pairs '((1 5)(6 4)(7 8)(15 10)))
(define (secondSum lst)
(if (null? lst) 0
(+ (car (cdr (car lst))) (secondSum (cdr lst)))
)
)
(secondSum pairs)
(+ 5 4 8 10)
The last two expressions both have the value 27.

Write a Scheme function (sumList)

Write a Scheme function (sumList) that returns the sum of all the numbers in a list which should be passed as a parameter. The list can have numbers, non-numeric symbols, and other lists. Your function should select all the number in the sublists and add them to the total. You can assume that the total is 0 if the list is empty. Example Usage:
(sumList '((1 2 3) 5 a (10) ())
21
(define (sumList lst)
(cond
([empty? lst]
0)
([list? (car lst)]
(+ (sumList (car lst)) (sumList (cdr lst))))
((not(number? (car lst)))
(sumList (cdr lst)))
(else
(+ (car lst)(sumList (cdr lst))))))

racket postfix to prefix

I have a series of expressions to convert from postfix to prefix and I thought that I would try to write a program to do it for me in DrRacket. I am getting stuck with some of the more complex ones such as (10 (1 2 3 +) ^).
I have the very simple case down for (1 2 \*) → (\* 1 2). I have set these expressions up as a list and I know that you have to use cdr/car and recursion to do it but that is where I get stuck.
My inputs will be something along the lines of '(1 2 +).
I have for simple things such as '(1 2 +):
(define ans '())
(define (post-pre lst)
(set! ans (list (last lst) (first lst) (second lst))))
For the more complex stuff I have this (which fails to work correctly):
(define ans '())
(define (post-pre-comp lst)
(cond [(pair? (car lst)) (post-pre-comp (car lst))]
[(pair? (cdr lst)) (post-pre-comp (cdr lst))]
[else (set! ans (list (last lst) (first lst) (second lst)))]))
Obviously I am getting tripped up because (cdr lst) will return a pair most of the time. I'm guessing my structure of the else statement is wrong and I need it to be cons instead of list, but I'm not sure how to get that to work properly in this case.
Were you thinking of something like this?
(define (pp sxp)
(cond
((null? sxp) sxp)
((list? sxp) (let-values (((args op) (split-at-right sxp 1)))
(cons (car op) (map pp args))))
(else sxp)))
then
> (pp '(1 2 *))
'(* 1 2)
> (pp '(10 (1 2 3 +) ^))
'(^ 10 (+ 1 2 3))
Try something like this:
(define (postfix->prefix expr)
(cond
[(and (list? expr) (not (null? expr)))
(define op (last expr))
(define args (drop-right expr 1))
(cons op (map postfix->prefix args))]
[else expr]))
This operates on the structure recursively by using map to call itself on the arguments to each call.