Related
I want to make a function that takes an array of integers as input and print an array of int as Fibonaci series like: third element= second element + first element.
Here is my code so far:
static void Result(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] < 0)
Console.WriteLine("arr[i]", arr[i], " number to get must be greater or equal than 0");
var n = arr[i] + 1;
var a = new int[n];
arr[0] = 0;
if (arr[i] == 0)
{
a[1] = 1;
}
for ( i = 2; i < n; i++)
{
a[i] = a[i - 2] + a[i - 1];
}
}
}
public static void Main()
{
int[] arr = {7, 8, 3, 9, 11,16,14,91, };
Result(arr);
}
if input is : 1 ,3 ,4 ,6, 7 ,8 10, 11, 15 ,25 output should be: 1, 3, 4, 7, 11 so 1+3=4, 4+3=7 and so on.
I took a look at your code and you were very close.
The biggest issue was you were starting at i = 0 which would cause errors if you attempted to access arr[-1] and arr[-2].
We can solve that by starting with i = 2.
For example:
static int[] Result(int[] arr)
{
int[] result = arr;
for (int i = 2; i < arr.Length; i++)
{
result[i] = result[i-1] + result[i-2];
}
return result;
}
int[] arr = { 1 ,3 ,4 ,6, 7 ,8, 10, 11, 15 ,25 };
arr = Result(arr);
Console.WriteLine(string.Join(", ",arr));
// outputs: 1, 3, 4, 7, 11, 18, 29, 47, 76, 123
Another side note is that unless you're passing the int[] arr as a reference you will need to return a new int[] as the result since Result()'s changes to arr are not reflected on the array.
Let's say I have an array with integers, which represent the daily changes in the price of a stock, as an example the following array:
[3, -1, -4, 1, 5, -9, 2, 6].
How would I find the amount of subarrays which have a sum between two values (lower and upper, so l <= s <= u), such as -1 (=lower) and 0 (=upper)? In this case, the answer would be 5. You can have the subarrays
[3, -1, -4, 1]
[-1]
[-1, -4, 1, 5, -9, 2, 6]
[1, 5, -9, 2]
[-9, 2, 6]
Another example array would be:
[4, 2, 2, -6, 7]
with lower bound 3, upper bound 4. The answer to this would be 3. I have tried the following very naïve approach, which I'm certain there are many faster alternatives for. I'm wondering how I can solve this problem faster, with divide-and-conquer or possibly through dynamically programming.
Class
public class Stock
{
public int sequenceLength;
public int[] prices;
public int lowerBound;
public int upperBound;
public int count = 0;
public Stock()
{
sequenceLength = Int32.Parse(Console.ReadLine());
prices = new int[sequenceLength];
var split = Console.ReadLine();
var splitSpace = split.Split(' ');
for (int i = 0; i < sequenceLength; i++)
prices[i] = Int32.Parse(splitSpace[i]);
lowerBound = Int32.Parse(Console.ReadLine());
upperBound = Int32.Parse(Console.ReadLine());
}
}
Usage
static void Main(string[] args)
{
int testcases = Int32.Parse(Console.ReadLine());
Stock[] stock = new Stock[testcases];
for (int i = 0; i < testcases; i++)
stock[i] = new Stock();
int count = 0;
for (int i = 0; i < stock.Length; i++)
{
for (int j = 0; j < stock[i].sequenceLength - 1; j++)
{
int sum = stock[i].prices[j];
if (sum >= stock[i].lowerBound && sum <= stock[i].upperBound)
count++;
for (int k = j + 1; k < stock[i].sequenceLength; k++)
{
sum += stock[i].prices[k];
if (sum >= stock[i].lowerBound && sum <= stock[i].upperBound)
count++;
}
}
if (stock[i].prices[stock[i].sequenceLength - 1] >= stock[i].lowerBound && stock[i].prices[stock[i].sequenceLength - 1] <= stock[i].upperBound)
count++;
stock[i].count = count;
count = 0;
}
Console.Clear();
for (int i = 0; i < stock.Length; i++)
Console.WriteLine(stock[i].count);
}
There's already an answer with O(N^2) complexity, I'll propose a O(NlogN) solution.
Create an array sums, where sums[0] = array[0] and sums[i] = sums[i-1]+array[i]. Now, for each index i in sums, you need to find number of indexes j such that sums[i] - sums[j] is in range [lower, upper]. But how to find number of indexes j?
Create a balanced binary search tree (AVL tree). Insert sums[0] in it. Start processing nodes from left to right. After processing a node, add it to the tree. You can search for the number of indexes in range [lower, upper] in O(logN) complexity, and same applies for the insertion as well. That will give you a total time complexity of O(NlogN).
If I understand the problem (and the jury is out)
The premise is, the first loop works its way across the array. The second loop is in charge of keeping a sum and checking the range, then yielding the result
Obviously this is O(n2) time complexity
Given
public static IEnumerable<int[]> GetSubs(int[] source, int lower, int upper)
{
for (var i = 0; i < source.Length; i++)
for (int j = i, sum = 0; j < source.Length; j++)
{
sum += source[j];
if (sum >= lower && sum <= upper)
yield return source[i..(j+1)];
}
}
Usage
var array = new[] { -5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6, 7, 8, 9 };
foreach (var sequence in GetSubs(array,2,5))
Console.WriteLine($"{sequence.Sum()} : [{string.Join(", ", sequence)}]");
Output
5 : [-5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6]
4 : [-4, -3, -2, -1, 0, 2, 3, 4, 5]
3 : [-3, -2, -1, 0, 2, 3, 4]
2 : [-2, -1, 0, 2, 3]
4 : [-1, 0, 2, 3]
2 : [0, 2]
5 : [0, 2, 3]
2 : [2]
5 : [2, 3]
3 : [3]
4 : [4]
5 : [5]
Full Demo Here
Note : You could probably do this in linq with Enumerable.Range, however this is pretty easy to understand
If you just wanted the count, you could remove the iterator all together, and just increment a counter when the if condition is true
public static int GetSubs(int[] source, int lower, int upper)
{
var result = 0;
for (var i = 0; i < source.Length; i++)
for (int j = i, sum = 0; j < source.Length; j++)
{
sum+= source[j];
if (sum >= lower && sum <= upper)
result++;
}
return result;
}
I need to solve a problem in which I need to split arrays into two sub-arrays such that the sum of their weights will be equal or "nearly equal".
Explanation
If I have an array [1,2,3,4,5] so I can possibly make two subsets of [1,2,4] = 7 and [3,5] = 8 OR [2,5] = 7 and [1,3,4] = 8.
I have done that part but by dry run i got to know that if i have even number of digits in the set of array then it always gives me wrong answers.
This program only works for odd number of digits. What am i missing?
using System.IO;
using System;
class Program
{
static void Main()
{
int[] a = {1,2,3,4};
int t;
Console.WriteLine("Original array :");
foreach (int aa in a)
Console.Write(aa + " ");
for (int p = 0; p <= a.Length - 2; p++)
{
for (int i = 0; i <= a.Length - 2; i++)
{
if (a[i] > a[i + 1])
{
t = a[i + 1];
a[i + 1] = a[i];
a[i] = t;
}
}
}
Console.WriteLine("\n" + "Sorted array :");
foreach (int aa in a)
Console.Write(aa + " ");
Console.Write("\n");
// int[] arr = new int[5] { 99, 95, 93, 89, 87 };
int z, max, min, n;
// size of the array
n = 4;
max = a[0];
min = a[0];
for (z = 1; z < n; z++)
{
if (a[z] > max)
{
max = a[z];
}
if (a[z] < min)
{
min = a[z];
}
}
Console.Write("Maximum element = {0}\n", max);
Console.Write("Minimum element = {0}\n\n", min);
int e = 0;
int f = 0;
int g = 0;
for(int i = 0; i < n; i++)
{
g = f - e;
int mm = max - min;
{
if(g > mm)
{
e += a[i];
}
else if(g < mm)
{
f += a[i];
}
}
min++;
}
Console.Write("The possible solution is:\n ");
Console.Write("First array = {0}\n", e);
Console.Write("Second array = {0}\n\n", f);
Console.ReadLine();
}
}
Here's a code snippet that might help:
var arr = new[] { 1, 2, 3, 4 };
var lst1 = new List<int>();
var lst2 = new List<int>();
var div = Math.DivRem(arr.Sum(), 2, out _);
foreach (var i in arr.OrderByDescending(x => x))
{
if (lst1.Sum() + i <= div)
lst1.Add(i);
else
lst2.Add(i);
}
Console.WriteLine(string.Join(", ", lst1.OrderBy(x => x)));
Console.WriteLine(string.Join(", ", lst2.OrderBy(x => x)));
Some outputs of:
{ 1, 2, 3, 4 }
1, 4
2, 3
{ 1, 2, 3, 4, 5 }
2, 5
1, 3, 4
{ 1, 2, 3, 4, 5, 6 }
4, 6
1, 2, 3, 5
So we iterated through the source array (arr) in a descending order to add numbers into lst1 if the sum of it's contents still less than or equal to the quotient of dividing the sum of the main array by 2, otherwise we add them (the numbers) into lst2 where the sum of it's numbers is equal or nearly equal to the mentioned quotient.
As a result, you have two lists where the sum of their contents are equal or nearly equal.
Below code will split array into 2 with equal sum or least difference in sum.
Apologies for lengthy solution, but it works perfectly for all combinations of odd and even.
Explicit names of variables and functions will help you to understand the logic.
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main(string[] input)
{
int[] a = {1, 2, 9, 26, 3, 4, 12, 7, 5};
int t;
Console.WriteLine("Original array :" + string.Join(", ", a));
for (int p = 0; p <= a.Length - 2; p++)
{
for (int i = 0; i <= a.Length - 2; i++)
{
if (a[i] > a[i + 1])
{
t = a[i + 1];
a[i + 1] = a[i];
a[i] = t;
}
}
}
Console.WriteLine("\n\nSorted array :" + string.Join(", ", a));
// Newly added code starts
int[] sortedArray = a;
List<int> array1 = new List<int>();
List<int> array2 = new List<int>();
for (int index = sortedArray.Length-1 ; index >=0 ; index-- )
{
if (array1.Sum() < array2.Sum())
{
array1.Add(sortedArray[index]);
}
else if (array1.Sum() > array2.Sum())
{
array2.Add(sortedArray[index]);
}
else
{
array1.Add(sortedArray[index]);
}
}
BalanceArray(array1, array2);
array1.Sort();
array2.Sort();
Console.WriteLine("\n\nArray1 { " + string.Join(", ", array1) + " }\tSum => " + array1.Sum());
Console.WriteLine("\n\nArray2 { " + string.Join(", ", array2) + " }\tSum => " + array2.Sum());
}
private static void BalanceArray(List<int> array1, List<int> array2)
{
int sumOfArray1 = array1.Sum();
int sumOfArray2= array2.Sum();
int difference = (sumOfArray1 < sumOfArray2) ? sumOfArray2- sumOfArray1 : sumOfArray1 - sumOfArray2;
if ( sumOfArray1 < sumOfArray2 )
{
SwapNumber(array2, array1, difference);
}
else if ( sumOfArray1 > sumOfArray2 )
{
SwapNumber(array1, array2, difference);
}
}
private static void SwapNumber(List<int> biggerArray,List<int> smallerArray, int difference)
{
//Console.Write("\n Difference :" + difference);
int expectedDifference = difference /2;
//Console.Write("\n Expected Difference :" + expectedDifference );
int lowerNoToSwap = 0;
int higherNoToSwap = 0;
for(int i=0; i < biggerArray.Count(); i++ )
{
if(biggerArray[i] <= expectedDifference)
{
lowerNoToSwap = biggerArray[i];
}
else if(biggerArray[i] > expectedDifference)
{
higherNoToSwap = biggerArray[i];
break;
}
}
if(lowerNoToSwap <= higherNoToSwap)
{
bool swapLower = (expectedDifference - lowerNoToSwap) < (higherNoToSwap - expectedDifference) ? true : false;
int numberToSwap = swapLower ? lowerNoToSwap : higherNoToSwap;
if(numberToSwap != 0)
{
smallerArray.Add(numberToSwap);
smallerArray.Sort();
biggerArray.Remove(numberToSwap);
}
}
}
}
Example 1
Original array :1, 2, 3, 4
Sorted array :1, 2, 3, 4
before Array1 { 4, 1 } Sum => 5
before Array2 { 3, 2 } Sum => 5
Array1 { 1, 4 } Sum => 5
Array2 { 2, 3 } Sum => 5
Example 2
Original array :1, 2, 3, 4, 5
Sorted array :1, 2, 3, 4, 5
Array1 { 3, 5 } Sum => 8
Array2 { 1, 2, 4 } Sum => 7
Example 3
Original array :1, 2, 9, 26, 3, 4, 12, 7, 5
Sorted array :1, 2, 3, 4, 5, 7, 9, 12, 26
Array1 { 1, 3, 5, 26 } Sum => 35
Array2 { 2, 4, 7, 9, 12 } Sum => 34
I want to create an subset from an array
array =[-2,1,3,-4,5]
I want the subset like this below.
[-2, 3, 5] [-2, 3] [-2, -4] [-2, 5] [1, -4] [1, 5] [3, 5]
-before the elements should be skipped one element
-2,3,5
1 -4
3.5
-then for each element, one neighbor should be skipped and the others taken one by one, forming pairs (without repeating the above)
-2,3
-2, -4
-2.5
1, -4 (do not take above have)
3.5 ((we do not have above)
-1.5
//This is my code.
static void Main(string[] args)
{
int[] kume = { -3, 4, 5, 6, 7};
String[] altkume = new string[10];
String s = "";
for(int m = 0; m<7; m++)
{
int b = m;
s += "[";
for (int j = 0; j < kume.Length; j += 2)
{
if ((b & 1) == 0)
{
s += kume[j].ToString() + ",";
}
b = b >> 1;
}
s += "]" + "\n";
altkume[m] = s;
}
for(int i = 0; i<altkume.Length; i++)
{
Console.WriteLine(altkume[i]);
}
Console.ReadKey();
}
Output:
[-3,5,7,]
[5,7,]
[-3,7,]
[7,]
[-3,5,]
[5,]
[-3,]
But i dont want like this [5,] [-3,] [7,]
I talked about problem. does anyone help ?
I've made a handy extension that will return the output you seek:
public static class Extensions
{
public static IEnumerable<List<T>> GetNonAdjacentSubsets<T>
(
this IEnumerable<T> source, // the collection we are evaluating
int min_distance, // minimum gap between numbers
List<T> subset = null // stores the progress of the subset we are evaluating
)
{
for (int i = 0; i < source.Count(); i++)
{
var new_subset = new List<T>(subset ?? Enumerable.Empty<T>())
{
source.ElementAt(i)
};
if (new_subset.Count > 1) //return subsets of more than one element
yield return new_subset;
if (source.Count() < 2) //end of list reached
yield break;
foreach (var ss in source.Skip(i + min_distance).GetNonAdjacentSubsets(min_distance, new_subset))
yield return ss;
}
}
}
Usage:
var arr = new int[] { -2, 1, 3, -4, 5 };
var subsets = new List<List<int>>(arr.GetNonAdjacentSubsets(2));
Output:
-2, 3
-2, 3, 5
-2, -4
-2, 5
1, -4
1, 5
3, 5
I have an int array in one dimension:
var intArray=new[] { 1, 2, 3, 4, 5, 6 };
and I want to convert it to two dimensions, such as:
var intArray2D=new[,] { {1, 2}, {3, 4}, {5, 6} };
How do I achieve this with C#?
with a loop perhaps:
for (int i = 0; i < oldArr.Length; i=i+2)
{
newArr[i/2, 0] = oldArr[i];
newArr[i/2, 1] = oldArr[i + 1];
}
Untested, but should get you pointed in the right direction...
If the one dimensional array contains the primitive data in row major order, and the total capacity of the 2 dimensional array equals the length of the one dimensional array, you can use this.
int[] source = new int[6];
int[,] target = new int[3, 2];
Buffer.BlockCopy(source, 0, target, 0, source.Length * sizeof(int));
Note that unlike Array.Copy and other array/list methods, Buffer.BlockCopy operates on a number of bytes of data, even if each element of the array is larger than 1 byte. It also only operates on arrays of primitive data types.
Additional references:
Multi-dimensional arrays are stored in row-major order (ECMA-335 Partition I, §8.9.1)
Buffer.BlockCopy
Edit: Here is a complete unit test.
[TestMethod]
public void SOTest16203210()
{
int[] source = new int[6] { 1, 2, 3, 4, 5, 6 };
int[,] destination = new int[3, 2];
Buffer.BlockCopy(source, 0, destination, 0, source.Length * sizeof(int));
Assert.AreEqual(destination[0, 0], 1);
Assert.AreEqual(destination[0, 1], 2);
Assert.AreEqual(destination[1, 0], 3);
Assert.AreEqual(destination[1, 1], 4);
Assert.AreEqual(destination[2, 0], 5);
Assert.AreEqual(destination[2, 1], 6);
}
I believe you want to split an integer array into an array of two integers each:
int[] list = new int[] { 1, 2, 3, 4, 5, 6};
int[][] newlist = new int[list.Length / 2][];
for (int i = 0, n = 0; i < list.Length; i += 2, n++)
{
newlist[n] = new[] { list[i], list[i + 1] };
}
To assign it to Points in particular you could try:
List<Point> plist = new List<Point>();
for (int i = 0; i < list.Length; i += 2)
{
plist.Add(new Point(list[i], list[i + 1]));
}
you may use this code. in here you can send any length you like. you can "deivde" the arry[] to arry[,] for any lenth.2 or 3 or what ever you like! as long as size % a.length ==0 !!!!
code
static int[,] convert(int[] a, int size)
{
int[,] value = new int[a.Length / size, size];
int counter = 0;
//
for (int b = 0; b < value.GetLength(0); b++)
for (int c = 0; c < value.GetLength(1); c++)
{
value[b, c] = a[counter];
counter++;
}
return value;
}
If the product of the dimensions are the same, the fastest way would probably be to pin the matrix using a fixed statement, then to use the Marshalling class to copy the continuous block from the array to an IntPtr created from the void* you got from the fixed.
You would have to wrap this in an unsafe statement and enable unsafe in the assembly's build config.
I have converted this from vb to c#
int Size = OldArray.Length;
int[,] NewPoints = null;
if (Size % 2 != 0) {
//Error - Array has odd number of elements!
} else {
for (i = 0; i <= Size - 1; i += 2) {
Array.Resize(ref AllPoints, (i / 2) + 1, 2);
NewPoints[i / 2, 0] = OldArray(i);
NewPoints[i / 2, 1] = OldArray(i + 1);
}
}
You could try this:
int [] a = {1,2,3,4,5,6};
int [,] b = new int[a.Length/2,2];
for(int i = 0;i<a.Length;i++)
{
b[i/2,i%2] = a[i];
}
Note that i/2 is an integer division, hence both 4/2 and 5/2 will give 2 which is a correct index in 2Darray for the tuple 5 and 6 from the original array. The second index is determined using reminder when divided by 2, it will give 0 if the index is even number and 1 if the index of the item from the original array is odd number.
I would consider this for any dimension of array:
public class TestClass {
public static void TestMethod2D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer2D=new ArrayIndexer<int>(3, 2);
for(var i=intLinear.Length; i-->0; indexer2D[i]=intLinear[i])
;
var int2D=(int[,])indexer2D.ToArray();
}
public static void TestMethod4D() {
var intLinear=new[] { 1, 2, 3, 4, 5, 6 };
var indexer4D=new ArrayIndexer<int>(2, 2, 2, 2);
for(var i=intLinear.Length; i-->0; indexer4D[i]=intLinear[i])
;
var int4D=(int[, , ,])indexer4D.ToArray();
}
}
public partial class ArrayIndexer<T> {
public Array ToArray() {
return m_Array;
}
public ArrayIndexer(params int[] lengths) {
m_Array=Array.CreateInstance(typeof(T), lengths);
}
public T this[params int[] indices] {
set {
m_Array.SetValue(value, indices.Transform(m_Array));
}
get {
return (T)m_Array.GetValue(indices.Transform(m_Array));
}
}
Array m_Array;
}
public static partial class ArrayExtensions {
public static int[] Transform(
this int[] indices, Array array, bool isRowMajor=true) {
if(indices.Length>array.Rank)
return indices;
else {
var list=indices.ToList();
if(isRowMajor)
list.Reverse();
for(int r, q=0, i=0, count=array.Rank; count-->0; ++i) {
var index=isRowMajor?count-i:i;
if(indices.Length>i) {
q=Math.DivRem(indices[i]+q, array.GetLength(index), out r);
list[i]=r;
}
else {
if(index<0) {
list.Add(q);
q=0;
}
else {
q=Math.DivRem(q, array.GetLength(index), out r);
list.Add(r);
}
}
}
if(isRowMajor)
list.Reverse();
return list.ToArray();
}
}
}
ArrayExtensions.Transform is an indices transformer, it performs the linear transformation with the geometry of a given array. isRowMajor controls the layout, such as you would regard an int[,] in x, y or in y, x order.