Arithmetic expression expressed as tree - scheme

Imagine an arithmetic expression such as (+ 1 (* 2 (- 3 5))) being thought of as a tree-like structure with numbers at the leaves and operator symbols at the interior nodes like below:
+
/ \
1 *
/ \
2 -
/ \
3 5
each node can be expressed by a three element list: (left-operand operator right-operand)
I am trying to write a function
(make-expr left-op operator right-op)
that produces
(left-op operator right-op)
for example:
(make-expr '(6 * 3) '+ '(5 -2)) => ((6 * 3) + (5 - 2))

> (list '(6 * 3) '+ '(5 - 2))
((6 * 3) + (5 - 2)
Yes, it's as simple as using the list function.

Related

Scheme making matrix

I am new to scheme and I'm having problems with matrices in Scheme. I need to create a function that takes one big and one small square matrices (with the condition: the small's length should be divisor of big one) and make a new matrix with doing an operation on the big one with small one. I've successfully split the big matrix to size that I wanted and I’m successfully operating on it to get the result.
Here is how I did it:
(define (matrix-op big small x y)
(if (< y (/ (length big) (length small))))
(if (< x (/ (length big) (length small)))
(cons (calculate (split-y (split-x big small x) small y) small)
(matrix-op big small (+ x 1) y))
(matrix-op big small 0 (+ y 1)) ; <- this is where i need to split
)
'()
)
)
My calculate function returns only 1 atomic value so when I run the function like this it gives me an output like '(val val val val), but what i want is formatting the output like '((val val) (val val)). How can I do it? Thanks in advance.
I realized that I couldn't explain the problem properly. What i want to have is a function that takes two different square matrices one big and one small, Splits the big one to same size as smaller one, operates on them to create a new matrix that has the size m/n if the big one is mxm and small one is nxn. Example:
big '( small '(
(8 0 3 1 5 3 2 2) (8 4)
(7 1 1 4 3 7 1 4) (9 5)
(1 3 7 4 3 6 6 3) )
(0 9 8 6 5 6 4 3)
(1 7 6 9 6 6 7 2)
(5 7 1 0 2 9 5 3)
(0 5 4 6 6 6 3 0)
(3 6 2 7 7 5 7 0)
)
I need to split big over the same size as small and calculate results like:
for x=0 y=0 part is '( calculate result is 5
(8 0)
(7 1)
)
for x=1 y=0 part is '( calculate result is 2
(3 1)
(1 4)
)
I actually did returned the results calculated but with the method i gave above my return was like '(5 2 4 2 2 6 4 4 4 3 5 4 2 4 6 3) but I wanted to return as:
'(
(5 2 4 2)
(2 6 4 4)
(4 3 5 4)
(2 4 6 3)
)
So how can I manage to split the return list where i want to split?
I think you are trying to do too much at once. It is always OK to split a bigger problem into a smaller problem.
If I understand yours, the idea is to take two square matrics, one of which may be some multiple of the other’s dimensions, and perform a pair-wise operation on the elements. For example:
'((1 2 3) '((1 2 3) '((7 7 7) '(( 8 9 10)
(4 5 6) + '((7)) --> (4 5 6) + (7 7 7) --> (11 12 13)
(7 8 9)) (7 8 9)) (7 7 7)) (14 15 16))
I will continue with the assumption that this is what is desired.
Notice that if the two matrices were the same size, a simple nested map would easily combine all elements. What is left is the problem of the different sizes.
Solve that and you are golden.
Recap:
(define (f op small-M big-M)
(f-apply-pairwise-op
op
(f-biggify small-M (/ (length big-M) (length small-M)))
big-M))
Now you have broken the problem into two smaller pieces:
(define (f-apply-pairwise-op op A B) ...) ; produces pairwise 'A op B'
(define (f-biggify M n) ...) ; tile M n times wider and taller
Good luck!

