Multiply 1st element of every sublist by -1?? Common Lisp - list

As part of a larger project I want to be able to multiple every first element of every sublistby -1. I am trying to do it using recursion at the moment like this:
(defun negative (secondpoly)
(let ((t1(car secondpoly))
(rem(cdr secondpoly)))
(let ((c1(car t1)))
(if (not (null (cdr secondpoly)))
(negative (append (* c1 -1) rem))
)
)
)
)
With this input:
(pminus '((5 x 2)(100 x 2)))
I want to receive this output:
(pminus '((-5 x 2)(-100 x 2)))
I was wondering if someone could show me a way to do this?

If your input really is something like: '(pminus ((5 x 2)(100 x 2)))
(defun negative-first (poly)
(cons (car poly)
(mapcar (lambda (el)
(cons (- (car el)) (cdr el)))
(cadr poly))))
CL-USER> (negative-first '(pminus ((5 x 2)(100 x 2))))
(PMINUS (-5 X 2) (-100 X 2))
But for me it looks like there is a mistake in explanation, and your input is '((5 x 2)(100 x 2)) and if so, your function is:
(defun negative-first (poly)
(mapcar (lambda (el)
(cons (- (car el)) (cdr el)))
poly))
CL-USER> (negative-first '((5 x 2)(100 x 2)))
((-5 X 2) (-100 X 2))
If you need to work with more nested and complex data, you probably should who some examples, this function will work only with one level ((5 x 2) (100 x 2) (40 x 3) .... ).

Related

When using recursion, how can I append or concatenate multiple pairs into a single, longer list?

This is a homework problem, so please point in a good direction w/o giving a solution.
Basically, within Scheme, I am trying to build a multi-bit adder starting with logic gates.
Thanks for reading/helping.
An example I am running is adding 101001 and 011101 with a 1 carry in.
I feel like I had a list and be appending throughout? But if this is the correct step, I cannot get this to work.
(define l-and (lambda (x y) (if (and (equal? x 1) (equal? y 1)) 1 0)))
(define l-or (lambda (x y) (if (or (equal? x 1) (equal? y 1)) 1 0)))
(define l-xor (lambda (x y) (if (or (equal? (l-and x y) 1) (and (equal? x 0) (equal? y 0)) ) 0 1)))
(define l-not (lambda (x) (if (equal? x 0) 1 0)))
(define fulladdr (lambda (x y z)
(cons
(l-xor (l-xor x y) z)
(l-or (l-and x y) (l-and z (l-xor x y)))
)
))
(define (removelast lis)
;(display (reverse(cdr (reverse lis)))) For debugging
(if (null? (cdr lis))
'()
(reverse(cdr (reverse lis)
))))
(define (last-element lis)
;(display (car(reverse lis))) For debugging
(if (null? (cdr lis))
'() (car(reverse lis))
))
(define n-bit-addr (lambda (l1 l2 x)
(if (or (null? l1) (null? l2))
'()
(let ((carry (cdr (fulladdr (last-element l1) (last-element l2) x))))
(let (( sum (car (fulladdr (last-element l1) (last-element l2) x))))
;(display carry) For debugging
(cons
(fulladdr (last-element l1) (last-element l2) x)
(n-bit-addr (removelast l1) (removelast l2) carry)
)))))
When I run my code with this example, a couple others, I get the correct output, kind of: ((1 . 1) (1 . 0) (1 . 0) (0 . 1) (0 . 1) (0 . 1))
I am trying to figure out how to format this so my output would be (111000.1). Basically (Binary . FinalCarry)
Here are some observations. An adder uses carry so you'll need to operate on leas significant digits to most significant.
A list is created from end to beginning. eg. (1 2) can be created (cons 1 (cons 2 '())) which means the second argument (cons 2 '()) needs to be finished.
I guess your arguments are binary digits in a list like (1 0 1 0) as 10. If you had a helper or a named let you could have the two arguments so far, the carry and sum as parameters so that you can use them as state. Also you are calling fulladdr with the same arguments 3 times. Here is what I think you should do:
(define (n-bit-addr l1 l2)
(helper (reverse l1) (reverse l2) 0 '()))
This defeats the purpose of getting and removing the "last" element and rather fetching and removing the first, which is much easier to do in Scheme.
Now here is the rest. I've abstracted some of the challenged out eg. what happens when you do (n-bit-addr '(1 1) '(1 1 1 0)) is magically worked around by not using car and cdr directly.
(define (helper l1 l2 carry acc)
;; actual implementation of n-bit-addr
(if (finished? l1 l2)
(finish acc carry)
(let* ((res (fulladdr (car0 l1) (car0 l2) carry))
(sum (car res))
(carry (cdr res)))
(helper (cdr* l1) <??> <??> <??>))))
(define (car0 lst)
;; returns 0 if lst is null? (car lst) otherwise
)
(define (cdr* lst)
;; return '() if lst is null? (cdr lst) otherwise
)
(define (finished? l1 l2)
;; return #t is both are null?
)
(define (finish sum carry)
;; return whatever structure one would want with the last result
;; I would imagine carry could be the the highest bit if it's set. thus
;; (n-bit-addr '(1) '(1)) ; ==> (1 0)
)
Now if (1 0 1 0) is not satisfactory you should make number->logic and logic->number that transform (1 0 1 0) to #b1010. This can easily be done with list iteration and arithmetic. Since you want to know how to do lists to number I'll do the other way:
(define (number->logic n)
(let loop ((n n) (acc '()))
(cond ((not (zero? n)) (loop (quotient n 2) (cons (remainder n 2) acc)))
((null? acc) '(0))
(else acc))))
(number->logic #b1010) ; ==> (1 0 1 0)
Note that #b1010 is just a fancy way of writing 10
(number->logic 10) ; ==> (1 0 1 0)
The other way around would be to start the accumulator at 0 and for each element in the list in order multiply the accumulator with 2 and add the bit. When the list is null? the accumulator would be the number.
(logic->number '(1 0 1 0)) ; ==> 10
I remember building adders with nand gates at School, but I haven't done so in programming. You should try it.

how to apply a function to all sublists recursively in common lisp?

now I have a list:
(+ x (- 4 9))
I first need (- 4 9) change to (- (4 . 0) (9 . 0))
(please do worry this part too much)
(defun typecheck (A)
(cond
((numberp A)
(cons A 0))
((equal A 'x)
(cons 1 1))
(t A)))
then I need to subtract (4 . 0) and (9 . 0) (still this is not my problem, I don't want to post this function because it is too long...
so it becomes
(+ x (-5 . 0))
now this time I change x to (1 . 1) so the list becomes (+ (1 . 1) (- 5 . 0))
I finally add them together (final result is (-4 . 1))
My main problem is how to let Lisp know I want to calculate them first after I got (- (4 . 0) (9 .0)) ? My function will just go stright to (+ (1 . 1) ((- 4 .0) (9 . 0)) and gave me an error msg.
My process :
(defun check (A)
(cond
((atom A)
(let ((newA (typecheck A)))
(calucalte A)))
((listp A)
(mapcar #'check A))
but this function won't store anything...and I have no idea how to do it :( can anyone give me some help? THANK YOU.
If I understood the problem correctly you should just write a single recursive function handling operations and number/symbol conversion, for example:
(defun tcheck (expr)
(cond
((numberp expr)
(cons expr 0))
((eq expr 'x)
(cons 1 1))
((listp expr)
(cond
((eq (first expr) '+)
(let ((a (tcheck (second expr)))
(b (tcheck (third expr))))
(cons (+ (car a) (car b))
(+ (cdr a) (cdr b)))))
((eq (first expr) '-)
(let ((a (tcheck (second expr)))
(b (tcheck (third expr))))
(cons (- (car a) (car b))
(- (cdr a) (cdr b)))))
(T
(error "Unknown operation"))))
(T expr)))
With the above function
(tcheck '(+ x (- 4 9)))
returns (-4 . 1)

Translating Python into Scheme/Racket

I'm currently trying to translate this python 2 code:
import math
def worstCaseArrayOfSize(n):
if n == 1:
return [1]
else:
top = worstCaseArrayOfSize(int(math.floor(float(n) / 2)))
bottom = worstCaseArrayOfSize(int(math.ceil(float(n) / 2)))
return map(lambda x: x * 2, top) + map(lambda x: x * 2 - 1, bottom)
into racket/scheme code, and having a difficult time.
This is what I have so far:
(define (msortWorstCase n)
(cond
[(equal? 1 n) 1]
[else (let* ([top (msortWorstCase(floor (/ n 2)))] [bottom (msortWorstCase (ceiling (/ n 2)))])
(append (map (lambda (x) (* x 2)) (list top)) (map (lambda (x) (- (* x 2) 1)) (list bottom))))]
)
)
Could anyone tell me where I am going wrong with this?
I am getting the following error:
*: contract violation
expected: number?
given: '(2 1)
argument position: 1st
other arguments...:
Your recursion is making lists of lists of lists of lists... with (list top) and (list bottom).
You should do the same thing in Racket as you did in Python; the base case should be a one-element list, and you should not wrap the results in lists in the recursive case.
(define (msortWorstCase n)
(cond
[(equal? 1 n) '(1)]
[else (let* ([top (msortWorstCase(floor (/ n 2)))]
[bottom (msortWorstCase (ceiling (/ n 2)))])
(append (map (lambda (x) (* x 2)) top)
(map (lambda (x) (- (* x 2) 1)) bottom)))]))

Concatenating list elements - Scheme

If i have a scheme code that generates the following result: (i'm using cons)
'((1 . 0) . 0)
How can i take this, and just simply display 100 as if it were just one integer number and not a list presented with those dots and parenthesis?
Thanks!
EDIT:
my full code:
(define (func X)
(if ( <= X 3 )
X
(cons (modulo X 4) (func(floor(/ X 4)) ))
))
If I understand correctly, you're trying to convert a number from base 10 to base 4, and then display it as a number, but there are several problems with your implementation.
You're building a list as output - but that's not what you want, you want a number. Also, you're traversing the input in the wrong order, and that's not the correct way to find the quotient between two numbers. Perhaps this will help:
(define (func X)
(let loop ((n X) (acc 0) (mult 1))
(if (< n 4)
(+ (* mult n) acc)
(loop (quotient n 4)
(+ (* mult (modulo n 4)) acc)
(* mult 10)))))
Alternatively, you could output a string to stress the fact that the output is not in base 10:
(define (func X)
(let loop ((n X) (acc ""))
(if (< n 4)
(string-append (number->string n) acc)
(loop (quotient n 4)
(string-append (number->string (modulo n 4)) acc)))))
It'll work as expected:
(func 16)
=> 100
Oscar Lopez's answer is excellent. I can't help adding that this problem doesn't need the "loop" construct:
;; translate a string to a base-4 string.
(define (func n)
(cond [(< n 4) (number->string n)]
[else (string-append (func (quotient n 4))
(number->string (modulo n 4)))]))

behavior differently with two input lists with same length vs. with different lengths (Scheme)

the code "tsFunc" gets two lists as input and it will pairs each elements from two lists.
It works most of cases.
but then I find a bit strange behavior when I give 2 equal length of lists (e.g. '(1 2) '(3 4).... or '(a b c) '(1 2 3).... , it works strangely. first, here are code.
[problem 1]
(define (tsFunc lst1 lst2)
(define (helper ls1 ls2 rst)
(reverse (if (or (null? ls1) (null? ls2))
rst
(helper (cdr ls1) (cdr ls2)
(cons (cons (car ls1) (car ls2)) rst)))))
(helper lst1 lst2 '()))
the behavior like this:
1) correct behavior with uneven length of lists :
(tsFunc '(1 2 3) '(a b)) ====> output: ((1 . a) (2 . b))
2) strange behavior with even length of lists
: (tsFunc '(1 2 3) '(a b c)) ===> output (wrong): ((3 . c) (2 . b) (1 . a))
===> expected : ((1 . a) (2 . b) (3 . c))
when the two input lists are same length, what is happening?
do the tsFunc logic have different behavior between the input lists with same lengths vs. the input lists with different lengths?
(Note. as I know, the code needs to have "reverse" for the final result. so it is not because of "reverse" in the code)
[problem 2] with the result of tsFunc => tsFunc result: (1 . 2) (3 . 4) => try to implement product like this (1*2)+(3*4) = 14, so I have like this..
(define (func l1 l2)
(tsFunc (l1 l2) ;; line 2 - how to call tsFunc's result??
(foldl (lambda (acc pair) ;; line 3
(+ acc (* (car pair) (cdr pair)))) ;; line 4
'()
l1 l2))) ;; like this?? or ??
line 3 , 4 ok..that's the logic what to do, then, how to call tsFunc result to use it as input and.. two lists for the last line.. unclear..
The first problem is that you keep reversing the lists at each iteration, if you really need to reverse the output, do it just once at the end:
(define (tsFunc lst1 lst2)
(define (helper ls1 ls2 rst)
(if (or (null? ls1) (null? ls2))
(reverse rst)
(helper (cdr ls1) (cdr ls2)
(cons (cons (car ls1) (car ls2)) rst))))
(helper lst1 lst2 '()))
Now, for the second problem - the code doesn't even compile: you're not correctly calling the tsFunc procedure, and you're calling it in the wrong point. Also the initial value for the accumulator parameter is wrong - you can't use a list if you intend to return a number:
(define (func l1 l2)
(foldl (lambda (acc pair)
(+ acc (* (car pair) (cdr pair))))
0
(tsFunc l1 l2)))
Using the sample input in the question, here's how it would work:
(func '(1 3) '(2 4))
=> 14
In the above tsFunc takes '(1 3) and '(2 4) as inputs, transforming them into '((1 . 2) (3 . 4)) and then foldl preforms the operation (1*2)+(3*4) = 14, as expected.
Since you are allowed to use higher order functions, why not use just SRFI-1 List library fold?
#!r6rs
(import (rnrs base)
(only (srfi :1) fold)) ;; srfi-1 fold stop at the shortest list
(define (func lst1 lst2)
(fold (lambda (x y acc)
(+ acc (* x y)))
0
lst1
lst2))
(func '(1 3) '(2 4 8)) ; ==> 14