All combinations of boolean values for array - c#

I have an array of strings, can be any length. How can I produce a boolean matrix (array of array of boolean values with the same width as the array of strings) that contains all combinations of booleans?
Result should look something like this
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
.
.
1 1 1 1
Edit:
To elaborate a little, this is part of a solution to a larger problem to generate dynamic SQL to handle where clause conditions across multiple tables each with 2 versions. In my attempt to narrow down the issue I agree I might have been too terse, I apologize.
This is what I ended up doing with the help of JamJar00.
var sWhere = TranslateCriteriaToSQL(oUoW, oCriteria, false, false, DataBaseID, User);
var sResult = "";
var tables = asTables.ToArray();
int n = tables.Length;
List<bool[]> matrix = new List<bool[]>();
double count = Math.Pow(2, n);
for (int i = 0; i < count; i++)
{
string str = Convert.ToString(i, 2).PadLeft(n, '0');
bool[] boolArr = str.Select((x) => x == '1').ToArray();
var sCondition = sWhere;
for (var j = 0; j < boolArr.Length; j++)
{
if (boolArr[j])
{
sCondition = " OR (" + sCondition.Replace("[" + tables[j] + "]", "[" + tables[j] + "Pending" + "]") +
")\n";
}
}
sResult += sCondition;
}
}

Your question isn't the most clear but I think this something like what you're after:
int n = 4;
List<bool[]> matrix = new List<bool[]>();
double count = Math.Pow(2, n);
for (int i = 0; i < count; i++)
{
string str = Convert.ToString(i, 2).PadLeft(n, '0');
bool[] boolArr = str.Select((x) => x == '1').ToArray();
matrix.Add(boolArr);
Console.WriteLine(String.Join(" ", boolArr.Select((x) => x ? "1" : "0")));
}
bool[][] arr = matrix.ToArray();
Where n is the width of the strings to create.
(Definitely not the most optimized code I've ever written...)

Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication87
{
class Program
{
static void Main(string[] args)
{
string input = "abcdef";
long max = (long)(Math.Pow(2, input.Length) - 1);
for (long count = 0; count <= max; count++)
{
List<string> array = new List<string>();
for (int j = input.Length - 1; j >= 0; j--)
{
array.Add((count >> j & 1) == 0 ? "0" : "1");
}
Console.WriteLine(string.Join(" ", array.ToArray()));
}
Console.ReadLine();
}
}
}

With an input string s and bool array b:
string s = "foo";
bool[,] b = new bool[(int)Math.Pow(2, s.Length), s.Length];
for (int i = 0; i < (int)Math.Pow(2, s.Length); i++)
{
for (int j = 0; j < s.Length; j++)
{
b[i, s.Length - 1 - j] = ((i & (int)Math.Pow(2, j)) > 0);
}
}

Appreciate this is an old question, however I found myself having to generate all permutations for an array of booleans and came up with the following:
bool[][] GeneratePermutations(int size)
{
return Enumerable.Range(0, (int)Math.Pow(2, size))
.Select(i =>
Enumerable.Range(0, size)
.Select(b => ((i & (1 << b)) > 0))
.ToArray()
).ToArray();
}

Related

Compare chars in two strings of different length in C#

In C#, Im trying to compare two strings and find out how many chars are different.
I Tried this:
static void Main(String[] args)
{
var strOne = "abcd";
var strTwo = "bcd";
var arrayOne = strOne.ToCharArray();
var arrayTwo = strTwo.ToCharArray();
var differentChars = arrayOne.Except(arrayTwo);
foreach (var character in differentChars)
Console.WriteLine(character); //Will print a
}
but there are problems with this:
if the strings contain same chars but on different positions within the string
it removes the duplicate occurences
If the strings would be the same length I would compare the chars one by one but if one is bigger than the other the positions are different
You may want to have a look at the Leventshtein Distance Algorithm.
As the article says
the Levenshtein distance between two words is the minimum number of
single-character edits (insertions, deletions or substitutions)
required to change one word into the other
You can find many reference implementations in the internet, like here or here.
public static int LevenshteinDistance(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
return d[n, m];
}
}
How about this? Append two strings into one and group them, you will have the count of the chars, > 1 will give the repeatings and = 0 will give the unique ones.
var strOne = "abcd";
var strTwo = "bcd";
var arrayOne = strOne.Concat(strTwo).GroupBy(x => x).Select(x => new { Key = x.Key, Count = x.Count() });
foreach (var character in arrayOne) {
if (character.Count > 1)
{
Console.WriteLine(character.Key); // the repeating chars
}
}
If the same character appears twice in the same string,
var strOne = "abbcdd";
var strTwo = "cd";
var arrayTwo = strOne.Select(x => new { Key = x, IsExists = strTwo.Any(y => y == x) });
foreach (var character in arrayTwo) {
if (character.IsExists)
{
Console.WriteLine(character.Key);
}
}

