Recursive functions in haskell? - haskell

I am trying to learn Haskell and was working on a book problem on recursive functions.
> If X_1 = 1 then X_2 = 1 + X_1 = 2, X_3 = 1 + X_1 + X_2
or when it is 5, X_5 = 1 + X_4 + X_3 + X_2 + X_1 = 16, and so forth.
I tried doing this on haskell:
test :: Int -> Int
test 1 = 1
test n = sum[test n .. test (n-1)]
but the output is always 1. I think I have to do a function guard first and then sum it but I dont know how to do it with recursive behavior.

A good place to start is with list comprehensions:
[ test i | i <- [1..5] ]
means
[ test 1, test 2, test 3, test 4, test 5 ]
See if you can solve it now.
Don't forget to add 1!

This part of your code is a Haskell range
[test n .. test (n-1)]
Ranges work by figuring out the left number and the right number, and then constructing a list that contains all steps from the left number to the right number. So:
[1 .. 6] --> [1,2,3,4,5,6]
[5 .. 9] --> [5,6,7,8,9]
As you can see, the default step is 1, so if you have a left number that is higher than the right, you will get an empty list:
[4 .. 3] --> []
As an aside, You can override the default step by providing another number:
[1, 3 .. 6] --> [1,3,5] -- step is 2
[8, 6 .. 3] --> [8,6,4] -- step is -2
As you can see, when you have another step size than 1, you have to be careful with what gets included in the resulting list. This goes especially for negative steps, and even more if you have non-integer steps like [1, 1.25, .. 2.1]. You should almost never generate a list of non-integer numbers using a range.
In your solution you have the line
test n = sum[test n .. test (n-1)]
According to the rules for ranges, this is bound to go wrong. When the program tries to make the list from the range, it tries to compute test n since that is the left number of the range. But that gets us nowhere, since test n is what this whole line is trying to compute in the first place. So we have an infinite loop, and the program hangs.
You could try to do
test n = sum[1 .. test (n-1)]
That looks closer to the examples you gave. It starts with 1 (which is test 1), and ends with test (n-1). But the problem is those values in between. Because ranges have the step of one, what you end up with is:
[1 .. test (n-1)] --> [1,2,3, ......., test (n-1)]
which is not the same as
[test 1, test 2, test 3, .... , test (n-1)]
And since a range can only have a constant step, there is no way to get this last line with a simple range, even if you override the default step. One hint on how to solve this is to notice the number of elements in the list.
length [1 .. test (n-1)] --> test (n-1),
-- because [1,2,3] has 3 elements, [1,2,3,4] has 4 and so on
length [test 1, test 2, test 3, ....... , test (n-1)] --> n-1
-- this is not quite Haskell syntax
The Haskell way here is to make a list that has the correct number of elements, and then transform it so each element is the correct one. How do you make a list of (n-1) elements? Simple:
[1..(n-1)]
From here you can go several ways. There is the list comprehension from luqui:
[test x | x <- [1..(n-1)]]
You can think of this as taking each number out of the range, assigning it to x and then applying the test function to x, so you get [test 1, test 2, test 3, ....... , test (n-1)]. Another way would be to use the map function:
map test [1..(n-1)]
I think of this as applying test to each element of the list at the same time, but it is exactly the same thing as the list comprehension, just two ways of looking at it. Notice that both ways use the [1..(n-1)] range.
If you use either of these instead of the [test n .. test (n-1)] range in your original code, you are very close to the solution. The only thing missing, as luqui reminds, is to remember to add the 1.

Related

how to change the type of constraint's arguments in ortools

