How can I count the number of elements in a list tree in Racket? - sql

I am going over some racket exercises, and one of these exercises asks to create a function called "count-trees" that will count all the elements in a ListTree. Per the instructions, a ListTree is a recursive data structure with the following definition(s):
-It can be an integer
-It can be a list or a list with sublists
-Per the instructions, we assume that a list tree can never be empty
Here are a few examples of what a List Tree looks like:
(list 1 2)
(list (list 1)
2
(list 1 4 5))
(list 1
(list 2 1)
1
1)
Now, here is what my code looks like:
(define count-tree (lambda (lst)
(if (empty? lst)
0
(length (lst)))))
When I execute the function, it works but only when there is one list, not on lists that contain sub-lists. It seems to only count how many lists there are, but I want it to count all elements in the list. Is there a way to go about this? Thanks!

Length can be implemented like this:
(define length
(lambda (lst)
(if (empty? lst)
0
(+ 1 (length (cdr lst))))))
And thus:
(length '((1 2) (3 4)))
; ==> 2
Since the list has two elements. It doesn't bother it that the two elements are two lists that also has elements and your function needs to do that. Thus your function need to do one more thing than length does. You need to sum the recursion of the car and the cdr in the event you have a pair in the car, otherwise the same as length.
There are more clever versions of length but I guess you'll learn about that later.

Related

Sum of numeric elements in a nested list LISP

Return the SUM of numeric elements in a nested list using LISP. If there are no numeric elements return an empty list/NIL
Examples:
(6 3 -2 5 (4 2 -3) 4) should return 19
(1 2 3 (-4 5) a b c) should return 7
Asking other people to do your homework for you is almost never a good way of learning anything.
But here's an answer, which is written in a Lisp (Racket) and which does show how you ought to go about solving this problem, and also (I think) demonstrates some nice ways of thinking about problems like this ... but which you almost certainly can't cut and paste.
Note that this does not quite agree with the requirements given: which is supposed to return a non-numeric value for a list with no numbers in it. That breaks a recursive algorithm like this, since the empty list is a list with no numbers in it. So this does something more sensible. Making this answer implement the requirements is left as an exercise to the student.
(define (sum-nested-list l)
(let sum-nested-list-loop ([thing l]
[running-total 0])
(match thing
['()
;; We're done if we've run out of list
running-total]
[(list* (? number? x) r)
;; A list whose first element is a number: add it to the running total
;; and carry on on the rest of the list
(sum-nested-list-loop r (+ running-total x))]
[(list* (? list? x) r)
;; A list whose first element is a nested list: recurse into the
;; nested list
(sum-nested-list-loop r (sum-nested-list-loop x running-total))]
[(list* _ r)
;; A list whose first element is not a number or a nested list:
;; carry on on the rest of the list
(sum-nested-list-loop r running-total)]
[_
;; Not a list at all: explode
(error 'sum-numeric-list "what?")])))
(defun flat-sum (tree)
(let ((count 0))
(tree-equal tree tree :test (lambda (left right)
(if (numberp left)
(incf count left) t)))
count))
1> (flat-sum '(1 2 3 (-4 5) a b c))
7

List split in Elm

Write a function to split a list into two lists. The length of the first part is specified by the caller.
I am new to Elm so I am not sure if my reasoning is correct. I think that I need to transform the input list in an array so I am able to slice it by the provided input number. I am struggling a bit with the syntax as well. Here is my code so far:
listSplit: List a -> Int -> List(List a)
listSplit inputList nr =
let myArray = Array.fromList inputList
in Array.slice 0 nr myArray
So I am thinking to return a list containing 2 lists(first one of the specified length), but I am stuck in the syntax. How can I fix this?
Alternative implementation:
split : Int -> List a -> (List a, List a)
split i xs =
(List.take i xs, List.drop i xs)
I'll venture a simple recursive definition, since a big part of learning functional programming is understanding recursion (which foldl is just an abstraction of):
split : Int -> List a -> (List a, List a)
split splitPoint inputList =
splitHelper splitPoint inputList []
{- We use a typical trick here, where we define a helper function
that requires some additional arguments. -}
splitHelper : Int -> List a -> List a -> (List a, List a)
splitHelper splitPoint inputList leftSplitList =
case inputList of
[] ->
-- This is a base case, we end here if we ran out of elements
(List.reverse leftSplitList, [])
head :: tail ->
if splitPoint > 0 then
-- This is the recursive case
-- Note the typical trick here: we are shuffling elements
-- from the input list and putting them onto the
-- leftSplitList.
-- This will reverse the list, so we need to reverse it back
-- in the base cases
splitHelper (splitPoint - 1) tail (head :: leftSplitList)
else
-- here we got to the split point,
-- so the rest of the list is the output
(List.reverse leftSplitList, inputList)
Use List.foldl
split : Int -> List a -> (List a, List a)
split i xs =
let
f : a -> (List a, List a) -> (List a, List a)
f x (p, q) =
if List.length p >= i then
(p, q++[x])
else
(p++[x], q)
in
List.foldl f ([], []) xs
When list p reaches the desired length, append element x to the second list q.
Append element x to list p otherwise.
Normally in Elm, you use List for a sequence of values. Array is used specifically for fast indexing access.
When dealing with lists in functional programming, try to think in terms of map, filter, and fold. They should be all you need.
To return a pair of something (e.g. two lists), use tuple. Elm supports tuples of up to three elements.
Additionally, there is a function splitAt in the List.Extra package that does exactly the same thing, although it is better to roll your own for the purpose of learning.

While loops working mechanism of a program in Scheme

DrRacket user.
I'm struggling to understand how this program works.I wrote it myself and it does what it must but I can't understand how.
I define while loops as:
(define (while test body)
(if (test)
(begin
(body)
(while test body))
(void)))
Now I need to write a program that applies the given procedure to each element of a mutable list.
Here what I wrote:
(define (mlist-map-while f x)
(while (lambda() (not (null? x)))
(lambda ()
(set-mcar! x (f (mcar x)))
(set! x (mcdr x))))
(void))
So, defining
list1 (mlist 1 2 3)
and applying
(mlist-map-while (lambda (x) (+ x 1)) list1)
we get '(2 3 4).
The thing that I don't understand is how the first element of the list stays in it, because if it's done how I wrote here
(set! x (mcdr x))
the first procedure that sets -mcar! must be useless and be overlapped with the second. Like in this example:
(define list1 (mlist 1 2 3))
(set-mcar! list1 9)
(set-mcdr! list1 (mcdr list!))
and we lack the first element, but this program somehow leaves it in and gives the desired output. I would like to know how it works and whether there is another way of traversing the given list.
There is a big difference between set-cdr! abd set!. The first alters the pair's cdr pointer, while the latter alters the binding, thus what the name should point to.
In your mlist-map-while the variable x alters the car, then changes what x represents, to be the cdr of x. It never changes the cdr so your binding list1 always points to the first pair while x points to the first, then second, etc...
Thus it's more like this:
(define list1 (mlist 1 2 3))
(define list1-ref list1) ; variable pointing to the same value as list1
(set-mcar! list1-ref 9) ; set-car! changes the pair
(set! list1-ref (mcdr list)) ; set! updates what list1-ref points to
list1 ; ==> (9 2 3)
list-ref ; ==> (2 3)
You can iterate over a list in the same fashion without using set!, with recursion:
(define (fold function init lst)
(if (null? lst)
init
(fold function
(function (car lst) init)
(cdr lst))))
(fold + 0 '(1 2 3)
; ==> 6
(fold cons '() '(1 2 3))
; ==> (3 2 1)
Notice that here we recurse and change what lst is, to be the cdr. Every recursion has its own lst, which is not to be confused with the caller's own. It ends up doing the same as set! in your example, without mutation.

Find Prime Factor Too Slow or Crashes

I am currently learning LISP by going through some of the problems on ProjectEuler site. One of the problems asks this:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
I have scrapped together Lisp code that does this. However, for numbers with 9+ digits, it is very slow. Most of the time I never get a solution, whereas for 8 digits, it takes about 4-5 seconds. What's more, sometimes I get "HEAP exceeded" error.
My question is am I doing something wrong in terms of running the code (use Aquamacs)? What are some ways this code can be optimized to be better suited for the task at hand? More importantly, how can "exceeded HEAP" crashes be avoided?
Code:
(defun potential-factors (number)
(loop for x from 1 to (ceiling (/ number 2))
for y = x
collect y))
(defun factors (number)
(let (prime-factors '())
(loop for x in (potential-factors number)
do (if (= (mod number x) 0)
(setq prime-factors (cons x prime-factors))))
prime-factors))
(defun is-prime (n &optional (d (- n 1)))
(if (/= n 1)
(or (= d 1)
(and (/= (rem n d) 0)
(is-prime n (- d 1)))) ()))
(defun problem-3 (number)
(last (sort (remove-if-not #'is-prime (factors number) :from-end t) #'<)))
The problem is that you are creating a list in potential-factors of all the numbers between 1 and n/2. That list takes a huge amount of memory and causes the program to crash. The good news is that you don't need to accumulate these numbers in a list, but simply use one number at a time. In factors replace the line (loop for x in (potential-factors number) with (loop for x from 1 to (ceiling (/ number 2))
That should do the trick.
I'm no mathematician, but another thought: The insight about dividing n by 2 seems to be that factors come in pairs. A is a factor of N only if A times B is N, so B has to be at least 2. But that logic can be extended, right? What about dividing by 3? Once you've checked to see if 3 is a factor, then there is no point in checking all numbers greater than 1/3 N. The same for 4, etc. The observation would seem to be that you really only need to check the numbers such that A is less than or equal to B -- so then what would the limit of that be? Well, if A = B, then A times B = A times A, which means that that in that case, A is the square root of N. So I would think you only need to check up as high as the square root N, instead of all the way up to N / 2.
But I'm no mathematician.
What do you think the result of (potential-factors 600851475143) is? How long would it take to compute a result and how much memory would the result need?

How to remove an element from a list without using remove function in LISP

(defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1))
(if (!= x e)
((my_append e list2 )
(setf y cdr(list1))
(my_remove(e y list2)))
((setf y cdr(list1))
(my_remove(e y list2))
)))))
I am trying to write a function to remove an element from a list but i am getting an error that "It should be lambada function" and I don't know that my code is correct or wrong.
Problems with your code
There are a few problems with your code. First, let's look at it with standard indentation
(defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1)) ; (i)
(if (!= x e)
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
((setf y cdr(list1)) ; (v)
(my_remove(e y list2))))))) ; (vi)
Each of the marked lines has a problem. The syntax for a function call in Lisp is
(function argument…)
That means that in your line (i), you're trying to call a function named (setf x car(list1)) with an argument (if (!= x e) …). Of course, that's not the name of a function, and I suspect that even if it was, you didn't want to call it with the argument (if (!= x e) …). Similarly
(setf x car (list1))
Is trying to to set x to the value of the value of a variable car (and there isn't one), and then assign a new value to the place (list1). Since the syntax for a function call is (function argument…), you want instead:
(setf x (car list1))
If you're trying to sequence forms, you might consider using cond, in which you can provide multiple forms, or progn (see In Common Lisp, why do multi-expression bodies of (if) statements require (progn)?).
For instance, instead of
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
you probably want
(progn
(my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
You'll have some problems with that, too, though. In (iii) and (iv), you'll need to use (cdr list1) and (my_remove e y list2), as discussed above, but you also have the problem that you're evaluating (ii) and (iii), but you're discarding the value.
A simplified approach
I think it might be to your benefit if you think about a simple definition of my-remove. In general, a list is either the empty list () or a cons cell whose car is the first element of the list and whose cdr is the rest of the list. You can use a definition like this, then:
remove(x,list)
if list is empty, then return list (it's empty, so it certainly doesn't contain x)
if list is not empty, then
if the first element of the list is x, then return remove(x,rest(list))
else, the first element of the list is not x, so return a new list whose first element is the first element of list, and whose rest is remove(x,rest(list)).
In code, that looks like:
(defun my-remove (element list)
(if (endp list)
list
(if (eql element (first list))
(my-remove element (rest list))
(list* (first list)
(my-remove element (rest list))))))
CL-USER> (my-remove 1 '(1 2 3 1 2 3))
(2 3 2 3)
Those nested ifs look a bit ugly, and you might want to use cond here, even though you don't need the multiple expression bodies that it permits:
(defun my-remove (element list)
(cond
((endp list)
list)
((eql element (first list))
(my-remove element (rest list)))
(t
(list* (first list) (my-remove element (rest list))))))
Since a cond clause with no body whose test form evaluates to true returns the value of the test form, you can even make that last clause a bit simpler:
(defun my-remove (element list)
(cond
((endp list) list)
((eql element (first list)) (my-remove element (rest list)))
((list* (first list) (my-remove element (rest list))))))