A sequence of n points in three-dimensional space is given.
It is necessary to find such an even permutation of its indices
that after its application the sequence becomes good.
Here is a link to the solution of this problem:
https://studwork.org/away?href=https%3A%2F%2Fhabr.com%2Fru%2Fcompany%2Fyandex%2Fblog%2F340784%2F%23%3A~%3Atext%3D%25D0%25BF%25D0%25B0%25D0%25BC%25D1%258F%25D1%2582%25D0%25B8%253A%2520256%2520%25D0%259C%25D0%2591-%2C%25D0%25A0%25D0%25B5%25D1%2588%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5%2C-%25D0%2597%25D0%25B0%25D0%25B4%25D0%25B0%25D1%2587%25D1%2583%2520%25D0%25BC%25D0%25BE%25D0%25B6%25D0%25BD%25D0%25BE%2520%25D1%2580%25D0%25B5%25D1%2588%25D0%25B8%25D1%2582%25D1%258C
I wrote a program, but the answer is incorrect or the program is written incorrectly. Here is the program:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace Journey_CSharp_5
{
class Program
{
private static void Main(string[] args)
{
List<List<int>> points;
int n;
using (StreamReader sr = new StreamReader("input.txt"))
{
n = int.Parse(sr.ReadLine());
points = new List<List<int>>(n);
for (int i = 0; i < n; i++)
{
String coords = sr.ReadLine();
string[] tokenscoord = coords?.Split(' ');
if (tokenscoord != null) points.Add(new List<int>
{
int.Parse(tokenscoord[0]),
int.Parse(tokenscoord[1]),
int.Parse(tokenscoord[2])
});
}
bool ok = Check(points);
int[] perm = { 0, 0, 0 };
Random rand = new Random();
while (!ok)
{
for (int j = 0; j < 3; j++) perm[j] = rand.Next() % n;
if (perm[0] == perm[1] || perm[0] == perm[2] || perm[1] == perm[2]) continue;
var points_copy = points;
var tmp = points_copy[perm[0]];
points_copy[perm[0]] = points_copy[perm[1]];
points_copy[perm[1]] = points_copy[perm[2]];
points_copy[perm[2]] = tmp;
ok = Check(points_copy);
}
List<int> ans = new List<int>();
for (int i = 0; i < n; i++) ans.Add(i);
int tmp1 = ans[perm[0]];
ans[perm[0]] = ans[perm[1]];
ans[perm[1]] = ans[perm[2]];
ans[perm[2]] = tmp1;
using (StreamWriter sw = new StreamWriter("output.txt"))
{
for (int i = 0; i < n; i++) sw.Write(ans[i] + 1);
}
}
}
private static long Vect(long xp, long yp, long xt, long yt)
{
return xp * yt - yp * xt;
}
private static bool CheckOrder(int i, int j, List<List<int>> points)
{
int[] signs = { 0, 0, 0 };
for (var k = 0; k < points.Count; k++)
{
int prv = (k - 1 + points.Count) % points.Count;
int cur = k;
int nxt = (k + 1) % points.Count;
long vres = Vect(
points[cur][(int)i] - points[prv][(int)i],
points[cur][(int)j] - points[prv][(int)j],
points[nxt][(int)i] - points[prv][(int)i],
points[nxt][(int)j] - points[prv][(int)j]);
switch (Math.Sign(vres))
{
case -1:
signs[0] += 1;
break;
case 0:
signs[1] += 1;
break;
case 1:
signs[2] += 1;
break;
}
}
return (signs[0] != 0 && signs[2] != 0) || (signs[1] != 0);
}
private static bool Check(List<List<int>> points)
{
List<Tuple<int, int>> ids = new List<Tuple<int, int>>
{
new Tuple<int, int>(0, 1),
new Tuple<int, int>(1, 2),
new Tuple<int, int>(0, 2)
};
bool ok = true;
for (int i = 0; i < 3; i++) ok &= CheckOrder(ids[i].Item1, ids[i].Item2, points);
return ok;
}
}
}
Verdict:
wrong-answer
I also rewrote this program in C# and get the compilation log:
stdout:
Compilation succeeded - 1 warning(s)
stderr:
warning CS8001: SDK path could not be resolved
Although only Mono C# 5.2.0 can be selected on this site.
Please tell me what is wrong with my program?
It is necessary to remove the directive using
System.Linq;
Related
I write some code with jagged array but when i sum middle number program not working and i cant fix it...:
public class JaggedArray
{
public static void Array()
{
int[][] arrayOfArray = ArrayOfArray();
var tong = 0;
for (var i = 1; i < arrayOfArray.Length; i++)
{
for (var j = 0; j < arrayOfArray[i].Length; j++)
{
var bienTam = arrayOfArray[i].Length;
var tamThoi = j;
if (bienTam%2==0&&tamThoi==bienTam/2)
{
tamThoi++;
tong += arrayOfArray[i][tamThoi];
}
}
}
OutPut(arrayOfArray, tong);
}
private static int[][] ArrayOfArray()
{
Random ngauNhien = new Random();
int[][] arrayOfArray = new int[13][];
for (var i = 0; i <arrayOfArray.Length; i++)
{
arrayOfArray[i] = new int[i];
for (var j = 0; j < arrayOfArray[i].Length; j++)
{
arrayOfArray[i][j] = ngauNhien.Next(0, 99); //throw exception
}
}
return arrayOfArray;
}
can someone explain reason why i wrong and how ti fix it?
The problem you are solving is the one Linq is very good for:
int[][] arrayOfArray = new int[][] {
new[] {1, 2, 3}, // 2 is the middle item
new[] {4, 5} // in case of tie, let 5 (right) be the middle item
new[] {7}, // 7
new int[] {}, // should be ignored
};
// 2 + 5 + 7 == 14
var result = arrayOfArray
.Where(line => line != null && line.Length > 0)
.Sum(line => line[line.Length / 2]);
So I've got it compiling:
public class JaggedArray
{
public static void Array()
{
int[][] arrayOfArray = ArrayOfArray();
var tong = 0;
for (var i = 1; i < arrayOfArray.Length; i++)
{
for (var j = 0; j < arrayOfArray[i].Length; j++)
{
var bienTam = arrayOfArray[i].Length;
var tamThoi = j;
if (j % 2 == 0 && j / 2 == bienTam / 2)
{
tamThoi++;
// You need to check here that tamThoi isn't
// outside the bounds of your array
if (tamThoi >= arrayOfArray[i].Length)
{
continue;
}
tong += arrayOfArray[i][tamThoi];
}
}
}
}
private static int[][] ArrayOfArray()
{
Random ngauNhien = new Random();
int[][] arrayOfArray = new int[13][];
for (var i = 0; i < 13; i++)
{
arrayOfArray[i] = new int[i];
// here you're better off using i
// instead of the arrayOfArray[i].Length - because you know the length
for (var j = 0; j < i; j++)
{
arrayOfArray[i][j] = ngauNhien.Next(0, 99);
}
}
return arrayOfArray;
}
}
You can make this far more succinct with LINQ.
I have to write a program that finds the difference between the sums of square matrix diagonals for homework, but my code throws IndexOutOFRange exception and I have no idea how to fix it.
Source code below:
//input 3 11 2 4 4 5 6 10 8 -12 //desired output: 15
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class diagonalDifference
{
static void Main()
{
int N = Convert.ToInt16(Console.ReadLine());
int[,] arr = new int[N, N];
string str = string.Empty;
for (int i = 0; i < N; ++i)
{
string[] strArr = Console.ReadLine().Split(' ');
for (int j = 0; j < strArr.Length; ++j)
{
arr[i, j] = Convert.ToInt16(strArr[j]);
}
}
int left = 0, right = N - 1, ldTotal = 0, rdTotal = 0;
while (left <= right)
{
ldTotal += arr[left, left];
rdTotal += arr[left++, right];
}
Console.WriteLine(Math.Abs(ldTotal - rdTotal));
}
}
class diagonalDifference
{
static void Main()
{
int N = Convert.ToInt16(Console.ReadLine());
int[,] arr = new int[N, N];
string str = string.Empty;
for (int i = 0; i < N; ++i)
{
string[] strArr = Console.ReadLine().Split(' ');
for (int j = 0; j < strArr.Length; ++j)
{
arr[i, j] = Convert.ToInt16(strArr[j]);
}
}
int left = 0, right = N - 1, ldTotal = 0, rdTotal = 0;
while (left <= (N-1))
{
ldTotal += arr[left, left];
rdTotal += arr[left, right];
Left++;
Right--;
}
Console.WriteLine(Math.Abs(ldTotal - rdTotal));
}
}
class Result
{
/*
* Complete the 'diagonalDifference' function below.
*
* The function is expected to return an INTEGER.
* The function accepts 2D_INTEGER_ARRAY arr as parameter.
*/
public static int diagonalDifference(List<List<int>> arr)
{
int l=arr.Count;
int d1=0;
int d2=0;
for(int i=0;i<l;i++)
{
d1=d1+arr[i][i];
d2=d2+arr[i][l-1-i];
}
return (Math.Abs(d1-d2));
}
}
I have a problem with one exercise. Task is to find all subsets within the array which have a sum equal to N and print them. Also I need to find all unique subsets and this is the problem. I am using Gray method to find all combinations but some of them are duplicated. Here's my code:
int matchSum = int.Parse(Console.ReadLine());
int[] numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();
int combinations = (int) Math.Pow(2, numbers.Length);
List<int> currentSequence = new List<int>();
bool foundMatch = false;
for (int i = 1; i < combinations; i++)
{
for (int bit = 0; bit < Convert.ToString(i,2).Length; bit++)
{
int mask = (i >> bit) & 1;
if (mask == 1)
{
currentSequence.Add(numbers[numbers.Length-bit-1]);
}
}
if (currentSequence.Sum() == matchSum)
{
Console.WriteLine("{0} = {1}", string.Join(" + ", currentSequence), matchSum);
foundMatch = true;
}
currentSequence.Clear();
}
if (!foundMatch)
{
Console.WriteLine("No matching subsets.");
}
Best regards!
Here is a backtracking algorithm implementation. It works by first sorting the input set and then producing the subsets and checking the sum. There are 3 key points. First, the algorithm maintains the current sum all the time so it doesn't need to fully calculate it at each step. Second, it early stops if the current sum becomes larger than the target sum. And finally, in order to produce unique subsets, the back step skips the numbers that are equal to the last number of the previous sequence. Hope that helps.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Samples
{
class Sample
{
static void Main(string[] args)
{
int matchSum = 20; // int.Parse(Console.ReadLine());
int[] numbers = { 5, 1, 3, 2, 5, 1, 8, 7, 4 }; // Console.ReadLine().Split().Select(int.Parse).ToArray();
Array.Sort(numbers);
var stack = new Stack<int>();
int matchCount = 0, currentSum = 0, nextPos = 0;
while (true)
{
// Next
for (int nextSum; nextPos < numbers.Length; currentSum = nextSum, nextPos++)
{
nextSum = currentSum + numbers[nextPos];
if (nextSum > matchSum) break;
stack.Push(nextPos);
if (nextSum < matchSum) continue;
matchCount++;
Console.WriteLine("{0} = {1}", matchSum, string.Join(" + ", stack.Reverse().Select(pos => numbers[pos])));
stack.Pop();
break;
}
// Back
if (stack.Count == 0) break;
var lastPos = stack.Pop();
var lastNumber = numbers[lastPos];
currentSum -= lastNumber;
nextPos = lastPos + 1;
while (nextPos < numbers.Length && numbers[nextPos] == lastNumber)
nextPos++;
}
if (matchCount == 0)
{
Console.WriteLine("No matching subsets.");
}
Console.ReadLine();
}
}
}
I found another way with a HashSet (thanks #Eric J.).
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static List<int> currentMatchList = new List<int>();
static void Main()
{
int matchSum = int.Parse(Console.ReadLine());
int[] numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();
int combinations = (int)Math.Pow(2, numbers.Length);
List<int> currentSequence = new List<int>();
HashSet<string> allResults = new HashSet<string>();
bool foundMatch = false;
for (int i = 1; i < combinations; i++)
{
for (int bit = 0; bit < Convert.ToString(i, 2).Length; bit++)
{
int mask = (i >> bit) & 1;
if (mask == 1)
{
currentSequence.Add(numbers[numbers.Length - bit - 1]);
}
}
if (currentSequence.Sum() == matchSum)
{
string temp = "";
currentSequence.OrderBy(a => a).ToList().ForEach(a => temp += a + " ");
if (!allResults.Contains(temp))
{
allResults.Add(temp);
Console.WriteLine("{0} = {1}", string.Join(" + ", currentSequence), matchSum);
}
foundMatch = true;
}
currentSequence.Clear();
}
if (!foundMatch)
{
Console.WriteLine("No matching subsets.");
}
}
}
I implemented MergeSort algorithm that's used on a 100,000 integer file. It takes care of the sorting and collects inversions that are in the file. It works with small test arrays, but as soon as I plug in the actual file, I get out of memory error. How do I fix it?
The error occurs during MergeSort, and the number of elements in my aux array is 12,500
Here's my code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment_1
{
class Program
{
static void Main(string[] args)
{
List<int> data = File2Array("IntegerArray.txt");
int[] unsorted = data.ToArray();
List<string> inversions = new List<string>();
Sort(ref unsorted, ref inversions);
Console.WriteLine("number of inversions is: " + inversions.Count());
Console.ReadLine();
}
public static void Sort(ref int[] unsorted, ref List<string>inversions)
{
int size = unsorted.Length;
if (size == 1)
return;
int mid = size / 2;
int leftSize = mid;
int rightSize = size - leftSize;
int[] left = new int[leftSize];
int[] right = new int[rightSize];
Array.Copy(unsorted, 0, left, 0, leftSize);
Array.Copy(unsorted, mid, right, 0, rightSize);
Sort(ref left, ref inversions);
Sort(ref right, ref inversions);
int[] aux = new int[leftSize + rightSize];
for (int i = 0, j = 0, k = 0; k < aux.Length; k++)
{
if (left[i] < right[j])
{
aux[k] = left[i++];
// if left array is exhausted, copy the remaining right array elements over
if (i == leftSize)
{
Array.Copy(right, j, aux, ++k, rightSize - j);
unsorted = aux;
break;
}
}
else
{
int temp = i;
while (temp < leftSize)
{
inversions.Add(left[temp++] + "-" + right[j]);
}
aux[k] = right[j++];
if (j == rightSize)
{
Array.Copy(left, i, aux, ++k, leftSize - i);
unsorted = aux;
break;
}
}
}
}
public static List<int> File2Array(string file)
{
List<int> data = new List<int>();
using (StreamReader reader = new StreamReader(file))
{
int line;
do
{
int.TryParse(reader.ReadLine(), out line);
data.Add(line);
}
while (!reader.EndOfStream);
}
return data;
}
}
}
Here's some code for you to look at.
This starts with recognizing that the file is already a collection of single elements. Therefore we can do the first grouping/sorting when we read the file. Since arrays are very impractical for this part I used Lists and then cast the return to int[][]
static int[][] makearrays(string filename)
{
List<List<int>> outval = new List<List<int>>();
using(StreamReader sr = new StreamReader(filename))
{
while(!sr.EndOfStream)
{
int a = 0, b = 0;
a = int.Parse(sr.ReadLine());
if(!sr.EndOfStream)
b = int.Parse(sr.ReadLine());
else
{
outval.Add(new List<int>() { a });
break;
}
if(a > b)
outval.Add(new List<int>() { b, a });
else
outval.Add(new List<int>() { a, b });
}
}
return outval.Select(x => x.ToArray()).ToArray();
}
With this array we can start the rest of the grouping/sorting
This uses recursion but has a minimal memory footprint:
static int[][] dosort(int[][] input)
{
if(input.Length == 1)
return input;
int i = 1, m = 0;
for(; i < input.Length; i += 2)
{
int limit = Math.Min(input[i].Length, input[i - 1].Length);
int[] temp = new int[input[i].Length + input[i - 1].Length];
int j = 0, k = 0, l = 0;
while(j < input[i].Length && k < input[i - 1].Length)
{
if(input[i][j] < input[i - 1][k])
{
temp[l++] = input[i][j++];
}
else
temp[l++] = input[i - 1][k++];
}
while(l < temp.Length)
{
if(j < input[i].Length)
temp[l++] = input[i][j++];
if(k < input[i - 1].Length)
temp[l++] = input[i - 1][k++];
}
input[m++] = temp;
}
if(input.Length % 2 == 1)
input[m++] = input.Last();
input = input.Take(m).ToArray();
return dosort(input);
}
In my tests the 100000 element file was sorted in less than a quarter of a second, including reading it into memory.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need help debugging and finishing a program that would: read a file with same number of lines and same number of integer values on each line (this will be a n x n matrix). The program should determines if the matrix is a magic square.
example of magic square: "ms.txt"
8,1,6;3,5,7;4,9,2
my code (working in progress), your help would be appreciated
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MagicSquare
{
class Program
{
static void Main(string[] args)
{
int[,]S;
string line; //to hold one line of file
string[] token; //to hold each token in line
char[] separator = { ',' };
int N;
//open file
try
{
using (StreamReader sr = new StreamReader("..\\..\\ms.txt"))
{
line = sr.ReadLine();
token = line.Split(separator);
N = token.Count();
S = new int[N, N];
for (int i = 0; i < N; i++)
S[0, i] = Convert.ToInt32(token[i]);
for (int r = 1; r < N; r++)
{
line = sr.ReadLine();
token = line.Split(separator);
for (int c = 0; c < N; c++)
S[r, c] = Convert.ToInt32(token[c]);
}
sr.Close();
}
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
//find Magic Number
int magic = 0;
for (int i = 0; i < N; i++)
magic += S[i, i];
int sum = 0;
for (int i=0;i<N;i++)
sum += S[i,N -1-i];
if (magic!=sum)
{
Console.Write("Not Magic");
return;
}
//check each column
for (int c=0;c<N;c++)
{
int sum1 =0;
for (int r=0;r<N;r++)
sum1 += S[r,c];
if (sum1!=magic)
{
Console.WriteLine("Not magic");
return;
}
}
}
}
}
I edit your solution. This works for rows and columns.
static void Main(string[] args)
{
int[,] S = null;
int N = 0;
string line; //to hold one line of file
string[] token; //to hold each token in line
char[] separator = { ',' };
//open file
try
{
using (StreamReader sr = new StreamReader(#"C:\Users\sb9923\Desktop\ms.txt"))
{
line = sr.ReadLine();
token = line.Split(separator);
N = token.Count();
S = new int[N, N];
for (int i = 0; i < N; i++)
S[0, i] = Convert.ToInt32(token[i]);
for (int r = 1; r < N; r++)
{
line = sr.ReadLine();
token = line.Split(separator);
for (int c = 0; c < N; c++)
S[r, c] = Convert.ToInt32(token[c]);
}
sr.Close();
}
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
int magicValue = GetSum(N * N) / N;
//Check for magic
bool isMagic = true;
for (int counterY = 0; counterY < S.GetLength(1); counterY++)
{
int rowValue = 0;
int columnValue = 0;
for (int counterX = 0; counterX < S.GetLength(0); counterX++)
{
rowValue += Convert.ToInt32(S[counterY, counterX]);
columnValue += Convert.ToInt32(S[counterX, counterY]);
}
if (rowValue != magicValue)
{
isMagic = false;
break;
}
if (columnValue != magicValue)
{
isMagic = false;
break;
}
rowValue = 0;
columnValue = 0;
}
if (isMagic)
{
Console.WriteLine("Yeah it is magic! :)");
}
else
{
Console.WriteLine("No magic in the air!");
}
}
private static int GetSum(int maxValue)
{
if (maxValue < 1)
{
return 0;
}
return maxValue + GetSum(maxValue - 1);
}
If you have a question go for asking ;)
Just one simple variation about "how to check if square is magical?"(and unit test, for testing purpose):
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using System.IO;
namespace MSquareTest
{
[TestClass]
public class MSquareTest
{
/// <summary>
/// Checks if array of int's
/// is an magick square
/// </summary>
/// <param name="matrix">Input array</param>
/// <returns>True/False</returns>
public bool IsMagicSquare(int[] matrix)
{
if (matrix.Length % 3 != 0)
throw new ArgumentException("Invalid 2D cube!");
// 2x2(6 cells) is minimum
if (matrix.Length < 6)
throw new ArgumentException("Use at least 2x2 cube!");
// Cube face length
int length = matrix.Length / 3;
// calculate first row sum
int excepted = 0;
for (int y = 0; y < length; y++)
excepted += matrix[y];
// calculate and check second and another rows
for (int x = 1; x < length; x++)
{
int actual = 0;
for (int y = 0; y < length; y++)
actual += matrix[(length * x) + y];
if (actual != excepted)
return false;
}
// calculate and check columns
for (int x = 0; x < length; x++)
{
int actual = 0;
for (int y = 0; y < length; y++)
actual += matrix[(length * y) + x];
if (actual != excepted)
return false;
}
return true;
}
[TestMethod]
public void TestMS()
{
var GoodInput = "8,1,6;3,5,7;4,9,2"; // = File.ReadAllText("..\\..\\ms.txt");
var GoodArray = (from x in GoodInput.Split(',', ';') select int.Parse(x)).ToArray();
var BadInput = "6,4,1;3,0,3;1,5,9";
var BadArray = (from x in BadInput.Split(',', ';') select int.Parse(x)).ToArray();
// Good array is magick square, and bad array is not
var Result = IsMagicSquare(GoodArray) && !IsMagicSquare(BadArray);
Assert.IsTrue(Result);
}
}
}