Finding unknown repeating patterns in a string consisting numbers - c#

I've been struggling with this for a week.
I have a string like this: 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1.....
What I need to find: 1 1 0
example 2: 1 1 2 0 2 2 1 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 ....
What I need to find: 1 1 2 0 2 2 1 0
example 3: 1 1 2 3 1 0 1 1 2 3 1 0 1 1 2 3 1 0 1 1 2 3 1 0 1 1 2 3 1 0...
112310
etc. etc.
My code as now:
private string tekrarArama(double[] mods)
{
string part1 = "";
string part2 = "";
string patern = "";
int number1 = mods.Length;
for (int i = 0; i < mods.Length; i++)
{
part1 = "";
part2 = "";
for (int j = 0; j < number1; j++)
{
part1 += mods[j] + ",";
}
for (int k = 0; k < mods.Length; k++)
{
part2 += mods[k] + ",";
}
int actualcount = Regex.Matches(part2, part1).Count;
int count = part2.Replace(",", "").Length / part1.Replace(",", "").Length;
if (part2.IndexOf(bolum1) >= 0 && actualcount == count )
{
patern = part2.Substring(part2.IndexOf(part1),part1.Length);
}
number1--;
}
return patern;
}
It creates two copies of the string and deletes 1 character at a time from one of the strings in each iteration, to find the smallest repeating pattern.
It's a mess and doesn't work very well at all.
How can I do this? Thanks in advance.

If you're looking for something simple and don't need optimal complexity, here's a concise way to represent the query.
string FindPattern(string text)
{
if (text == null)
{
return null;
}
return Enumerable
.Range(1, text.Length / 2)
.Where(n => text.Length % n == 0)
.Select(n => text.Substring(0, n))
.Where(pattern => Enumerable
.Range(0, text.Length / pattern.Length)
.SelectMany(i => pattern)
.SequenceEqual(text))
.FirstOrDefault();
}
Note that the complexity here is quadratic in the worst case, so it's not a good idea to use it for very long strings.

Related

C# getting the biggest area of a matrix which has the same element

In C# I've come to a problem I can't solve myself. I have a 2d matrix which looks like this
1 1 1 0 0 0 0 1 1 1
1 0 1 0 0 0 0 1 1 1
1 0 1 1 1 1 1 0 1 1
1 0 1 1 1 1 1 0 1 1
1 0 1 1 1 1 1 1 1 1
1 1 1 0 0 1 1 1 1 1
1 1 1 0 0 1 1 1 1 1
I want to find out the biggest 4-connected (north, west, south, east) area of 0. For the example above the answer is 8 (the biggest area of all zeroes is on the top of the matrix):
0 0 0 0
0 0 0 0
I have no idea how to cope such a task, so anything could help.
Thanks!
I've tried iterating through the matrix with a for but its not working if the biggest area where 0 are on the same line (or column).
You can scan the map and on each 0 perform a search (in the code below it is Breadth First Search):
Code: (Fiddle)
private static int MaxIsland(int[,] ocean) {
int result = 0;
if (ocean == null)
return result;
var visited = new HashSet<(int y, int x)>();
for (int y = 0; y < ocean.GetLength(0); ++y)
for (int x = 0; x < ocean.GetLength(1); ++x) {
if (ocean[y, x] != 0)
continue;
if (!visited.Add((y, x)))
continue;
int current = 1;
var agenda = new Queue<(int y, int x)>();
agenda.Enqueue((y, x));
while (agenda.Count > 0) {
var (r, c) = agenda.Dequeue();
for (int d = 0; d < 4; ++d) {
int newR = r + (d - 1) % 2;
int newC = c + (d - 2) % 2;
if (newC < 0 || newR < 0 ||
newR >= ocean.GetLength(0) || newC >= ocean.GetLength(1))
continue;
if (ocean[newR, newC] != 0)
continue;
if (visited.Add((newR, newC))) {
agenda.Enqueue((newR, newC));
current += 1;
}
}
}
result = Math.Max(result, current);
}
return result;
}
Time complexity: O(n * m) where n and m are matrix dimensions
Space complexity: O(n * m) in the worst case

Draw diagonal line from top right corner to bottom left using nested for loop in c# console app

