Help needed in finding coordinate count - c#

I have an 8 X 8 matrix. Now, The below coordinates are occupied
{ 6, 3 }, { 5, 5 }, { 3, 3 }.... What needs to be done is that, I need to build straight line
through these points and needs to count how many coordinates they have touched?
My program so far stands as
private static void GetCount(int[,] Positions)
{
int rcount = 8;
int firstRow = Positions[0, 0];
for (int i = 1; i < Positions.Length/2; i++)
{
int currentRow = Positions[i, 0];
if (currentRow != firstRow)
{
rcount += 8;
firstRow = currentRow;
}
}
int cCount = 8;
int firstCol = Positions[0, 1];
for (int i = 1; i < Positions.Length / 2; i++)
{
int currentCol = Positions[i, 1];
if (currentCol != firstCol)
{
cCount += 8;
firstCol = currentCol;
}
}
int totalCount = rcount - cCount;
Console.WriteLine(totalCount);
}
And I am invoking it as
GetCount(new int[,] { { 6, 3 }, { 5, 5 }, { 3, 3 } });
The output will be 40 here. (count will be 24 for each 3 unique rows i.e. 6,5,3 and count will be 16 for 2 unique columns i.e. 3 and 5... So, the total count is 24+16 = 40)
But I am getting the output as 48.
Also is it possible to do the porgram using one single loop?
I am using C# 1.0
Edited
This does work
List<int> lstRows = new List<int>();
List<int> lstCols = new List<int>();
int count = 0;
//Get the unique rows and columns
for (int i = 0; i < marinePositions.Length / 2; i++)
{
if (!lstRows.Contains(marinePositions[i, 0])) lstRows.Add(Positions[i, 0]);
if (!lstCols.Contains(marinePositions[i, 1])) lstCols.Add(Positions[i, 1]);
}
//get row count
for (int i = 0; i < lstRows.Count; i++) count += 8;
//get column count
for (int i = 0; i < lstCols.Count; i++) count += 8;
Console.WriteLine(count);
But need a much better one.. if possible using linq/lambda and no loop
Please help

Here u go... but this in is LINQ and not C# 1.0 which is way too old.. not sure why are you using such old version of the language:
private static void GetCount(int[,] Positions)
{
List<int> x = new List<int>();
List<int> y = new List<int>();
for (int i = 0; i < Positions.Length/2; i++)
{
x.Add(Positions[i, 0]);
y.Add(Positions[i, 1]);
}
int result = (x.Distinct().Count() * 8) + (y.Distinct().Count() * 8);
Console.WriteLine(result);
}
No loops magic:
private static void GetCount(int[,] Positions)
{
var range = Enumerable.Range(0, Positions.Length / 2);
var result = (range.Select(i => Positions[i, 0]).Distinct().Count() * 8) +
(range.Select(i => Positions[i, 1]).Distinct().Count() * 8);
Console.WriteLine(result);
}

CORRECTIONS:
1-
int cCount = 8;
To:
int cCount = 0;
2-
int totalCount = rcount - cCount;
To:
int totalCount = rcount + cCount;
The program should work fine now.

Related

How to find 3x3 square matrix with maximum sum in bigger rectangular matrix in C#?

I have matrix with size N x M and I want to find smaller matrix inside which has maximum sum and is of size 3 x 3. I can manually sum all the elements but wthis is imposible in bigger matrices, can you point me a better approach.
Look for Kadane 2D algorithm.
I think it is one of the best solution for this problem
If I understand the problem ¯\_(ツ)_/¯
Given
public static int FindStuff(int[,] array)
{
var largest = 0;
for (var i = 0; i < array.GetLength(0) - 2; i++)
for (var j = 0; j < array.GetLength(1) - 2; j++)
{
var sum = 0;
for (var x = i; x < i+3; x++)
for (var y = j; y < j+3; y++)
sum += array[x, y];
if (sum > largest)
largest = sum;
}
return largest;
}
Usage
var array = new[,]
{
{1, 1, 1, 1},
{1, 2, 3, 4},
{1, 1, 1, 1},
{5, 1, 1, 1},
};
Console.WriteLine(FindStuff(array));
Result
16
In pure C# you must calculate all inner matricies, you can speed up algorithms with paraller task, you can also use CUDA, and a naive solution with checking inner matrices should looks like this:
public void TestMethod(int[][] matrix)
{
int largestSum = 0;
int columnLargestIdx = 0;
int rowLargestIdx = 0;
for (int column = 0; column < matrix.Length; column++)
for (int row = 0; row < matrix[column].Length; row++)
{
if (IsBuild3x3Possible(matrix, column, row))
{
int sum = CalculateSum(matrix, column, row);
if (sum > largestSum)
{
largestSum = sum;
columnLargestIdx = column;
rowLargestIdx = row;
}
}
}
}
public bool IsBuild3x3Possible(int[][] matrix, int column, int row)
{
var columns = (matrix.Length - column) >= 3;
var rows = (matrix[column].Length - row) >= 3;
return columns && rows;
}
public int CalculateSum(int[][] matrix, int column, int row)
{
int sum = 0;
for (int i = column; i < column + 3; i++)
for (int j = row; j < row + 3; j++)
sum += matrix[i][j];
return sum;
}

