Creating anti-diagonal identity matrix - c#

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

Related

Get the amount of binary numbers that meet a criteria and are less than "x"

I am trying to get the count (just a number, not a list) of binary numbers that contain exactly 3 ones and that are less than 1000000000 ie: 10011, 100000011 and so on.
The code below works for integers, but how can I make it work with binary?
static void Main(string[] args)
{
int con = 0;
for (int i = 0; i < 1000000000; i++)
{
string test = i.ToString();
int count = test.Split('1').Length - 1;
if (count == 3)
{
con++;
}
}
Console.WriteLine(con);
}
And for your continued education, here's another way to solve the problem. We wish to know how many binary strings there are with exactly on on bits and off off bits.
There are some easy problems to solve in there. N(on, off) is equal to one if on and off are both zero, because the only solution is the empty string. And if either is zero then the answer is one, because the string that is all zeros or all ones is unique.
Let's start tabulating this in a table.
on
0 1 2 3 4 5
+---------------------
o 0| 1 1 1 1 1 1
f 1| 1
f 2| 1
3| 1
4| 1
5| 1
6| 1
Now what should go at (1, 1)? Well, the number of binary strings that have one on and one off bit is equal to the number of such strings that start with one, plus the number of such strings that start with zero. So we have:
N(1, 1) = N(1, 0) + N(0, 1) = 2
What about N(2, 1) ? Same deal:
N(2, 1) = N(1, 1) + N(2, 0) = 3
And we can see that similarly N(x, 1) = N(1, x) = x + 1. Fill in the array:
on
0 1 2 3 4 5
+---------------------
o 0| 1 1 1 1 1 1
f 1| 1 2 3 4 5 6
f 2| 1 3
3| 1 4
4| 1 5
5| 1 6
6| 1 7
in general for on, off not zero:
N(on, off) = N(on - 1, off) + N(on, off - 1)
which means that we can fill in this entire array by repeatedly applying this rule. Can you write a program which does so?
Once you do, you can simply read your answer out of the array at [6, 3].
Have you seen this pattern in this array before? It has a name. Hint: you probably have not seen it laid out as a square.
The simplest way to alter your code would be:
static void Main(string[] args)
{
int con = 0;
for (int i = 0; i < 512; i++)
{
string test = Convert.ToString(i, 2);
int count = test.Split('1').Length - 1;
if (count == 3)
{
con++;
}
}
Console.WriteLine(con);
}
This could be done as a pure mathematical equation though:
9! / (6!*3!) = 84
For your amusement and education, consider the following:
static IEnumerable<string> Combinations(int on, int off)
{
if (on == 0 && off == 0)
yield return "";
if (on > 0)
foreach(var s in Combinations(on - 1, off))
yield return "1" + s;
if (off > 0)
foreach(var s in Combinations(on, off - 1))
yield return "0" + s;
}
Study this implementation: it yields a sequence of binary strings with on bits on and off bits off. Do you see how it does so?
Plainly calling .Count() on this thing solves your problem, though such a solution is enormously less efficient than simply doing the math.
I present this for your study because a recursive enumerator such as this one is a powerful tool when investigating permutations and combinations.
A solution without resorting to string representations:
static int CountBits(int i)
{
var current = i;
var bits = 0;
while (current != 0)
{
if ((current & 1) == 1)
{
bits += 1;
}
current >>= 1;
}
return bits;
}
With this helper method, the count is easy:
var count = Enumerable.Range(0, 0b1000000000)
.Count(i => CountBits(i) == 3);
And the answer is 84.
Long code (grumpy style)
var con = 0;
for (var i = 0; i < 10000; i++)
{
var test = i.ToString();
if (test.Count(x => x == '1') == 3)
{
con++;
}
}
Console.WriteLine(con);
Shorter (more mature)
var con = Enumerable.Range(0, 10000)
.Select(x => $"{x:00000}")
.Count(x =>
x.Count(c => c == '1') == 3
);
Console.WriteLine(con);
PS: They both seem to have the same performance.

Copying a smaller array into a larger one

