Finding sum a multi-dimensional array's reverse diagonal elements - c#

this is my multi dimensional array.
1-2-3-4
5-6-7-8
9-10-11-12
13-14-15-16
And i want find sum of reverse diagonal elements (From:right top To:left bottom) (4 -> 7 -> 10 -> 13)
Here is my code, it gives an error but i still can't find why.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace sketchboard
{
class Program
{
static int reversediagonaladder (int[,] a)
{
int sum = 0;
for(int row=a.GetLength(0) ; row>0 ; row--)
{
for(int column=a.GetLength(1) ; column>0 ; column--)
{
if (row == column)
sum += a[row , column];
}
}
Console.WriteLine($"{sum}");
return sum;
}
static void Main(string[] args)
{
int[,] a ={ {1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,16 } };
reversediagonaladder(a);
Console.ReadLine(); // added for hold console on screen
}
}
}

Your loop starts with a.GetLength(1) or a.GetLength(0) in both cases this will resolve to 4 but there is no index with 4 since indexes start with 0.
So index will be 0, 1, 2 or 3 which equals to a length of 4.
To fix your problem you need to substract 1 from the length.
Currently you are also skipping the index 0, I don't know why you are doing so, maybe it is an error aswell, to fix this you have to change the break condidtion of the for loop from > 0 to >= 0.
This should work
for (int row = a.GetLength(0) - 1; row >= 0; row--)
{
for (int column = a.GetLength(1) - 1; column >= 0; column--)
{
if (row == column)
sum += a[row , column];
}
}
Edit:
Here a version which actually does what the question claims it does, it also gets rid of the double for loop which should run more performant
var column = a.GetLength(1);
for (int row = 0; row < a.GetLength(0); row++)
{
column--;
var item = a[row, column];
sum += item;
}
Here you can see it in action:
https://dotnetfiddle.net/S5imGs

If you don't want to deal with the -1, use GetUpperBound instead.
Here's an example doing as Self suggested with just one for loop:
public static void Main(string[] args)
{
int[,] a ={ {1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,16} };
int sum = reversediagonaladder(a);
Console.WriteLine("sum = " + sum);
Console.WriteLine();
Console.WriteLine("Press Enter to Quit");
Console.ReadLine();
}
static int reversediagonaladder(int[,] a)
{
// code assumes a SQUARE matrix
int sum = 0;
for (int row=0, col=a.GetUpperBound(1); row<=a.GetUpperBound(0) && col>=0; row++, col--)
{
sum += a[row, col];
}
return sum;
}

Related

C# checking if next value in array is null

This code cycles thru an array of integers, adding the int at the current index with the int at the next index (i + 1) and then finding their average (dividing by 2). This double is then appended to an array of doubles. When I get to the end of the array however, since there is no value beyond the last value, an error occurs. I thought I could just check to see if the value was null but the error is occurring beforehand. Error occurs at line 15 "if (numbers[i + 1] != null)."
using System;
using System.Collections;
using System.Linq;
public class Test
{
public static double[] Averages(int[] numbers)
{
double[] averageArray = new double[0];
for (int i = 0; i < numbers.Length; i++)
{
double sum = 0;
double avg = 0;
if (numbers[i + 1] != null)
{
sum += numbers[i] + numbers[i + 1];
avg = sum / 2;
}
averageArray = averageArray.Append(avg).ToArray();
}
return averageArray;
}
public static void Main()
{
int[] testArray1 = { 2, 2, 2, 2 };
Console.WriteLine(Averages(testArray1));
}
}
Ok, so, couple of things that need to be considered with your code. How you have it right now will throw an out of range exception.
You should never be able to have a null object in your int array so thats not a check you need to do.
If you need it to accept nulls, you need to declare it as int?[]
The way you have your code now, the output \ return value is an array of 5 values, when you have 4 going in
2, 2, 2, 1, 0
void Main()
{
int[] testArray1 = { 2, 2, 2, 2, };
Console.WriteLine(Averages(testArray1));
}
public static double[] Averages(int[] numbers)
{
double[] averageArray = new double[0];
for (int i = 0; i <= numbers.Length; i++)
{
double sum = 0;
double avg = 0; // This will cause a last object to be added to your array
if (i == numbers.Length - 1) // This adds the last item, this also needs to have order or preference as this would also then cause a Index Out of Range Exception
{
sum += numbers[i];
}
else if(i <= numbers.Length -1) // This adds all items that are not the last item in the array
{
sum += numbers[i] + numbers[i + 1];
}
avg = sum / 2;
averageArray = averageArray.Append(avg).ToArray();
}
return averageArray;
}

