How can I rotate a 2D rectangular array of integers that has odd number of rows by 45 degrees?
So something like
int[] myArray = new int[,]
{
{1, 0 ,1},
{0, 1 ,0},
{0, 0 ,0},
}
into
int[] rotatedArray = new int[,]
{
{0, 1 ,0},
{0, 1 ,1},
{0, 0 ,0},
}
for any dimension (3x3, 5x5, 7x7, etc.).
5x5
0 0 0 0 0
2 0 0 0 0
1 1 1 1 1
0 0 0 0 0
0 0 0 0 0
into
1 2 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
5x5
0 0 0 3 0
0 0 0 3 0
0 0 0 3 0
0 0 0 3 0
0 0 0 3 0
into
0 0 0 0 0
0 0 0 0 3
0 0 0 3 0
0 0 3 3 0
0 3 0 0 0
This is a code written by me and a friend that solves this:
public static class ArrayExtensions
{
public static Point RoundIndexToPoint(int index, int radius)
{
if (radius == 0)
return new Point(0, 0);
Point result = new Point(-radius, -radius);
while (index < 0) index += radius * 8;
index = index % (radius * 8);
int edgeLen = radius * 2;
if (index < edgeLen)
{
result.X += index;
}
else if ((index -= edgeLen) < edgeLen)
{
result.X = radius;
result.Y += index;
}
else if ((index -= edgeLen) < edgeLen)
{
result.X = radius - index;
result.Y = radius;
}
else if ((index -= edgeLen) < edgeLen)
{
result.Y = radius - index;
}
return result;
}
public static T[,] Rotate45<T>(this T[,] array)
{
int dim = Math.Max(array.GetLength(0), array.GetLength(0));
T[,] result = new T[dim, dim];
Point center = new Point((result.GetLength(0) - 1) / 2, (result.GetLength(1) - 1) / 2);
Point center2 = new Point((array.GetLength(0) - 1) / 2, (array.GetLength(1) - 1) / 2);
for (int r = 0; r <= (dim - 1) / 2; r++)
{
for (int i = 0; i <= r * 8; i++)
{
Point source = RoundIndexToPoint(i, r);
Point target = RoundIndexToPoint(i + r, r);
if (!(center2.X + source.X < 0 || center2.Y + source.Y < 0 || center2.X + source.X >= array.GetLength(0) || center2.Y + source.Y >= array.GetLength(1)))
result[center.X + target.X, center.Y + target.Y] = array[center2.X + source.X, center2.Y + source.Y];
}
}
return result;
}
}
You can try this library:
Math.NET Project for matrices operations... http://numerics.mathdotnet.com/
This code appears to be useful too:
http://www.drunkenhyena.com/cgi-bin/view_net_article.pl?chapter=2;article=28#Rotation
Don't forget the DirectX managed and unmanaged namespaces and classes. Lots
and lots of good stuff there to check.
For example:
Matrix..::.Rotate Method (Single, MatrixOrder)
I think we have these rules:
Imagine the matrix as a set of "frames or boxes without centers" within each other like "Russian dolls".
Elements at the center of a side (top/left/right/bottom) move towards the nearest corner clockwise.
Corners move towards the next center clockwise.
Elements that are not corners nor centers move to the next spot (clockwise) that is the same distance from a corner as they currently are.
I've started writing some code but I don't think it's trivial and I haven't had time to test.
You can see my solution for the matrix rotation in codesignal
Related
I have an image that is stored in a DenseMatrix, using MathNet Numerics.
For rotating the image by 90 degrees counter-clockwise I want to get the transpose and then flip the result vertically by multiplying by the anti-diagonal identity matrix.
Is there a quick way to initialize that identity matrix?
For a 2x2 matrix that would look like:
0 1
1 0
Update:
I ended up doing pretty much what #Joseph suggested. Turns out to be sufficiently fast.
public static Matrix<double> CreateAntiIdentityMatrix(int n)
{
var output = Matrix<double>.Build.Dense(n, n, 0);
for (int i = 0; i <= n - 1; i++)
{
output[i, n - i - 1] = 1;
}
return output;
}
Something like this should work:
var M = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(N, N, 0);
for (i = 0; i <= N - 1; i++)
{
M(i, N - i - 1) = 1;
}
#Joseph's way is fast. But I'd like to introduce a way which is expressively shows MathNet functionality:
var size = 3;
var diagonal = DenseMatrix.CreateDiagonal(size, size, 1);
Console.WriteLine(diagonal);
var reversedColumns = diagonal.EnumerateColumns().Select(c => c.Reverse());
var anti = DenseMatrix.OfColumns(reversedColumns);
Console.WriteLine(anti);
To get an anti-diagonal matrix one can take a diagonal one and reflect it by width (reverse columns).
Result is:
DenseMatrix 3x3-Double
1 0 0
0 1 0
0 0 1
DenseMatrix 3x3-Double
0 0 1
0 1 0
1 0 0
Question: What program / file format should I use?
I want to create an image (handdrawn pixel by pixel) and have it exported to text file formated as a pseudo-array of integers like this:
16 8
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 9 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 10 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 12 0 0 256 0
I want every number to represent unique color (not actually matter what color as long as drawing program (the simpler, the better - MS Paint would do) itself can read it and I can distinguish it from others). Ultimately I want the ability to quickly draw an image with external program and use such exported data within my code. Can someone point me to the right direction?
I tried to export image to .c with GIMP, but the results:
/* GIMP RGB C-Source image dump (Bez nazwy.c) */
static const struct {
guint width;
guint height;
guint bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
guint8 pixel_data[64 * 64 * 2 + 1];
} gimp_image = {
64, 64, 2,
"\377\377\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"...
though close to the point, are not exactly what I expect.
And here I see other possible solution: draw simply bmp image and try to translate it to an array of ints in my actual code (C#). But I would like to avoid this unless there is some simple and quick way / handy library to do this.
Or maybe some of You know any online converter that can take .bmp and return an array of ints?
#include "ui_mainwindow.h"
#include <QString>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
void generate(Ui::MainWindow* ui)
{
if (ui->pic_label->pixmap() != 0)
{
int cap = 1024 * 4;
int ct = 32; //color tolerance
//int number_of_colors_third = 256 / color_tolerance;//=256/32=8
int *uncompressedcolortable = new int[256*256*256];
for (int k=0; k<256; k++){
for (int j=0; j<256; j++){
for (int i=0; i< 256; i++){
uncompressedcolortable[k*256*256+j*256+i] = k*1000000+j*1000+i;
}
}
}
int width = ui->pic_label->pixmap()->width();
int height = ui->pic_label->pixmap()->height();
// int tiles = width * height;
if ( (width > cap || height > cap) && !(ui->actionSurpass_sanity_check->isChecked())){
ui->label->setText("File is too big to generate map. Check menu option if you want to process it anyway.");
return;
}
QImage image = ui->pic_label->pixmap()->toImage();
ui->lcdRED->setPalette(Qt::red);
ui->lcdGREEN->setPalette(Qt::green);
ui->lcdBLUE->setPalette(Qt::blue);
ui->progressBar->setMaximum(height);
QColor pixel_color;
ofstream outfile ("C:/Users/Niewzruszony/Desktop/map.map");
outfile << width << " " << height << std::endl;
for (int j = 0; j < height; j++ )
{
outfile << std::endl;
for (int i = 0; i < width; i++)
{
pixel_color = image.pixelColor(i,j);
outfile << uncompressedcolortable[pixel_color.red()*256*256 + pixel_color.green()*256 + pixel_color.blue()];
if(i != width-1) outfile << "\t";
ui->lcdRED->display(QString::fromStdString(to_string( pixel_color.red())));
ui->lcdGREEN->display(QString::fromStdString(to_string( pixel_color.green())));
ui->lcdBLUE->display(QString::fromStdString(to_string( pixel_color.blue())));
}
ui->progressBar->setValue(j+1);
}
ui->lcdRED->setPalette(Qt::lightGray);
ui->lcdGREEN->setPalette(Qt::lightGray);
ui->lcdBLUE->setPalette(Qt::lightGray);
ui->lcdRED->display(QString::fromStdString("0"));
ui->lcdGREEN->display(QString::fromStdString("0"));
ui->lcdBLUE->display(QString::fromStdString("0"));
ui->label->setText("Generated RGB map.");
return;
}
ui->pic_label->setText("First please choose image to process!");
}
Done it wit Qt. Just thougth I will share the code.
Note I've done some quick cleanup while posting, to not to include unimportant stuff (at least not all).
So I have an integer, e.g. 1234567890, and a given set of numbers, e.g. {4, 7, 18, 32, 57, 68}
The question is whether 1234567890 can be made up from the numbers given (you can use a number more than once, and you don't have to use all of them). In the case above, one solution is:38580246 * 32 + 1 * 18
(Doesn't need to give specific solution, only if it can be done)
My idea would be to try all solutions. For example I would try1 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 42 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 83 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 12.....308 641 972 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 1234567888308 641 973 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 1234567892 ==> exceeds0 * 4 * + 1 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 71 * 4 * + 1 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 112 * 4 * + 1 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 15and so on...
Here is my code in c#:
static int toCreate = 1234567890;
static int[] numbers = new int[6] { 4, 7, 18, 32, 57, 68};
static int[] multiplier;
static bool createable = false;
static void Main(string[] args)
{
multiplier = new int[numbers.Length];
for (int i = 0; i < multiplier.Length; i++)
multiplier[i] = 0;
if (Solve())
{
Console.WriteLine(1);
}
else
{
Console.WriteLine(0);
}
}
static bool Solve()
{
int lastIndex = 0;
while (true)
{
int comp = compare(multiplier);
if (comp == 0)
{
return true;
}
else if (comp < 0)
{
lastIndex = 0;
multiplier[multiplier.Length - 1]++;
}
else
{
lastIndex++;
for (int i = 0; i < lastIndex; i++)
{
multiplier[multiplier.Length - 1 - i] = 0;
}
if (lastIndex >= multiplier.Length)
{
return false;
}
multiplier[multiplier.Length - 1 - lastIndex]++;
}
}
}
static int compare(int[] multi)
{
int osszeg = 0;
for (int i = 0; i < multi.Length; i++)
{
osszeg += multi[i] * numbers[i];
}
if (osszeg == toCreate)
{
return 0;
}
else if (osszeg < toCreate)
{
return -1;
}
else
{
return 1;
}
}
The code works fine (as far as I know) but is way too slow. It takes about 3 secs to solve the example, and there may be 10000 numbers to make from 100 numbers.
I have a recursive solution. It solves the OP's original problem in about .005 seconds (on my machine) and tells you the calculations.
private static readonly int Target = 1234567890;
private static readonly List<int> Parts = new List<int> { 4, 7, 18, 32, 57, 68 };
static void Main(string[] args)
{
Console.WriteLine(Solve(Target, Parts));
Console.ReadLine();
}
private static bool Solve(int target, List<int> parts)
{
parts.RemoveAll(x => x > target || x <= 0);
if (parts.Count == 0) return false;
var divisor = parts.First();
var quotient = target / divisor;
var modulus = target % divisor;
if (modulus == 0)
{
Console.WriteLine("{0} X {1}", quotient, divisor);
return true;
}
if (quotient == 0 || parts.Count == 1) return false;
while (!Solve(target - divisor * quotient, parts.Skip(1).ToList()))
{
if (--quotient != 0) continue;
return Solve(target, parts.Skip(1).ToList());
}
Console.WriteLine("{0} X {1}", quotient, divisor);
return true;
}
Basically, it goes through each number to see if there is a possible solution "below" it given the current quotient and number. If there isn't, it subtracts 1 from the quotient and tries again. It does this until it exhausts all options for that number and then moves on to the next number if available. If all numbers are exhausted, there is no solution.
Don't have the means test the solution, but the following should do.
Given a target number target and a set numbers of valid numbers:
bool FindDecomposition(int target, IEnumerable<int> numbers, Queue<int> decomposition)
{
foreach (var i in numbers)
{
var remainder = target % i;
if (remainder == 0)
{
decomposition.Enqueue(i);
return true;
}
if (FindDecomposition(remainder, numbers.Where(n => n < i), decomposition))
{
return true;
}
}
return false
}
Building up n from decomposition is pretty straightforward.
You could always try using the modulo function in conjunction with LINQ expressions to solve the problem.
You would have a list and a running modulo variable to keep track of where you are at in your iteration. Then simply use recursion to determine whether or not you have meet the conditions.
One example would be the following:
static int toCreate = 1234567890;
static List<int> numbers = new List<int> { 4, 7 };
static void Main(string[] args)
{
numbers.Sort();
numbers.Reverse();
Console.WriteLine(Solve(numbers,toCreate).ToString());
}
static bool Solve(List<int> lst1, int runningModulo)
{
if (lst1.Count == 0 && runningModulo != 0)
return false;
if (lst1.Count == 0 || runningModulo == 0)
return true;
return numbers.Any(o => o < (toCreate % lst1.First())) ? //Are there any in the remaining list that are smaller in value than the runningModulo mod the first element in the list.
Solve(lst1.Where(o => o != lst1.First()).ToList(), runningModulo % lst1.First()) //If yes, then remove the first element and set the running modulo = to your new modulo
: Solve(lst1.Where(o => o != lst1.First()).ToList(), toCreate); //Otherwise, set the running modulo back to the original toCreate value.
}
i have this system of equations1=x⊕y⊕z
1=x⊕y⊕w
0=x⊕w⊕z
1=w⊕y⊕zI'm trying to implement gaussian elimination to solve this system as described here , replacing division,subtraction and multiplication by XOR, but it gives my wrong answer..the correct answer is (x,y,z,w)=(0,1,0,0) what am i doing wrong ?
public static void ComputeCoefficents(byte[,] X, byte[] Y)
{
int I, J, K, K1, N;
N = Y.Length;
for (K = 0; K < N; K++)
{
K1 = K + 1;
for (I = K; I < N; I++)
{
if (X[I, K] != 0)
{
for (J = K1; J < N; J++)
{
X[I, J] /= X[I, K];
}
//Y[I] /= X[I, K];
Y[I] ^= X[I, K];
}
}
for (I = K1; I < N; I++)
{
if (X[I, K] != 0)
{
for (J = K1; J < N; J++)
{
X[I, J] ^= X[K, J];
}
Y[I] ^= Y[K];
}
}
}
for (I = N - 2; I >= 0; I--)
{
for (J = N - 1; J >= I + 1; J--)
{
//Y[I] -= AndOperation(X[I, J], Y[J]);
Y[I] ^= (byte)(X[I, J]* Y[J]);
}
}
}
I think you're trying to apply Gaussian elimination mod 2 for this.
In general you can do Gaussian elimination mod k, if your equations are of the form
a_1 * x + b_1 * y + c_1 * z = d_1
a_2 * x + b_2 * y + c_2 * z = d_2
a_3 * x + b_3 * y + c_3 * z = d_3
a_4 * x + b_4 * y + c_4 * z = d_4
And in Z2 * is and and + is xor, so you can use Gausian elimination to solve equations of the form
x (xor) y (xor) z = 1
x (xor) y (xor) w = 1
x (xor) z (xor) w = 0
y (xor) z (xor) w = 1
Lets do this equation using Gausian elimination by hand.
The corresponding augmented matrix is:
1 1 1 0 | 1
1 1 0 1 | 1
1 0 1 1 | 0
0 1 1 1 | 1
1 1 1 0 | 1
0 0 1 1 | 0 (R2 = R2 + R1)
0 1 0 1 | 1 (R3 = R3 + R1)
0 1 1 1 | 1
1 1 1 0 | 1
0 1 1 1 | 1 (R2 = R4)
0 1 0 1 | 1
0 0 1 1 | 0 (R4 = R2)
1 0 0 1 | 0 (R1 = R1 + R2)
0 1 1 1 | 1
0 0 1 0 | 0 (R3 = R3 + R2)
0 0 1 1 | 0
1 0 0 1 | 0
0 1 0 1 | 1 (R2 = R2 + R3)
0 0 1 0 | 0
0 0 0 1 | 0 (R4 = R4 + R3)
1 0 0 0 | 0 (R1 = R1 + R4)
0 1 0 0 | 1 (R2 = R2 + R4)
0 0 1 0 | 0
0 0 0 1 | 0
Giving your solution of (x,y,z,w) = (0,1,0,0).
But this requires row pivoting - which I can't see in your code.
There's also some multiplications and divisions floating around in your code that probably dont need to be there. I'd expect the code to look like this: (You'll need to fix the TODOs).
public static void ComputeCoefficents(byte[,] X, byte[] Y) {
int I, J, K, K1, N;
N = Y.Length;
for (K = 0; K < N; K++) {
//First ensure that we have a non-zero entry in X[K,K]
if( X[K,K] == 0 ) {
for(int i = 0; i<N ; ++i ) {
if(X[i,K] != 0 ) {
for( ... ) //TODO: A loop to swap the entries
//TODO swap entries in Y too
}
}
if( X[K,K] == 0 ) {
// TODO: Handle the case where we have a zero column
// - for now we just move on to the next column
// - This means we have no solutions or multiple
// solutions
continue
}
// Do full row elimination.
for( int I = 0; I<N; ++I)
{
if( I!=K ){ //Don't self eliminate
if( X[I,K] ) {
for( int J=K; J<N; ++J ) { X[I,J] = X[I,J] ^ X[K,J]; }
Y[J] = Y[J] ^ Y[K];
}
}
}
}
//Now assuming we didnt hit any zero columns Y should be our solution.
}
There is two-dimensional array of zeros and ones. Need algorithm (the implementation) that determines whether in this array closed path of ones, that surround the zeros
Example:
there EXISTS a closed path(center):
1 0 0 0 0
0 0 1 0 0
0 1 0 1 0
0 0 1 1 0
0 0 1 0 0
there is NO
0 0 0 0 1
0 1 0 1 0
0 0 1 0 0
0 0 1 0 1
0 1 0 1 0
You can look at Connected Components Labeling algorithms, e.g. in Wikipedia or google for them. These algorithms are used e.g. to separate foreground pixels from background pixels in a digital white/black image. To apply them to your specific problem, you can think of your matrix as a digital image where 0 means foreground and 1 means background (or vice versa according to your needs). The algorithm finds largest connected foreground regions (containing only 0) that are surrounded by the background (1's). So, if you found such a foreground region you know there is a cycle of 1's surrounding it. When the foreground region is at the boundary you can decide whether you consider it as surrounded or not.
It's homework so I'll just give a general sketch. Construct an undirected graph; each 1 is a node, adjacent 1s have an edge between them. Google for undirected graph cycle detection to find closed paths. Then you have to go back to the original matrix and make sure there's at least one 0 inside.
Another idea would be to flood-fill starting at each 0 bounded by 1s. If it doesn't reach an edge, it's surrounded.
Here is sample code i tried. test it through
Logic i tried is loop through all the rows except first and last row.
if you find 0 then check it neighbour to left,right,top and bottom if all the neighbours are 1 then closed.
private void Form1_Load(object sender, EventArgs e)
{
int[,] graph = new int[5, 5] {
{ 1, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 1, 0, 1, 0 },
{ 0, 0, 1, 1, 0 },
{ 0, 0, 1, 0, 0 }
};
int[,] graph1 = new int[5, 5] {
{ 0, 0, 0, 0, 1 },
{ 0, 1, 0, 1, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 1, 0, 1, 0 }
};
isClosed(graph1);
}
private bool isClosed(int[,] graph)
{
for (int i = 1; i < graph.GetUpperBound(0); i++)
{
for (int j = 1; j < graph.GetUpperBound(1); j++)
{
if (graph[i, j] == 0)
{
if (graph[i - 1, j] == 1 && graph[i + 1, j] == 1 && graph[i, j - 1] == 1 && graph[i, j + 1] == 1)
{
return true;
}
}
}
}
return false;
}