I don't know my question is possible or not. I am using ortools to solve an optimization problem and I know in the part of conditions the argument should be defined in double type, like this:
constraints[i] = solver.Constraint(0.0 , 10,0)
But my problem is that, I don't want to use this type of argument in creating conditions. For example I want to have a list.
So I wrote this in my code:
constraints[i] = solver.Constraint([1,2,3,...])
And I got this error:
return _pywraplp.Solver_Constraint(self, *args)
NotImplementedError: Wrong number or type of arguments for overloaded
function 'Solver_Constraint'.
Possible C/C++ prototypes are:
operations_research::MPSolver::MakeRowConstraint(double,double)
operations_research::MPSolver::MakeRowConstraint()
operations_research::MPSolver::MakeRowConstraint(double,double,std::string
const &)
operations_research::MPSolver::MakeRowConstraint(std::string const &)
Is there any way to change the type of condition's argument?
My Assumptions
your constraint expression is "a sum of some lists", meaning something along the lines of what the NumPy library does: e.g., if you have two lists of values, [1, 2, 3] and [4, 5, 6], their sum would be element-wise, s.t. [1, 2, 3] + [4, 5, 6] = [1+4, 2+5, 3+6] = [5, 7, 9].
your "list constraint" is also element-wise; e.g., [x1, x2, x3] <= [1, 2, 3] means x1 <= 1, x2 <= 2 and x3 <= 3.
you're using the GLOP Linear Solver. (Everything I say below applies to the ILP/CP/CP-SAT solvers, but some of the particular method names/other details are different.)
My Answer
The thing is, ortools only lets you set scalar values (like numbers) as variables; you can't make a "list variable", so to speak.
Therefore, you'll have to make a list of scalar variables that effectively represents the same thing.
For example, let's say you wanted your "list variable" to be a list of values, each one subjected to a particular constraint which you have stored in a list. Let's say you have a list of upper bounds:
upper_bounds = [1, 2, 3, ..., n]
And you have several lists of solver variables like so:
vars1 = [
# variable bounds here are chosen arbitrarily; set them to your purposes
solver.NumVar(0, solver.infinity, 'x{0}'.format(i))
for i in range(n)
]
vars2 = [...] # you define any other variable lists in the same way
Then, you would make a list of constraint objects, one constraint for each upper bound in your list:
constraints = [
solver.Constraint(0, ubound)
for ubound in upper_bounds
]
And you insert the variables into your constraints however is dictated for your problem:
# Example expression: X1 - X2 + 0.5*X3 < UBOUND
for i in range(n):
constraints[i].SetCoefficient(vars1[i], 1)
constraints[i].SetCoefficient(vars2[i], -1)
constraints[i].SetCoefficient(vars3[i], 0.5)
Hope this helps! I recommend taking (another, if you already have) look at the examples for your particular solver. The one for GLOP can be found here.

Periodicity (Fibonacci mod sequence) in infinites list Haskell

