How does this Haskell function work? - haskell

I was struggling to see how this function worked. For the nth number it should calculate the sum of the previous three elements.
f' :: Integer->Integer
f' = helper 0 0 1
where
helper a b c 0 = a
helper a b c n = helper b c (a+b+c) (n-1)
Thanks for your time

Perhaps the part that you're missing is that
f' = helper 0 0 1
is the same thing as
f' x = helper 0 0 1 x
Otherwise, see Dave's answer.

It's a fairly simple recursive function. When called with three elements (I'm guessing seeds for the sequence) and a number of terms, it calls itself, cycling the seed left by one and adding the new term (a+b+c). When the "number of steps remaining" counter reaches 0, the edge case kicks in and just returns the current sequence value. This value is passed back up all the function calls, giving the final output.
The f' function provides a simple wrapper around the helper function (which does the work I described above), providing a standard seed and passing the requested term as the 4th parameter (MathematicalOrchid explains this nicely).

say its called with f' 5
below is the sequence in which it will get executed:
iteration 1: helper 0 0 1 5
iteration 2: helper 0 1 (0+0+1) 4
iteration 3: helper 1 1 (0+1+1) 3
iteration 4: helper 1 2 (1+1+2) 2
iteration 5: helper 2 4 (1+2+4) 1
iteration 6: helper 4 7 (2+4+7) 0 => 4

It is like a Fibonacci sequence, but for 3 numbers, not 2:
F'_n = F'_{n-1} + F'_{n-2} + F'_{n-3}
where Fibonacci sequence is
F_n = F_{n-1} + F_{n-2}

Related

function to get the highest common divisor between two numbers

I am trying to implement a function to get the highest common divisor between two numbers, but I am getting an error Ambiguous variable occurrence "gcd".
gcd a 0 = 0
gcd 0 a = 0
gcd a b = if a > b
then (if mod a b == 0 then a else gcd a (b-1))
else (if mod b a == 0 then b else gcd (a-1) b)
How it will be executed:
1- find the greatest of two numbers
2- then the greatest mod smallest; if it equals zero then it will return the smallest, otherwise
it will call method again but with (smallest - 1) and the same value for the greatest

Sum of arrays with repeated indices

