This question already has answers here:
How to split a number into individual digits in c#? [duplicate]
(6 answers)
Closed 9 years ago.
I'm getting integeres to my controller as 123456 in one variable.
Now I want to transform each number to separated from other with comma between as array of numbers as { 1, 2, 3, 4, 5 }.
Try this
var integers = "123456";
var enumOfInts = integers.ToCharArray().Select(x => Char.GetNumericValue(x));
try this:
int[] array = new int["123456".ToArray().Count()];
int i = 0;
foreach (var item in "123456".ToArray())
{
array[i++] = int.Parse(item.ToString());
}
or
int[] array = "123456".ToArray().Select(data=>(int)data).ToArray();
{
string s = "1234567890";
var lst = new List<int>();
for (int n = 0; n < s.Length; n++)
{
int x;
if (int.TryParse(s[n].ToString(), out x))
lst.Add(x);
}
int[] arr = lst.ToArray();
}
If you are getting parameter as string then
The Linq Way :
string str_num = "123456"
var arrayOfInts = str_num.ToCharArray().Select(x => x - 48).ToArray();
for the above Linq expression it has been assumed that all character are between 48 & 57
Non Linq Way :
int[] GetIntArray(string str_num)
{
int num = Int32.Parse(str_num);
List<int> listOfInts = new List<int>();
while(num > 0)
{
listOfInts.Add(num % 10);
num = num / 10;
}
listOfInts.Reverse();
return listOfInts.ToArray();
}
Solution extended from : How to split a number into individual digits in c#?
Related
I am partaking on an Amazon interview and they tasked us with this coding challenge, Given an integer array arr write code that will return the minimal subset of that array where the elements of the subset yield the higher value against the sum of the remaining subset. An example is the array 3,7,5,6,2, the code needs to return either two subsets, the first one being 5,7 which yields a maximal value of 12 against the sum of the remaining subset 3,6,2 which yields a maximal value of 11. The second one being 6,7 which will yield a maximal value of 13 against the remaining subset 3,5,2 which will yield a maximal value of 10. I think my code is failing at the minimal array elements that yield a maximal value.
The code I have tried is below but its only passing only two of the thirteen test cases.
The test page is a demo assessment but serves as a preparation for an actual test that will come later, help me write this code correctly to return the correct output.
public static List<int> minimalHeaviestSetA(List<int> arr)
{
List<int> sol = new List<int>();List<int> sec= new List<int>();
//try finding the two largest numbers in the array and add
int max=0;
foreach(int u in arr){
if(u>max){
max=u;
}
}
//add the maximum element to the list
//initialize the sum
int sum=0;
//remove the maximum element from the list
arr.Remove(max);
foreach(int p in arr){
if((p+max)>sum){
sum=p+max;
sec.Clear();
sec.Add(p);
}
}
sol.Add(sec[0]);
sol.Add(max);
return sol;
}
Some additional instruction from the site include
The intersection of subset A and B is null
The union of A and B returns the original array
The number of elements in subset A is minimal
The sum of subset A elements is greater than subset B elements
/*
* Given an integer array nums of length n and an integer target, find three integers in nums such that the sum is closest to target.
Return the sum of the three integers.
You may assume that each input would have exactly one solution.
Example 1:
Input: nums = [-1,2,1,-4], target = 1
Output: 2
Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
Example 2:
Input: nums = [0,0,0], target = 1
Output: 0
Constraints:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
*/
public class Tuples
{
public int sum;
public int[] Array;
public int distance;
}
public class _3SumClosest
{
public int[] input;
public _3SumClosest()
{
input = new int[] { -1, 2, 1, -4 };
}
public int ThreeSumClosest(int[] nums, int target)
{
//Get comnbination of all indexes of Array
double count = Math.Pow(2, nums.Length);
var list = new List<int>();
for (int i = 0; i < nums.Length; i++)
list.Add(i);
List<int[]> combinations = new List<int[]>();
for (int i = 1; i <= count - 1; i++)
{
string str = Convert.ToString(i, 2).PadLeft(nums.Length, '0');
List<int> temp = new List<int>(); ;
for (int j = 0; j < str.Length; j++)
{
if (str[j] == '1')
{
temp.Add(list[j]);
}
}
combinations.Add(temp.ToArray());
}
//filter combinations with 2sum, 3sum or nsum array combination. Dont filter if no requirement
//if you want 3 number combination
var tupleComb = combinations.Where(x => x.Length == 3);
List<Tuples> tupleList = new List<Tuples>();
foreach(var tuple in tupleComb)
{
var sum = nums[tuple[0]] + nums[tuple[1]] + nums[tuple[2]];
Tuples tp = new Tuples();
tp.sum = sum;
tp.Array = new int[] { nums[tuple[0]], nums[tuple[1]], nums[tuple[2]] };
tupleList.Add(tp);
}
var final = tupleList.Select(x => new Tuples() { sum = x.sum, Array = x.Array, distance = x.sum - target });
return final.OrderBy(x => x.distance).FirstOrDefault().sum;
}
}
Keep removing maximal elements from the list till the sum of elements in subset A return a value greater than the sum of the elements remaining in the original subset using a while loop, I used several test cases for testing the effectiveness of the code. There are functions to return the highest element and others to return the sum of elements in that list.
Console.WriteLine("Test Case 1");
int[] arr = new int[] { 9, 8, 7, 6 ,5,3};
List<int> soln = MinimalElements(arr.ToList());
if (soln != null)
{
foreach (var VARIABLE in soln)
{
Console.WriteLine(VARIABLE);
}
}
Console.WriteLine("Test Case 2");
int[] arr1 = new int[] { 3,5,7,0,11};
List<int> soln1 = MinimalElements(arr1.ToList());
if (soln != null)
{
foreach (var VARIABLE in soln1)
{
Console.WriteLine(VARIABLE);
}
}
Console.WriteLine("Test Case 3");
int[] arr2 = new int[]{0,9};
List<int> soln2 = MinimalElements(arr2.ToList());
if (soln2 != null)
{
foreach (var VARIABLE in soln2)
{
Console.WriteLine(VARIABLE);
}
}
Console.WriteLine("Test Case 4");
int[] arr3 = new int[] { 0, 17, 6, 10, 2 };
List<int> soln3 = MinimalElements(arr3.ToList());
if (soln3 != null)
{
foreach (var r in soln3)
{
Console.WriteLine(r);
}
}
//pseudocode
//get the first element of the array and compare with the sum of the
//remaining elements if its less than the sum of the remaining elements then
static List<int> MinimalElements(List<int> arr)
{
//check if the array contains elements
if (arr.Count() > 0)
{
//sort the array first
arr.Sort();
//create the return list
List<int> result = new List<int>();
//get the maximum of the original list and remove it
int max = MaxInTheList(arr);
//add the maximum to our list
result.Add(max);
//pop the element from the original collection
arr.Remove(max);
//loop through each list while comparing sum and keep adding elements until the sum of the
//resulting list is better than the elements removed from the original list
while (sumList(result) < sumList(arr))
{
int mm = MaxInTheList(arr);
//add the next biggest element to the array
result.Add(mm);
//keep reducing elements from arr
arr.Remove(mm);
}
//return a sorted integer array to the calling function
result.Sort();
return result;
}
else
{
//return an empty integer array
return new List<int>();
}
}
//define method to sum up all the elements of a list
static int sumList(List<int> arr)
{
int sum = 0;
foreach (var s in arr)
{
sum += s;
}
return sum;
}
//first get the maximum integer of each list using a method
static int MaxInTheList(List<int> arr)
{
int max = 0;
foreach (int u in arr)
{
if (u > max)
{
max = u;
}
}
return max;
}
Sorting arrays by absolute value using a input array refuses to work but replacing it with a simple array works. I have no idea why it doesn't work, I just don't see what is wrong.
I need the result to be like this:
Input: -5 4 8 -2 1
Output: 1 -2 4 -5 8
static void Main()
{
var sampleInput = Console.ReadLine().Split().Select(int.Parse).ToArray();
int[] x = sampleInput;
int n = sampleInput.Length;
int[] output = new int[n];
string sOutput = string.Empty;
int start = 0;
int last = n - 1;
while (last >= start)
{
n--;
if (Math.Abs(x[start]) > Math.Abs(x[last]))
{
output[n] = x[start++];
}
else
{
output[n] = x[last--];
}
sOutput = output[n].ToString() + " " + sOutput;
}
Console.Write(sOutput);
}
why not
using System.Linq;
var sorted = new [] {-5, 4, 8, -2 , 1}.OrderBy(Math.Abs);
(and of course to get an Array, you can tack on a .ToArray() at the end there).
And to pass what you want:
var sampleInput = Console.ReadLine().Split().Select(int.Parse).ToArray();
var sorted = sampleInput.OrderBy(Math.Abs);
Here is your solution.
var array = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
var sorted = array.OrderBy(Math.Abs);
foreach (int element in sorted)
{
Console.WriteLine(element);
}
Kind regards,
A classmate?
I want to combine an integer array to a single integer value. So I have the following code that will combine the array to a single value.
int[] array = { 5, 6, 2, 4 };
int combine = 0;
for (int i = 0; i < array.Length; i++)
{
combine += array[i] * Convert.ToInt32(Math.Pow(10, array.Length-i-1));
}
this yield combine = 5624. Which is correct.
My issue is my array is not in the form of 0-9. So my array could be {51,62,23,44}
int[] array = { 51, 62, 23, 44 };
int combine = 0;
for (int i = 0; i < array.Length; i++)
{
combine += array[i] * Convert.ToInt32(Math.Pow(10, array.Length-i-1));
}
yielding combine as 574774, not 51622344. How would I correct this?
Do the following:
var number = int.Parse(string.Join("", array));
Explanation:
string.Join will take any enumeration of type T, call ToString() on each member and join them in a single string with the specified separator.
Once you have a string representing your number, you simply parse it to get the number itself.
Of course this is not safe and depending on your possible inputs, this could fail: {1, 4, -5, 4 }. Some error detection and int.TryParse is probably the best way to solve this, the example is simply to get the idea across.
Why not convert them to strings and then concatenate?
using System;
public class Program
{
public static void Main()
{
int[] intArray = { 5, 6, 2, 4 };
var result = string.Concat(intArray);
Console.WriteLine(result);
try {
int resultNumber = int.Parse(result);
}
catch(OverflowException) {
// this can occur if you exceed the maximum value of an int
long resultBigNumber = long.Parse(result);
}
}
}
Try using a StringBuilder, like this:
using System;
using System.Text;
public class Program {
public static void Main(string[] args) {
StringBuilder sb = new StringBuilder();
int[] array = new Int[] { 51, 62, 23, 44 };
int combine = 0;
foreach(int single in array) {
string oneNum = single.ToString();
sb.Append(oneNum);
}
string final = sb.ToString();
combine = Convert.ToInt32(final);
}
}
This will convert the numbers in the array into a string, which then gets converted into a number.
Linq and some simple math can help here (without strings or Math.Pow). I'm also going to seed it with numbers of widely varying magnitude (i.e., not all single digit numbers or all 2-digit numbers). First some preliminary code:
private readonly int[] PowersOf10 = new [] {10, 100, 1000, 10000, 100000};
private int DecimalShiftAccumulate(int numToShift, int numToAdd)
{
var nextPowerOf10 = PowersOf10.First(x => x > numToAdd);
return (numToShift * nextPowerOf10) + numToAdd;
}
You can include more numbers in the PowersOf10 array; I got tired of counting zeros.
Then declare your int array and calculate the result:
var intArray = new[] { 1051, 7, 923, 44 };
var arrayResult = intArray.Aggregate((a, b) => DecimalShiftAccumulate(a, b));
I get arrayesult = 1051792344 (i.e. (using & as concatenation) 1051 & 7 & 923 & 44)
In my C# program, I have an int array containing a set of integers and occasionally duplicates of those integers. I want to create an array that only contains the numbers that exist as duplicates in the initial array, but in itself contains no duplicates. Based on my newbie understanding of C# I thought that the following code would do the trick:
int a = 9;
int b = 6;
int c = 3;
int index = 0;
int[] mltpls = new int[a + b + c];
while (a > 0)
{
mltpls[index] = 2 * a;
a -= 1;
index += 1;
}
while(b > 0)
{
mltpls[index] = 3 * b;
b -= 1;
index += 1;
}
while(c > 0)
{
mltpls[index] = 5 * c;
c -= 1;
index += 1;
}
int[] mltpls_unique = mltpls.Distinct().ToArray();
int[] mltpls_dplcts = mltpls.Except(mltpls_unique).ToArray();
Console.WriteLine(mltpls_dplcts);
//EDIT
//By running the following code I can write out all numbers in "mltpls"
for (int i = 0; i < mltpls.Length; i++)
{
Console.Write(mltpls[i] + ", ");
}
/*If I try to run equivalent code for the "mltpls_dplcts" array nothing
only a blank line is displayed.*/
When I run this goal my the final result of my console application is a blank row. My interpretation of this is that the array mltpls_dplcts is empty or that I'm incorrectly going about printing the array.
How do get only the duplicate values from an array?
My interpretation of this is that the array mltpls_dplcts is empty or that I'm incorrectly going about printing the array.
Both interpretations are correct
Distinct will return every item that is at least once present in mltps. If you now apply Except you get nothing because all items that are in mltpls_unique are also present in mltps. The items in the array are compared by value, so for Except it does not matter whether a number occurs multiple times in the other array. If it is there once it will not return the number. So you get an empty array.
Furthermore you cannot simply shove an entire array into Console.WriteLine. Either use a loop or String.Join to print the content:
Console.WriteLine(String.Join(" ",mltpls_dplcts));
Solution: You can solve it using a good old loop approach ;)
int[] mltpls_unique = mltpls.Distinct().ToArray();
// The amount of duplicates is the difference between the original and the unique array
int[] mltpls_dplcts = new int[mltpls.Length-mltpls_unique.Length];
int dupCount = 0;
for (int i = 0; i < mltpls.Length; i++)
{
for (int j = i+1; j < mltpls.Length; j++)
{
if (mltpls[i] == mltpls[j])
{
mltpls_dplcts[dupCount] = mltpls[i];
dupCount++;
}
}
}
Output: 18 12 10 6 15
You cannot print the array directly. You need to loop and print one by one:
foreach (var element in mltpls_dplcts)
{
Console.WriteLine(element);
}
You can get array of distinct duplicates like this:
var duplicates = mltpls.GroupBy(o => o)
.Where(g => g.Count() > 1)
.Select(g => g.First()).ToArray();
To get new array that contains only the elements from the original one that are not in the second array you can use:
var newArr = mltpls.Except(duplicates).ToArray();
It is not proper way to find duplicates. You can determine the duplicates by using GroupBy and print them to console like this;
var mltpls_dplcts = mltpls.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x.Key).ToArray();
foreach (var duplicate in mltpls_dplcts)
{
Console.WriteLine(duplicate);
}
Also, If it isn't must to use Array for you, I suggest you to use List<int>.
Updated question from OP:
How do get only the duplicate values from an array?
var arr1 = new[] {1, 2, 4, 4, 5, 5, 5, 5, 6, 7, 1};
var duplicates = arr1.ToLookup(_ => _, _ => _).Where(_ => _.Count()>1).Select(_ => _.Key).ToArray();
// duplicates is now { 1, 4, 5 }
Original question from OP:
How do I delete all elements in an int array that exist in another int array in C#?
var arr1 = new[] {1, 2, 4, 5, 6, 7};
var arr2 = new[] {4, 5};
var hash = new HashSet<int>(arr1);
hash.ExceptWith(arr2);
var filteredArray = hash.ToArray();
// filteredArray is now { 1, 2, 6, 7 }
There is a list called cardReaderHistory . That contains some time records in ordered fashion as follows,
InTime1
OutTime1
InTime2
OutTime2
InTime3
OutTime3
InTime4
OutTime4.....furthermore..
What I need is Calculate Working time by (OutTime1 - Intime1) + (OutTime1 - Intime1).....
double
How could I do this in C#...????
double hr = ((outTime1 - inTime1)+(OutTime2 - Intime2)+...);
Thank you..
Poor Beginner
You can filter the input sequence based on the index, and then zip the two sequences:
var inTimes = source.Where((x, index) => index % 2 == 0);
var outTimes = source.Where((x, index) => index % 2 == 1);
var result = inTimes.Zip(outTimes, (inTime, outTime) => outTime - inTime).Sum();
If you don't need the intermediary values, you can also do this:
var result = source.Select((x, index) => (index % 2 == 0) ? -x : x).Sum();
Assuming your cardReaderHistory list is a list of doubles:
List<double> cardReaderHistory = new List<double>(); //fill it somewhere
double result;
for(int i = 0; i < cardReaderHistory.Count(); i++)
{
if(i%2==0) //If it is equal
result -= cardReaderHistory[i];
else //its unequal
result += cardReaderHistory[i];
}
You just loop over your values and add or subtract based on if its even or not.
Something like this...
List<double> l = new List<double> { 1, 2, 3, 4, 5, 6, 7, 8 };
double hr = 0;
for (int i = 0; i < l.Count; i++)
{
hr += i%2 == 0 ? -l[i] : l[i];
}
It seems plausible that the list contains datetimes and not hours. Currently none of the other answers handles that. Here's my take.
var cardReaderHistory = new List<DateTime> {DateTime.Now.AddMinutes(-120), DateTime.Now.AddMinutes(-100), DateTime.Now.AddMinutes(-20), DateTime.Now};
var hours = cardReaderHistory.Split(2).Select(h => (h.Last() - h.First()).TotalHours).Sum();
Split is an extension method
static class ExtentionsMethods
{
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> seq, int size)
{
while (seq.Any())
{
yield return seq.Take(size);
seq = seq.Skip(size);
}
}
}