I need to create a function in Haskell, which works as follows
periodicity ::[Integer] ->[Integer]
periodicity [1,2,3,3,4,1,2,3,3,4...] = [1,2,3,4]
periodicity [0,1,2,2,5,4,3,3,0,1,2,5,4...] = [0,1,2,5,4,3]
That is to say, that from a list you get the part that is always repeated, what in Mathematical Sciences would be called period of a function.
I've tried this, but I doesn't work like I want for the reason that I want that work with infinites list
periodicty :: Eq a => [a] -> [a]
periodicity xs = take n xs
where l = length xs
n = head [m | m <- divisors l,
concat (replicate (l `div` m) (take m xs)) == xs]
I have found this function that gives me the length of period, I could have solved the problem, but I don't understand the code after where:
periodo 1 = 1
periodo n = f 1 ps 0
where
f 0 (1 : xs) pi = pi
f _ (x : xs) pi = f x xs (pi + 1)
ps = 1 : 1 : zipWith (\u v -> (u + v) `mod` n) (tail ps) ps
The function you want, as you have stated it, is impossible1.
But since you said you are really after is the Pisano period, it's enough to notice that two successive numbers is enough to determine the remainder of a fibonacci sequence (mod n or otherwise). So you are really looking for the first reoccurrence of an adjacent pair, e.g.
0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0
^^^^ ^^^^
[--------- 8 -----------)
I am not much for coding people's problems for them, but I can sketch the way I would solve this. One thing to keep in mind is that the periodicity might have a prefix that does not repeat -- I don't know whether this actually occurs in Fibonacci sequences mod n, but it occurs in general. So we need to be prepared to throw away a prefix.
First, zip the list with its tail to get a list of adjacent pairs
[ 0, 1, 1, 2, 0, 2, 2, 1 ...]
-> [(0,1), (1,1), (1,2), (2,0), (0,2), (2,2), (2,1), ... ]
From this, fold through the list building a Data.Map keyed on this pair, where the value is the index it first occurred. You could do this with foldr but I'd probably just use a recursive function with an accumulator. For the above example the map at each step would look like:
{(0,1): 0}
{(0,1): 0, (1,1): 1}
{(0,1): 0, (1,1): 1, (1,2): 2}
{(0,1): 0, (1,1): 1, (1,2): 2, (2,0): 3}
...
When you reach a point in the list where the key is already present, you can then subtract the current index from the one in the map, and there's your period.
1 Here's a proof. Let's say you have the specification for a Turing machine, and you make a list steps of the steps of its execution. This list will be finite if it halts, infinite otherwise. Now construct this list:
bad = zipWith const (cycle [1,2,3]) steps ++ cycle [1,2,3,4]
This list cycles with period 3 as long as the machine runs, and with period 4 afterward. So if the Turing machine halts, periodicity bad = 4, otherwise periodicity bad = 3. That is, periodicity can decide the halting problem, which is impossible.
What you are asking for is impossible for an arbitrary infinite list. We can only examine a finite sublist in finite time, and the next element of the list might, for all we know, break the pattern.
In your comments, you clarify that you really are looking for a periodic part of the Fibonacci sequence, modulo m. In that special case, it is possible, if I understand you correctly.
The Fibonacci sequence (mod m) is periodic after a certain point if either the same value repeats three times: the previous two values are both equal to their predecessors, so the function becomes periodic with a period of 1. It is also periodic after a certain point if any sequence of two or more numbers repeats even once, as then we know that the this value and its predecessor are repeats of the ones k and k-1 terms ago, and the function will generate the same subsequence again with period k. There is no shorter period, or we would have detected it, going left to right.
Furthermore, any sequence that repeats infinitely will repeat once first, so this detects all such sequences.
Therefore, a better way to calculate this than I originally wrote would be to search for the current number and its predecessor earlier in the list. (You can use luqui’s strategy of building a list of consecutive pairs, or search the same data structure recursively instead of building a new one.) If a match exists, the sequence is guaranteed to repeat with a period equal to the distance between the two appearances of the same pair.
That takes time quadratic in the length of the non-periodic initial subsequence, since you search each initial subsequence from the beginning. To do it in linear time with an upper bound of m ²+2 steps: we know there are only m possible values, meaning only m ² possible pairs of values, a sequence of k numbers contains k-1 consecutive pairs of numbers, and therefore by the pigeonhole principle the first m ²+2 elements of the sequence must contain some pair of consecutive values in two different places, and become periodic from the first instance of the pair onward. So searching that fixed-length initial subsequence suffices, and we can build a table of the index (if any) of each of the n ² potential pairs in the list until we encounter the first duplicate. (That said, we would need to use a mutable array, so we sacrifice either speed or functional purity.)
This is similar to lugui’s algorithm, but with a faster lookup.
Conjecture
The sequence is periodic iff 0:1 appears more than once. If every Fibonacci sequence (mod m) is periodic, then the period is simply the position of the second occurrence of [0,1].
0:1 would be generated only by a preceding -1:1, which would be generated by a preceding -3:2, which would be generated by a preceding -8:5, and so on. [...,-8,5,-3,2,-1,1,0] is exactly the fibonacci sequence, backwards, with alternating sign, mod m, and if any two consecutive numbers appear in the original sequence, it is periodic. Thus, iff [0,1,1] would ever be generated by this pattern, it will eventually generate 0:1 in the Fibonacci sequence mod m. This occurs iff m-1 and 1 occur consecutively in Fibo mod m, in either order.
Two Special Cases
If Fibo mod m contains m-1:1 at position i, the sequence has period i+2, and if it contains 1:m-1, the sequence has period 2 i+4. (If the sequence contains 1:-1, the next position is i+2 and the next i+2 steps are: {0,-1,-1,-2,-3,-5,...,-1,1}). So this lets us shortcut a bit; when we see 1,4 at position 8 of Fibo mod 5, we know the sequence has a period of 20. In this special case, the scan needs fewer than half the elements on average, has an upper bound of m ²/2+1 elements to scan in order to rule the case out, and uses constant memory.

Mutable variables in Haskell?