Most efficient way to find the smallest index where its value minus the value of a previous index is smaller than a given x?

I have five long integers p, q, s, m and x. An array numbers[] is created by the following formula.
numbers[0] = s;
for(int i=1; i<numbers.Length;i++){
numbers[i] = (p * numbers[i-1] + q) % m;
}
The first value of numbers (numbers[0]) is s.
What is the most efficient way to find index j where i < j and |numbers[j] - numbers[i]| <= x or |numbers[j] - numbers[i]| >= m-x.
For instance, in a case where p = 3, q= 7, s= 1, m= 29 en x= 1 the array will be:
numbers[0] = 1, numbers[1] = 10, numbers[2] = 8 and numbers[3] = 2.
In this case index j would be 3, because numbers[3] - numbers[0]<=x, because x is 1.
I thought about using something such as a variant of counting sort or radix sort but I can't get anything to work.
As i < j, then you need to grant that numbers has a length of at least 2.
You could do two nested loops, the outer one ranging from j = 1 to numbers.Length - 1 (granting the possible solution to be the smallest j) to i = 0 to i < j.
Then you compare both positions according your specs. If true, return j. If it finishes both loops, then there is no solution.
Edit: Code Sample
public int GetSmallestIndex(long[] numbers, long x, long m)
{
if (numbers.Length >= 2)
{
for (int j = 1; j < numbers.Length; j++)
{
for (int i = 0; i < j; i++)
{
long diff = Math.Abs(numbers[j] - numbers[i]);
if (diff <= x || diff >= m - x)
return j;
}
}
}
return -1; //If no solution is found, return -1 as convention
}
The only way to find out if something is more efficient is to benchmark it by using the StopWatch in System.Diagnostics.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
public static void Main()
{
var stopWatch = new Stopwatch();
stopWatch.Start();
const long x = 1;
var numbers = new long[] {3, 7, 1, 29};
var theSmallestIndex = SmallestIndex(x, numbers);
stopWatch.Stop();
Console.WriteLine("Elapsed Time: {0}", stopWatch.Elapsed);
Console.WriteLine("Smallest Index: {0}", theSmallestIndex);
Console.ReadKey();
}
public static long SmallestIndex(long x, long[] numbers)
{
var values = ValuesMinusTheValueOfPreviousIndex(x, numbers.ToList());
var smallest = values.Values.OrderBy(n => n).FirstOrDefault();
var result = values.Where(n => n.Value.Equals(smallest));
return result.FirstOrDefault().Key;
}
public static Dictionary<int, long> ValuesMinusTheValueOfPreviousIndex(long x, List<long> numbers)
{
var results = new Dictionary<int, long>();
foreach (var number in numbers)
{
var index = numbers.IndexOf(number);
var previousNumber = index > 0 ? numbers.ElementAt(index - 1) : 0;
var result = number - previousNumber;
results.Add(index, result);
}
return results;
}
}
}
EDIT: Added Math.Abs as you requested in the comments
long p = 3, q = 7, s = 1, m = 29, x = 1;
long[] numbers = new long[10];
numbers[0] = s;
for (int i = 1; i < numbers.Length; i++)
{
numbers[i] = (p * numbers[i - 1] + q) % m;
}
// Find the smallest index j in numbers, where i < j &&
// (numbers[j] - numbers[i] <= x || numbers[j] - numbers[i] >= m-x)
int smallestIndex = 0;
long comparison;
for (int j = 1; j < numbers.Length; j++)
{
for (int i = 0; i < j; i++)
{
comparison = Math.Abs(numbers[j] - numbers[i]);
if (comparison <= x || comparison >= m - x)
{
smallestIndex = j;
break;
}
}
if (smallestIndex != 0) break;
}
if (smallestIndex == 0)
{
// No result matches the conditions
}
else
{
// j is the smallest index matching the conditions
// Before using Abs, in the example j is 2, because 8 - 10 = -2, lesser than x
// Now using absolute values, In the example j is 3
}

Clean algorithm to generate all sets of the kind (0) to (0,1,2,3,4,5,6,7,8,9)

