Counting Bars Ago since peak - c#

I am writing an algorithm to count the number of bars have passed since the n-th peak.
Assuming that I have a list of integer which keeps track of all the occurrences of peak as below.
3, 7, 10, 13
The above tells me that the peak occurs at the index 3, 7, 10 and 13.
The length of the source data is 15.
Let n = 1
then I should be seeing a resultant list as below:
index 0 = null - there is no peak yet
index 1 = null - there is no peak yet
index 2 = null - there is no peak yet
index 3 = 0 - peak was hit here so there bars passed is 0
index 4 = 1 - peak was hit in previous bar so the bars passed is 1
index 5 = 2 - peak was already hit and the number of bars passed is 2
index 6 = 3 - peak was already hit and the number of bars passed is 3
index 7 = 0 - peak hit here again so the number of bars passed since the last 1 (n) peak is 0 and result follows as below:
index 8 = 1,
index 9 = 2,
index 10 = 0,
index 11 = 1,
index 12 = 2,
index 13 = 0,
index 14 = 1
Assume n = 2
number of bars passed since 2 most recent peaks. So the result is as below:
index 0 = null
index 1 = null
index 2 = null
index 3 = null - first peak but n = 2 so there is no 2nd peak so far...
index 4 = null
index 5 = null
index 6 = null
index 7 = 4 - second peak only hit here, so the number of days passed since the last 2 peak is 4, this is counted from the index where the first peak was hit, in this case is 3
index 8 = 5
index 9 = 6
index 10 = 3 - another peak hit here, the peak before this (n = 2) happened at index = 7, so it is counted from index = 7
index 11 = 4
index 12 = 5
index 13 = 3 - another peak hit here, the peak before this (n = 2) happened at index = 10, so it is counted from index = 10
index 14 = 4
I wrote an algorithm to accomplish this however, it's not giving me the right output. I would appreciate if someone could tell me what's wrong with my algo or propose a better way doing this.
int nth = GetNValue();// Get the N Value...
//SourceData = listData
int peakCount = 0;
int value= 0;
int barssince = 0;
List<Data> listValue = new List<Data>();
List<int> listResult = new List<int); //to hold the result..
List<int> listPeaks = GetPeakValue();
for (int index = 0; index < listData.Count; index++)
{
if (peakcount > 0)
{
barssince++;
listValue[listValue.Count - 1].Value = barssince;
}
int foundPeak = listPeaks.Find(delegate(int p) { return p == index; });
if (foundPeak != -1)//Peak FOund
{
peakcount++;
listValue.Add(new Data() { Value = barssince });
if (peakcount > nth)
{
listValue.RemoveAt(0);
}
barssince = 0;
}
value = listValue.Count >= nth ? listValue.Sum(p => p.Value) : null;
listResult.Add(value);
}
private class Data
{
public int Value { get; set; }
}

Try this:
int n = GetNValue();// Get the N Value...
List<int> listPeaks = GetPeakValue();
List<int?> result = new List<int?>(listData.Count);
for (int index = 0, peakIndex = -1, nextPeakIndex = peakIndex + n; index < listData.Count; index++)
{
if (nextPeakIndex < listPeaks.Length && index == listPeaks[nextPeakIndex])
{
peakIndex++;
nextPeakIndex++;
}
if (peakIndex < 0)
{
result.Add((int?)null);
}
else
{
result.Add((int?)(index - listPeaks[peakIndex]));
}
}

Simple algo with working code (sorry, but in Delphi):
function IsPeak(i: Integer): Boolean;//modelling
begin
Result := i in [3, 7, 10, 13, 15];
end;
var
i, N: Integer;
Q: TQueue<Integer>;
begin
N := 2;
//queue for last N peaks
Q := TQueue<Integer>.Create;
for i := 0 to 20 do begin
//insert new peak in queue
if IsPeak(i) then begin
Q.Enqueue(i);
//remove too old peak
if Q.Count > N then
Q.Dequeue;
end;
if Q.Count < N then
Memo1.Lines.Add(Format('%d null',[i]))
else //return difference with front element of the queue
Memo1.Lines.Add(Format('%d %d',[i, i - Q.Peek]))
end;
Q.Free;
Result:
0 null
1 null
2 null
3 null
4 null
5 null
6 null
7 4
8 5
9 6
10 3
11 4
12 5
13 3
14 4
15 2
16 3
17 4
18 5
19 6
20 7