I'm starting to wrap my head around Haskell and do some exciting experiments. And there's one thing I just seem to be unable to comprehend (previous "imperativist" experience talks maybe).
Recently, I was yearning to implement integer division function as if there where no multiply/divide operations. An immensely interesting brain-teaser which led to great confusion.
divide x y =
if x < y then 0
else 1 + divide (x - y) y
I compiled it and it.. works(!). That's mind-blowing. However, I was told, I was sure that variables are immutable in Haskell. How comes that with each recursive step variable x keeps it's value from previous step? Or is my glorious compiler lying to me? Why does it work at all?
Your x here doesn't change during one function call (i.e., after creation) - that's exactly what immutable means. What does change is value of x during multiple (recursive) calls. In a single stack frame (function call) the value of x is constant.
An example of execution of your code, for a simple case
call divide 8 3 -- (x = 8, y = 3), stack: divide 8 3
step 1: x < y ? NO
step 2: 1 + divide 5 3
call: divide 5 3 -- (x = 5, y = 3), stack: divide 8 3, divide 5 3
step 1: x < y ? NO
step 2: 1 + divide 2 3
call divide 2 3 -- (x = 2, y = 3), stack: divide 8 3, divide 5 3, divide 2 3
step 1: x < y ? YES
return: 0 -- unwinding bottom call
return 1 + 0 -- stack: divide 8 3, divide 5 3, unwinding middle call
return 1 + 1 + 0 -- stack: divide 8 3
I am aware that the above notation is not anyhow formalized, but I hope it helps to understand what recursion is about and that x might have different values in different calls, because it's simply a different instance of whole call, thus also different instance of x.
x is actually not a variable, but a parameter, and isn't that different from parameters in imperative languages.
Maybe it'd look more obvious with explicit return statements?
-- for illustrative purposes only, doesn't actually work
divide x y =
if x < y
then return 0
else return 1 + divide (x - y) y
You're not mutating x, just stacking up several function calls to calculate your desired result with the values they return.
Here's the same function in Python:
def divide(x, y):
if x < y:
return 0
else:
return 1 + divide(x - y, y)
Looks familiar, right? You can translate this to any language that allows recursion, and none of them would require you to mutate a variable.
Other than that, yes, your compiler is lying to you. Because you're not allowed to directly mutate values, the compiler can make a lot of extra assumptions based on your code, which helps translating it to efficient machine code, and at that level, there's no escaping mutability. The major benefit is that compilers are way less likely to introduce mutability-related bugs than us mortals.

What is the fastest way to generate the first n powers of 2?

I'm writing in Python, and any tiny optimizations would help (I'm 0.01 seconds off the time limit). I need to generate a list of the first n powers of 2:
[1, 2, 4, ... 2 ^ n]
I have a few pieces of code written now:
powers = [1 << i for i in range(n)]
or
powers = [1 for i in range(n)]
for i in range(1, n):
powers[i] = powers[i - 1] * 2
What optimizations can i make to these pieces of code, or is there a new way of approaching the problem entirely?
A good interpreter will convert multiplication by 2 and left shift into the same bytecode instruction(s).So both the approaches should eventually translate to same bytecode,hence same speed.

Counting change in Haskell

I came across the following solution to the DP problem of counting change:
count' :: Int -> [Int] -> Int
count' cents coins = aux coins !! cents
where aux = foldr addCoin (1:repeat 0)
where addCoin c oldlist = newlist
where newlist = (take c oldlist) ++ zipWith (+) newlist (drop c oldlist)
It ran much faster than my naive top-down recursive solution, and I'm still trying to understand it.
I get that given a list of coins, aux computes every solution for the positive integers. Thus the solution for an amount is to index the list at that position.
I'm less clear on addCoin, though. It somehow uses the value of each coin to draw elements from the list of coins? I'm struggling to find an intuitive meaning for it.
The fold in aux also ties my brain up in knots. Why is 1:repeat 0 the initial value? What does it represent?
It's a direct translation of the imperative DP algorithm for the problem, which looks like this (in Python):
def count(cents, coins):
solutions = [1] + [0]*cents # [1, 0, 0, 0, ... 0]
for coin in coins:
for i in range(coin, cents + 1):
solutions[i] += solutions[i - coin]
return solutions[cents]
In particular, addCoin coin solutions corresponds to
for i in range(coin, cents + 1):
solutions[i] += solutions[i - coin]
except that addCoin returns a modified list instead of mutating the old one. As to the Haskell version, the result should have an unchanged section at the beginning until the coin-th element, and after that we must implement solutions[i] += solutions[i - coin].
We realize the unchanged part by take c oldlist and the modified part by zipWith (+) newlist (drop c oldlist). In the modified part we add together the i-th elements of the old list and i - coin-th elements of the resulting list. The shifting of indices is implicit in the drop and take operations.
A simpler, classic example for this kind of shifting and recursive definition is the Fibonacci numbers:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
We would write this imperatively as
def fibs(limit):
res = [0, 1] + [0]*(limit - 2)
for i in range(2, limit):
res[i] = res[i - 2] + res[i - 1]
return res
Turning back to coin change, foldr addCoin (1:repeat 0) corresponds to the initialization of solutions and the for loop on the coins, with the change that the initial list is infinite instead of finite (because laziness lets us do that).

Resources