How do I get rid of circular numbers in my list

Okay, I know that this code is crude, and all around a messy, but I am no programmer, so bear with me. I have this code that lists a bunch of numbers, but I want it to not list any circular copies of the numbers.
For example, if the number 111262 is on my list, I don't want 112621, 126211, 262111, 621112, or 211126 to be listed.
Sorry, that number cannot be on the list.
For a true example, if the number 111252 is on my list, I don't want 112521, 125211, 252111, 521112, or 211125 to be listed.
Any help is appreciated!
namespace Toric_Classes
{
class Program
{
static void Main(string[] args)
{
int number_of_perms=0;
bool badsubsum1;
bool badsubsum2;
int subsum1 = 0;
int subsum2 = 0;
int sum = 0;
int class_length=6;
int[] toric_class=new int[class_length];
// The nested for loops scroll through every possible number of length class_length, where each digit can have a value of 1,2,..., or class_length-1
// Each number is looked at as an array, and is not stored anywhere, only printed if it satisfies certain conditions
for(int i1=1; i1<class_length; i1++)
{
toric_class[0] = i1;
for (int i2 = 1; i2 < class_length; i2++)
{
toric_class[1] = i2;
for (int i3 = 1; i3 < class_length; i3++)
{
toric_class[2] = i3;
for (int i4 = 1; i4 < class_length; i4++)
{
toric_class[3] = i4;
for (int i5 = 1; i5 < class_length; i5++)
{
toric_class[4] = i5;
for (int i6 = 1; i6 < class_length; i6++)
{
badsubsum1 = false;
badsubsum2 = false;
toric_class[5] = i6;
// Find the value of the sum of the digits of our array.
// We only want numbers that have a total digit sum being a multiple of class_length
for (int k = 0; k < class_length; k++)
{
sum += toric_class[k];
}
// The follwong two nested loops find the value of every contiguous subsum of our number, but not the total subsum.
// We *do not* want any subsum to be a multiple of class_length.
// That is, if our number is, say, 121342, we want to find 1+2, 1+2+1, 1+2+1+3, 1+2+1+3+4, 2+1, 2+1+3, 2+1+3+4, 2+1+3+4+2, 1+3, 1+3+4, 1+3+4+2, 3+4, 3+4+2, and 4+2
// The following checks 1+2, 1+2+1, 1+2+1+3, 1+2+1+3+4, 2+1, 2+1+3, 2+1+3+4, 1+3, 1+3+4, and 3+4
for (int i = 0; i < class_length - 1; i++)
{
for (int j = i + 1; j < class_length - 1; j++)
{
for (int k = i; k < j; k++)
{
subsum1 += toric_class[k];
}
if (subsum1 % class_length == 0)
{
badsubsum1 = true;
break;
}
subsum1 = 0;
}
}
// The following checks 2+1, 2+1+3, 2+1+3+4, 2+1+3+4+2, 1+3, 1+3+4, 1+3+4+2, 3+4, 3+4+2, and 4+2
for (int i = 1; i < class_length; i++)
{
for (int j = i + 1; j < class_length; j++)
{
for (int k = i; k < j; k++)
{
subsum2 += toric_class[k];
}
if (subsum2 % class_length == 0)
{
badsubsum2 = true;
break;
}
subsum2 = 0;
}
}
// We only want numbers that satisfies the following conditions
if (sum % class_length == 0 && badsubsum1 == false && badsubsum2 == false)
{
foreach (var item in toric_class)
{
Console.Write(item.ToString());
}
Console.Write(Environment.NewLine);
number_of_perms++;
}
sum = 0;
subsum1 = 0;
subsum2 = 0;
}
}
}
}
}
}
Console.WriteLine("Number of Permuatations: "+number_of_perms);
Console.Read();
}
}
}
EDIT
To clarify, I am creating a list of all numbers with length n that satisfy certain conditions. Consider the number d1d2...dn, where each di is a digit of our number. Each di may have value 1,2,...,n. Our number is in the list if it satisfies the following
The sum of all the digits is a multiple of n, that is,
d1+d2+...+dn = 0 mod n
Every contiguous subsum of the digits is not a multiple of n, aside from the total sum, that is, if i !=1 and j != n, then
di+d(i+1)+...+dj != 0 mod n
I should mention again that a "number" does not strictly use the numbers 0-9 in its digits. It may take any value between 1 and n. In my code, I am using the case where n=6.
The code works by creating an array of length class_length (in the code above, I use class_length=6). We first have 6 nested for loops that simply assign values to the array toric_class. The first for assigns toric_class[0], the second for assigns toric_class[1], and so on. In the first go around, we are generating the array 111111, then 111112, up to 111115, then 111121, etc. So essentially, we are looking at all heximal numbers that do not include 0. Once we reach our sixth value in our array, we check the array toric_class and check its values to ensure that it satisfies the above conditions. If it does, we simply print the array in a line, and move on.
Here is my easy and inefficient way that should work with minimal changes to your code. It requires shared string list var strList = new List<string>(); to store the used numbers. Then this part:
foreach (var item in toric_class)
{
Console.Write(item.ToString());
}
Console.Write(Environment.NewLine);
number_of_perms++;
becomes something like this:
string strItem = " " + string.Join(" ", toric_class) + " "; // Example: int[] {1, 12, 123} becomes " 1 12 123 "
if (!strList.Any(str => str.Contains(strItem))) // Example: if " 1 12 123 1 12 123 " contains " 1 12 123 "
{
Console.WriteLine(strItem);
strItem += strItem.Substring(1); // double the string, but keep only one space between them
strList.Add(strItem);
}
number_of_perms++; // not sure if this should be in the if statement
The idea is that for example the string " 1 1 1 2 5 2 1 1 1 2 5 2 " contains all circular copies of the numbers {1, 1, 1, 2, 5, 2}. I used string as a lazy way to check if array contains sub-array, but you can use similar approach to store copy of the used numbers in a list of arrays new List<int[]>() and check if any of the arrays in the list is circular copy of the current array, or even better HashSet<int[]>() approach similar to #slavanap's answer.
The first version of my answer was the easiest, but it works only with array of single digit items.
List is almost the same as array (new List<string>() instead of new string[]), but makes it much easier and efficient to add items to it. For example {1,2}.Add(3) becomes {1,2,3}.
str => str.Contains(strItem) is shortcut for a function that accepts parameter str and returns the result of str.Contains(strItem). That "function" is then passed to the .Any LINQ extension, so
strList.Any(str => str.Contains(strItem))
is shortcut for something like this:
foreach(string str in strList)
{
if (str.Contains(strItem))
{
return true;
}
}
return false;
The following method:
private static List<int> GetCircularEquivalents(int value)
{
var circularList = new List<int>();
var valueString = value.ToString();
var length = valueString.Length - 1;
for (var i = 0; i < length; i++)
{
valueString = valueString.Substring(1, length) + valueString.Substring(0, 1);
circularList.Add(int.Parse(valueString));
}
return circularList;
}
will return a list of the circular numbers derived from the input value. Using your example, this method can be called like this:
var circularList = GetCircularEquivalents(111262);
var dirtyList = new List<int> { 1, 112621, 2, 126211, 3, 262111, 4, 621112, 5, 211126, 6 };
var cleanList = dirtyList.Except(circularList).ToList();
which would result in a cleanList made up of the numbers 1 through 6, i.e. the dirtyList with all the circular numbers derived from 111262 removed.
That's where OOP really benefits. Comments inlined.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3 {
struct MyInt : IEquatable<MyInt> {
private int _value;
public MyInt(int value) {
_value = value;
}
// make it look like int
static public implicit operator MyInt(int value) {
return new MyInt(value);
}
public static explicit operator int(MyInt instance) {
return instance._value;
}
// main difference in these 3 methods
private int GetDigitsNum() {
int temp, res;
for (res = 0, temp = Math.Abs(_value); temp > 0; ++res, temp /= 10);
return res;
}
public bool Equals(MyInt other) {
int digits = other.GetDigitsNum();
if (digits != this.GetDigitsNum())
return false;
int temp = other._value;
// prepare mul used in shifts
int mul = 1;
for (int i = 0; i < digits - 1; ++i)
mul *= 10;
// compare
for (int i = 0; i < digits; ++i) {
if (temp == _value)
return true;
// ROR
int t = temp % 10;
temp = temp / 10 + t * mul;
}
return false;
}
public override int GetHashCode() {
// hash code must be equal for "equal" items,
// that's why use a sum of digits.
int sum = 0;
for (int temp = _value; temp > 0; temp /= 10)
sum += temp % 10;
return sum;
}
// be consistent
public override bool Equals(object obj) {
return (obj is MyInt) ? Equals((MyInt)obj) : false;
}
public override string ToString() {
return _value.ToString();
}
}
class Program {
static void Main(string[] args) {
List<MyInt> list = new List<MyInt> { 112621, 126211, 262111, 621112, 211126 };
// make a set of unique items from list
HashSet<MyInt> set = new HashSet<MyInt>(list);
// print that set
foreach(int item in set)
Console.WriteLine(item);
}
}
}
Output:
112621

