Wrong N times matrix rotation - c#

I have a task to rotate 2D matrix R`times what has n columns and m rows. Rotation should be in anti-clockwise direction.
The problems with my code below:
Looks like the StepValuesOperation method wrongly get or set values from matrix. I've already break a head to find out where is a problem.
Is it possible to rotate values without moving it into separated array?
About the code:
I have and a console application, which randomly initialize the matrix size, its values and count of rotation by InitializeParams method;
I get the count of iterations of matrix and for each get an array of values of the current iteration by StepValuesOperation method;
From the count of rotations, which could be greater than the count of digits in the current iteration, I get rotCount by mod operation.
Then rotate values by the RorateValues method and move it back to matrix by StepValuesOperation
private static void Main(string[] args)
{
int m, r, n;
long[,] matrix;
InitializeParams(out n, out m, out r, out matrix);
Console.WriteLine("Rotation times: " + r);
Console.WriteLine("Input matrix:");
PrintMatrix(matrix);
Console.WriteLine();
int deep = Math.Min(m, n) / 2;
for (int step = 0; step < deep; step++)
{
List<long> oldArr = new List<long>((n + m) * 2);
StepValuesOperation(false, step, oldArr, matrix);
int perim = oldArr.Count;
int rotCount = perim < r ? r % perim : r;
if (rotCount != 0 && rotCount != perim)
{
long[] newArr = new long[perim];
Console.WriteLine($"Rest rotation count {rotCount} from {r} with perimeter {perim}");
Console.WriteLine(string.Join(", ", oldArr));
RorateValues(rotCount, newArr, oldArr);
Console.WriteLine(string.Join(", ", newArr));
StepValuesOperation(true, step, newArr, matrix);
}
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("Output matrix:");
PrintMatrix(matrix);
Console.ReadLine();
}
private static void RorateValues(int rotCount, IList<long> newArr, IList<long> oldArr)
{
int perim = oldArr.Count;
for (int i = 0; i < perim; i++)
{
int pos = i + rotCount;
if (pos >= perim)
{
pos -= perim;
}
newArr[pos] = oldArr[i];
}
}
Random initialization parameters of the matrix
private static void InitializeParams(out int n, out int m, out int r, out long[,] matrix)
{
Random rand = new Random();
n = 4;//rand.Next(2, 7) * 2;
m = 6;//rand.Next(1, 5) * 2;
r = rand.Next(1, 10000);
matrix = new long[n, m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i, j] = rand.Next(i + j, i + j + n * 10);
}
}
}
Move out of or into array the values of matrix
private static void StepValuesOperation(bool initialized, int step, IList<long> arr, long[,] matrix)
{
int sizeI = matrix.GetLength(0) - step;
int sizeJ = matrix.GetLength(1) - step;
int pos = 0;
for (int i = step; i < sizeI; i++, pos++)
{
if (!initialized)
arr.Add(matrix[i, step]);
else
matrix[i, step] = arr[pos];
}
for (int j = step; j < sizeJ; j++, pos++)
{
if (!initialized)
arr.Add(matrix[sizeI - 1, j]);
else
matrix[sizeI - 1, j] = arr[pos];
}
for (int i = sizeI - 1; i > step; i--, pos++)
{
if (!initialized)
arr.Add(matrix[i, sizeJ - 1]);
else
matrix[i, sizeJ - 1] = arr[pos];
}
for (int j = sizeJ - 1; j > step; j--, pos++)
{
if (!initialized)
arr.Add(matrix[step, j]);
else
matrix[step, j] = arr[pos];
}
}
private static void PrintMatrix(long[,] matrix)
{
int n = matrix.GetLength(0);
int m = matrix.GetLength(1);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
Console.Write(matrix[i, j] + " ");
Console.WriteLine();
}
}
My wrong output:
Rotation times: 9402
Input matrix:
29 3 24 9 39 28
9 38 31 20 24 44
27 27 38 31 10 37
32 15 25 40 40 42
Output matrix:
44 37 42 42 40 40
28 20 24 10 10 25
39 38 27 27 31 15
24 3 29 9 27 32

Yes the rotation can be done In Place. I am not a C# programmer so I stick to C++ syntax which is pretty close.
I would create function that rotate rectangle circumference
It can be done in place with single temp value (exactly as jackmott suggest). something like this:
void matrix_rect_ccw(int **a,int x0,int y0,int xs,int ys)
{
int x,y,xx,yy,x1,y1,a0;
// prepare constants
x1=x0+xs-1;
y1=y0+ys-1;
// rotate CCW
a0=a[x0][y0]; // store first element to temp
x=x0; y=y0; // destination
xx=x; yy=y; // source
for (xx++;x<x1;x++,xx++) a[x][y]=a[xx][yy]; xx--;
for (yy++;y<y1;y++,yy++) a[x][y]=a[xx][yy]; yy--;
for (xx--;x>x0;x--,xx--) a[x][y]=a[xx][yy]; xx++;
for (yy--;y>y0;y--,yy--) a[x][y]=a[xx][yy]; yy++;
a[x0][y0+1]=a0; // restore last element from temp
}
where x0,y0 is upper left corner of rectangle and xs,ys its size. The a[][] is the matrix. No need for matrix size parameter if the rectangle is fully inside...
To debug you can instead rotating filling the loop with increasing index for example:
int i=0;
for (xx++;x<x1;x++,xx++,i++) a[x][y]=i; xx--;
for (yy++;y<y1;y++,yy++,i++) a[x][y]=i; yy--;
for (xx--;x>x0;x--,xx--,i++) a[x][y]=i; xx++;
for (yy--;y>y0;y--,yy--,i++) a[x][y]=i; yy++;
or:
int i=0;
for (xx++;x<x1;x++,xx++,i++) a[xx][yy]=i; xx--;
for (yy++;y<y1;y++,yy++,i++) a[xx][yy]=i; yy--;
for (xx--;x>x0;x--,xx--,i++) a[xx][yy]=i; xx++;
for (yy--;y>y0;y--,yy--,i++) a[xx][yy]=i; yy++;
So you can check if the iterations goes through the right elements in the right order. This is the result for (x,y) called for all loops:
0 1 2 3 4
13 0 1 2 5
12 5 4 3 6
11 10 9 8 7
This is the (xx,yy) case:
13 0 1 2 3
12 5 0 1 4
11 4 3 2 5
10 9 8 7 6
do a for loop to rotate whole matrix
simply call the rotate from #1 for all loops. And also the whole thing step times. Something like this:
void matrix_ccw(int **a,int xs,int ys,int step)
{
int i,j,n;
// smallest size / 2 ... number of loops to rotate
n=xs; if (n<ys) n=ys; n/=2;
for (j=0;j<step;j++)
for (i=0;i<n;i++)
matrix_rect_ccw(a,i,i,xs-i-i,ys-i-i);
}
You should handle the CW/CCW separately just by changing the for loops order in the #1. Also you should bound step to modulo loop size. If the step is larger then half of the loop size then convert it to the opposite direction rotation to speed up the process. This is the input matrix I tested on:
11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
41 42 43 44 45
And this is rotated by step=1 in CCW direction:
12 13 14 15 25
11 23 24 34 35
21 22 32 33 45
31 41 42 43 44
You should also handle invalid matrix sizes for rotation to avoid confusion in future use...
[Notes]
The rotation can be done also without the step looping the whole thing by copying directly with step offset but for that you need to store a0[step] values instead of single one complicating this all a lot ...

I wonder if you could simplify it by representing the outer points as one circularly linked list and the inner points as another. Then it becomes pretty easy to rotate them in place with a single temp variable. If performance is a concern you can use a 1 dimensional array for each, and just handle the edge cases at the start and end.
edit - looks like the algorithm has to be more general than that, which would mean "n" circularly linked lists, which might not be any simpler.

Related

c# Hackerrank code terminated due to time out but there is no way to optimize this code further?

I was doing a hacker rank challenge in c# to try and bring some of my c skills over to c#. Now I know hacker rank is notoriously stupid with killing programs due to time out (in this case if it lasts more than 3 seconds). But I honestly cannot think of a way to optimize this code further.
Here are the instructions:
https://www.hackerrank.com/challenges/ctci-array-left-rotation
Basically the challenge is to shift an array of numbers some x amount of times over in the left direction inside the array.
To my knowledge this code is as minimal as it can get and still do the thing they requested. The only way I can think to optimize this code further is to merge the constraint "if(a[i] > 1000000 || a[i] < 1 )" with the writeline forloop at the end of the code, but I tried that and it didn't work.
To me this is literally the minimum number of operations to move the array over by an amount x. But the code fails in test case 7 and 8 (out of 8) due to time out. Am I missing something?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int i, j;
int temp = 0;
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
//constraints
if(n >= 100000 || n < 1 )
{
System.Environment.Exit(1);
}
if(k > n || n < 1 )
{
System.Environment.Exit(1);
}
for(i = 0; i< n; i++)
{
if(a[i] > 1000000 || a[i] < 1 )
{
System.Environment.Exit(1);
}
}
//double for loop. one adjust position by one. then repeat k number of times.
for(j = 0; j<k; j++)
{
for(i = 0; i< n-1; i++)
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
//view array
for(i = 0; i< n; i++)
{
Console.Write(a[i] + " " );
}
}
}
I used a queue mechanism to get this working. That way you don't have to do any array copy and just rotating the string to the end.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {
static int[] leftRotation(int[] arr, int rotation) {
Queue<int> queue = new Queue<int>(arr);
for (int i = 0; i < rotation; i++)
{
queue.Enqueue(queue.Dequeue());
}
return queue.ToArray();
}
static void Main(String[] args) {
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int d = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
int[] result = leftRotation(a, d);
Console.WriteLine(String.Join(" ", result));
}
}
Shuffling the values one at a time is very slow. There is no need to do this. One can think of the rotation as moving 2 blocks - the values to the left of the rotation point and the values including and to the right of the rotation point
1 2 3 4 5 6 7 8 9
Rotate this 3 times is
move 1-3 to a temp variable
move 4-9 to the start of the array
move 1-3 to the end of 4-9
Edit: Add a bit more detail
We want to rotate the array 3 places.
move 1 2 3 to a temporary array
1 2 3
1 2 3 4 5 6 7 8 9
move 4-9 to the start of the array
1 2 3
4 5 6 7 8 9 7 8 9
move 1-3 to the end of the array
1 2 3
4 5 6 7 8 9 1 2 3
We can get away without the temp array for the left hand block if we create a new target array and copy everything to it. The following passes all the tests for the problem
var result = new int[a.Length];
var block2Length = a.Length - k;
Array.Copy(a, k, result, 0, block2Length);
Array.Copy(a, 0, result, block2Length, k);
Console.WriteLine(string.Join(" ", result.Select(v => v.ToString())));
Other Points
The constraints in HackerRank are part of the problem definition - they are telling us what the values can/will do so that we don't have to worry about solving a more general problem
e.g.
1 <= a[i] < 10^6
tells us the numbers will all be within the range for standard integers, no need to use long or BigInteger. As part of the solution we don't need to confirm these. In a real world situation different rules apply but here we have as much code checking values that cannot be wrong as we have solving the problem.
This has already been answered but there is a different solution that is very fast:
The idea is that you use the periodicity of the shifting. Shifting an element n+1 times is the same as shifting it 1 time which boils down to k % n.
Thus, you can simply create a new array and move the "old" elements directly to the correct spot. See the sample code below:
static void Main(String[] args) {
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
// use the periodicity of the shifting creating a shift between 0 and n - 1.
int shifts = k % n;
// Create a new array to hold the elements at their new positions.
int[] newPositions = new int[a.Length];
// You only need to iterate of the array once assigning each element its new position.
for(int i= 0; i < a.Length; ++i)
{
// Here is the magic: (for clarification see table below)
int position = (i - shifts + n)%n;
newPositions[position] = a[i];
}
foreach(var element in newPositions)
Console.Write($"{element} ");
}
This is more intuitive once you write it down on paper. The table might prints more values than the array contains to show the actual positions in the array.
-4 -3 -2 -1 | 0 1 2 3 4 (array indices)
=============================
2 3 4 5 | 1 2 3 4 5 (array contents without shift)
3 4 5 1 | 2 3 4 5 1 (shifted 1 time)
4 5 1 2 | 3 4 5 1 2 (shifted 2 times)
5 1 2 3 | 4 5 1 2 3 (shifted 3 times)
1 2 3 4 | 5 1 2 3 4 (shifted 4 times)
formula: i - k + n
results:
i=0: 0 - 4 + 5 = 1
i=1: 1 - 4 + 5 = 2
i=2: 2 - 4 + 5 = 3
i=3: 3 - 4 + 5 = 4
i=4: 4 - 4 + 5 = 5
i=5: 5 - 4 + 5 = 6 => 0
EDIT: I skipped the parts to check the boundaries for the sake of simplicity.
Updated answer.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int i, j, z;
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
int[] temparray = new int[2*n];
//constraints
if(n >= 100000 || n < 1 )
{
System.Environment.Exit(1);
}
if(k > n || n < 1 )
{
System.Environment.Exit(1);
}
for(i = 0; i< n; i++)
{
if(a[i] > 1000000 || a[i] < 1 )
{
System.Environment.Exit(1);
}
}
for(j = 0; j<n; j++)
{
z = (j-k) %n;
if(z != 0)
{
z= (n+ z) %n;
}
temparray[z] = a[j];
}
//view array
for(i = 0; i< n; i++)
{
Console.Write(temparray[i] + " " );
}
}
}

C# Formatting Long List of Numbers To Be More Compact

Console.WriteLine(" Even Table \n");
int MaxNumber = 100;
int EvenNumbers = 0;
int i;
for (i = 0; i <=MaxNumber; i+=2)
{
if (i % 2 == 0)
{
EvenNumbers = i;
}
Console.Write(EvenNumbers);
}
OUTPUT:
Even Table
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100
I am making a program that displays the even numbers between 2 and 100 inclusively. I am able to display the even numbers, although the formatting for the output is in a straight line due to the Console.Write, is there a string format that can I use to have the output display each even number, but cut to a new line every interval of 20? So it would look like:
1-20
20-40
40-60
ETC
Less lines with Linq! :p
foreach (var even in Enumerable.Range(2, 100).Where(i => i % 2 == 0))
Console.Write(even % 20 != 0 ? even.ToString() + " " : even.ToString() + "\n");
Use this:
for (i = 0; i <=MaxNumber; i+=2)
{
EvenNumbers = i;
Console.Write(EvenNumbers+" ");
if(i%20==0){
Console.WriteLine();
}
}
You do not need condition if (i % 2 == 0) because your step is 2.
In complement for Luis solution, you can do it easily with this code :
foreach (var item in Enumerable.Range(1, 100).Where(o => o % 2 == 0).GroupBy(o => (int)(o / 20.01)))
{
Console.WriteLine(string.Join(" ", item.ToArray()));
}
Loop on group by '20' filtered by modulo 2 enumeration of int and print it in one line with string.join
You need to cast the groupby if you want your first number are 20, 40, 60... else it starts with 22, 42, 62...
Hope this helps
Try below; It will consider 0 as well; Otherwise 0 will be isolated.
Console.WriteLine(" Even Table \n");
int MaxNumber = 100;
int EvenNumbers = 0;
int i;
for (i = 0; i <= MaxNumber; i += 2)
{
if (i % 2 == 0)
{
EvenNumbers = i;
}
Console.Write(" ");
Console.Write(EvenNumbers);
if (i % 20 == 0 && i>0)
{
Console.WriteLine();
}
}
Here is a different approach using Enumerable.Range and String.Join:
int MaxNumber = 100;
// create a list of all even numbers
List<int> even_list = Enumerable.Range(0, MaxNumber+1).Where(x => x % 2 == 0).ToList();
// for the amount of numbers to be displayed in a line
int numbers_in_single_line = 10
for (int i = 1; i <= even_list.Count; i += numbers_in_single_line)
{
Console.WriteLine(String.Join(" ", even_list.Skip(i).Take(numbers_in_single_line )));
}
Skip() and Take() allow you to select values from the list at certain positions

Sequence Alignment Algorithm with a group of characters instead of one character

Summary:
I'm beginning with some details about alignment algorithms, and at the end, I ask my question. If you know about alignment algorithm pass the beginning.
Consider we have two strings like:
ACCGAATCGA
ACCGGTATTAAC
There is some algorithms like: Smith-Waterman Or Needleman–Wunsch, that align this two sequence and create a matrix. take a look at the result in the following section:
Smith-Waterman Matrix
§ § A C C G A A T C G A
§ 0 0 0 0 0 0 0 0 0 0 0
A 0 4 0 0 0 4 4 0 0 0 4
C 0 0 13 9 4 0 4 3 9 4 0
C 0 0 9 22 17 12 7 3 12 7 4
G 0 0 4 17 28 23 18 13 8 18 13
G 0 0 0 12 23 28 23 18 13 14 18
T 0 0 0 7 18 23 28 28 23 18 14
A 0 4 0 2 13 22 27 28 28 23 22
T 0 0 3 0 8 17 22 32 27 26 23
T 0 0 0 2 3 12 17 27 31 26 26
A 0 4 0 0 2 7 16 22 27 31 30
A 0 4 4 0 0 6 11 17 22 27 35
C 0 0 13 13 8 3 6 12 26 22 30
Optimal Alignments
A C C G A - A T C G A
A C C G G A A T T A A
Question:
My question is simple, but maybe the answer is not easy as it looks. I want to use a group of character as a single one like: [A0][C0][A1][B1]. But in these algorithms, we have to use individual characters. How can we achieve that?
P.S. Consider we have this sequence: #read #write #add #write. Then I convert this to something like that: #read to A .... #write to B.... #add to C. Then my sequence become to: ABCB. But I have a lot of different words that start with #. And the ASCII table is not enough to convert all of them. Then I need more characters. the only way is to use something like [A0] ... [Z9] for each word. OR to use numbers.
P.S: some sample code for Smith-Waterman is exist in this link
P.S: there is another post that want something like that, but what I want is different. In this question, we have a group of character that begins with a [ and ends with ]. And no need to use semantic like ee is equal to i.
I adapted this Python implementation (GPL version 3 licensed) of both the Smith-Waterman and the Needleman-Wunsch algorithms to support sequences with multiple character groups:
#This software is a free software. Thus, it is licensed under GNU General Public License.
#Python implementation to Smith-Waterman Algorithm for Homework 1 of Bioinformatics class.
#Forrest Bao, Sept. 26 <http://fsbao.net> <forrest.bao aT gmail.com>
# zeros() was origianlly from NumPy.
# This version is implemented by alevchuk 2011-04-10
def zeros(shape):
retval = []
for x in range(shape[0]):
retval.append([])
for y in range(shape[1]):
retval[-1].append(0)
return retval
match_award = 10
mismatch_penalty = -5
gap_penalty = -5 # both for opening and extanding
gap = '----' # should be as long as your group of characters
space = ' ' # should be as long as your group of characters
def match_score(alpha, beta):
if alpha == beta:
return match_award
elif alpha == gap or beta == gap:
return gap_penalty
else:
return mismatch_penalty
def finalize(align1, align2):
align1 = align1[::-1] #reverse sequence 1
align2 = align2[::-1] #reverse sequence 2
i,j = 0,0
#calcuate identity, score and aligned sequeces
symbol = []
found = 0
score = 0
identity = 0
for i in range(0,len(align1)):
# if two AAs are the same, then output the letter
if align1[i] == align2[i]:
symbol.append(align1[i])
identity = identity + 1
score += match_score(align1[i], align2[i])
# if they are not identical and none of them is gap
elif align1[i] != align2[i] and align1[i] != gap and align2[i] != gap:
score += match_score(align1[i], align2[i])
symbol.append(space)
found = 0
#if one of them is a gap, output a space
elif align1[i] == gap or align2[i] == gap:
symbol.append(space)
score += gap_penalty
identity = float(identity) / len(align1) * 100
print 'Identity =', "%3.3f" % identity, 'percent'
print 'Score =', score
print ''.join(align1)
# print ''.join(symbol)
print ''.join(align2)
def needle(seq1, seq2):
m, n = len(seq1), len(seq2) # length of two sequences
# Generate DP table and traceback path pointer matrix
score = zeros((m+1, n+1)) # the DP table
# Calculate DP table
for i in range(0, m + 1):
score[i][0] = gap_penalty * i
for j in range(0, n + 1):
score[0][j] = gap_penalty * j
for i in range(1, m + 1):
for j in range(1, n + 1):
match = score[i - 1][j - 1] + match_score(seq1[i-1], seq2[j-1])
delete = score[i - 1][j] + gap_penalty
insert = score[i][j - 1] + gap_penalty
score[i][j] = max(match, delete, insert)
# Traceback and compute the alignment
align1, align2 = [], []
i,j = m,n # start from the bottom right cell
while i > 0 and j > 0: # end toching the top or the left edge
score_current = score[i][j]
score_diagonal = score[i-1][j-1]
score_up = score[i][j-1]
score_left = score[i-1][j]
if score_current == score_diagonal + match_score(seq1[i-1], seq2[j-1]):
align1.append(seq1[i-1])
align2.append(seq2[j-1])
i -= 1
j -= 1
elif score_current == score_left + gap_penalty:
align1.append(seq1[i-1])
align2.append(gap)
i -= 1
elif score_current == score_up + gap_penalty:
align1.append(gap)
align2.append(seq2[j-1])
j -= 1
# Finish tracing up to the top left cell
while i > 0:
align1.append(seq1[i-1])
align2.append(gap)
i -= 1
while j > 0:
align1.append(gap)
align2.append(seq2[j-1])
j -= 1
finalize(align1, align2)
def water(seq1, seq2):
m, n = len(seq1), len(seq2) # length of two sequences
# Generate DP table and traceback path pointer matrix
score = zeros((m+1, n+1)) # the DP table
pointer = zeros((m+1, n+1)) # to store the traceback path
max_score = 0 # initial maximum score in DP table
# Calculate DP table and mark pointers
for i in range(1, m + 1):
for j in range(1, n + 1):
score_diagonal = score[i-1][j-1] + match_score(seq1[i-1], seq2[j-1])
score_up = score[i][j-1] + gap_penalty
score_left = score[i-1][j] + gap_penalty
score[i][j] = max(0,score_left, score_up, score_diagonal)
if score[i][j] == 0:
pointer[i][j] = 0 # 0 means end of the path
if score[i][j] == score_left:
pointer[i][j] = 1 # 1 means trace up
if score[i][j] == score_up:
pointer[i][j] = 2 # 2 means trace left
if score[i][j] == score_diagonal:
pointer[i][j] = 3 # 3 means trace diagonal
if score[i][j] >= max_score:
max_i = i
max_j = j
max_score = score[i][j];
align1, align2 = [], [] # initial sequences
i,j = max_i,max_j # indices of path starting point
#traceback, follow pointers
while pointer[i][j] != 0:
if pointer[i][j] == 3:
align1.append(seq1[i-1])
align2.append(seq2[j-1])
i -= 1
j -= 1
elif pointer[i][j] == 2:
align1.append(gap)
align2.append(seq2[j-1])
j -= 1
elif pointer[i][j] == 1:
align1.append(seq1[i-1])
align2.append(gap)
i -= 1
finalize(align1, align2)
If we run this with the following input:
seq1 = ['[A0]', '[C0]', '[A1]', '[B1]']
seq2 = ['[A0]', '[A1]', '[B1]', '[C1]']
print "Needleman-Wunsch"
needle(seq1, seq2)
print
print "Smith-Waterman"
water(seq1, seq2)
We get this output:
Needleman-Wunsch
Identity = 60.000 percent
Score = 20
[A0][C0][A1][B1]----
[A0]----[A1][B1][C1]
Smith-Waterman
Identity = 75.000 percent
Score = 25
[A0][C0][A1][B1]
[A0]----[A1][B1]
For the specific changes I made, see: this GitHub repository.
Imagine we have a log file with alphabetic sequences. Like something you said, I converted sequences to A0A1... . For example, if there was a sequence like #read #write #add #write, it converted to A0A1A2A1. Every time, I read two character and compare them but keep score matrix like before. Here is my code in C# for smith-waterman string alignment.
Notice that Cell is a user defined class.
private void alignment()
{
string strSeq1;
string strSeq2;
string strTemp1;
string strTemp2;
scoreMatrix = new int[Log.Length, Log.Length];
// Lists That Holds Alignments
List<char> SeqAlign1 = new List<char>();
List<char> SeqAlign2 = new List<char>();
for (int i = 0; i<Log.Length; i++ )
{
for (int j=i+1 ; j<Log.Length; j++)
{
strSeq1 = "--" + logFile.Sequence(i);
strSeq2 = "--" + logFile.Sequence(j);
//prepare Matrix for Computing optimal alignment
Cell[,] Matrix = DynamicProgramming.Intialization_Step(strSeq1, strSeq2, intSim, intNonsim, intGap);
// Trace back matrix from end cell that contains max score
DynamicProgramming.Traceback_Step(Matrix, strSeq1, strSeq2, SeqAlign1, SeqAlign2);
this.scoreMatrix[i, j] = DynamicProgramming.intMaxScore;
strTemp1 = Reverse(string.Join("", SeqAlign1));
strTemp2 = Reverse(string.Join("", SeqAlign2));
}
}
}
class DynamicProgramming
{
public static Cell[,] Intialization_Step(string Seq1, string Seq2,int Sim,int NonSimilar,int Gap)
{
int M = Seq1.Length / 2 ;//Length+1//-AAA //Changed: /2
int N = Seq2.Length / 2 ;//Length+1//-AAA
Cell[,] Matrix = new Cell[N, M];
//Intialize the first Row With Gap Penality Equal To Zero
for (int i = 0; i < Matrix.GetLength(1); i++)
{
Matrix[0, i] = new Cell(0, i, 0);
}
//Intialize the first Column With Gap Penality Equal To Zero
for (int i = 0; i < Matrix.GetLength(0); i++)
{
Matrix[i, 0] = new Cell(i, 0, 0);
}
// Fill Matrix with each cell has a value result from method Get_Max
for (int j = 1; j < Matrix.GetLength(0); j++)
{
for (int i = 1; i < Matrix.GetLength(1); i++)
{
Matrix[j, i] = Get_Max(i, j, Seq1, Seq2, Matrix,Sim,NonSimilar,Gap);
}
}
return Matrix;
}
public static Cell Get_Max(int i, int j, string Seq1, string Seq2, Cell[,] Matrix,int Similar,int NonSimilar,int GapPenality)
{
Cell Temp = new Cell();
int intDiagonal_score;
int intUp_Score;
int intLeft_Score;
int Gap = GapPenality;
//string temp1, temp2;
//temp1 = Seq1[i*2].ToString() + Seq1[i*2 + 1]; temp2 = Seq2[j*2] + Seq2[j*2 + 1].ToString();
if ((Seq1[i * 2] + Seq1[i * 2 + 1]) == (Seq2[j * 2] + Seq2[j * 2 + 1])) //Changed: +
{
intDiagonal_score = Matrix[j - 1, i - 1].CellScore + Similar;
}
else
{
intDiagonal_score = Matrix[j - 1, i - 1].CellScore + NonSimilar;
}
//Calculate gap score
intUp_Score = Matrix[j - 1, i].CellScore + GapPenality;
intLeft_Score = Matrix[j, i - 1].CellScore + GapPenality;
if (intDiagonal_score<=0 && intUp_Score<=0 && intLeft_Score <= 0)
{
return Temp = new Cell(j, i, 0);
}
if (intDiagonal_score >= intUp_Score)
{
if (intDiagonal_score>= intLeft_Score)
{
Temp = new Cell(j, i, intDiagonal_score, Matrix[j - 1, i - 1], Cell.PrevcellType.Diagonal);
}
else
{
Temp = new Cell(j, i, intDiagonal_score, Matrix[j , i - 1], Cell.PrevcellType.Left);
}
}
else
{
if (intUp_Score >= intLeft_Score)
{
Temp = new Cell(j, i, intDiagonal_score, Matrix[j - 1, i], Cell.PrevcellType.Above);
}
else
{
Temp = new Cell(j, i, intDiagonal_score, Matrix[j , i - 1], Cell.PrevcellType.Left);
}
}
if (MaxScore.CellScore <= Temp.CellScore)
{
MaxScore = Temp;
}
return Temp;
}
public static void Traceback_Step(Cell[,] Matrix, string Sq1, string Sq2, List<char> Seq1, List<char> Seq2)
{
intMaxScore = MaxScore.CellScore;
while (MaxScore.CellPointer != null)
{
if (MaxScore.Type == Cell.PrevcellType.Diagonal)
{
Seq1.Add(Sq1[MaxScore.CellColumn * 2 + 1]); //Changed: All of the following lines with *2 and +1
Seq1.Add(Sq1[MaxScore.CellColumn * 2]);
Seq2.Add(Sq2[MaxScore.CellRow * 2 + 1]);
Seq2.Add(Sq2[MaxScore.CellRow * 2]);
}
if (MaxScore.Type == Cell.PrevcellType.Left)
{
Seq1.Add(Sq1[MaxScore.CellColumn * 2 + 1]);
Seq1.Add(Sq1[MaxScore.CellColumn * 2]);
Seq2.Add('-');
}
if (MaxScore.Type == Cell.PrevcellType.Above)
{
Seq1.Add('-');
Seq2.Add(Sq2[MaxScore.CellRow * 2 + 1]);
Seq2.Add(Sq2[MaxScore.CellRow * 2]);
}
MaxScore = MaxScore.CellPointer;
}
}
}

How to iterate through a grid algorithm

I am looking for an algorithm that can iterate through a grid and transform it into another grid with the indexes in a new order.
Basically, given a grid of size n*m:
1_1 1_2 1_3 ... 1_n
2_1 2_2 2_3 ... 2_n
.
.
.
m_1 m_2 m_3 ... m_m
How could I transform it to:
1_1 1_2 1_4 ...
1_3 1_5 ...
1_6 ...
...
.
.
.
Assume, you iterate through the first grid, going left to right in the top row, then
left to right in the second row, all the way to, left to right in the bottom row.
Basically I pushing the elements into an upper triangle.
Another problem is how do I figure out the length and width of the grid used to store the triangle just by knowing what n and m is?
Is there a formula for that?
For example, a grid of 5*6, gets changed to 8*7...
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
becomes:
1 2 4 7 11 16 22 29
3 5 8 12 17 23 30
6 9 13 18 24
10 14 19 25
15 20 26
21 27
28
The following seems to work for me:
public static T[,] ConvertToUpperTriangle<T>(T[,] arr)
{
// calculate the dimensions
int elements = arr.GetLength(0) * arr.GetLength(1);
double rows = 0.5 * (Math.Sqrt(8 * elements + 1) - 1);
int newHeight = (int)rows;
int newWidth = (int)Math.Ceiling(rows);
// create the new array
var arr2 = new T[newHeight, newWidth];
int j = 0;
int i = 0;
foreach (T element in arr)
{
arr2[j, i] = element;
i--;
j++;
if (i < 0)
{
i = j;
j = 0;
}
}
return arr2;
}
The 0.5 * (Math.Sqrt(8 * elements + 1) - 1) comes from running sum from 1 to n of n and then solve a = 0.5 * n * (n + 1) for n through Wolfram Alpha.
Edit:
You can get the indices i and j for a given index as follows:
int rows = (int)(0.5 * (Math.Sqrt(8 * index + 1) - 1));
int bottomLeft = (int)(0.5 * rows * (rows + 1));
int difference = index - bottomLeft;
int i;
int j;
if (bottomLeft == index)
{
i = 0;
j = rows - 1;
}
else
{
i = rows + 1 - difference;
j = difference - 1;
}
Let's define the "ordinal position" O(i,j) of each grid element (i,j) in a starting grid NxM, which is the function (i,j) -> i*N + j.
Now for the largest triangular number less than O(i,j), call it T == (k(k+1)/2 for some k, the new grid position for our (i,j) will be:
(i,j) -> ( O(i,j) - T, k + T - O(i,j) )
Now substitute for O(i,j) and T to get:
(i,j) -> ( i*N + j - k(k+1)/2, k + (k+1)(k+2)/2 - i*N + j)
= ( i*N + j - k(k+1)/2, (k+1)(k+2)/2 - i*N + j)
That's as far as I can get it just now.
Update:
Note again that k is the side-length for the triangualr number T == k(k+1)/2.

How to solve this weird multiple loops scenario (Java or C#)?

I've got this - possibly trivial - loop/combinations problem similar to binary combinations. I don't know how to approach it efficiently. Consider this scenario, I need unique loop to pass through all these combinations in a sequence:
Round ABC
01. 000 <- values of A=0, B=0, C=0
02. 001
03. 010
04. 011
05. 100
06. 101
07. 110
08. 111
09. 002
10. 012
11. 102
12. 112
13. 020
14. 021
15. 120
16. 121 <- values of A=1, B=2, C=1
17. 022
18. 122
19. 220
20. 221
21. 222
Except there are 12 letters (A-L), and also the "bit" size is not just 0,1 or 2 but any integer number (from 0 possibly up-to 1000 or 1024, not to make it crazy). I know it's a huge load of combinations, but I'll just scrap just top few that also fulfill my other conditions. So no need to worry about computational madness.
Disclaimer: The order has to be exactly as shown above. NOT a multiple FOR loops going first 0-1024 for C, then B.
Thanks in advance, I just can't seem to find the way to "algorithm it".
Update: Added whole sequence for combinations of ABC/012
regards,
Kate
Explanation:
I've encountered this problem when trying to tackle problem of analyzing sum of money for its combination of coins/notes:
For example $5001 to find out x optimal combinations.
10x $500 + 1x $1
50x $100 + 1x $1
..
Now letters (A,B,C..) correspond to a number of possible values of banknotes or coins ($1, $5,.. $100). While base correspond to a number of pieces of that banknotes/coins (for example $5001/$5000 = 1piece max.)
if I guess your sequence right, you will have it easier to generate it recursively
here an approach in Java, which should generate a sequence that matches your scenario.
I hope it helps you (maybe I add more explanation later):
public static void init() {
// define constants
final int length = 3;
final char maxValue = '3';
// define buffer
final char[] array = new char[length]; java.util.Arrays.fill(array, '0');
final boolean[] alreadySet = new boolean[length]; java.util.Arrays.fill(alreadySet, false);
// fill first digit, then let the recursion take place
for(char c = '1'; c <= (char)(maxValue); c++) {
// iterate from lowest to highest digit
for(int i = array.length-1; i >= 0; i--) {
// set value
array[i] = c;
alreadySet[i] = true;
// print value
System.out.println(new String(array));
// call recursion
recursive(array, c, i, alreadySet, length);
// unset value
alreadySet[i] = false;
array[i] = '0';
}
}
}
public static void recursive(char[] array, char lastValue, int lastIndex, boolean[] alreadySet, int leftToSet) {
// if we didn't set all digits
if(leftToSet > 0) {
// iterate from lowest to highest digit
for(int i = array.length-1; i >= 0; i--) {
// missing all digits already set
if(!alreadySet[i]) {
// count from 1 to lastValue-1
for(char c = '1'; c < lastValue; c++) {
// set value
array[i] = c;
alreadySet[i] = true;
// print value
System.out.println(new String(array));
// call recursion
recursive(array, c, i, alreadySet, leftToSet-1);
// unset value
alreadySet[i] = false;
array[i] = '0';
}
}
}
char c = lastValue;
// iterate from lowest to highest digit
for(int i = array.length-1; i > lastIndex; i--) {
// missing all digits already set
if(!alreadySet[i]) {
// set value
array[i] = c;
alreadySet[i] = true;
// print value
System.out.println(new String(array));
// call recursion
recursive(array, c, i, alreadySet, leftToSet-1);
// unset value
alreadySet[i] = false;
array[i] = '0';
}
}
}
}
A rough sketch in pseudo C#/Java:
Mapping A-L to indexes 0-11
const int[] maxvalues = { define max values for each var }
int[] counters = { initialize with 0s }
while (true)
{
for(i in 11..0)
{
counters[i]++;
if (counters[i] < maxvalues[i])
break; // for
counters[i] = 0;
}
if (counters[0] == maxvalues[0])
break; // while
print(counters.ToDisplayString());
}
(Just noted that the second sequence does not match the first sequence in OP. If OP is correct, I guess I didn't "get" the sequence)
The sequence of numbers you've described can be enumerated by counting upward from 0 in a base representation of numbers one higher than the amount of "letters" used to create your individual sequences.
One simple way to do this is to use a radix converter from base 10 which will act on a variable being incremented in a single loop from 0 to the maximum number of combinations you are looking to achieve.
Here is an implementation:
void Main()
{
for(int i=0; i< 50; i++){
Console.Write(convert(5,i));
Console.Write("\n");
}
}
string convert(int N, int M){
Stack<int> stack = new Stack<int>();
while (M >= N){
stack.Push(M %N);
M = M / N;
}
string str = M.ToString();
while(stack.Count() > 0)
str = str + stack.Pop().ToString();
return str;
}
Starting output:
0
1
2
3
4
10
11
12
13
14
20
21
22
23
24
30
31
32
33
34
40
41
42
43
44
100
101
102
103
104

Categories