I have matrix 5x5 filled with zeroe.
I'm going to draw diagonal line from top right corner to bottom left corner using nested for loop.
expected output :
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 1 0 0 0
1 0 0 0 0
my output:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
my code so far:
using System;
namespace practice_04
{
class Program
{
static void Main(string[] args)
{
int[,] array = new int[5, 5];
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
array[i, j] = (i == j) ? 1 : 0;
Console.Write($"{array[i, j]} ");
}
Console.WriteLine(Environment.NewLine);
}
}
}
}
I don't get it how to reverse my output into expected output
Just slight modification will do the trick:
array[i, j] = (i == 4 - j) ? 1 : 0;
For better code quality I'd suggest using array sizes further down the code after initializing it:
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
and
array[i, j] = (i == array.GetLength(0) - 1 - j) ? 1 : 0;
You print your array like this:
i\j 0 1 2 3 4
0 0 0 0 0 1
1 0 0 0 1 0
2 0 0 1 0 0
3 0 1 0 0 0
4 1 0 0 0 0
Therefore you want i + j == 4 instead of i == j
This is how i+j looks like, if you're not convinced yet:
i\j 0 1 2 3 4
0 0 1 2 3 4
1 1 2 3 4 5
2 2 3 4 5 6
3 3 4 5 6 7
4 4 5 6 7 8
A Little Mistake in the for loop. Attached the correct Line:
for (int j = 4; j >= 0; j--)
{
array[i, j] = (i == j) ? 1 : 0;
Console.Write($"{array[i, j]} ");
}
Then your output will be mirrored:
i\j 4 3 2 1 0
0 0 0 0 0 1
1 0 0 0 1 0
2 0 0 1 0 0
3 0 1 0 0 0
4 1 0 0 0 0

How to get all combinations with a fixed number of flags in array

here I have an array with a specific length and also a specific number of flags which have to be set. The length and number of flags can change from case to case, so they should be generic.
Example:
var array = new bool[] { false, false, false, false, false, false };
var numberOfFlags = 2;
I'd now like to get all permutations / combinations which are possible, when always 2 flags have to be set. Example:
1 1 0 0 0 0
0 1 1 0 0 0
0 0 1 1 0 0
But also for example:
0 1 0 0 0 1
Or:
0 0 0 1 0 1
I simply need a way to get all possible combinations where the predefined number of flags are set. No pattern or anything, just all possible combinations. Preferrably in C#.
I'm really looking forward to an answer and thanks a lot!
I found this on rosettacode.org. (I changed it a little bit). It's non-recursive. It just uses a Stack. It returns the same (modified) array every time, but that can be easily changed if needed.
public static IEnumerable<int[]> Combinations(int n, int k)
{
var result = new int[k];
var stack = new Stack<int>();
stack.Push(0);
while (stack.Count > 0) {
int index = stack.Count - 1;
int value = stack.Pop();
while (value < n) {
result[index++] = value++;
stack.Push(value);
if (index == k) {
yield return result;
break;
}
}
}
}
Combinations(6, 2) will give:
[0,1], [0,2], [0,3], [0,4], [0,5], [1,2], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5], [3,4], [3,5], [4,5]
Just for numberOfFlags = 2 this is a simple sollution:
static void Main(string[] args)
{
var array = new bool[] { false, false, false, false, false, false };
var length = array.Length;
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length; j++)
{
var arr = (bool[])array.Clone();
arr[i] = arr[j] = true;
arr.ToList().ForEach(s => Console.Write((s ? 1 : 0) + " "));
Console.WriteLine();
}
}
Console.Read();
}
Output:
1 1 0 0 0 0
1 0 1 0 0 0
1 0 0 1 0 0
1 0 0 0 1 0
1 0 0 0 0 1
0 1 1 0 0 0
0 1 0 1 0 0
0 1 0 0 1 0
0 1 0 0 0 1
0 0 1 1 0 0
0 0 1 0 1 0
0 0 1 0 0 1
0 0 0 1 1 0
0 0 0 1 0 1
0 0 0 0 1 1
The number of combinations can be calculed with:
P=(n!)/(a!·b!)
Where n is the lenght of the array, a is numberOfFlags and b is n - a.
This is a method of achieving what you want:
bool[] array = new bool[] { false, false, false,false};
int numberOfFlags = 1;
int n, a, b,_n,_a,_b;
n = array.Length;
_n = n;
a = numberOfFlags;
_a = a;
b = n - a;
_b = b;
//Calculate n!
for (int i = _n - 1; i >= 1; i--)
n = n * i;
//Calculate a!
for (int i = _a - 1; i >= 1; i--)
a = a * i;
//Calculate a!
for (int i = _b - 1; i >= 1; i--)
b = b * i;
int NumberOfPermutations = n / (a * b);
------EDIT------
This code works only for an array with only 2 possible values. Imagine that we have 3 possible values, then:
n = lenght of the array
a = repetitions of the first value
b = repetitions of the second value
c = n - (a+b) = repetitions of the third value
The number of permutations could be calculed with
P=(n!)/(a!·b!·c! ...)
In the code you should add only some variables, some loops...et voilà

Find string with most frequency of a character in List of strings using LINQ C#