Delete border of matrix

I have a 2d array[,] and I need to delete the border of it (or create a new array without it). I tried everything I thought of and nothing worked since I don't usually work with 2d arrays. Help please?
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
becomes:
6 7
1 2
Queue<int> numbers = new Queue<int>();
int[,] b = new int[4, 4];
for (int i = 0; i < b.GetLength(0); i++)
{
for (int j = 0; j < b.GetLength(1); j++)
{
int x = int.Parse(Console.ReadLine());
b[i, j] = x;
}
}
int rows = b.GetLength(0);
Console.WriteLine("Number of rows: "+rows);
int columns = b.GetLength(1);
Console.WriteLine("Number of columns: " + columns);
int[,] arrayUpdated = new int[columns - 2,rows - 2];
for (int n = 0; n < b.GetUpperBound(1); n++)
{
for (int i = 0; i < b.GetUpperBound(0); i++)
{
arrayUpdated[i, n] = b[i, n];
Console.WriteLine(arrayUpdated[i, n]);
}
}
public static T[,] RemoveBorders<T>(T[,] source)
{
//index of last item, not number of items
var ROW = source.GetUpperBound(0);
if (ROW < 2) throw new ArgumentException("source array is not tall enough");
var COL = source.GetUpperBound(1);
if (COL < 2) throw new ArgumentException("source array is not wide enough");
var result = new T[ROW - 1, COL - 1];
for (int r = 1; r < ROW; r++)
{
for (int c = 1; c < COL; c++)
{
result[r-1, c-1] = source[r, c];
}
}
return result;
}
https://dotnetfiddle.net/dtUpRA
You would use it in the code in the question like this:
int[,] arrayUpdated = RemoveBorders(b);

Digit difference sort