Related

Generating a for while foreach algorithm in c# with a pyramidal structure

I have been trying to get this to work for 3 days, and I feel like I'm using the wrong approach, if anyone can correct me I will wax your car. Background, client asked to me make a simple pyramid algorithm. I want to select add everything to a list of objects and make everything on the left side true and everything on the right side false. Every other line reads the line 2 lines prior and adds multiple entries. The first time it adds a number like 1 it's one time, then it adds two 1's for each 1 until there is 4. So the first time it enters a 1 on line 1, then on line 3 it adds a 1 two times, then on line 5 it reads from line 3 and adds each of those 1's 2 times.
Here is a visual representation.
|1|
|2| |3|
|1|1| |4|5|
|2|2|3|3| |6|7|8|9|
|1|1|1|1|4|4|5|5| |10|11|12|13|14|15|16|17|
|2|2|2|2|3|3|3|3|6|6|7|7|8|8|9|9| |18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33
The order this list would be is:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17...
I keep getting close, but it fails to generate the correct output. `
for (int i = 1; i < 50; i = i * 2)
{
Response.Write(i.ToString() + " - ");
var previousLevel = (i / 2 / 2);
foreach (var oc in infoRows.Where(x => x.level == previousLevel))
{
for (int p = i; p > 0; p--)
{
Response.Write(oc.id + "*");
}
}
while (level <= i)
{
for (int r = 1; r <= i; r++)
{
InfoRow tempInforow = new InfoRow();
tempInforow.customerCode = GenerateCustomerNumber(position);
tempInforow.id = customerId;
tempInforow.sendtoidnumber = level.ToString();
tempInforow.status = 0; // GetStatus(position, totalCount);
tempInforow.position = position;
tempInforow.level = i;
infoRows.Add(tempInforow);
customerId++;
position++;
Response.Write(tempInforow.id + "-");
level++;
}
}
}
`
Essentially this generates the following:
1 - 1-
2 - 2-3-
4 - 1*1*1*1*4-5-6-7-
8 - 2*2*2*2*2*2*2*2*3*3*3*3*3*3*3*3*8-9-10-11-12-13-14-15-
16 - 4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-
32 -
I've tried 30 different ways with switch statements, while statements, for and foreach statements, the closest I can get to this working is level 4.
Can someone suggest another way. Maybe a multidimensional array or idk what. Thank you.
Let's write the sequence down and have a look on what's going on:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...
seq 1 2 3 1 1 4 5 2 2 3 3 6 7 8 9 1 1 1 1 4 4 5 5 10 ...
^ ^ ^ ^ ^ ^
| |
if # is power of 2 (e.g. 8 == 2**3)
we should copy and double # / 4 items (here 8 / 4 == 2 items)
starting from # / 4 item (here 8 / 4 == 2, starting from item #2)
Time to implement this algorithm
Code:
using System.Linq;
...
private static List<int> Pyramid(int size) {
if (size < 0)
throw new ArgumentOutOfRangeException(nameof(size));
if (size <= 3)
return Enumerable.Range(1, size).ToList();
List<int> result = new List<int>(size) { 1, 2, 3 };
for (int value = 4; result.Count < size; )
if (BitOperations.IsPow2(result.Count + 1)) {
int chunk = (result.Count + 1) / 4;
for (int i = 0; i < chunk && result.Count < size; ++i) {
result.Add(result[chunk - 1 + i]);
if (result.Count >= size)
return result;
result.Add(result[chunk - 1 + i]);
}
}
else
result.Add(value++);
return result;
}
Demo:
// First 31 items from the pyramid
Console.Write(string.Join("|", Pyramid(31)));
Output:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17

Identify Sequence and Provide 4th Integer