Basically, I'd like a set of sets that contains from (0..9), then (0, 1..9), (1, 2..9)..(8,9), and so on and so forth up until (0,1,2,3,4,5,6,7,8,9). I know this can be accomplished by nesting for loops in the manner below, but I'm wondering if there's a neater way of doing it?
Preferably something that could be accomplished within C#, but I'm interested in any algorithm.
for (int i = 0; i < max; i++) {
yield {i};
for (int j = i + 1; j < max; j++) {
yield {i, j};
for (int k = j + 1; k < max; k++) {
yield {i, j, k};
for (int l = k + 1; l < max; l++) {
yield {i, j, k, l};
for (int m = l + 1; m < max; m++) {
yield {i, j, k, l, m};
// And so on and so forth
}
}
}
}
}
I wrote this a while ago. It uses a Stack. It's generic, so it can be used for other sequences as well.
static IEnumerable<T[]> CombinationsAnyLength<T>(params T[] values)
{
Stack<int> stack = new Stack<int>(values.Length);
int i = 0;
while (stack.Count > 0 || i < values.Length) {
if (i < values.Length) {
stack.Push(i++);
int c = stack.Count;
T[] result = new T[c];
foreach (var index in stack) result[--c] = values[index];
yield return result;
} else {
i = stack.Pop() + 1;
if (stack.Count > 0) i = stack.Pop() + 1;
}
}
}
CombinationsAnyLength(1, 2, 3, 4) outputs:
1
12
123
1234
124
13
134
14
2
23
234
24
3
34
4
Why not treat this as bits and generate the set from the bits?
IEnumberable<List<int>> MakeSets()
{
// count from 1 to 2^10 - 1 (if you want the empty set, start at 0
for (uint i=1; i < (1 << 10); i++) {
// enumerate the bits as elements in a set
List<int> set = BitsIn(i);
yield return set;
}
}
List<int> MakeSet(uint i)
{
List<int> set = new List<int>();
// this will give you values from 0..max
// if you want 1, start with 1
// if you want non-integers, pass in an array of values and index into that
int val = 0;
// for every bit in i
while (i != 0)
{
// add the val if the corresponding bit is set
if ((i & 1) != 0) set.Add(val);
i = i >> 1;
val++;
}
return set;
}
and since I like the generic version above, let's make this generic too:
IEnumerable<List<T>> MakeSets(params T[] values)
{
if (values.Length > 63) throw new IllegalArgumentException("63 is the limit");
for (ulong i = i; i < (1 << (values.Length + 1); i++) {
List<T> set = new List<T>();
int val = 0;
ulong j = i;
while (j != 0) {
if ((j & 1) != 0) set.Add(values[val]);
j = j >> 1;
val++;
}
yield return set;
}
}
here is a algorithm for generating sub-sets.
let you have a set S = [a,b,c,d,e,f].
and you want to generate all the subsets then length of the array containing all the sub-sets will be
2^n where n is number of elements in S.
int A = [] // array containing all sub-sets
for i = 0 --- 2^n
x = binary(i) // like for i = 5 -> x = '000101' where x is a string of n digits.
ns = [] // new array
for j = 0 --- n
if x[j] == '1'
push S[j] into ns array
push ns into A
return A
A will have every set you wanted or you can modify it to get new result.
Using Dennis signature:
public static IEnumerable<T[]> CombinationsAnyLength<T>(params T[] values)
{
for(var i = 0; i < (1 << values.Length); i++)
{
var result = new List<T>();
for(var j = 0; j < values.Length; j++)
{
if(((1 << j) & i) != 0)
{
result.Add(values[j]);
}
}
yield return result.ToArray();
}
}

Latest Codility Time Problems

Just got done with the latest Codility, passed it, but didnt get 100% on it
Here is the spec
A prefix of a string S is any leading contiguous part of S. For example, "c" and "cod" are prefixes of the string "codility". For simplicity, we require prefixes to be non-empty.
The product of prefix P of string S is the number of occurrences of P multiplied by the length of P. More precisely, if prefix P consists of K characters and P occurs exactly T times in S, then the product equals K * T.
For example, S = "abababa" has the following prefixes:
"a", whose product equals 1 * 4 = 4,
"ab", whose product equals 2 * 3 = 6,
"aba", whose product equals 3 * 3 = 9,
"abab", whose product equals 4 * 2 = 8,
"ababa", whose product equals 5 * 2 = 10,
"ababab", whose product equals 6 * 1 = 6,
"abababa", whose product equals 7 * 1 = 7.
The longest prefix is identical to the original string. The goal is to choose such a prefix as maximizes the value of the product. In above example the maximal product is 10.
In this problem we consider only strings that consist of lower-case English letters (a−z).
So basically, it is a string traverse problem. I was able to pass all the validation parts, but I lost on the time. Here is what I wrote
int Solution(string S)
{
int finalCount = 0;
for (int i = 0; i <= S.Length - 1; i++)
{
string prefix = S.Substring(0, i + 1);
int count = 0;
for (int j = 0; j <= S.Length - 1; j++)
{
if (prefix.Length + j <= S.Length)
{
string newStr = S.Substring(j, prefix.Length);
if (newStr == prefix)
{
count++;
}
}
if (j == S.Length - 1)
{
int product = count * prefix.Length;
if (product > finalCount)
{
finalCount = product;
}
}
}
}
return finalCount;
}
I know that the nested loop is killing me, but I cannot think of a way to traverse the "sections" of the string without adding the other loop.
Any help would be appreciated.
Naive brute-force solution takes O(N ** 3) time. Choose length from 1 to N, get a prefix of its length and count occurences by brute-force searching. Сhoosing length takes O(N) time and brute force takes O(N ** 2) time, totally O(N ** 3).
If you use KMP or Z-algo, you can find occurences in O(N) time, so the whole solution will be O(N ** 2) time.
And you can precalc occurences, so it will take O(N) + O(N) = O(N) time solution.
vector<int> z_function(string &S); //z-function, z[0] = S.length()
vector<int> z = z_function(S);
//cnt[i] - count of i-length prefix occurrences of S
for (int i = 0; i < n; ++i)
++cnt[z[i]];
//if cnt[i] is in S, cnt[i - 1] will be in S
int previous = 0;
for (int i = n; i > 0; --i) {
cnt[i] += previous;
previous = cnt[i];
}
Here's the blog post, explaining all O(N ** 3), O(N ** 2), O(N) solutions.
my effort was as follows trying to eliminate unnecessary string compares, i read isaacs blog but it is in c how would this translate to c#, i even went as far as using arrays everywhere to avoid the string immutability factor but there was no improvement
int Rtn = 0;
int len = S.Length;
if (len > 1000000000)
return 1000000000;
for (int i = 1; i <= len; i++)
{
string tofind = S.Substring(0, i);
int tofindlen = tofind.Length;
int occurencies = 0;
for (int ii = 0; ii < len; ii++)
{
int found = FastIndexOf(S, tofind.ToCharArray(), ii);
if (found != -1)
{
if ((found == 0 && tofindlen != 1) || (found >= 0))
{
ii = found;
}
++occurencies ;
}
}
if (occurencies > 0)
{
int total = occurencies * tofindlen;
if (total > Rtn)
{
Rtn = total;
}
}
}
return Rtn;
}
static int FastIndexOf(string source, char[] pattern, int start)
{
if (pattern.Length == 0) return 0;
if (pattern.Length == 1) return source.IndexOf(pattern[0], start);
bool found;
int limit = source.Length - pattern.Length + 1 - start;
if (limit < 1) return -1;
char c0 = pattern[0];
char c1 = pattern[1];
// Find the first occurrence of the first character
int first = source.IndexOf(c0, start, limit);
while ((first != -1) && (first + pattern.Length <= source.Length))
{
if (source[first + 1] != c1)
{
first = source.IndexOf(c0, ++first);
continue;
}
found = true;
for (int j = 2; j < pattern.Length; j++)
if (source[first + j] != pattern[j])
{
found = false;
break;
}
if (found) return first;
first = source.IndexOf(c0, ++first);
}
return -1;
}
I only got a 43... I like my code though! Same script in javascript got 56 for what it's worth.
using System;
class Solution
{
public int solution(string S)
{
int highestCount = 0;
for (var i = S.Length; i > 0; i--)
{
int occurs = 0;
string prefix = S.Substring(0, i);
int tempIndex = S.IndexOf(prefix) + 1;
string tempString = S;
while (tempIndex > 0)
{
tempString = tempString.Substring(tempIndex);
tempIndex = tempString.IndexOf(prefix);
tempIndex++;
occurs++;
}
int product = occurs * prefix.Length;
if ((product) > highestCount)
{
if (highestCount > 1000000000)
return 1000000000;
highestCount = product;
}
}
return highestCount;
}
}
This works better
private int MaxiumValueOfProduct(string input)
{
var positions = new List<int>();
int max = 0;
for (int i = 1; i <= input.Length; i++)
{
var subString = input.Substring(0, i);
int position = 0;
while ((position < input.Length) &&
(position = input.IndexOf(subString, position, StringComparison.OrdinalIgnoreCase)) != -1)
{
positions.Add(position);
++position;
}
var currentMax = subString.Length * positions.Count;
if (currentMax > max) max = currentMax;
positions.Clear();
}
return max;
}