I am dealing with binary vectors so each string in a List<string> looks like
vectors[0] = "1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1";
vectors[1] = "1 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1";
I want to get the biggest string from the List<string>, with most number of 1's.
I feel like the provided solutions here are way too complicated.
So here is mine:
vectors.OrderByDescending(v => v.Count(c => c == '1')).First();
Note that Count is only evaluated once per "Vector". EnumerableSorter does this for you.
If you want a more performant solution then go with #octavioccls answer
I would do this:
var biggest= vectors.Select(v=> new {Vector = v, Count = v.Count(c => c=='1')})
.Aggregate((seed, current) => seed.Count < current.Count ? current:seed)
.Vector;
You can also use OrderBy extension method but Aggregate is O(n) while OrderBy is O(n* log n).
I first call Select extension to avoid calculate multiple times the amount of 1's of seed:
var biggest= vectors.Aggregate((seed, current)=>seed.Count(c=>c=='1')<current.Count(c=>c=='1')?current:seed);
You can use Count() method:
int index = 0;
int max = vectors[0].Count(x => x == '1');
for (int a = 1; a < vectors.Length; a++)
{
var count = vectors[a].Count(x => x == '$');
if (count > max)
{
max = count;
index = a;
}
}
after loop you will have index of string which has maximum '1'
Using LINQ
var result = vectors.Select(d => new { Item = d,
OneCount = d.Split(' ').Count(y => y == "1")})
.OrderByDescending(t => t.OneCount)
.Select(k=>k.Item).FirstOrDefault();
vectors.OrderByDescending(b => b.Split('1').Length).First()
You can do a loop on the list and for each string calculate the number of occurences of '1' in this way:
int count = myString.Split('1').Length - 1;
Then store a temporary variable with the local maximum and the number of string with that maximum.
Like this:
int max = list[0].Split('1').Length - 1;
int stringMax = 0;
for (int i = 1; i < list.Length; i++)
{
var count = list[i].Split('1').Length - 1;
if (count > max)
{
max = count;
stringMax = i;
}
}
At the end stringMax is the string with max value and max is that value
var vectors = new[] {
"1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1",
"1 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1",
};
var q = from v in vectors
select new
{
v,
c = v.Split(' ').Count(b => b == "1"),
};
var m = q.First(c => c.c == q.Max(b => b.c)).v;
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var vectors = new List<string>();
vectors.Add("1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1");
vectors.Add("1 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1");
foreach(var v in vectors)
{
var result = new List<string>();
int max = 0;
foreach(var c in v)
{
if(string.IsNullOrEmpty(c.ToString().Trim())) continue;
//Console.Write(c);
//Console.Write(max);
if(c != '1')
{
max = 0;
}
else
{
max++;
if(max > result.Count)
{
result.Add(c.ToString());
}
}
}
Console.WriteLine("Final Result: " + string.Join(" ", result));
}
}
}

word permutation with repetition where words are used multiple times

I am trying to generate a list of combinations from an array of words.
I have been using http://www.codeproject.com/Articles/26050/Permutations-Combinations-and-Variations-using-C-G to generate Combinations
var words = File.ReadAllLines(#"C:\words.txt");
var allCombinations = new List<string>();
var combis = new Combinations<string>(words, 3, GenerateOption.WithRepetition);
allCombinations.AddRange(combis.Select(c => c.Aggregate((j, k) => j + "-" + k)));
given 3 words "Word1", "Word2" and "Word3" I get a list of combinations like
"Word1-Word1-Word1"
"Word1-Word1-Word2"
"Word1-Word1-Word3"
etc.
But I am missing combinations where a word is used multiple times
"Word1-Word2-Word1"
"Word1-Word3-Word1"
"Word2-Word1-Word2"
How do I get combinations of words that uses words multiple times?
Your situation is basically like counting in base 3:
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
// and so on..
If the library you're using doesn't implement the logic you require, you can implement it yourself. Here is the idea:
public static IEnumerable<string> Permutate(string[] words)
{
// 0 0 0
int[] indices = new int[words.Length];
// yield 0 0 0
yield return string.Join("-", indicies.Select(x => words[x]));
// moves to 0 0 1 and so on, returns false after 3 3 3
while (CountStep(indicies))
{
// yield next permutation
yield return string.Join("-", indicies.Select(x => words[x]));
}
}
Implementing CountStep is not hard either:
public static bool CountStep(int[] arr)
{
// assumes we count in base N for an N sized array
var maxDigit = arr.Length - 1;
for (var i = arr.Length - 1; i >= 0; i--)
{
if (arr[i] < maxDigit)
{
arr[i]++;
for (var j = i + 1; j < arr.Length; j++)
{
arr[j] = 0;
}
return true;
}
}
return false;
}

Categories