How can I add an array of numbers to another array by indices? Especially with repeated indices. Like that
x
1 2 3 4
idx
0 1 0
y
5 6 7
] x add idx;y NB. (1 + 5 + 7) , (2 + 6) , 3 , 4
13 8 3 4
All nouns (x, idx, y) can be millions of items and I need to fast 'add' verb.
UPDATE
Solution (thanks to Dan Bron):
cumIdx =: 1 : 0
:
'i z' =. y
n =. ~. i
x n}~ (n{x) + i u//. z
)
(1 2 3 4) + cumIdx (0 1 0);(5 6 7)
13 8 3 4
For now, a short answer in the "get it done" mode:
data =. 1 2 3 4
idx =. 0 1 0
updat =. 5 6 7
cumIdx =: adverb define
:
n =. ~. m
y n}~ (n{y) + m +//. x
)
updat idx cumIdx data NB. 13 8 3 4
In brief:
Start by grouping the update array (in your post, y¹) where your index array has the same value, and taking the sum of each group
Accomplish this using the adverb key (/.) with sum (+/) as its verbal argument, deriving a dyadic verb whose arguments are idx on the left and the update array (your y, my updat) on the right.
Get the nub (~.) of your index array
Select these (unique) indices from your value array (your x, my data)
This will, by definition, have the same length as the cumulative sums we calculated in (1.)
Add these to the cumulative sum
Now you have your final updates to the data; updat and idx have the same length, so you just merge them into your value array using }, as you did in your code
Since we kept the update array small (never greater than its original length), this should have decent performance on larger inputs, though I haven't run any tests. The only performance drawback is the double computation of the nub of idx (once explicitly with ~. and once implicitly with /.), though since your values are integers, this should be relatively cheap; it's one of J's stronger areas, performance-wise.
¹ I realize renaming your arrays makes this answer more verbose than it needs to be. However, since you named your primary data x rather than y (which is the convention), if I had just kept your naming convention, then when I invoked cumIdx, the names of the nouns inside the definition would have the opposite meanings to the ones outside the definition, which I thought would cause greater confusion. For this reason, it's best to keep "primary data" on the right (y), and "control data" on the left (x).You might also consider constraining your use of the special names x,y,u,v,m and n to where they're already implicitly defined by invoking an explicit definition; definitely never change their nameclasses.
This approach also uses key (/.) but is a bit more simplistic in its approach.
It is likely to use more space especially for big updates than Dan Bron's.
addByIdx=: {{ (m , i.## y) +//. x,y }}
updat idx addByIdx data
13 8 3 4

Calculate The Total Result of The Arithmetic Sequence With Big Number in Less Than 1 Second

How to Construct a Python 3 function sum(n) that takes a positive integer n as an input and perform the following computation:
sum(n)=5+10+⋯+5(n−1)+5n.
The value of 𝑛n is between 1 and 10^15. The timelimit for the computation is 1 second. To make your code efficient, try to use the explicit formula (closed form) of sum(n).
Test:
print(sum(1))
print(sum(2))
print(sum(3))
Result:
5
15
30
What I Have Tried:
def sum(n):
AK = 0
n += 1
for i in range(1,n):
P = 5 * i
AK += P
return AK
Unfortunately it takes more than 1 second to finish
as Hans Kesting said, the result is 5 times the sum of 1...n and so you can try this simple and easy piece of code. I haven't actually tried it but in practice, it should be less than one second
def sum(n):
return 5 * (n * (n + 1) // 2)

How to calculate the time complexity for nested for loops in the following example?

So in the following code, I am trying I am passing a (huge)number-string to the function where I have to find the maximum product of consecutive m digits
So, first, I am looping through let's say n-string and then the inner loop looping through m numbers.
So the inner loop is affected by the if-statement which makes a jump of m indexes if the next number is 0.
EDIT : 1
Actual Problem Question:
The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.
731671765313306249192251....(1000digits)
Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
Example:
m = 12 number = "1234567891120123456704832...(1000 digits)"
So in 1st iteration function will calculate the product of 1st 12 digits(i.e. from index-11 to index-0 - "1234567891120123456704832..."
Now, in 2nd iteration when it checks the value at index-12 which is 0 then index will jump to index-13. This way the loop will skip 11 iterations.
For the 3rd Iteration, the inner loop will execute for 4 iterations until it finds 0 ("0123456704832...".
def LargestProductInSeries_1(number,m):
max = -1
product = 1
index = 0
x = 0
while index < len(number)-(m-1):
for j in range(index+(m-1), index-1, -1):
num = int(number[j])
if(not num):
index = j
break
product = product * int(number[j])
max = product if max < product else max
product = 1
index += 1
return max
So according to me, the Worst Case Time Complexity would be O(n*m)
I think the Best Time would be O(n/m) if only once the inner loop is completely iterated or every mth digit is 0 which will make the outer loop execute but the index will jump to every mth digit.
Is my analysis correct?
What will be the Average Time for this case?
Will it be O(n*(log m)). Can anyone explain how? Or how to find Complexity in such cases?

Haskell multivariable Lambda function for lists

I am confused on how this is computed.
Input: groupBy (\x y -> (x*y `mod` 3) == 0) [1,2,3,4,5,6,7,8,9]
Output: [[1],[2,3],[4],[5,6],[7],[8,9]]
First, does x and y refer to the current and the next element?
Second, is this saying that it will group the elements that equal 0 when it is modded by 3? If so, how come there are elements that are not equal to 0 when modded by 3 in the output?
Found here: http://zvon.org/other/haskell/Outputlist/groupBy_f.html
To answer your second question: We compare two elements by multiplying them and seeing if the result is divisible by 3. "So why are there elements in the output not divisible by 3?" If they aren't divisible, that doesn't filter them out (that's what filter does); rather, when the predicate fails, the element goes into a separate group. When it succeeds, the element goes into the current group.
As to your first question, this took me a little while to figure out... x and y aren't two consecutive elements; rather, y is the current element and x is the first element in the current group. (!)
1 * 2 = 2; 2 `mod` 3 = 2; 1 and 2 go in separate groups.
2 * 3 = 6; 6 `mod` 3 = 0; 2 and 3 go in the same group.
2 * 4 = 8; 8 `mod` 3 = 2; 4 gets put in a different group.
...
Notice, on that last line, we're looking at 2 and 4 — not 3 and 4, as you might reasonably expect.
First, does x and y refer to the current and the next element?
Roughly, yes.
Second, is this saying that it will group the elements that equal 0 when it is modded by 3? If so, how come there are elements that are not equal to 0 when modded by 3 in the output?
The lambda defines a relation between two integers x and y, which holds whenever the product x*y is a multiple of 3. Since 3 is prime, x must be a multiple of 3 or y must be such.
For the input [1,2,3,4,5,6,7,8,9], it is first checked whether 1 is in relation with 2. This is false, so 1 gets its own singleton group [1]. Then, we proceed we 2 and 3: now the relation holds, so 2,3 will share their group. Next, we check whether 2 and 4 are in relation: this is false. So, the group is [2,3] and not any larger. Then we proceed with 4 and 5 ...
I must confess that I do not like this example very much, since the relation is not an equivalence relation (because it is not transitive). Because of this, the exact result of groupBy is not guaranteed: the implementation might test the relation on 3,4 (true) instead of 2,4 (false), and build a group [2,3,4] instead.
Quoting from the docs:
The predicate is assumed to define an equivalence.
So, once this contract is violated, there are no guarantees on what the output of groupBy might be.
The groupBy function takes a list and returns a list of lists such that each sublist in the result contains only equal elements, based on the equality function you provide.
In this case, you are trying to find all subsets where for all sublist elements x and y, mod (x*y) 3 == 0 (and the ones where it doesn't == 0). Slightly weird, but there you go. groupBy only looks at adjacent elements. sort the list to reduce the number of duplicate sets.

Resources