So I am trying to solve this task "Digit Difference Sort" on Codefights
Given an array of integers, sort its elements by the difference of their largest and smallest digits.
In the case of a tie, that with the larger index in the array should come first.
Example
For a = [152, 23, 7, 887, 243], the output should be digitDifferenceSort(a) = [7, 887, 23, 243, 152].
Here are the differences of all the numbers:
152: difference = 5 - 1 = 4;
23: difference = 3 - 2 = 1;
7: difference = 7 - 7 = 0;
887: difference = 8 - 7 = 1;
243: difference = 4 - 2 = 2.
23 and 887 have the same difference, but 887 goes after 23 in a, so in the sorted array it comes first.
I have an issue with two numbers having the same difference. Here's what I wrote so far:
int[] digitDifferenceSort(int[] a) {
return a.OrderBy(x => difference(x)).ToArray();
}
int difference(int x)
{
int min = 9, max = 0;
do
{
int tmp = x % 10;
min = Math.Min(min, tmp);
max = Math.Max(max, tmp);
} while ((x /= 10) > 0);
return max - min;
}
Didn't do much (for example the output is still [7, 23, 887, 243, 152] rather than [7, 887, 23, 243, 152])
How do I make element with larger index come first in result? What should I use instead of OrderBy?
I don't consider your difference method, i assume it works fine.
To your question: you have to keep revered order of the array (that the items with the same difference arrive will be sorted reverse). To do it, you could just reverse you input array: all items with not identical difference will be ordered correctly, and with the same differece will be ordered reversed:
int[] digitDifferenceSort(int[] a)
{
return a.Reverse().OrderBy(x => difference(x)).ToArray();
}
Following is my code for the above question digit difference sort. I am also getting output when running in Eclipse but when I paste the code on code signal it gives me a null pointer exception.
package NormalPrograms;
import java.util.ArrayList;
import java.util.Collections;
public class DigitDifferenceSort {
// For index wise sorting in descending order
public static int[] sortingnumberindexwise(int[] a, ArrayList<Integer> index) {
int k = 0;
int[] res = new int[index.size()];
int[] finalres = new int[index.size()];
for (int i = a.length - 1; i >= 0; i--) {
for (int j = 0; j < index.size(); j++) {
if (a[i] == (int) index.get(j)) {
res[k] = i;
index.remove(j);
k++;
break;
}
}
}
int g = 0;
k = 0;
for (int i = 0; i < res.length; i++) {
finalres[g] = a[res[k]];
g++;
k++;
}
return finalres;
}
public static int[] finddigitDifferenceandSort(int[] p) {
int[] finres = new int[p.length];
for (int i = 0; i < finres.length; i++) {
finres[i] = p[i];
}
// This finres array act as an temp array and reused to make final result array
int digit = 0;
ArrayList<Integer> A = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> B = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i++) {
B.add(new ArrayList<Integer>());
}
for (int i = 0; i < p.length; i++) {
int temp = 0;
temp = p[i];
while (p[i] > 0) {
digit = p[i] % 10;
p[i] /= 10;
A.add(digit);
}
int b = Collections.max(A);
int c = Collections.min(A);
int diff = b - c;
B.get(diff).add(temp);
A.clear();
}
for (int i = 0; i < B.size(); i++) {
if (B.get(i).size() > 1) {
ArrayList<Integer> C = new ArrayList<Integer>();
for (int k = 0; k < B.get(i).size(); k++) {
C.add(B.get(i).get(k));
}
B.get(i).clear();
for (int j : sortingnumberindexwise(finres, C)) {
B.get(i).add(j);
}
} else {
continue;
}
}
int k = 0;
for (int i = 0; i < B.size(); i++) {
for (int j = 0; j < B.get(i).size(); j++) {
if (B.get(i).size() == 0)
continue;
else {
finres[k] = B.get(i).get(j);
k++;
}
}
}
return finres;
}
public static void main(String[] args) {
int[] a = { 12, 21, 1, 1, 1, 2, 2, 3 };
for (int i : finddigitDifferenceandSort(a)) {
System.out.print(i + " ");
}
}
}

Rechange array so it could be sorted in C#

I have been given this task to solve:
Write a program that reads an array of integers and removes from it a minimal number of elements in such a way that the remaining array is sorted in increasing order. Print the minimal number of elements that need to be removed in order for the array to become sorted.
Time limit 0.1sec.
Sample test:
Input:
1,
4,
3,
3,
6,
3,
2,
3
Output:
3
Unfortunately, my program is slower. This is my code:
using System;
static bool CheckAscending(List<int> list)
{
bool ascending = true;
for (int i = 0; i < list.Count - 1; i++)
{
if (list[i] > list[i + 1])
{
ascending = false;
}
}
return ascending;
}
static void Main()
{
int n;
n = int.Parse(Console.ReadLine());
List<int> arr = new List<int>();
List<int> sorted = new List<int>();
int maxSubsetLenght = 0;
for (int i = 0; i < n; i++)
{
arr.Add(int.Parse(Console.ReadLine()));
}
for (int i = 1; i <= (int)Math.Pow(2, n) - 1; i++)
{
int tempSubsetLenght = 0;
List<int> temp = new List<int>();
for (int j = 1; j <= n; j++)
{
if (((i >> (j - 1)) & 1) == 1)
{
temp.Add(arr[j - 1]);
tempSubsetLenght++;
}
}
if ((tempSubsetLenght > maxSubsetLenght) && (CheckAscending(temp)))
{
sorted = temp;
maxSubsetLenght = tempSubsetLenght;
}
}
Console.WriteLine(n - sorted.Count);
}
Can someone help me to make my program a bit faster. I will be glad if you could answer in the near future.
Ok I found how to soleve it and thanks #Gabor for your help :). Here is my solution:
using System;
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
List<int> numbers = new List<int>();
for (int i = 0; i < n; i++)
{
int currentNumber = int.Parse(Console.ReadLine());
numbers.Add(currentNumber);
}
int[] size = new int[numbers.Count];
// Define each number as subsequence.
for (int i = 0; i < numbers.Count; i++)
{
size[i] = 1;
}
int max = 1;
// Compare current number with the numbers before.
for (int i = 1; i < numbers.Count; i++)
{
for (int j = 0; j < i; j++)
{
if (numbers[i] >= numbers[j] && size[i] <= size[j] + 1)
{
size[i] = size[j] + 1;
// Update max increasing subsequence.
if (max < size[i])
{
max = size[i];
}
}
}
}
// Print numbers to remove as a result.
int numbersToRemove = n - max;
Console.WriteLine(numbersToRemove);
}
I think it would be helpful for other people, who have the same task to do like me.
UPDATE #2
When there is a decrease then we should delete not only the current number but all the numbers before which are more than the new minValue.
The Stopwatch is in the System.Diagnostic namespace.
// int?[] numbers = new int?[] { 8, 1, 4, 3, 3, 6, 3, 2, 3 };
int?[] numbers = new int?[] { -7, -7, -7, -100, -100, -99, 4, -90, -80, -70 };
Console.WriteLine("Array: [{0}]", String.Join(", ", numbers));
System.Diagnostics.Stopwatch watch = new Stopwatch();
watch.Start();
int minValue = Int32.MinValue;
for (int i = 0; i < numbers.Length - 1; i++)
{
var currentNumber = numbers[i];
var nextNumber = numbers[i + 1];
if (currentNumber > nextNumber)
{
if (nextNumber < minValue)
{
numbers[i + 1] = null;
}
else
{
minValue = nextNumber.Value;
for (int j = i; j >= 0; j--)
{
if (numbers[j] > minValue)
{
numbers[j] = null;
}
}
}
}
}
watch.Stop();
Console.WriteLine("Result: {0}; Time: {1} ms", numbers.Count(number => number == null), watch.ElapsedMilliseconds);
Console.WriteLine("Array: [{0}]", String.Join(", ", numbers));

