How to make convert this long assignment statement into a function in Amibroker? - amibroker

I have this long assignment statement in Amibroker.
num_times_above = iif(Ref(CLOSE, -0)>Ref(CLOSE, -4) , 1, 0)
+ iif(Ref(CLOSE, -1)>Ref(CLOSE, -4), 1, 0)
+ iif(Ref(CLOSE, -2)>Ref(CLOSE, -4), 1, 0)
+ iif(Ref(CLOSE, -3)>Ref(CLOSE, -4), 1, 0)
+ iif(Ref(CLOSE, -4)>Ref(CLOSE, -4), 1, 0)
;
I would like to convert this long statement into a generic function that accepts a parameter n.
function get_num_times_above(n)
{
//code
}
The code on top is for the case when n == 4. I am stuck at this seemingly simple problem because of the array format used in Amibroker.
if n == 3, the equivalent code will be;
num_times_above = iif(Ref(CLOSE, -0)>Ref(CLOSE, -3) , 1, 0)
+ iif(Ref(CLOSE, -1)>Ref(CLOSE, -3), 1, 0)
+ iif(Ref(CLOSE, -2)>Ref(CLOSE, -3), 1, 0)
+ iif(Ref(CLOSE, -3)>Ref(CLOSE, -3), 1, 0)
;
I am using Amibroker ver6.28

Try this.
function get_num_times_above(n)
{
num_times_above = 0;
refn = Ref(C, -n);
for (i=0; i<n; i++)
num_times_above += Ref(C, -i)>refn;
return num_times_above;
}
Credit goes to fxshrat who provided the answer here.
https://forum.amibroker.com/t/how-to-make-convert-this-long-assignment-statement-into-a-function/7181/2

Related

I need made a combinatorial analysis on an array and generate a number with this