I'm struggling to think of the most elegant/simple way of doing this. Perhaps I'm overthinking it a little.
Lets say I've got a 5x5 array of integers that looks like this:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
And another 2x2 array of integers that looks like this:
5 1
2 3
I want to pick a location in the 5x5 array, say [2][2], and place the values from the second array into the first, so it looks like this:
0 0 0 0 0
0 0 0 0 0
0 0 5 1 0
0 0 2 3 0
0 0 0 0 0
My initial thought was to use a for loop after determining the number of rows/columns in the array to be copied, but I can't seem to puzzle out a way in my head to do that this morning.
Any suggestions?
Edit:
Sorry, here's the way I'm doing it currently. Just wondering if there's a better way.
This is actually part of a unity thing I'm doing - "RoomDoors" is our smaller array, and "map" is the larger array it's being moved into. It's part of a random map generator that needs to know which "edges" of tiles in rooms have doors on them that can connect to other rooms. RoomDoors stores 4 booleans, one for each direction telling me if there's a door there.
roomDoors = previousRoom.GetComponent<RoomDataInterface> ().rooms; //2d array of room/door arrangement in new room
sizeCol = roomDoors.GetLength (0);
sizeRow = roomDoors.GetLength (1);
map [10, 10] = roomDoors [0, 0]; // top left of the room goes in the spot
for (int i = 0; i < sizeCol; i ++){
for (int j = 0; j < sizeRow; j ++) {
map [i + 10,j + 10] = roomDoors[i,j];
}
I think you can't do much better, just remove the unnecessary assignment:
roomDoors = previousRoom.GetComponent<RoomDataInterface> ().rooms;
sizeCol = roomDoors.GetLength (0);
sizeRow = roomDoors.GetLength (1);
for (int i = 0; i < sizeCol; i ++)
for (int j = 0; j < sizeRow; j ++)
map [i + 10, j + 10] = roomDoors[i, j];
The line
map [10, 10] = roomDoors [0, 0];
is redundant, as the same assignment will be performed by the first iteration of the loop. Removal of the line will result in a solution that is smaller and more efficient.

Explain the Peak and Flag Algorithm

EDIT
Just was pointed that the requirements state peaks cannot be ends of Arrays.
So I ran across this site
http://codility.com/
Which gives you programming problems and gives you certificates if you can solve them in 2 hours. The very first question is one I have seen before, typically called the Peaks and Flags question. If you are not familiar
A non-empty zero-indexed array A consisting of N integers is given. A peak is an array element which is larger than its neighbours. More precisely, it is an index P such that
0 < P < N − 1 and A[P − 1] < A[P] > A[P + 1]
.
For example, the following array A:
A[0] = 1
A[1] = 5
A[2] = 3
A[3] = 4
A[4] = 3
A[5] = 4
A[6] = 1
A[7] = 2
A[8] = 3
A[9] = 4
A[10] = 6
A[11] = 2
has exactly four peaks: elements 1, 3, 5 and 10.
You are going on a trip to a range of mountains whose relative heights are represented by array A. You have to choose how many flags you should take with you. The goal is to set the maximum number of flags on the peaks, according to certain rules.
Flags can only be set on peaks. What's more, if you take K flags, then the distance between any two flags should be greater than or equal to K. The distance between indices P and Q is the absolute value |P − Q|.
For example, given the mountain range represented by array A, above, with N = 12, if you take:
two flags, you can set them on peaks 1 and 5;
three flags, you can set them on peaks 1, 5 and 10;
four flags, you can set only three flags, on peaks 1, 5 and 10.
You can therefore set a maximum of three flags in this case.
Write a function that, given a non-empty zero-indexed array A of N integers, returns the maximum number of flags that can be set on the peaks of the array.
For example, given the array above
the function should return 3, as explained above.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [0..1,000,000,000].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the
storage required for input arguments).
Elements of input arrays can be modified.
So this makes sense, but I failed it using this code
public int GetFlags(int[] A)
{
List<int> peakList = new List<int>();
for (int i = 0; i <= A.Length - 1; i++)
{
if ((A[i] > A[i + 1] && A[i] > A[i - 1]))
{
peakList.Add(i);
}
}
List<int> flagList = new List<int>();
int distance = peakList.Count;
flagList.Add(peakList[0]);
for (int i = 1, j = 0, max = peakList.Count; i < max; i++)
{
if (Math.Abs(Convert.ToDecimal(peakList[j]) - Convert.ToDecimal(peakList[i])) >= distance)
{
flagList.Add(peakList[i]);
j = i;
}
}
return flagList.Count;
}
EDIT
int[] A = new int[] { 7, 10, 4, 5, 7, 4, 6, 1, 4, 3, 3, 7 };
The correct answer is 3, but my application says 2
This I do not get, since there are 4 peaks (indices 1,4,6,8) and from that, you should be able to place a flag at 2 of the peaks (1 and 6)
Am I missing something here? Obviously my assumption is that the beginning or end of an Array can be a peak, is this not the case?
If this needs to go in Stack Exchange Programmers, I will move it, but thought dialog here would be helpful.
EDIT
Obviously my assumption is that the beginning or end of an Array can
be a peak, is this not the case?
Your assumption is wrong since peak is defined as:
0 < P < N − 1
When it comes to your second example you can set 3 flags on 1, 4, 8.
Here is a hint: If it is possible to set m flags, then there must be at least m * (m - 1) + 1 array elements. Given that N < 100,000, turning the above around should give you confidence that the problem can be efficiently brute-forced.
Here is a hint: If it is possible to set m flags, then there must be
at least m * (m - 1) + 1 array elements. Given that N < 100,000,
turning the above around should give you confidence that the problem
can be efficiently brute-forced.
No, that is wrong. Codility puts custom solutions through a series of tests, and brute forcing can easily fail on time.
I give here my solution of the task that makes 100% score (correctness and performance) in codility, implemented in C++. To understand the solution you must realize for a given distance of indexes (for example, when first peak starts at index 2 and the last peak at index 58 the distance is 56), that contains n peaks there is an upper limit for the maximal number of peaks that can hold flags according to condition described in the task.
#include <vector>
#include <math.h>
typedef unsigned int uint;
void flagPeaks(const std::vector<uint> & peaks,
std::vector<uint> & flaggedPeaks,
const uint & minDist)
{
flaggedPeaks.clear();
uint dist = peaks[peaks.size() - 1] - peaks[0];
if (minDist > dist / 2)
return;
flaggedPeaks.push_back(peaks[0]);
for (uint i = 0; i < peaks.size(); ) {
uint j = i + 1;
while (j < (peaks.size()) && ((peaks[j] - peaks[i]) < minDist))
++j;
if (j < (peaks.size()) && ((peaks[j] - peaks[i]) >= minDist))
flaggedPeaks.push_back(peaks[j]);
i = j;
}
}
int solution(std::vector<int> & A)
{
std::vector<uint> peaks;
uint min = A.size();
for (uint i = 1; i < A.size() - 1; i++) {
if ((A[i] > A[i - 1]) && (A[i] > A[i + 1])) {
peaks.push_back(i);
if (peaks.size() > 1) {
if (peaks[peaks.size() - 1] - peaks[peaks.size() - 2] < min)
min = peaks[peaks.size() - 1] - peaks[peaks.size() - 2];
}
}
}
// minimal distance between 2 peaks is 2
// so when we have less than 3 peaks we are done
if (peaks.size() < 3 || min >= peaks.size())
return peaks.size();
const uint distance = peaks[peaks.size() - 1] - peaks[0];
// parts are the number of pieces between peaks
// given n + 1 peaks we always have n parts
uint parts = peaks.size() - 1;
// calculate maximal possible number of parts
// for the given distance and number of peaks
double avgOptimal = static_cast<double>(distance) / static_cast<double> (parts);
while (parts > 1 && avgOptimal < static_cast<double>(parts + 1)) {
parts--;
avgOptimal = static_cast<double>(distance) / static_cast<double>(parts);
}
std::vector<uint> flaggedPeaks;
// check how many peaks we can flag for the
// minimal possible distance between two flags
flagPeaks(peaks, flaggedPeaks, parts + 1);
uint flags = flaggedPeaks.size();
if (flags >= parts + 1)
return parts + 1;
// reduce the minimal distance between flags
// until the condition fulfilled
while ((parts > 0) && (flags < parts + 1)) {
--parts;
flagPeaks(peaks, flaggedPeaks, parts + 1);
flags = flaggedPeaks.size();
}
// return the maximal possible number of flags
return parts + 1;
}