Store value from a whileloop into an array then sum the array

I'm trying to store an unknown amount of data into an array, while using a forloop to get data! My task is to find and sum all the numbers form 1 to 1000 that can be divided be 3 and 5.
for (int i = 1; i < 1001; i++)
if (i%3==0)
{
if (i%5==0)
{
//this doesn't work, have tried to convert it to string, didn't work either
int[] array = { i };
//trying to loop the values
for (int j = 0; j < array.Length; i++)
{
//how can I loop this so I dont have to write it all out?
int sum1 = array[j]
}
}
}
Console.ReadKey();
Just because computers can perform repetitive task well doesn't mean you ignore Mathematics. If I got it right, you are trying to find the sum of all the numbers less than 1000 which are divisible by both 3 and 5. So that boils down to all the multiples of 15. Now if you take the floor of 1000/15, you get the the last multiple, which in this case is 66. So, you have to sum the series:
15, 15*2, 15*3,...15*66
=15*(1+2+3+..+66) [15*sum of first 66 positive natural numbers]
=15*66*67/2
So generalizing, finding sum of all numbers less than a and divisible by b is given by:
limit = floor(a/b);
sum = b*limit*(limit+1)/2;
Something like this:
var ListOfInts=new List<int>();
for (int i = 1; i < 1001; i++) {
if (i % 3 == 0 && i % 5 == 0)
ListOfInts.Add(i);
}
var result = ListOfInts.Sum();
Perhaps this code does what you want:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<int> li = new List<int>();
for (int i = 1; i <= 1000; i++)
{
if (i%3 == 0 && i%5 == 0)
{
li.Add(i);
}
}
Console.Write("sum is " + li.Sum());
Console.ReadLine();
}
}
}
The number devides by 3 and 5 means it devides by 15. So you can start iterating from 15 and incrementing by 15 to skip some iterations:
int sum = 0;
for (int i = 15; i <= 1000; i += 15)
sum += i;
Thanks guys! Alot of good answers, i'm still trying to understand some of them but thanks :)
How come that
List<int> li = new List<int>();
for (int i = 1; i <= 1000; i++)
{
if (i%3 == 0 && i%5 == 0)
{
li.Add(i);
}
}
Console.Write("sum is " + li.Sum());
Console.ReadLine();
give me this
while the code down under
var ListofInts = new List<int>();
for (int i = 0; i < 1001; i++)
{
if (i%3==0 && i%5==0)
{
ListofInts.Add(i);
var result = ListofInts.Sum();
Console.Write(result + ", ");
}
}
gives me this?

