I want to create a list of Fibonacci numbers.
I want to call fib x and it should give me a list till the xth element.
How do I achieve that.
I would calculate fib numbers like this:
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
How do I put the result in a list to call the list till the element I need?
A compact definition (that scales linear) is the following:
fib :: Num n => [n]
fib = 0 : nxt
where nxt = 1 : zipWith (+) fib nxt
fibN :: Num n => Int -> [n]
fibN = flip take fib
What we here do is constructing a list fib that is "cons" of 0 and nxt (the rest of the lists). nxt is defined in the where clause as a "cons" of 1 and and the result of zipWith (+) fib nxt. The zipWith elementwise adds the elements of fib and nxt together, since nxt is always one element "ahead" of fib, we thus add the two last elements together. We then take the first n elements in the fibN function.
So we obtain a list like:
fib nxt
| |
v v
+-------+ +-------+ +-------------+
| (:) | ,->| (:) | ,->| zipWith |
+---+---+ | +---+---+ | +-----+---+---+
| 0 | o---' | 1 | o---' | (+) | o | o |
+---+---+ +---+---+ +-----+-|-+-|-+
^ ^ | |
| `------------------|---'
`-------------------------------'
In case we thus evaluate up to the third element, this means that we call zipWith, and this will produce the sum of the head of fib and nxt and advance both points, like:
fib nxt
| |
v v
+-------+ +-------+ +-------+ +-------------+
| (:) | ,->| (:) | ,->| (:) | ,->| zipWith |
+---+---+ | +---+---+ | +---+---+ | +-----+---+---+
| 0 | o---' | 1 | o---' | 1 | o---' | (+) | o | o |
+---+---+ +---+---+ +---+---+ +-----+-|-+-|-+
^ ^ | |
| `------------------|---'
`-------------------------------'
and so on.
Not a fast way (because your function runs in exponential time), but using your function fib
nfibs :: Int -> [Integer]
nfibs n = take n (map fib [0..])
Related
So I am trying to debug my code to reverse a double-linked list. It runs correctly, but for some reason, when I try to assign the front -> next = front -> prev. It gives to next to NULL, which occurs because NULL is behind the first element of the linked list. I am trying to figure out a way to overcome this issue.
void List::reverse(Node *front) //front == head
{
cout << "Head: " << front << endl;
if(front == NULL)
{
cout << "Head is NULL" << endl;
return;
}
Node *temp = front->next;
cout << "Node *temp = front -> next: " << temp << endl;
front -> next = front -> prev;
cout << "front -> next = front -> prev: " << front->next << endl;
front -> prev = temp;
cout << "front -> prev = temp: " << front->prev << endl;
cout << "-------" << endl;
if(front->prev == NULL)
{
cout << "front->prev: " << front ->prev << endl;
cout << "ITS BEEN REVERSED" << endl;
return;
}
reverse(front->prev);
}
The error is front -> next = front -> prev
The List I'm using for an example is
["Hello", "Human", "test", "Boo"]
With the code above, this is what outputs within the console as I was debugging this.
Reverse Test Below:
--------------
Before Reversed: [Hello, Human, test, Boo]
Head: 0x55a98ae172c0
Node *temp = front -> next: 0x55a98ae17300
front -> next = front -> prev: 0
front -> prev = temp: 0x55a98ae17300
-------
Head: 0x55a98ae17300
Node *temp = front -> next: 0x55a98ae17340
front -> next = front -> prev: 0
front -> prev = temp: 0x55a98ae17340
-------
Head: 0x55a98ae17340
Node *temp = front -> next: 0x55a98ae17380
front -> next = front -> prev: 0
front -> prev = temp: 0x55a98ae17380
-------
Head: 0x55a98ae17380
Node *temp = front -> next: 0
front -> next = front -> prev: 0
front -> prev = temp: 0
-------
front->prev: 0
ITS BEEN REVERSED
---
After Reversed: [Hello]
--------------
I think everything else is pretty okay; I just dont know how to change the
front -> next = front -> prev
It would help you understand what is going on if you draw out the state of your list on each step.
Your list looks like this upon entry to the initial call to reverse():
+-----------+ +-----------+ +----------+ +---------+
| "Hello" [n] -> | "Human" [n] -> | "test" [n] -> | "Boo" [n] -> NULL
NULL <- [p] | <- [p] | <- [p] | <- [p] |
+-----------+ +-----------+ +----------+ +---------+
^
head
front
front is not NULL, so you swap front->next and front-prev, and now the list looks like this:
+-----------+ +-----------+ +----------+ +---------+
| "Hello" [n] -> NULL | "Human" [n] -> | "test" [n] -> | "Boo" [n] -> NULL
+- [p] | <------- [p] | <- [p] | <- [p] |
| +-----------+ +-----------+ +----------+ +---------+
| ^ ^
| head |
| front |
+-------------------------+
front->prev is not NULL, so you execute reverse(front->prev).
front is not NULL, so you swap front->next and front-prev, and now the list looks like this:
+-------------------------------------+
| |
\/ |
+-----------+ +-----------+ | +----------+ +---------+
| "Hello" [n] -> NULL | "Human" [n] -+ | "test" [n] -> | "Boo" [n] -> NULL
+- [p] | +- [p] | <-- [p] | <- [p] |
| +-----------+ | +-----------+ +----------+ +---------+
| ^ | ^ ^ ^
| head | | front |
| +--|-----------------+
+-------------------------+
front->prev is not NULL, so you execute reverse(front->prev).
front is not NULL, so you swap front->next and front-prev, and now the list looks like this:
+-------------------------------------+
| +-------------|----------------+
\/ \/ | |
+-----------+ +-----------+ | +----------+ | +---------+
| "Hello" [n] -> NULL | "Human" [n] -+ | "test" [n] -+ | "Boo" [n] -> NULL
+- [p] | +- [p] | +- [p] | <-- [p] |
| +-----------+ | +-----------+ | +----------+ +---------+
| ^ | ^ | ^ ^ ^
| head | | | | front |
| +--|--------------|--+ |
+-------------------------+ +-------------------+
front->prev is not NULL, so you execute reverse(front->prev).
front is not NULL, so you swap front->next and front-prev, and now the list looks like this:
+-------------------------------------+ +----------------------------------+
| +--------------|--|-------------+ |
\/ \/ | \/ | |
+-----------+ +-----------+ | +----------+ | +---------+ |
| "Hello" [n] -> NULL | "Human" [n] -+ | "test" [n] -+ | "Boo" [n] -+
+- [p] | +- [p] | +- [p] | NULL <- [p] |
| +-----------+ | +-----------+ | +----------+ +---------+
| ^ | ^ | ^ ^ ^
| head | | | | | front
| +--|--------------|--+ |
+-------------------------+ +------------------------+
And finally, front->prev is NULL, so you exit.
The above is a little messy, so let's re-draw it cleaner with the new arrows:
+---------+ +----------+ +-----------+ +-----------+
| "Boo" [n] -> | "test" [n] -> | "Human" [n] -> | "Hello" [n] -> NULL
NULL <- [p] | <- [p] | <- [p] | <- [p] |
+---------+ +----------+ +-----------+ +-----------+
^
head
Look, the nodes were reversed correctly!
However, notice anything wrong? When you try to printout the new list, you only see Hello, because that is where head is still pointing! You need to update head to point at Boo instead:
+---------+ +----------+ +-----------+ +-----------+
| "Boo" [n] -> | "test" [n] -> | "Human" [n] -> | "Hello" [n] -> NULL
NULL <- [p] | <- [p] | <- [p] | <- [p] |
+---------+ +----------+ +-----------+ +-----------+
^
head
If your List class is maintaining both head and tail pointers, you can simply swap them:
void List::reverse(Node *front)
{
...
}
void List::reverse()
{
reverse(head);
Node *temp = head;
tail = head;
head = temp;
}
But, if you don't have a tail pointer, then you will need to make reverse() return the new head pointer after its work is finished, eg:
Node* List::reverse(Node *front)
{
...
if(front == NULL)
{
...
return NULL;
}
...
if(front->prev == NULL)
{
...
return front;
}
return reverse(front->prev);
}
void List::reverse()
{
head = reverse(head);
}
I am struggling to understand the logic of the code below. I know the code will return a list of Fibonacci numbers from the first till nth e.g. fib 3 will produce [2,1,1,0]. I do not understand how 'n' is split up in (x:y:xs).
I would appreciate any light on this.
Thanks
fib 1 = [1, 0]
fib n = x + y : (x:y:xs)
where (x:y:xs) = fib (n-1)
Your comment about "how" the code splits up the list returned by fib I cannot answer as I don't know all the internals of GHC. This process is called patter matching. In Python and other languages you may be familiar with, this can be done
a, b = (1,2)
# a == 1
# b == 2
Your function is of type
fib :: Int -> [Int]
so you can use pattern matching to extract the head, next head, and next tail of the list it returns, which is what happens in
where (x:y:xs) = fib (n-1)
Perhaps an area of confusion is where the list is being reconstructed so it can be appended to the rest of the list you are returning. Your function can also be written like this
fib 1 = [1, 0]
fib n = x + y : (fib (n-1))
where (x:y:xs) = fib (n-1)
I do not understand how n is split up in (x:y:xs).
n is not being split; the list resulting from fib is being split.
The original code:
fib 1 = [1, 0]
fib n = x + y : (x:y:xs)
where (x:y:xs) = fib (n-1)
Is equivalent to the following, with some of the syntactic sugar removed:
fib n =
if n == 1
then [1, 0]
else case fib (n - 1) of
x : (y : xs) -> (x + y) : (x : (y : xs))
_ -> error "pattern match failure"
Since this code just destructures the list and then rebuilds an identical one, the case branch can also be written using an “as” pattern, e.g.: res#(x : y : xs) -> (x + y) : res
So fib is a function which takes one parameter n, which may be of any numeric type. In the base case when n is 1, the code just returns a constant list [1, 0]. In the recursive case, fib calls itself recursively, replacing n with n - 1. The result will be a list, so the function then pattern-matches on that list to extract its components.
In the pattern x : y : xs, which is syntactic sugar for (:) x ((:) y xs), the operator (:) :: a -> [a] -> [a] is the data constructor for a list that is not empty, and x, y, and xs are variables; so this is equivalent to saying “if the input (the result of fib (n - 1)) is non-empty, then name its head x; and if its tail is non-empty, then name the head and tail of that y and xs respectively”. In other words, if it’s a list of at least two elements, then call the first element x, the second y, and the remainder xs (which may be empty).
In fact it can be implemented in that explicit way, as you’d do in a language that lacks pattern-matching, by using guards or if expressions. The result is quite unwieldy and error-prone, but it may be helpful as an illustration of how to mentally break it down:
fib n
| n == 1
= [1, 0]
| let temp1 = fib (n - 1)
, not (null temp1)
, let x = head temp1
, let temp2 = tail temp1
, not (null temp2)
, let y = head temp2
, let xs = tail temp2
= x + y : temp1
| otherwise
= error "pattern match failure"
fib n =
if n == 1
then [1, 0]
else let
temp1 = fib (n - 1)
in if not (null temp1)
then let
x = head temp1
temp2 = tail temp1
in if not (null temp2)
then let
y = head temp2
xs = tail temp2
in x + y : temp1
else error "pattern match failure"
else error "pattern match failure"
Obviously pattern matching is much simpler!
So here’s an example of how the original code would evaluate on the example input you gave, fib 3:
evaluate: fib 3
matches equation #2 with n₀ = 3: let (x₀ : y₀ : xs₀) = fib (3 - 1) in x₀ + y₀ : (x₀ : y₀ : xs₀)
evaluate: fib 2
matches equation #2 with n₁ = 2: let (x₁ : y₁ : xs₁) = fib (2 - 1) in x₁ + y₁ : (x₁ : y₁ : xs₁)
evaluate: fib 1
matches equation #1: [1, 0]
substitute: let (x₁ : y₁ : xs₁) = 1 : 0 : [] in x₁ + y₁ : (x₁ : y₁ : xs₁)
evaluate let with x₁ = 1, y₁ = 0, xs₁ = []: 1 + 0 : (1 : 0 : [])
substitute: let (x₀ : y₀ : xs₀) = 1 : 1 : [0] in x₀ + y₀ : (x₀ : y₀ : xs₀)
evaluate let with x₀ = 1, y₀ = 1, xs₀ = [0]: 1 + 1 : (1 : 1 : [0])
syntactic sugar for lists: [2, 1, 1, 0]
And a diagram, showing how it builds up a list where each element’s value refers to the subsequent two elements:
┌─────┬───────────┬───────┐ ┌─────┬───────────┬───────────┐ ┌─────┬───┬─────┐ ┌─────┬───┬───┐ ┌────┐
… fib 3───▶ (:) │ (+) x₁ y₁ │ fib 2─┼─▶ (:) │ (+) x₀ y₀ │ xs₁/fib 1─┼─▶ (:) │ 1 │ xs₀─┼─▶ (:) │ 0 │ ○─┼─▶ [] │
└─────┴─────┼──┼──┴───────┘ └─────┴──▲──┼──┼──┴───────────┘ └─────┴─▲─┴─────┘ └─────┴─▲─┴───┘ └────┘
└──┼─────────────────────┘ │ └────────────────────────┼─────────────────┘
└────────────────────────┴───────────────────────────┘
ASCII version:
+-----+-----------+-------+ +-----+-----------+-----------+ +-----+---+-----+ +-----+---+---+ +----+
| | | | | | | | | | | | | | | | | |
… fib 3---> (:) | (+) x1 y1 | fib 2-+---> (:) | (+) x0 y0 | xs1/fib 1-+---> (:) | 1 | xs0-+---> (:) | 0 | o-+---> [] |
| | | | | | | | | | | | | | | | | | | | | |
+-----+-----+--+--+-------+ +-----+--^--+--+--+-----------+ +-----+-^-+-----+ +-----+-^-+---+ +----+
| | | | | | |
+--+-----------------------+ | +--------------------------+-------------------+
| | |
+--------------------------+-----------------------------+
Notice the calls to error: if you try to evaluate a pattern match that isn’t exhaustive, it will throw an exception. In this case, fib will always have at least two elements, so the let binding is safe, but consider how you could change the structure of the code to avoid needing this partial match.
This Prolog code returns:
?- [a,b,c,d] = [a|[b,c,d]].
true
and this one
?- [X,Y] = [a|[b,c,d]].
returns false.
I am not totally grasping why [X, Y] is false. Trace is not helpful here. I would expect the following assignment to hold
X = a
Y = [b,c,d]
and the statement be true.
What does | do besides splitting on head and tail?
A list in Prolog is implemented as a linked list of functors. If you write a list like [a, b, c, d]. it looks in reality like:
+-------+
| (|)/2 |
+---+---+ +-------+
| o | o---->| (|)/2 |
+-|-+---+ +---+---+ +-------+
v | o | o---->| (|)/2 |
a +-|-+---+ +---+---+ +-------+
v | o | o---->| (|)/2 |
b +-|-+---+ +---+---+
v | o | o----> []
c +-|-+---+
v
d
or in Prolog notation [a | [b | c | [d | [] ] ] ]. The comma-separated list is syntactical sugar: if you write [a, b, c, d], the Prolog interpreter converts it to a representation as above.
Since [b, c, d] is equal to:
[ b | [ c | [ d | [] ] ] ]
and thus [ a | [b, c, d] ] is thus equal to
[a | [b | c | [d | [] ] ] ]
But the list [X, Y] is just equal to
[X, Y] == [ X | [ Y | [] ] ]
or in a structural way:
+-------+
| (|)/2 |
+---+---+ +-------+
| o | o---->| (|)/2 |
+-|-+---+ +---+---+
v | o | o----> []
X +-|-+---+
v
Y
If we then match it with [a | [b | c | [d | [] ] ] ] this means the "outer" shell can be matched, so X = a, but then Y = b, and [] = [ c | [ d | [] ] ]. The last part does not match, and thus it returns false. The X and Y are thus not the problem. The problem is that [] is a constant, and it does not match with the functor that represents [ c | [d] ].
If we would for example unify [ X | Y ] == [a, b, c, d] we get:
?- [ X | Y ] = [a, b, c, d].
X = a,
Y = [b, c, d].
So to conclude, one can say that | itself "does" nothing. It is a functor, just like f(1, 2). In Lisp they used cons [wiki] for this, and nil for the empty list. So [1, 4, 2, 5] looks in Lisp like cons 1 (cons 4 (cons 2 (cons 5 nil))), or in Prolog it would look like cons(1, cons(4, cons(2, cons(5, nil)))). It is only a bit cumbersome to write. In fact the comma separated notation is more the "magic" part. Prolog just performs unification for lists, just like it does for other functors and constants.
In one Functional Language Family of LISP and with possibility of Defining Variables,
(defvar a '(1 2 3))
(defvar b (cons a (cdr a)))
(rplacd a '(5))
creates the b list as
((1 5) 2 3)
!! I'm surprized. How do these Code Fragments make this list? Could anyone explain these confusing commands ?!
After you do the first two defvar calls, you have the following variable assignments to conses.
A => +---+---+ +---+---+ +---+---+
+--> | 1 | ---->| 2 ---->| 3 | ----> NIL
\ +---+---+ +---+---+ +---+---+
\ --^
\ /
\ /
\ /
\ /
B => +-\-+-|-+
| | | | |
+---+---+
In printed representation, this looks like:
A => (1 2 3)
B => ((1 2 3) 2 3)
When you perform the rplacd, it modifies the cdr of a to refer to a new cons. But the cdr of b still refers to the same cons as it did before this.
+---+---+
->| 5 | ----> NIL
/ +---+---+
/
A => +---+-|-+ +---+---+ +---+---+
+--> | 1 | | | | 2 ---->| 3 | ----> NIL
\ +---+---+ +---+---+ +---+---+
\ --^
\ /
\ /
\ /
\ /
B => +-\-+-|-+
| | | | |
+---+---+
In printed form, this looks like:
A => (1 5)
B => ((1 5) 2 3)
The important thing to understand about Lisp assignments is that they don't make copies of the list structure, they just assign references to the conses (if you're familiar with languages like C, it's like everything is a pointer to a struct).
I know that xs !! n gives me nth element in a list, but I don't know how to edit nth element in that list. Can you tell me how can I edit nth element in a list or give a hint at least?
For example how can I make the second element 'a' an 'e' in this: ['s','t','a','c','k']?
Changing the nth element
A common operation in many languages is to assign to an indexed position in an array. In python you might:
>>> a = [1,2,3,4,5]
>>> a[3] = 9
>>> a
[1, 2, 3, 9, 5]
The
lens package gives this functionality with the (.~) operator. Though unlike in python the original list is not mutated, rather a new list is returned.
> let a = [1,2,3,4,5]
> a & element 3 .~ 9
[1,2,3,9,5]
> a
[1,2,3,4,5]
element 3 .~ 9 is just a function and the (&) operator, part of the
lens package, is just reverse function application. Here it is with more common function application.
> (element 3 .~ 9) [1,2,3,4,5]
[1,2,3,9,5]
Assignment again works perfectly fine with arbitrary nesting of Traversables.
> [[1,2,3],[4,5,6]] & element 0 . element 1 .~ 9
[[1,9,3],[4,5,6]]
or
> set (element 3) 9 [1,2,3,4,5,6,7]
Or if you want to effect multiple elements you can use:
> over (elements (>3)) (const 99) [1,2,3,4,5,6,7]
> [1,2,3,4,99,99,99]
Working with types other then lists
This is not just limited to lists however, it will work with any datatype that is an instance of the Traversable typeclass.
Take for example the same technique works on trees form the standard
containers package.
> import Data.Tree
> :{
let
tree = Node 1 [
Node 2 [Node 4[], Node 5 []]
, Node 3 [Node 6 [], Node 7 []]
]
:}
> putStrLn . drawTree . fmap show $ tree
1
|
+- 2
| |
| +- 4
| |
| `- 5
|
`- 3
|
+- 6
|
`- 7
> putStrLn . drawTree . fmap show $ tree & element 1 .~ 99
1
|
+- 99
| |
| +- 4
| |
| `- 5
|
`- 3
|
+- 6
|
`- 7
> putStrLn . drawTree . fmap show $ tree & element 3 .~ 99
1
|
+- 2
| |
| +- 4
| |
| `- 99
|
`- 3
|
+- 6
|
`- 7
> putStrLn . drawTree . fmap show $ over (elements (>3)) (const 99) tree
1
|
+- 2
| |
| +- 4
| |
| `- 5
|
`- 99
|
+- 99
|
`- 99
Because Haskell is a functional language, you cannot 'edit' elements in lists, because everything is immutable. Instead, you can create a new list with something like:
take n xs ++ [newElement] ++ drop (n + 1) xs
However, it is not recommended in Haskell. For some more information you can see this post: Haskell replace element in list
You can't edit the nth element of a list, values are immutable. You have to create a new list. But due to the immutability, it can share the part after the changed element with the original list.
So if you want to apply a transformation to the nth element of a list (and have the parts before and after identical), you have three parts
the front of the list before the element in question, say front
the element in question, say element
the back of the list after the element in question, say back.
Then you'd assemble the parts
front ++ transform element : back
so it remains to get a hold on the interesting parts in a nice way.
splitAt :: Int -> [a] -> ([a],[a])
does that, splitAt idx list gives back the first part of the list, before the index idx as the first component of the pair, and the rest as the second, so
changeNthElement :: Int -> (a -> a) -> [a] -> [a]
changeNthElement idx transform list
| idx < 0 = list
| otherwise = case spliAt idx list of
(front, element:back) -> front ++ transform element : back
_ -> list -- if the list doesn't have an element at index idx
(Note: I have started counting elements at 0, if you want to start counting at 1, you need to adjust and use idx-1.)
I' surprised the following method was not yet mentioned, so I will add it for further reference:
replace index elem = map (\(index', elem') -> if index' == index then elem else elem') . zip [0..]
> replace 2 'e' "stack"
"steck"
It handle the casse of out of range index.
> replace (-1) 'z' "abc"
"abc"
> replace 0 'z' "abc"
"zbc"
> replace 2 'z' "abc"
"abz"
> replace 3 'z' "abc"
"abc"
It is not slower than the splitAt method ( O(2N) ).
There is also the possibility of writing a simple recursive solution.
The basic idea is that, in order to substitute element #5 in a list, you just have to substitute element #4 in the tail of that list.
Using the notations from the answer of #DanielFisher, this gives the following code:
changeNthElement :: Int -> (a -> a) -> [a] -> [a]
changeNthElement n fn [] = [] -- nothing to change
changeNthElement n fn (x:xs)
| (n < 0) = x:xs -- no change for a negative index
| (n == 0) = (fn x) : xs -- easy case
| otherwise = x : (changeNthElement (n-1) fn xs) -- recursion
If the new value does not depend on the old one, one can specialize the above function:
setNthElement :: Int -> a -> [a] -> [a]
setNthElement n v xs = changeNthElement n (const v) xs
Testing:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
...
λ>
λ> :load q15530511.hs
[1 of 1] Compiling Main ( q15530511.hs, interpreted )
Ok, one module loaded.
λ>
λ> xs = replicate 10 7
λ>
λ> xs
[7,7,7,7,7,7,7,7,7,7]
λ>
λ> changeNthElement 3 (+2) xs
[7,7,7,9,7,7,7,7,7,7]
λ>
λ> setNthElement 2 42 xs
[7,7,42,7,7,7,7,7,7,7]
λ>