Longest Common Subsequence

Hi this is my code for longest common subsequence for 2 strings in c# . I need help in backtracking . I need to find out the subsequence : GTCGT
String str1 = "GTCGTTCG";
String str2 = "ACCGGTCGAGTG";
int[,] l = new int[str1.Length, str2.Length]; // String 1 length and string 2 length storing it in a 2-dimensional array
int lcs = -1;
string substr = string.Empty;
int end = -1;
for (int i = 0; i <str1.Length ; i++) // Looping based on string1 length
{
for (int j = 0; j < str2.Length; j++) // Looping based on string2 Length
{
if (str1[i] == str2[j]) // if match found
{
if (i == 0 || j == 0) // i is first element or j is first elemnt then array [i,j] = 1
{
l[i, j] = 1;
}
else
{
l[i, j] = l[i - 1, j - 1] + 1; // fetch the upper value and increment by 1
}
if (l[i, j] > lcs)
{
lcs = l[i, j]; // store lcs value - how many time lcs is found
end = i; // index on longest continuous string
}
}
else // if match not found store zero initialze the array value by zero
{
l[i, j] = 0;
}
}
Your function needs to return a collection of strings. There might be several longest common sub-sequence with same length.
public List<string> LCS(string firstString, string secondString)
{
// to create the lcs table easier which has first row and column empty.
string firstStringTemp = " " + firstString;
string secondStringTemp = " " + secondString;
// create the table
List<string>[,] temp = new List<string>[firstStringTemp.Length, secondStringTemp.Length];
// loop over all items in the table.
for (int i = 0; i < firstStringTemp.Length; i++)
{
for (int j = 0; j < secondStringTemp.Length; j++)
{
temp[i, j] = new List<string>();
if (i == 0 || j == 0) continue;
if (firstStringTemp[i] == secondStringTemp[j])
{
var a = firstStringTemp[i].ToString();
if (temp[i - 1, j - 1].Count == 0)
{
temp[i, j].Add(a);
}
else
{
foreach (string s in temp[i - 1, j - 1])
{
temp[i, j].Add(s + a);
}
}
}
else
{
List<string> b = temp[i - 1, j].Concat(temp[i, j - 1]).Distinct().ToList();
if (b.Count == 0) continue;
int max = b.Max(p => p.Length);
b = b.Where(p => p.Length == max).ToList();
temp[i, j] = b;
}
}
}
return temp[firstStringTemp.Length - 1, secondStringTemp.Length - 1];
}
You need to have a collection set in each entry of table. So you can still keep different strings with the same length in each cell of table.
As far as I've understood your question, I think you want to know the subsequence value i.e. that string. So, to get the subsequence, I've learnt a little bit differently. First, I calculate the table the one we do in standard Longest Common Subsequence (LCS) problem. Then I traverse the table to get the subsequence value. Sorry, I'm not familiar with C#, so, I will give you CPP code. Please have a look and let me know if you face any problem.
#include<iostream>
#include<vector>
#include<string>
using namespace std;
string printLongestCommonSubsequence(vector<vector<int> >& dp, int m, int n, string text1, string text2){
int i = m, j = n;
string lcs = "";
while(i > 0 && j > 0){
if(text1[i-1] == text2[j-1]){
lcs.push_back(text1[i-1]);
i--; j--;
}
else{
if(dp[i][j-1] > dp[i-1][j]) j--;
else i--;
}
}
reverse(lcs.begin(), lcs.end());
return lcs;
}
string longestCommonSubsequence(string text1, string text2){
int m = text1.size();
int n = text2.size();
vector<vector<int> > dp(m+1, vector<int>(n+1));
//initialization
for(int i=0; i<m+1; i++){
for(int j=0; j<n+1; j++){
if(i == 0 || j == 0) dp[i][j] = 0;
}
}
//solving the subproblems to solve the bigger problems
for(int i=1; i<m+1; i++){
for(int j=1; j<n+1; j++){
if(text1[i-1] == text2[j-1])
dp[i][j] = 1 + dp[i-1][j-1];
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
return printLongestCommonSubsequence(dp, m, n, text1, text2);
}
int main(){
string text1, text2;
cout<<"Enter the first string: ";
cin>>text1;
cout<<"\nEnter the second string: ";
cin>>text2;
string lcs = longestCommonSubsequence(text1, text2);
cout<<"Longest Common Subsequence is: "<<lcs<<endl;
return(0);
}
Please have a look at the diagram.
With respect to printing the LCS,
The basic idea is:
When the characters are equal of both the strings then move towards diagonal.
When the characters are not equal of both the strings then move towards the maximum of both the directions.
I hope this helps 🙂
Happy Learning
Thanks

Categories

Resources