Float array resampling

I want to "stretch" a one-dimensional float array into a bigger array.
//expected behaviour
float[] initialArray = {2.0, 6.5, 2.0}
float[] biggerArray = resample(initialArray, 7 /*new size*/)
//output: {2.0, 3.5, 5.0, 6.5, 5.0, 3.5, 2.0}
The new values should propobaly be calculated from linear interpolation of the previous array values but i can't figure out how to achieve that.
Any hint ?
Lets the length of a source array is N, and the length of a destination array is M where N < M and N > 1.
You can calculate the new index of the source i-th element by the formula:
j = i * (M - 1)/(N - 1);
When i == 0 then j == 0; and when i == N - 1 then j == M - 1. The external loop can looks like this:
float[] source = ...;
float[] destination = ...;
destination[0] = source[0];
for (int i = 1; i < source.Length; i++)
{
int j = i * (destination.Length - 1)/(source.Length - 1);
destination[j] = source[i];
// interpolation
}
To interpolation you should calculate intermediate values for each pair (source[i - 1], source[i]). You'll need to store previous value of j:
destination[0] = source[0];
int jPrevious = 0;
for (int i = 1; i < source.Length; i++)
{
int j = i * (destination.Length - 1)/(source.Length - 1);
Interpolate(destination, jPrevious, j, source[i - 1], source[i]);
jPrevious = j;
}
private static void Interpolate(float[] destination, int destFrom, int destTo, float valueFrom, float valueTo)
{
int destLength = destTo - destFrom;
float valueLength = valueTo - valueFrom;
for (int i = 0; i <= destLength; i++)
destination[destFrom + i] = valueFrom + (valueLength * i)/destLength;
}
This one works for both if source size is larger than destination and vice versa.
private double[] Resample(double[] source, int n)
{
//n destination length
int m = source.Length; //source length
double[] destination = new double[n];
destination[0] = source[0];
destination[n-1] = source[m-1];
for (int i = 1; i < n-1; i++)
{
double jd = ((double)i * (double)(m - 1) / (double)(n - 1));
int j = (int)jd;
destination[i] = source[j] + (source[j + 1] - source[j]) * (jd - (double)j);
}
return destination;
}
You can use List<float>:
float[] initialArray = { 2.0f, 6.5f, 2.0f };
List<float> initialArrayTemp = ToListFloat(initialArray);
private List<float> ToListFloat(float[] array)
{
List<float> list = new List<float>();
for (int i = 0; i < array.Length; i++)
{
list.Add(array[i]);
}
return list;
}
Now your array is a dynamic array and you can add your new nodes anywhere of your Array by using Insert() method.
As soon as you need a new static array, use below:
float[] newInitialArray = initialArrayTemp.ToArray();

Categories

Resources