Array duplicate deletion in C#

This is my code so far I have display all items in the array as the user enters and create an error message for duplicate numbers that deletes the duplicate and continues the loop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace midterm
{
class Program
{
static void Main(string[] args)
{
int size;
Console.WriteLine("How many numbers will you enter?");
size = Convert.ToInt32(Console.ReadLine());
int[] numbers = new int[size];
int i;
for (i = 0; i < size; i++)
{
Console.WriteLine("Enter number: ");
numbers[i] = Convert.ToInt32(Console.ReadLine());
}
for (i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (i != j)
{
if (numbers[j] == numbers[i])
{
int k = j;
while (k < size - 1)
{
numbers[k] = numbers[k + 1];
k++;
}
size--;
}
}
}
}
Console.WriteLine("Duplicate Removed:");
for (i = 0; i < size; i++)
{
Console.WriteLine(numbers[i]);
}
Console.ReadLine();
}
}
}
Every time I go to change the for loops around or add an error message then the program stops deleting the duplicates I am really stumped on this one can someone lend me a hand.
Have a look at LINQ, it has some great functions that can be used for collection manipulation. In your situation I would do the following:
Distinct() here filters the array to only unique values.
int[] initialArray = new int[] { 1, 1, 2, 3, 4, 5 };
int[] noDuplicates = initialArray.Distinct().ToArray(); // [1,2,3,4,5]
I would recommend using a List instead of array. A List will allow you to keep adding entries to it without having to specify the size.
With the list, you can check if entry exists already before adding it, so you wont have to remove or delete
Easy way, use a HashSet
HashSet<int> mySet = new HashSet<int>();
//...
for (i = 0; i < size; i++)
{
Console.WriteLine("Enter number: ");
int number = Convert.ToInt32(Console.ReadLine());
if (!mySet.Add(number))
{
Console.WriteLine("That was a duplicate. Try again");
i--;
}
}
If you must use arrays:
for (i = 0; i < size; i++)
{
Console.WriteLine("Enter number: ");
int numbers = Convert.ToInt32(Console.ReadLine());
if (ExistsInArray(number, numbers))
{
Console.WriteLine("That was a duplicate. Try again");
i--;
}
else
{
numbers[i] = number;
}
}
And then:
private static bool ExistsInArray(number, numbers)
{
// Your code to search numbers for number and return true if found
// Left as an exercise for the OP
}
One important note here is that it's a lot easier to check whether your array already contains the element you are trying to add than to remove it after the fact. If it already exists, just don't add it again.

A logic issue regarding a very simple solution that performs the factorizing function

This solution factorizes a number (numInput), it works perfectly well except for a logic error I can't seem to find no matter how much I track the solution. The logic error causes the returned result to be 0 no matter the value initialized for numInput.
using System;
namespace factorizer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(factorialise());
Console.ReadKey();
}
private static int factorialise()
{
int numInput = int.Parse(Console.ReadLine());
int[] number = new int[numInput];
for (int i = 1; i < numInput; i++) //stores the (n-1)...(n-i) value for the number input'd in the array number[i]
{
number[i - 1] = numInput - i; //the element indicating the index number is 'i - 1' index values start from zero
}
for (int index = 0; index < number.Length; index++) //multiplies the element corresponding the index number with the number input'd
{
numInput = numInput * number[index];
}
return numInput;
}
}
}
Your last item in array stays uninitialized (i.e. equal to zero). Change items count:
int[] number = new int[numInput-1];
Also why not simply use for loop?
int result = 1;
for(int i = 1; i <= numInput; i++)
result *= i;
And another sample just for fun
Enumerable.Range(1, numInput).Aggregate(1, (a,i) => a * i)

Categories