Preserving list structure with sorting a list of sublists in Lisp [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
So I have list structure as follows:
(defparameter *list* '( ((2 2 2) (0.1))
((5 5 5) (0.4))
((1 1 1) (1.2))
((3 3 3) (3.4))
((4 4 4) (4.5)) )
I want to sort it where it returns an output of
'( ((1 1 1) (1.2))
((2 2 2) (0.1))
((3 3 3) (3.4))
((4 4 4) (4.5)) )
So here is my attempt:
(sort *list*
#'(lambda (a b)
(< (squared a '(0 0 0))
(squared b '(0 0 0))))
:key #'first)
Where squared takes in two lists and calculates the squared distance of each element and sums them (ie (squared '(1 2 3) '(0 3 5)) => 48))
I am sorting the list of lists by its first element of the sublist '(# # #) and calculating the distance from '(0 0 0) then sorting by that distance.
But my attempt outputs the following => ((1) (1 1 1) (2) (3) (2 2 2) (4) (5) (3 3 3) (4 4 4) (5 5 5))
How do I sort by '(# # #) but also preserve the list structure? Also using Common Lisp!
Thank you!
EDIT
I had typed into lisp wrong but correctly into this forum. I had typed list as the following
(defparameter list '( (2 2 2) (0.1)
(5 5 5) (0.4)
(1 1 1) (1.2)
(3 3 3) (3.4)
(4 4 4) (4.5) ))
Careful: sort may destroy the input data. Your input as shown here contains literal data. Modifying literal data has undefined consequences. Use copy-tree or copy-list to create non-literal from literal data.
Actually my first attempt works! I just typed in list incorrectly (forgot some parenthesis). So it sorts and maintains the structure!

functional forward checking implementation

I would like to implement the forward checking search algorithm in a functional way in scheme. Forward checking search is a depth first search that chooses a variable at each node of a graph, tries all the values in the domain of this variable and recursively calls itself until a variable domain is empty or a solution is found. In pseudo code the algorithm is
bool ForwardChecking ()
if no free variable then
return true
choose a free variable var
for all values in the domain of var
assign value to var
update the domains of the free variables
if no domain is empty or inconsistent then
if (ForwardChecking ()) then
return true
return false
In my particular problem I have a vector where some of the elements have seteq representing the possible values that element can take and other elements have an integer. For example a 6x6 vector is
#(1 (seteq 2 4 6) 5 (seteq 2 3 6) (seteq 2 3 4 6) (seteq 3 4)
(seteq 2 3 4) (seteq 2 4 6) (seteq 2 3 6) (seteq 2 3 6) 1 (seteq 3 4 5)
6 (seteq 1 2 5) (seteq 1 2 3) 4 (seteq 2 3 5) (seteq 1 3 5)
(seteq 2 3 5) (seteq 1 2 5) 4 (seteq 1 2 3) (seteq 2 3 5) 6
(seteq 2 4 5) 3 (seteq 1 2 6) (seteq 1 6) (seteq 4 6) (seteq 1 4)
(seteq 4)(seteq 1 4 6) (seteq 1 6) 5 (seteq 3 4 6) 2)
my goal is to figure out the integer that goes into the elements of the vector with seteq using forward checking.
My incomplete attempt at implementing the algorithm in scheme follows
(find-min-pos is a function that finds the positions of all elements of the vector with the smallest number of integers; vector-update is a function that sets one of those elements to one of the integers in its seteq)
(define (forward-checking vec)
; get list of position of elements of vec with smallest number of
; seteq elements
(define min-free-pos (find-min-pos vec))
(cond
; if no free variable return true
[(empty? min-free-pos) #t]
; pick a random element of min-free-pos
[else
(define free-elem-pos (list-ref min-free-pos (random (length min-free-pos))))
; find the vector element
(define free-elem (board-ref board free-elem-pos))
; loop through all values that free-elem contains
; this is a seteq
(for ([i (in-set free-elem)])
(define vec2 (vector-update vec free-elem-pos i))
; the following is incorrect
(if vec2
if forward-checking vec2)
)
#f]
))
How to complete it? Is there a different (maybe more functional) way of implementing it?

Scheme add columns in a matrix

I am trying to write a function that takes a matrix (represented as a list of lists) and adds the elements down the columns and returns a vector (represented as a list):
Example:
(define sample
'((2 6 0 4)
(7 5 1 4)
(6 0 2 2)))
should return '(15 11 3 10).
I was trying to use the (list-ref) function twice to obtain the first element of each column with no luck. I am trying something like:
(map (lambda (matrix) ((list-ref (list-ref matrix 0) 0)) (+ matrix))
The solution is simple if we forget about the indexes and think about higher-order procedures, try this:
(define sample
'((2 6 0 4)
(7 5 1 4)
(6 0 2 2)))
(apply map + sample)
=> '(15 11 3 10)
Explanation: map can take multiple lists as arguments. If we apply it to sample (which is a list of lists) and pass + as the procedure to do the mapping, it'll take one element from each list in turn and add them, producing a list with the results - effectively, adding all the columns in the matrix.

Range data type or generator in Emacs Lisp (elisp)?

What is elisp's equivalent for Python's range(start, end, [step])?
number-sequence is similar to python's range but its output is quite different.
For example:
(number-sequence 5)
=> (5)
(number-sequence 1 5)
=> (1 2 3 4 5)
(number-sequence 1 5 2)
=> (1 3 5)
I use this function to give me an output like that from python's range:
(defun py-range (start &optional end step)
(unless end
(setq end start
start 0))
(number-sequence start (1- end) step))
Now everything works as expected:
(py-range 5)
=> (0 1 2 3 4)
(py-range 1 5)
=> (1 2 3 4)
(py-range 1 5 2)
=> (1 3)
(number-sequence FROM &optional TO INC)

Resources