Determine if number is in the binary sequence 1 2 4 8 16 32 64 etc [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to check if a number is a power of 2
I want to determine if a number is in
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
...
I tried this:
public static void Main(string[] args)
{
int result = 1;
for (int i = 0; i < 15; i++)
{
//Console.WriteLine(result);
Console.WriteLine(result % 2);
result *= 2;
}
}
As you can see it returns
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
...
How should I efficiently make the above print to be 0 for all of them including 1?
The following expression should be true if i is in your sequence.
(i & (i-1)) == 0)
http://rextester.com/JRH41036
How about something like this?
bool IsInBinarySequence( int number ){
var numbertocheck = 1;
do{
if( number == numbertocheck ) return true;
numbertocheck *= 2;
}while( numbertocheck <= number );
return false;
}
This has no specific limit on the number to check, but makes sure it stops checking if the number to check grows larger than the actual number we're trying to decide if is in the binary sequence.
Since the first time result is odd, you will get 1, since right after that you multiply it by 2, you will always get 0.
You need to print result if you want to get the list of powers of 2.
Console.WriteLine(result);
A primitive way to do that will be:
public static void Main(string[] args)
{
int result = 1;
int numToCheck = 141234;
boolean found = false;
for (int i = 0; i < 15; i++)
{
if (numToCheck == result) {
found = true;
break;
}
result *= 2;
}
if(found) Console.WriteLine("Awesome");
}
You can determine if a number is a power of 2 (including 2^0) by using the following method:
public bool IsPowerOfTwo(int x) {
return (x > 0) && ((x & (x - 1)) == 0)
}
Over here you can read why and how this works.
It's a bit of a hack, but this works ...
static void Main()
{
for (int i = 0; i < 40; i++)
{
var str = Convert.ToString(i, 2);
var bitCount = str.Count(c => c == '1');
Console.ForegroundColor = bitCount == 1 ? ConsoleColor.White : ConsoleColor.DarkGray;
Console.WriteLine(i + ": " + (bitCount == 1));
}
}
it seems you're actually asking if only one bit in the binary representation of the number is a 1
What you is not a test whether the number is in the sequence BUT it is a generator for such numbers... only the print part is containing some sort of a test...
Try this code for a test:
public static void Main(string[] args)
{
int result = 0;
int numToTest = 0;
if ( int.TryParse (args[0], out numToTest) )
{
result = ((from c in Convert.ToString (numToTest, 2) where c == '1' select c).Count() == 1 ) ? 1 : 0;
}
Console.WriteLine(result);
}
The above code takes a commandline argument and tests it for being in the binary sequence according to the criterion you posted... if so it prints 1, otherwise it prints 0.
Thats correct. 1 0 0 0 0 0 is the correct sequence.
Result is 1 in the first loop. 1 % 2 is 1.
Then result *= 2 gives result the value 2. In the next loop run 2 % 2 = 0. Then result *= 2 is 4. 4%2 is 0. 4 *= 2 is 8. 8 %2 is 0. Since result is always multiplied with 2 it keeps to be in the powers of 2 row and thus als MOD operations with 2 result to 0. So all is fine with that code.
your code will print only Binary sequences. as you are applying MOD 2 . so either you will get 0 or 1 . so it will be print in Binary Sequence.
Boolean result = false;
Int32 numberToTest = 64;
Int32 limit = 15;
for (int i = 0; i < limit && !result; i++)
{
if (Math.Pow(2, i).Equals(numberToTest))
{
result = true;
}
}
Console.WriteLine(String.Format("Number {0} {1} a power of 2.", numberToTest, result ? "is" : "is not"));

Rotate 2D Array by 45 degrees

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

Categories

Resources