I have to present 16 financial products in a 4x4 matrix on a website. The matrix replaces the representation of a scatter graph, where the returns of the product are represented in the X axis and the risk in the Y (they are simply pairs of values), so the product in the lowest left place are the one with the minor risk and the minor returns and the ones in the top right are the ones with the major risk and the major return.
To reach this result, I thought of putting the products in a multidimensional 4x4 array, but I don't know how to sort the pairs of values correctly.
I tried some sorting methods but nobody gave me the required result.
Here is an Exammple of what I want to obtain:
Taking this sixteen couple of values:
(3,5)-(2,8)-(7,3)-(4,9)-(3,2)-(4,10)-(6,2)-(1,4)-(5,2)-(8,9)-(7,11)-(10,12)-(3,11)-(5,10)-(2,16)-(9,15)
I would like to show it in the matrix in this order
Y
^
|(7,3)(8,9)(10,12)(9,15)
|(5,2)(6,2)(5,10)(7,11)
|(3,2)(3,5)(4,9)(4,10)
|(1,4)(2,8)(3,11)(2,16)
|_____________________>X
I'm adding another answer because the first one and its comments are before you added an example and that answer was way off.
Your example is helpful. It looks like the first value in your pair is Y and the second is X? If so, that's opposite normal convention.
It seems your unspoken rules for arrangement are to arrange the pairs in such a way that the Y (left) values are increasing upward in each column, and the X (right) values are increasing rightward in each row. Importantly, it seems for Y values the columns are otherwise independent, and for the X values the rows are otherwise independent. Independent meaning you don't care about absolute placement from position to position. Like for Y, you don't care that a 3 in the third column is lower than the 3 in the first column.
But these rules will still produce multiple valid result sets. For example, in your example, (7,3) and (6,2) can be swapped and the rules as outlined above still apply.
If these unspoken rules are correct, try this broad approach:
(1) Put the list into a matrix, (2) sort all of the columns, (3) sort all of the rows, (4) repeat sorting columns and rows a few times.
Here is some code to illustrate this. Because this is just a 4x4 matrix, efficiency isn't important.
public static void Main()
{
Tuple<int,int>[] pairs = {
Tuple.Create(3, 5),
Tuple.Create(2, 8),
Tuple.Create(7, 3),
Tuple.Create(4, 9),
Tuple.Create(3, 2),
Tuple.Create(4, 10),
Tuple.Create(6, 2),
Tuple.Create(1, 4),
Tuple.Create(5, 2),
Tuple.Create(8, 9),
Tuple.Create(7, 11),
Tuple.Create(10, 12),
Tuple.Create(3, 11),
Tuple.Create(5, 10),
Tuple.Create(2, 16),
Tuple.Create(9, 15)
};
var matrix = load(pairs); //Put data into a 4x4 matrix, order doesn't matter
Console.WriteLine("Original input:");
print(matrix);
matrix = sort(matrix);
Console.WriteLine("Ordered output:");
print(matrix);
}
private static Tuple<int,int>[,] load(Tuple<int,int>[] pairs) {
var rv = new Tuple<int, int>[4, 4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
rv[i, j] = pairs[i * 4 + j];
}
}
return rv;
}
private static Tuple<int, int>[, ] sort(Tuple<int, int>[,] matrix) {
var rv = matrix;
for (int i = 0; i < 4; i++) {
rv = orderCols(rv);
rv = orderRows(rv);
}
return rv;
}
private static Tuple<int,int>[,] orderCols(Tuple<int,int>[,] matrix) {
for (int c = 0; c < 4; c++) {
//Convert column to 1D array, sort it, then apply it back
Tuple<int, int>[] a = new Tuple<int, int>[4];
for (int r = 0; r < 4; r++) a[r] = matrix[r, c];
a = a.OrderByDescending(t => t.Item1).ToArray();
for (int r = 0; r < 4; r++) matrix[r, c] = a[r];
}
return matrix;
}
private static Tuple<int,int>[,] orderRows(Tuple<int,int>[,] matrix) {
for (int r = 0; r < 4; r++) {
//Convert row to 1D array, sort it, then apply it back
Tuple<int, int>[] a = new Tuple<int, int>[4];
for (int c = 0; c < 4; c++) a[c] = matrix[r, c];
a = a.OrderBy(t => t.Item2).ToArray();
for (int c = 0; c < 4; c++) matrix[r, c] = a[c];
}
return matrix;
}
private static void print(Tuple<int, int>[,] matrix) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++)
Console.Write(writeTuple(matrix[i, j]));
Console.WriteLine();
}
Console.WriteLine();
}
private static string writeTuple(Tuple<int, int> t) {
var a = t.Item1.ToString().PadLeft(2, ' ');
var b = t.Item2.ToString().PadLeft(2, ' ');
return String.Format("({0}, {1}) ", a, b);
}
Output:
Original input:
( 3, 5) ( 2, 8) ( 7, 3) ( 4, 9)
( 3, 2) ( 4, 10) ( 6, 2) ( 1, 4)
( 5, 2) ( 8, 9) ( 7, 11) (10, 12)
( 3, 11) ( 5, 10) ( 2, 16) ( 9, 15)
Ordered output:
( 6, 2) ( 7, 3) ( 8, 9) (10, 12)
( 5, 2) ( 4, 9) ( 7, 11) ( 9, 15)
( 3, 2) ( 3, 5) ( 5, 10) ( 4, 10)
( 1, 4) ( 2, 8) ( 3, 11) ( 2, 16)
As you can see, the output does not match your example output exactly, but it is valid per the rules you seem to want. Depending on the ordering of the input, the output will be different because there are multiple valid result sets. If I'm wrong in any assumptions, let me know.
Unless I misunderstand your problem, it seems to me you need to sort your collection linearly (1-dimensional), and then present it (2-dimensional). There's a distinction between data storage and data presentation. Here's what I came up with:
//Sample data to work with
var products = new List<KeyValuePair<string, int>>();
products.Add(new KeyValuePair<string, int>("A", 12));
products.Add(new KeyValuePair<string, int>("B", 23));
products.Add(new KeyValuePair<string, int>("C", 62));
products.Add(new KeyValuePair<string, int>("D", 17));
products.Add(new KeyValuePair<string, int>("E", 11));
products.Add(new KeyValuePair<string, int>("F", 75));
products.Add(new KeyValuePair<string, int>("G", 95));
products.Add(new KeyValuePair<string, int>("H", 24));
products.Add(new KeyValuePair<string, int>("I", 85));
products.Add(new KeyValuePair<string, int>("J", 41));
products.Add(new KeyValuePair<string, int>("K", 76));
products.Add(new KeyValuePair<string, int>("L", 77));
products.Add(new KeyValuePair<string, int>("M", 33));
products.Add(new KeyValuePair<string, int>("N", 81));
products.Add(new KeyValuePair<string, int>("O", 34));
products.Add(new KeyValuePair<string, int>("P", 45));
//Sort the collection
List<KeyValuePair<string, int>> ordered = products.OrderBy(x => x.Value).ToList();
//Put linear results into 2D array (4x4)
var matrix = new KeyValuePair<string, int>[4,4];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
matrix[i, j] = ordered[i * 4 + j];
//Write out results
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
var c = ordered[i * 4 + j];
Console.Write(c.Key + ": " + c.Value.ToString() + " ");
}
Console.WriteLine();
}
Output:
E: 11 A: 12 D: 17 B: 23
H: 24 M: 33 O: 34 J: 41
P: 45 C: 62 F: 75 K: 76
L: 77 N: 81 I: 85 G: 95
Related
(FF14:RR) This item can have 5 materias, 1 highlevel, 4 lowlevel.
I simplified the loops by having 3 types of materias (but i have 6, anw).
I put the materia in an item and then call Group.GetStats() to evaluate the statistics of the item then i store it in a List first checking its unicity.
Calling Group.GetStats() gives me a Dictionary with 3 caracteristics. And i want to filter the number of possibilities based on those statistics.
Example :
Stat1 - Stat2 - Stat3
(9, 7, 5)
(3, 10, 5)
(9, 7, 6)
(8, 6, 4)
(7, 6, 8)
(7, 7, 7) <-
(7, 7, 6)
(6, 6, 5)
(7, 6, 7)
All the tuples under (7, 7, 7) are useless because adding nothing more.
I already ended the algorithm to get all the possible materia combinations but i want to filter the combinations that are not useful.
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = j; k < 3; k++)
{
for (int l = k; l < 3; l++)
{
for (int m = l; m < 3; m++)
{
ItemContainer Group = new ItemContainer(735, 400, 0, 1, 4, 864, 471, 6, new string[] { "Facet Alembic", "Facet Mortar" });
Group.AddMateria(new Materia(i >= 3 ? i-3 : i));
Group.AddMateria(new Materia(j));
Group.AddMateria(new Materia(k));
Group.AddMateria(new Materia(l));
Group.AddMateria(new Materia(m));
if (DEBUG) Console.WriteLine("{" + string.Join(",", Group.GetStats()) + "}");
string tempkey = string.Join(",", Group.GetStats());
if (i >= 3)
{
if (!unicityChecker.ContainsKey(tempkey))
{
if (isAnyBetter(Group.GetStats(),betterChecker.GetStats())) // Condition to keep it
{
ContainerList_1.Add(Group);
unicityChecker.Add(tempkey, Group.GetStats());
}
}
}
else
{
/*
find the betterChecker in order to do isAnyBetter to only get the useful items
*/
if (betterChecker == null) betterChecker = Group;
else
{
if (isAllBetter(Group.GetStats(), betterChecker.GetStats())) betterChecker = Group;
}
}
}
}
}
}
}
The i < 6 sounds weird but this way i made 2 passes on the same generation of combinations.
In output of the entire algorithm (that embricks 7 of this one) i have about 10M records. I thought by removing the useless items at the first generation i could lower the size of the ouput (1Gb in json).
EDIT :
static bool isAnyBetter(Dictionary<String, int> stats1, Dictionary<String, int> stats2)
{
return stats1["craftmanship"] > stats2["craftmanship"] || stats1["control"] > stats2["control"] || stats1["cp"] > stats2["cp"];
}
For example, if the array is like
1 1 0 0
0 1 1 0
0 0 1 0
1 0 0 0
then the answer is 5.
I have a helper function
// Returns the size of the region of 1s containing the point (x0, y0).
// For example, if mat = 0 0 1
// 1 0 0
// 1 1 1
// then max_connected_region(0,0,mat) = 0,
// max_connected_region(2,0,mat) = 1,
// and max_connected_region(0,1,mat) = 4
static int max_connected_region(int x0, int y0, int[,] mat)
{
if(mat[x0,y0] == 0)
return 0;
var surroundings = (new int[][] {
new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 },
new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
int count = 1;
foreach(var pair in surroundings)
count += max_connected_region(pair[0], pair[1], mat);
mat[x0,y0] = 0;
return count;
}
and how I find the maximum connection in an n x m array (n rows, m columns) is using it like
int max_connections = 0;
for(int j = 0; j < n; ++j)
{
for(int i = 0; i < m; ++i)
{
if(matrix[i,j] == 0)
continue;
int connections = max_connected_region(i,j,matrix);
if(connections > max_connections)
max_connections = connections;
}
}
This procedure is giving me either a timeout or an out-of-bounds in the test cases and I can't figure out why.
As noted in the comments, your algorithm is revisiting array elements it's already checked, putting it in an endless loop.
You actually have a program statement that appears to be trying to avoid this, but you execute it after your recursive call. So it has no useful effect. If you simply move it before the loop that performs the recursive calls, your algorithm will work:
static int max_connected_region(int x0, int y0, int[,] mat)
{
if (mat[x0, y0] == 0)
return 0;
var surroundings = (new int[][] {
new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 },
new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
int count = 1;
mat[x0, y0] = 0;
foreach (var pair in surroundings)
count += max_connected_region(pair[0], pair[1], mat);
return count;
}
I note that your algorithm is destructive. That is, it modifies the array that's passed to it. This may be acceptable for your scenario — at worst, it means the caller needs to make sure that it passes a copy of its data. But if this were to be some sort of library method, you might consider making the copy yourself, or using an appropriately-sized bool[,] to track where the algorithm has already visited.
I also feel that allocating a whole new array for the surroundings with each iteration of the method is maybe not the best approach. If you intend to run this algorithm on much larger data sets, it might make more sense to have a static array containing the valid offsets, and then just have an explicit for loop iterating through that array for the recursive calls. This will minimize the extra memory allocation and garbage collection overhead as you visit each array element.
Making those changes, the method, and its supporting class members, would look more like this:
static int max_connected_region2(int x0, int y0, int[,] mat)
{
return max_connected_region2_impl(x0, y0, (int[,])mat.Clone());
}
static int max_connected_region2_impl(int x0, int y0, int[,] mat)
{
if (mat[x0, y0] == 0)
return 0;
int count = 1;
mat[x0, y0] = 0;
for (int i = 0; i < adjacentCells.Length; i++)
{
int[] pair = adjacentCells[i];
int x1 = pair[0] + x0, y1 = pair[1] + y0;
if (x1 >= 0 && x1 < mat.GetLength(0) && y1 >= 0 && y1 < mat.GetLength(1))
{
count += max_connected_region2_impl(x1, y1, mat);
}
}
return count;
}
private static readonly int[][] adjacentCells =
{
new [] { -1, 0 }, new [] { 1, 0 }, new [] { -1, 1 }, new [] {0, 1 },
new [] { 1, 1 }, new [] { -1, -1}, new [] { 0, -1 }, new [] { 1, -1 }
};
I have a array
int[] Values = new int[] { 5, 43, 45, 25, 16, 89, 65, 36, 62 };
and currently i am calculating the maximum distance between all values 84 = 89 - 5
int MaxDistance = Values.SelectMany((a) => Values.Select((b) => Math.Abs(a - b))).Max();
now I want to calculate the minimum distance 2 = 45 - 43
#ycsun's commment - this doesn't work
int MinDistancee = Values.SelectMany((ia, a) => Values.Select((ib, b) => ib == ia ? int.MaxValue : Math.Abs(a - b))).Min();
Try this instead
int MinDistance = Values.SelectMany(
(a, i) => Values.Skip(i + 1).Select((b) => Math.Abs(a - b))).Min();
This makes sure you don't calculate the difference between numbers at the same index or a set of numbers at different indexes twice. Basically this uses the overload of SelectMany that includes the index, then you just want to do your difference with all the numbers after the current index by using Skip.
It should be noted that a solution using for loops in the form of
for(int i = 0; i < Values.Length - 1; i++)
for(int j = i + 1; j < Values.Length; j++)
would be more performant though.
One caveat here though is if you have negative numbers. Then there will be a difference between the absolute value of a-b versus b-a. In that case you'd want to sort the list first to make sure the difference always has a as the larger number.
Just two simple loops:
int[] Values = new int[] { 5, 43, 45, 25, 16, 89, 65, 36, 62 };
int min = -1;
for (int i = 0; i < Values.Length - 1; ++i)
for (int j = i + 1; j < Values.Length; ++j) { // please, notice j = i + 1
int v = Math.Abs(Values[i] - Values[j]);
if ((min < 0) || (v < min))
min = v;
}
// 2 == 45 - 43
Console.Write(min);
I'm having trouble with int[] arrays and adding them to a List<>. I'd like to add the values of my int[] array to something each loop but every time I do this my "something" gets the same value for every element I add. Very annoying. I understand arrays are always reference vars. However even the "new" key word doesn't seem to help. What needs to happen is to add result to some enumerated object like a List or Array or ArrayList.
Here's the codility question:
You are given N counters, initially set to 0, and you have two possible operations on them:
increase(X) − counter X is increased by 1,
max_counter − all counters are set to the maximum value of any counter.
A non-empty zero-indexed array A of M integers is given. This array represents consecutive operations:
if A[K] = X, such that 1 ≤ X ≤ N, then operation K is increase(X),
if A[K] = N + 1 then operation K is max_counter.
For example, given integer N = 5 and array A such that:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the values of the counters after each consecutive operation will be:
(0, 0, 1, 0, 0)
(0, 0, 1, 1, 0)
(0, 0, 1, 2, 0)
(2, 2, 2, 2, 2)
(3, 2, 2, 2, 2)
(3, 2, 2, 3, 2)
(3, 2, 2, 4, 2)
The goal is to calculate the value of every counter after all operations.
I copied some code from others and the variable "result" does indeed load the data correctly. I just wanted to copy it back to the main program so I could see it. The only method that works is += add it into a string. Thus losing any efficiency I might have gained.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testarray
{
class Program
{
static void Main(string[] args)
{
int[] A = new int[7];
A[0] = 3;
A[1] = 4;
A[2] = 4;
A[3] = 6;
A[4] = 1;
A[5] = 4;
A[6] = 4;
List<int[]> finish = solution(5, A);
}
public static List<int[]> solution(int N, int[] A)
{
int[] result = new int[N];
int maximum = 0;
int resetlimit = 0;
int iter = 0;
List<int[]> collected_result = new List<int[]>;
for (int K = 0; K < A.Length; K++)
{
if (A[K] < 1 || A[K] > N + 1)
{
throw new InvalidOperationException();
}
if (A[K] >= 1 && A[K] <= N)
{
if (result[A[K] - 1] < resetlimit)
{
result[A[K] - 1] = resetlimit + 1;
}
else
{
result[A[K] - 1]++;
}
if (result[A[K] - 1] > maximum)
{
maximum = result[A[K] - 1];
}
}
else
{
resetlimit = maximum;
result = Enumerable.Repeat(maximum, result.Length).ToArray<int>();
}
collected_result.Add(result);
}
// for (int i = 0; i < result.Length; i++)
//result[i] = Math.max(resetLimit, result[i]);
return collected_result;
}
}
}
This doesn't work, the collected_result ends up like:
(0,0,1,2,0)
(0,0,1,2,0)
(0,0,1,2,0)
(3,2,2,4,2)
(3,2,2,4,2)
(3,2,2,4,2)
(3,2,2,4,2)
I know it's the line collected_result.Add(result); adding the reference each time to every instance of result in the List<>. Bother. I've tried adding "new" which is a compiler error. Finally in desperation I just added everything to a very long string. Can someone help me figure out how to properly load an object to pass back to main?
Easiest way to go:
Get a copy of your array before adding it to list:
collected_result.Add(result.ToArray());
Here is a Python solution:
def solution(A, N):
lenA = len(A)
k = 0
max_counter_value = 0
counters = [0 for x in range(0, N)]
for k in range(0, lenA):
if A[k] >= 1 and A[k] <= N:
counters[A[k] - 1] += 1
max_counter_value = max(counters)
if A[k] == N + 1:
counters = [max_counter_value for x in range(0, N)]
print counters
A = [3, 4, 4, 6, 1, 4, 4]
N = 5
solution(A, N)
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
Let's say I have two byte array which each contain a series of values like:
byte[] b = {50,60,70,80,90,10,20,1,2,3,4,5,50,2,3,1,2,3,4,5};
byte[] b2 = {1,2,3,4,5}
I can compare these two arrays and look for the equal values using LinQ methods. In this way, if I make a comparison between these two arrays, the result would be an index of b array where a value in an index of b2 array is a match.
I've been trying to exactly find the range where b2 array is recurring in b array. I mean
if (TheLenghtOfSearch==5) {Now the indexes of two regions must be return }
Result ->(7, 11), (15, 19)
if (TheLenghtOfSearch==2) {Now the indexes of around 9 regions where the two consecutive values in b2 recurred in b must be returned}
Result ->(7, 8), (15, 16), (8, 9), (13, 14), (16, 17), (9, 10), (17, 18), (10, 11), (18, 19)
I guess the solution is more mathematical.
I decided to use List, not array, because it have more helpers for this kind of operations.
As I understand depth = the amount of items that have to be equals in each array. This one works, check this out:
class Program
{
static void Main(string[] args)
{
List<byte> b = new List<byte>() { 50, 60, 70, 80, 90, 10, 20, 1, 2, 3, 4, 5, 50, 2, 3, 1, 2, 3, 4, 5 };
List<byte> b2 = new List<byte>() { 1, 2, 3, 4, 5 };
SmartComparer comparer = new SmartComparer();
//Setting the depth here, now the depth is = 5
var result = comparer.CompareArraysWithDepth(b, b2, 5);
foreach (var keyValuePair in result)
{
Console.WriteLine(String.Format("b[{0}]->b[{1}] are equal to b2[{2}]->b2[{3}]", keyValuePair.Key.Key,
keyValuePair.Key.Value, keyValuePair.Value.Key, keyValuePair.Value.Value));
}
}
}
public class SmartComparer
{
public Boolean CompareRange(List<byte> a, List<byte> b)
{
for (int i = 0; i < a.Count; i++)
{
if (a[i] != b[i])
{
return false;
}
}
return true;
}
/// <summary>
/// |
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="depth"></param>
/// <returns>Key->range in 'a', Value->range in 'b'</returns>
public List<KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>>> CompareArraysWithDepth(
List<byte> a, List<byte> b, int depth)
{
var result = new List<KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>>>();
if (depth > b.Count)
throw new ArgumentException("Array 'b' item count should be more then depth");
if(a.Count<b.Count)
throw new ArgumentException("Array 'a' item count should be more then Array 'b' item count");
for (int i = 0; i <= a.Count - depth; i++)
{
for (int j = 0; j <= b.Count - depth; j++)
{
if (CompareRange(a.GetRange(i, depth), b.GetRange(j, depth)))
{
result.Add(new KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>>(new KeyValuePair<int, int>(i, i + depth-1), new KeyValuePair<int, int>(j, j + depth-1)));
}
}
}
return result;
}
}
ADDED
The result of this operation for depth = 3:
b[7]->b[9] are equal to b2[0]->b2[2]
b[8]->b[10] are equal to b2[1]->b2[3]
b[9]->b[11] are equal to b2[2]->b2[4]
b[15]->b[17] are equal to b2[0]->b2[2]
b[16]->b[18] are equal to b2[1]->b2[3]
b[17]->b[19] are equal to b2[2]->b2[4]
The result of this operation for depth = 2:
b[7]->b[8] are equal to b2[0]->b2[1]
b[8]->b[9] are equal to b2[1]->b2[2]
b[9]->b[10] are equal to b2[2]->b2[3]
b[10]->b[11] are equal to b2[3]->b2[4]
b[13]->b[14] are equal to b2[1]->b2[2]
b[15]->b[16] are equal to b2[0]->b2[1]
b[16]->b[17] are equal to b2[1]->b2[2]
b[17]->b[18] are equal to b2[2]->b2[3]
b[18]->b[19] are equal to b2[3]->b2[4]
The result of this operation for depth = 5:
b[7]->b[11] are equal to b2[0]->b2[4]
b[15]->b[19] are equal to b2[0]->b2[4]
If Linq is not a absolutly required option for you, you can obtain the result by for loop:
public static IList<Tuple<int, int>> RecurringIndexes(Byte[] master, Byte[] toFind, int length) {
List<Tuple<int, int>> result = new List<Tuple<int, int>>();
// Let's return empty list ... Or throw appropriate exception
if (Object.ReferenceEquals(null, master))
return result;
else if (Object.ReferenceEquals(null, toFind))
return result;
else if (length < 0)
return result;
else if (length > toFind.Length)
return result;
Byte[] subRegion = new Byte[length];
for (int i = 0; i <= toFind.Length - length; ++i) {
for (int j = 0; j < length; ++j)
subRegion[j] = toFind[j + i];
for (int j = 0; j < master.Length - length + 1; ++j) {
Boolean counterExample = false;
for (int k = 0; k < length; ++k)
if (master[j + k] != subRegion[k]) {
counterExample = true;
break;
}
if (counterExample)
continue;
result.Add(new Tuple<int, int>(j, j + length - 1));
}
}
return result;
}
....
byte[] b = {50,60,70,80,90,10,20,1,2,3,4,5,50,2,3,1,2,3,4,5};
byte[] b2 = { 1, 2, 3, 4, 5 };
// Returns 2 patterns: {(7, 11), (15, 19)}
IList<Tuple<int, int>> indice5 = RecurringIndexes(b, b2, 5);
// Return 9 patterns: {(7, 8), (15, 16), (8, 9), (13, 14), (16, 17), (9, 10), (17, 18), (10, 11), (18, 19)}
IList<Tuple<int, int>> indice2 = RecurringIndexes(b, b2, 2);