I was tasked to solve this challenge on a programming exam, but I'm not sure that I have properly solved it. I am inquisitive about what really is the solution to this task:
Make an application that will tell the user to input 3 numbers, identify the sequence, and provide the 4th integer. It should prompt if no relations is found
Note: Possible operators may include addition, subtraction, multiplication, division, exponent, and modulo division.
Sample Output:
2, 4, 6, 8
10, 9, 7, 4
1, 4, 9, 16
1, 1, 2, 6
120, 120, 60, 20
Here is my solution so far:
using System;
using System.IO;
namespace TestQuestionnaire
{
class Program
{
static void Main(string[] args)
{
var numbers = new int[3];
string answer;
bool exit = false;
while (!exit)
{
// Loop for 5 times
for (int n = 0; n <= 5; n++)
{
// User Input
Console.WriteLine("Please Enter 3 Numbers.");
for (var i = 0; i < numbers.Length; i++)
{
var error = false;
while (!error)
{
Console.Write("Enter Number: ");
error = int.TryParse(Console.ReadLine(), out numbers[i]);
if (!error) Console.WriteLine("Invalid Number! Enter a Valid Number and Try Again. ");
}
}
NextNumber(numbers);
}
// Prompt for exit
Console.WriteLine("Finished! Try Again? Y/N");
answer = Console.ReadLine()?.ToUpper();
if (answer == "N")
{
exit = true;
}
}
}
private static void NextNumber(int[] numbers)
{
int next = 0;
int interval_one = 0;
int interval_two = 0;
// determine if first two number is descending, ascending or equal (addition and subtraction)
if (numbers[0] < numbers[1])
{
interval_one = (numbers[1] - numbers[0]);
if (numbers[1] > numbers[2])
{
interval_two = (numbers[1] - numbers[2]);
}
else
{
interval_two = (numbers[2] - numbers[1]);
}
//determine if constant interval (eg, 2,4,6,8 or 1,2,3,4) otherwise evaluate more
if (interval_one == interval_two)
{
next = numbers[2] + interval_two;
}
else
{
next = numbers[2] + interval_two + (interval_two - interval_one);
}
}
else if (numbers[0] > numbers[1])
{
interval_one = numbers[0] - numbers[1];
if (numbers[1] > numbers[2])
{
interval_two = (numbers[1] - numbers[2]);
}
else
{
interval_two = (numbers[2] - numbers[1]);
}
if (interval_one == interval_two)
{
next = numbers[2] - interval_two;
}
else
{
next = numbers[2] - interval_two + (interval_one - interval_two);
}
}
else
{
if (numbers[0]/1 == numbers[1] && numbers[1]/2 == numbers [2])
{
next = numbers[2] / 3;
}
else if (numbers[0] * 1 == numbers[1] && numbers[1]*2 == numbers[2])
{
next = numbers[2] * 3;
}
}
Console.WriteLine("Predicted 4th Number: {0}", next);
}
}
}
Thanks!
I just have an Idea but I hope this can help
using +
2 4 6 8
2 2 2
10 9 7 4
1 2 3
1 1
1 4 9 16
3 5 7
2 2
diffrent way(*)
1 1 2 6
1 2 3# now +
1 1
use '/'
120 120 60 20
1 2 3# use +
1 1
There is no way to recognize all sequences of numbers, as each is defined by a very different relation. You would essentially have to hardcode each case as listed in the examples. And even then, there is no one correct answer. For your fourth example, I could see the sequence 1 1 2 2 3 3... being just as reasonable as 1 1 2 6.... In fact, the Online Encyclopedia of Integer Sequences finds 35,000 results for the the sequence 1 1 2 (see https://oeis.org/search?q=1%2C1%2C2&sort=&language=english&go=Search)
Putting that aside though, I'll give some pseudocode for the examples (I'm assuming, given that you are fine with Python or C#, that the language itself is not particularly important, and that you probably already know how to do the "getting input" and "returning results" portions.).
if the difference between each number is equal, add that difference to the last number and return it
if the difference between each number is the sequence 1 2 3..., return the last number plus the next difference (4 in this case)
If the numbers are the squares, return the next square (16 in this case)
If each number divided by the previous number is the sequence 1 2 3, return 4 * the last number
If each number divided by the next number is the sequence 1 2 3, return the last number divided by 4.
Of course, a more robust solution would account for negative sequences, or those that bounce back and forth between positive and negative. But again, it is an underdetermined problem.

How does an equilibrium index of an array work?

I tried a demo test on Codility for finding the equilibrium index(es) of an array. I'm not sure if the test was to find the equilibrium indexes of an array or what. I googled around and found the following example:
The equilibrium index of a sequence is an index such that the sum of elements at lower indexes is equal to the sum of elements at higher indexes. For example, in a sequence A:
A[0]=-7 A[1]=1 A[2]=5 A[3]=2 A[4]=-4 A[5]=3 A[6]=0
3 is an equilibrium index, because:
A[0] + A[1] + A[2] = A[4] + A[5] +A[6]
6 is also an equilibrium index, because:
A[0] + A[1] + A[2] + A[3] + A[4] + A[5] = 0
Based on this information I see the test array contains 7 elements. It looks like the middle element A[3]=2 is being ignored. Is it because it is between the first 3 elements and the last 3 elements? How is the equilibrium index of 6 arrived at in this example?
Here is the method that was used to compute this:
int equi(int arr[], int n) {
if (n==0) return -1;
long long sum = 0;
int i;
for(i=0;i<n;i++) sum+=(long long) arr[i];
long long sum_left = 0;
for(i=0;i<n;i++) {
long long sum_right = sum - sum_left - (long long) arr[i];
if (sum_left == sum_right) return i;
sum_left += (long long) arr[i];
}
return -1;
}
When I took the Codility demo test I used the method (below) with the for loops initially beginning at 0. I received a "wrong answer" message for the test case of 1, 5, 2, 1, 4, 0 and that Codility was looking for a result of 11.
I modified the two for loops in my method and started the first loop at i = 1 and the second loop at i = 2 until it yielded a result of 11, which Codility was satisfied with. I basically just tweaked the method until Codility was happy (I was shooting for 11 because Codility specified that was the answer they were looking for), but I don't really know why Codility was happy or what was the significance of my tweaks -- just hit and miss:
...
int[] B = new int[] { 1, 5, 2, 1, 4, 0 };
Console.WriteLine(solution3(B));
}
public int solution3(int[] A)
{
long rsum = 0;
for (int i = 1; i < A.Count(); i++)
rsum += A[i];
long lsum = A[0];
int min = (int)Math.Abs(lsum - rsum);
for (int i = 2; i < A.Count() - 1; i++)
{
lsum += A[i];
rsum -= A[i];
int diff = (int)Math.Abs(lsum - rsum);
if (diff >= min)
min = diff;
}
return min;
}
Why did this tweak (of hit and miss) satisfy the Codility test? What is an equilibrium index actually? How is it arrived at? Note: if there are steps between step A and step E (which I would have to intuit the in between steps) what are steps B, C, and D?
What is an equilibrium index and how is it determined?
Think of your array like a board with weights of different sizes on it (negative weights can be thought of as helium balloons attached to the board). Each weight is numbered from left to right. Your task is to place a fulcrum under the board at any of the numbered positions to make the board balance. (We will treat the board itself as weightless, and assume distance of the weights from the center doesn't matter.) Whichever positions make the board balance are the equilibrium indexes. The weight at the fulcrum doesn't "count" because it's not on either side; it is in the middle.
Here is a picture of the first example:
Here, 3 is an equilibrium index, because the sum of the weights to the left of the fulcrum equal the sum of the weights to the right of the fulcrum (-7 + 5 + 1 = -1 = -4 + 3 + 0).
Here is the second example:
We see that 6 is also an equilibrium index for the same reason. All the elements to the left of the fulcrum add up to zero. As there are no elements to the right of the fulcrum, that sum is also zero.
The basic algorithm to find the equilibrium indexes is this:
Loop over the array and add up all the elements. Call this sum total.
Initialize a variable left_sum to zero.
Initialize a variable right_sum to total.
Now loop over the array a second time. For each array item:
Subtract the value of the current item from right_sum.
Compare the left_sum to the right_sum. If they are equal, then the index of the current item is an equilibrium index.
Add the value of the current item to left_sum.
And that's all there is to it. Does it make sense now?
What's going on with my algorithm?
As for why the "Codility demo test" was expecting a result of 11 for an array containing the elements { 1, 5, 2, 1, 4, 0 }, I cannot say. You never said in your question what the demo problem actually was. If the problem was to find the first equilibrium index in that array, then the answer is that there is none for that array. Stepping through the above algorithm, here are the left and right sums for each array index:
Index Left Right
----- ---- -----
0 0 12
1 1 7
2 6 5
3 8 4
4 9 0
5 13 0
As you can see, there is no index at which the left sum equals the right sum. An expected result of 11 does not even make sense anyway because there are only six elements. So if there were an equilibrium index for this array, it would have to between 0 and 5 inclusive. So I'm guessing the problem posed must have been something else. You would have to include the problem statement in your question before I could even begin to guess why your algorithm is or isn't correct.
Well, based on what I understand about an equilibrium index of an array I came up with the following algorithm which I tested on another array which has equilibrium indexes as index 3 and index 6, but I also tested this algorithm on the original array which returned a -1 (nothing to do with an 11). Here is the sample:
private void button6_Click_1(object sender, EventArgs e)
{
//int[] arr = new int[7] { -7, 1, 5, 2, -4, 3, 0 }; //--new array
int[] arr = new int[6] { 1, 5, 2, 1, 4, 0 }; //--original array
List<int> lst = new List<int>();
int p = arr.Length;
int i = 0;
int q = 0;
int t = 0;
do
{
t = equilibrium(arr, arr.Length, q);
if (lst.IndexOf(t) == -1)
lst.Add(t);
q = t;
i++;
} while (i < p);
foreach (var m in lst)
Console.WriteLine(m);
}
private int equilibrium( int[] arr, int n, int q1)
{
int i, j;
int leftsum, rightsum;
for (i = 0; i < n; ++i)
{
leftsum = 0;
rightsum = 0;
for (j = 0; j < i; j++)
leftsum += arr[j];
for (j = i + 1; j < n; j++)
rightsum += arr[j];
if (leftsum == rightsum && q1 != i)
return i;
}
return -1;
}
This algorithm makes sense to me, but when I tried it on Codility with an array of int[] arr = new int[] { 2, 2, 1, 0, 1 }; I got a "wrong Answer -- expected 3" In my test app my algorithm returned a 1 which is what it returned on Codility. Where did they come up with 3 for this array? Thus, I do not understand the equilibrium index of an array. Any suggestions appreciated.

Binding Variable Nested List to GridView

I am trying to make a multiplication table appear on a page based on input from the user. This is my code:
<asp:GridView runat="server" ID="TableData"></asp:GridView>
List<List<int>> nestedList = new List<List<int>>();
protected void LoadTable(int val)
{
for (int y = 0; y <= val; y++)
{
List<int> list = new List<int>();
for (int x = 0; x <= val; x++)
list.Add(x * y);
nestedList.Add(list);
}
TableData.DataSource = nestedList;
TableData.DataBind();
}
But this displays as:
Capacity Count
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
16 14
What am I doing wrong?
For clarification, if the user enters 5, the output should be:
0 0 0 0 0 0
0 1 2 3 4 5
0 2 4 6 8 10
0 3 6 9 12 15
0 4 8 12 16 20
0 5 10 15 20 25
I am not worried about column or row headers at this time.
The problem is with your items Source.
a list< list < ?? > > is not a good choice (as i think).
For a Linear view you can use this approach
Code Snippet
var objList = new List<object>();
for (int i = 0; i < 5; i++)
{
var temp = new { operation = string.Format("{0} * {1}", i, i + 1), result = i * (i + 1) };
objList.Add(temp);
}
GridView does not support 2d list binding, consider using another methode.
For exemple, use a simple List , each string will represent a row, you can fill up each string by using a loop that goes like :
(first loop)
{
string s;
for(int x = 0; x < val; x ++)
{
s += (x * y).Tostring() + " ");
}
nestedList.Add(s);
}