Hi i am an amateur in programing, but i propose me to getting better and because that i start to solve problems in online judges and i don't know how to do a combinatorial analysis, i found some similar question but i can't apply to my code, if you are able to explain me how to do it, i will be incredibly grateful.
so here is the full text of the problem, translated of Portuguese to English. At end is my code.
To prove her scientific skills Princess Bubblegum learned to program using BMO (The best computer in the Candy kingdom) and like every programmer she fell in love with binary numbers.
Because of her addiction to binary numbers she loves decimal numbers that look like a binary number (i.e. a decimal number that contains only digits 0 and 1, for example 101) so given a decimal number N she wants to find a multiple of that number that looks like a number binary, but for some numbers it was taking a long time to find that multiple, even with the help of BMO. Because of her problem-solving addiction, she wasn't doing anything until she found this multiple. Perfect situation for the Earl of Lemongrab, who has taken over the Candy Kingdom. As Finn and Jake, the heroes of the Candy kingdom, can't do anything against the Count and know nothing about multiples, they asked to find the multiples and thus save the kingdom.
Prohibited
The input contains up to 2*10^5 lines, each line with an integer N (0 < N < 10^12), the number Princess Bubblegum wants to find the multiple M (M != 0), this number must be smaller than 10^12, otherwise it doesn't fit in the BMO architecture.
Exit
Print a single integer per line, if there are multiple multiples print the smallest one. If there is no solution print -1
#include <stdlib.h>
#include <math.h>
int main() // normal ways works fine but i have to do it faster, time limit is 2s//
//doing 11 fors works to but its have same tle problem//
{
long long int n, R, num, res, expo;
int b = 0, dig[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, E=0, an, anmax = 1024, reseter, cob, casa;
while (E < 200000)
{
E++;
num = 0;
scanf("%lld", &n); //I have to read a decimal number and from that found the smaller multiple number that is similar to a binary number, and cannot be 0//
res=n%10;
if ((res==1) || (res==0)) // in case the read number is already similar to binary, this works fine//
{ b=1;
for ( num=n;((num>0) && (b==1)); num=num/10)
{
res=num%10;
if ((res==1) || (res==0)){
b=1;
R=n;
}else
{
b=0;
R=-1;
}
}
}else{
if ((n > 0) && (n < 1000000000000))
{
if (n < 500000000000)
{
num = n;
for (expo = -1; num >= 1; expo++, num = num / 10)//so expo is a varieble to found the smaller house of input to made a number, its just for reduce cycles//
{
res = num % 10;
}
if (res > 1)
{
expo = expo + 1;
}
dig[expo] = 1;
R = ((dig[11] * 100000000000) + (dig[10] * 10000000000) + (dig[9] * 1000000000) + (dig[8] * 100000000) + (dig[7] * 10000000) + (dig[6] * 1000000) + (dig[5] * 100000) + (dig[4] * 10000) + (dig[3] * 1000) + (dig[2] * 100) + (dig[1] * 10) + (dig[0] * 1));
for (dig[expo] = 1; ((expo < 11) && (b == 0)); expo++)//// 1 is fixed value until no one of numbers is divisible//
{
anmax = pow(2, expo);//forget this line//
dig[expo] = 1;
for (casa = 0; ((casa < expo) && (b == 0)); casa++)//here is my problem i dont know how to alternate all values that can be ninary//
{ //this is my original idea to solve but this don't generate all possible values//
for (cob = 0; ((cob < 2) && (b == 0)); cob++)
{
dig[casa] = cob;
R = ((dig[11] * 100000000000) + (dig[10] * 10000000000) + (dig[9] * 1000000000) + (dig[8] * 100000000) + (dig[7] * 10000000) + (dig[6] * 1000000) + (dig[5] * 100000) + (dig[4] * 10000) + (dig[3] * 1000) + (dig[2] * 100) + (dig[1] * 10) + (dig[0] * 1));
if ((R % n) == 0)
{
b = 1;
}
}
}
if ((cob == 2) || (b==1))
{
for (reseter = expo; reseter >= 0; reseter--)//it works fine is just to start all values with 0 before its repeats//
{
dig[reseter] = 0;
}
}
}
}
else
{
R = -1;
}
if((R==11111111111) && ((n!=21649) || (n!=513239))){
R=-1; //its not important//
}
}else
{
R=-1;
}
}
// reset para proximos valores//
b = 0;
printf("%lld\n", R);
}
return 0;
}

Can anyone tell me the logical difference between the mentioned codes

I am unable to figure out the why my code is not able to satisfy a test case for the question while editorial's code is working fine.
Question:
You are in an infinite 2D grid where you can move in any of the 8 directions :
(x, y) to
(x+1, y),
(x-1, y),
(x, y+1),
(x, y-1),
(x-1, y-1),
(x+1, y+1),
(x-1, y+1),
(x+1, y-1)
You are given a sequence of points and the order in which you need to cover the points. Give the minimum number of steps by which you can achieve it. You start from the first point.
Input:
Given two integer arrays A and B, where A[i] is x coordinate and B[i] is y coordinate of the ith point, respectively.
Output:
Return an Integer, (i.e minimum number of steps).
Example:
Input : [(0, 0), (1, 1), (1, 2)]
Output : 2
It takes one step to move from (0, 0) to (1, 1). It takes one more step to move from (1, 1) to (1, 2).
my code:-
int coverPoints(int *A, int n1, int *B, int n2) {
int count = 0, ele1 = 0, ele2 = 0, i;
for (i = 0; i < n1 - 1; i++) {
ele1 = abs(A[i+1] - A[i]);
ele2 = abs(B[i+1] - A[i]);
if (ele1 > ele2) {
count += ele1;
} else {
count += ele2;
}
}
return count;
}
editorial solution:-
int coverPoints(int *X, int n1, int *Y, int n2) {
int stepsx = 0, stepsy = 0, diffx = 0, diffy = 0, steps = 0;
int i = 0;
for(i = 0; i < (n1-1); i++) {
diffx = X[i+1] - X[i];
if (diffx < 0)
diffx = diffx * (-1);
//stepsx = stepsx + diffx;
diffy = Y[i+1] - Y[i];
if (diffy < 0)
diffy = diffy * (-1);
//stepsy = stepsy + diffy;
if (diffx > diffy)
steps = steps + diffx;
else
steps = steps + diffy;
}
return steps;
}
The test case that is not working is: -
A : [ 4, 8, -7, -5, -13, 9, -7, 8 ]
B : [ 4, -15, -10, -3, -13, 12, 8, -8 ]
expected output = 108
my output = 105
There is a problem in this line
ele2 = abs(B[i+1]-A[i]);
diffy = Y[i+1] - Y[i];
it will be :
ele2 = abs(B[i+1]-B[i]);
There is a copy+paste typo in ele2 = abs(B[i+1] - A[i]);. The code should be:
ele2 = abs(B[i+1] - B[i]);

C - Verify win condition in Connect Four game

This is the verification from a connect four game prototype, but it seems I've done something wrong.
I want that everytime the player is making a move, the function will verify if there he won or not, by verifying vertically, horizontally, and eventually, on the diagonal.
But it seems that it does not verify correctly, because in some cases, even though there are only 2 moves made, the functions returns 1.
int verifyGame(int gamePosition, int gameVariable, char gameArray[HEIGTH][WIDTH])
{
if(gameArray[gamePosition][gameVariable] == gameArray[gamePosition + 1][gameVariable] == gameArray[gamePosition + 2][gameVariable] == gameArray[gamePosition + 3][gameVariable]) //verify vertically
return 1;
else
if(gameArray[gamePosition][gameVariable] == gameArray[gamePosition][gameVariable - 3] == gameArray[gamePosition][gameVariable - 2] == gameArray[gamePosition][gameVariable - 1]) //verify horizontally
return 1;
else
if(gameArray[gamePosition][gameVariable] == gameArray[gamePosition][gameVariable - 2] == gameArray[gamePosition][gameVariable - 1] == gameArray[gamePosition][gameVariable + 1])
return 1;
else
if(gameArray[gamePosition][gameVariable] == gameArray[gamePosition][gameVariable - 1] == gameArray[gamePosition][gameVariable + 1] == gameArray[gamePosition][gameVariable + 2])
return 1;
else
if(gameArray[gamePosition][gameVariable] == gameArray[gamePosition][gameVariable + 1] == gameArray[gamePosition][gameVariable+ 2] == gameArray[gamePosition][gameVariable + 3])
return 1;
//verify diagonally
else return 0;
};
This is where the function is called. The switch verifies the users input, and then it places the value in the matrix, and then verifies for won
printf("playerPick is : %d\n", playerPick);
fflush(stdout);
switch(playerPick)
{
case 1:
if(gameVariables[0] >0 && gameVariables[0] < 7)
{
--gameVariables[0];
gameArray[gameVariables[0]][0] = (char) 82;
ifWon = verifyGame(gameVariables[0], 0, gameArray);
}
printArray(gameArray);
break;
case 2:
if(gameVariables[1] >0 && gameVariables[1] < 7)
{
--gameVariables[1];
gameArray[gameVariables[1]][1] = (char) 82;
ifWon = verifyGame(gameVariables[1], 1, gameArray);
}
printArray(gameArray);
break;
case 3:
if(gameVariables[2] >0 && gameVariables[2] < 7)
{
--gameVariables[2];
gameArray[gameVariables[2]][2] = (char) 82;
ifWon = verifyGame(gameVariables[2], 2, gameArray);
}
printArray(gameArray);
break;
case 4:
if(gameVariables[3] >0 && gameVariables[3] < 7)
{
--gameVariables[3];
gameArray[gameVariables[3]][3] = (char) 82;
ifWon = verifyGame(gameVariables[3], 3, gameArray);
}
printArray(gameArray);
break;
case 5:
if(gameVariables[4] >0 && gameVariables[4] < 7)
{
--gameVariables[4];
gameArray[gameVariables[4]][4] = (char) 82;
ifWon = verifyGame(gameVariables[4], 4, gameArray);
}
printArray(gameArray);
break;
case 6:
if(gameVariables[5] >0 && gameVariables[5] < 7)
{
--gameVariables[5];
gameArray[gameVariables[5]][5] = (char) 82;
ifWon = verifyGame(gameVariables[5], 5, gameArray);
}
printArray(gameArray);
break;
case 7:
if(gameVariables[6] >0 && gameVariables[6] < 7)
{
--gameVariables[6];
gameArray[gameVariables[6]][6] = (char) 82;
ifWon = verifyGame(gameVariables[6], 6, gameArray);
}
printArray(gameArray);
break;
}
printf("%d %d %d %d %d %d %d\n", gameVariables[0], gameVariables[1], gameVariables[2], gameVariables[3], gameVariables[4], gameVariables[5], gameVariables[6]);
printf("ifwon : %d\n", ifWon);
#Weather Vane's answer is correct. The logic used in your original post is not correct for a verification.
One reason you may not have caught it yourself may be the complicated way it was written. Try simplifying the user input verification code: (Range checking the user input values is all that is necessary.)
//User input range checking:
if((gamePosition >= x)&& //where `x` is minimum for gamePosition
(gamePosition <= y)&& //where `y` is maximum for gamePosition
(gameVariable >= z)&& //where `z` is minimum for gameVariable
(gameVariable <= w)) //where `w` is maximum for gameVariable
{//continue }
else
{
printf("Invalid value. Please re-enter");
return -1;
}
Another opportunity for simplification is to note that each of your case statements contain identical code, with the exception of the value of the case. Because of this the entire switch(...){...} can be replaced with a single if statement:
//assuming playerPick >= 1
if(gameVariables[playerPick-1] >0 && gameVariables[playerPick-1] < 7)
{
--gameVariables[playerPick-1];
gameArray[gameVariables[playerPick-1]][playerPick-1] = (char) 82;
ifWon = verifyGame(gameVariables[playerPick-1], playerPick-1, gameArray);
}
printArray(gameArray);
Also note that although the statement:
gameArray[gameVariables[0][0] = (char) 82; //what is 82?
is perfectly legal, the variable gameArray[0][0] is just a char, so casting the value 82 is not necessary. Also, C syntax provides a way to pull out the ASCII decimal value of the character by surrounding it with the graves symbol, allowing the following form, which is more readable:
gameArray[gameVariables[0]][0] = `R`; //intuitive
You cannot chain equality testing as you are attempting. The code will execute, but not as you suppose. Your code
if(gameArray[gamePosition][gameVariable] ==
gameArray[gamePosition + 1][gameVariable] ==
gameArray[gamePosition + 2][gameVariable] ==
gameArray[gamePosition + 3][gameVariable])
must be split up into individual tests, such as:
if(gameArray[gamePosition][gameVariable] == gameArray[gamePosition + 1][gameVariable] &&
gameArray[gamePosition][gameVariable] == gameArray[gamePosition + 2][gameVariable] &&
gameArray[gamePosition][gameVariable] == gameArray[gamePosition + 3][gameVariable])
and on the other lines too.

What will be the output of my recursive function in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Consider the following recursive C function that takes two arguments.
unsigned int foo(unsigned int n, unsigned int r)
{
if (n > 0)
return (n % r) + foo(n / r, r);
else
return 0;
}
What is value of function foo when it called as foo(512,2)?
This code ,actually is a recursion.
follow the return happened:
If n == 0; return 0;
If n == 1; return 1+foo(0,2)
If n == 2; return 0 + foo(1,2);
If n == 4; return 0 + foo(2,2);
...
if n == 2^n return 0 + foo(0+foo(z^n-1,2));
....
So foo(512,2) == foo (2^n,2) == 0+f(1,2) == 1 +f(0,2) = 1;
It return 1.
Your result is going to be 1. Here is what happens:
First call: n = 512, r = 2, n % r = 0; calls foo (256, 2)
Second call: n = 256, r= 2, n % r = 0; calls foo (128, 2)
Third call: n = 128, r = 2, n % r = 0; calls foo (64, 2)
Fourth call: n = 64, r = 2, n % r = 0; calls foo (32, 2)
Fifth call: n = 32, r = 2, n % r = 0; calls foo (16, 2)
Sixth call: n = 16, r = 2, n % r = 0; calls foo (8, 2)
Seventh call: n = 8, r = 2, n % r = 0; calls foo (4, 2)
Eighth call: n = 4, r = 2, n % r = 0; calls foo (2, 2)
Ninth call: n = 2, r = 2, n % r = 0; calls foo (1, 2)
Tenth call: n = 1, r = 2, n % r = 1; calls foo (0, 2)
Eleventh call: n = 0, r = 2; returns 0
Tenth call returns 1 + 0 = 1
Ninth call and subsequent calls all return 0 + 1 = 1
Unwinding is complete and the function returns 1.

A priori and asymptotic complexity level

How to determine the a priori and asymptotic complexity of following program code?
#include<stdio.h>
int br_nacina_zaba(int br_lopoca, int tren_poz, int korak) {
if (korak == 18) return 0;
else if (tren_poz == br_lopoca) return 1;
else if (tren_poz <= 0 && korak != 0) return 0;
else if (tren_poz > br_lopoca) return 0;
else return
br_nacina_zaba(br_lopoca, tren_poz + 2, korak + 1)
+ br_nacina_zaba(br_lopoca, tren_poz + 3, korak + 1)
+ br_nacina_zaba(br_lopoca, tren_poz - 2, korak + 1)
+ br_nacina_zaba(br_lopoca, tren_poz - 3, korak + 1);
}
So I need to know the complexity of function br_nacina_zaba(n,0,0).
In my opinion, br_nacina_zaba(n,0,0) is in O(1). The maximum depth of the (quaternary) call tree is limited by 19 in the function's first LOC:
korak gets incremented in each recursive call. If you start with korak=0 and call the function at most 4 times in each recursive step, you'll have at most 4^18 recursive calls. 4^18 doesn't depend on n, hence the function is in O(1).
I don't know what you mean "complexity of function", but I run your function on codepad ( http://codepad.org/jFUW1ATj ) and got this result
br_nacina_zaba(1, 0, 0) was called 5 times.
br_nacina_zaba(2, 0, 0) was called 5 times.
br_nacina_zaba(3, 0, 0) was called 9 times.
br_nacina_zaba(4, 0, 0) was called 77 times.
br_nacina_zaba(5, 0, 0) was called 33445 times.
br_nacina_zaba(6, 0, 0) was called 1048573 times.
br_nacina_zaba(7, 0, 0) was called 15530681 times.

Resources