Multiply every other array element by 2

I have an array of 10 digits. I want to multiply by 2, each element of the array with an even index. The elements with an odd index I want to multiply by 1 (in reality, leave unchanged). Hence, array[0] * 2, array[1] * 1, array[2] * 2, etc.
I tried using the modulus operator on the index number of each element, but I don't think that is what my code actually did. My previous silly attempt is as follows:
for (int i = 0; i < 10; i++)
{
if ((Array.IndexOf(myArray, i) % 2) == 0)
{
// multiply myArray[i] by 2
}
else // multiply myArray[i] by 1
}
This code is for any no.of element in the list. (Array can have 1 or more element)
myArray = myArray.Select(x => ((Array.IndexOf(myArray, x) % 2 == 0) ? x * 2 : x * 1)).ToArray();
would give you the array of integers with even index element multiplied by 2, and odd on multipled by 1.
for (int i = 0; i < 10; i++)
{
if((i % 2) == 0)
{
// multiply myArray[i] by 2
}
else // multiply myArray[i] by 1
}
Array.IndexOf(firstParam,secondParam) will give you the index of secondParam. For example:
arr[0] = 10
arr[1] = 3
arr[2] = 5
arr[3] = 1
Array.IndexOf(arr,1) = 3, Array.IndexOf(arr,3) = 1, etc.

Categories

Resources