Related
In my office there was a jackpot programming event was conducted, in that event they asked 3 questions, but 1 of the puzzles was really tough for us and I just tried in my own interest
Question:
A = {10, 15, 25}
B = {1, 5, 20, 30}
Expected output:
10 20
10 20 25 30
10 30
15 20
15 20 25 30
15 30
25 30
In output:
10 20 --> A's 1st element and B's 1st smallest element that greater than A's 1st element
10 20 25 30 --> A's 1st element Check with B array, which is greater than A, and again Check with A , repeat it until B doesn't have any greater element in compared to A, if B doesn't have to end up with previous B value.
10 30 --> A's 1st element and B's largest element that greater than A's 1st element
the above method will iterate all over the A elements.
Here is my solution, the only thing that didn't make sense was why he skipped 15 in the first set of sets, and since you don't have any more information I had to suppose the reason for skipping it(call it an exception)
int[] A = { 10, 15, 25 };
int[] B = { 1, 5, 20, 30 };
//10 20
//10 20 25 30
//10 30
//15 20
//15 20 25 30
//15 30
//25 30
var result = A.SelectMany(x => GetIllogicalPermutations(x, A, B)).DistinctBy(x => x.Sum());
for (int i = 0; i < result.Count(); i++)
{
Console.WriteLine(string.Join(' ', result.ElementAt(i).Select(x => x.ToString())));
}
Console.ReadLine();
static IEnumerable<int[]> GetIllogicalPermutations(int item, int[] setA, int[] setB)
{
yield return new int[] { item, setB.Where(x => x > item).Min() };
yield return setA.Where(x => x > item && x != (setA.Max() - setA.Min())).Concat(setB.Where(x => x > item)).Prepend(item).OrderBy(x => x).ToArray();
yield return new int[] { item, setB.Where(x => x > item).Max() };
}
If I understood your problem correctly it is like this
class Solution
{
int[] a;
int[] b;
public Solution(int[] a, int[] b)
{
this.a = a;
this.b = b;
}
void InterateA(int min, string output)
{
foreach (var a in a.OrderBy(n => n).SkipWhile(n => n <= min))
{
InterateB(a, $"{output}\t{a}");
}
}
void InterateB(int min, string output)
{
foreach (var b in b.OrderBy(n => n).SkipWhile(n => n <= min))
{
var str = $"{output} {b}";
Console.WriteLine(str);
InterateA(b, str);
}
output = null;
}
public void Print()
{
InterateA(a.OrderBy(n => n).First() - 1, null);
}
}
Test code
static void Main(string[] args)
{
var a = new int[] { 10, 15, 25, 35 };
var b = new int[] { 1, 5, 20, 30, 40 };
var solution = new Solution(a, b);
solution.Print();
Console.ReadKey();
}
Performance is minimum as this is initial trivial solution and canbe optimized if it does the job correctly.
12,13,14,15,16,19,19,19,19
to
12,19,13,19,14,19,15,19,16
Hey all. Can anyone point me to clues/samples on how to distribute the first array of Int32 values, where a bunch of 19 values were appended, to the second where the 19 values are fairly evenly interspersed in the array?
I am not looking for a random shuffling, as in this example #19 could still appear consecutively if there was randomization. I want to make sure that #19 is placed in between the other numbers in a predictable pattern.
The use-case for this is something like teams taking turns presenting a topic: teams 12-16 each present once and then team #19 shows up but should not show their topic four times in a row, they should show their topic in between the other teams.
Later, if twelve values of 7 are added to the array, then they will also have to be evenly distributed into the sequence as well, the array would be 21 elements but the same rule that neither #19 or #7 should have consecutive showings.
I thought there might be something in Math.NET library that would do this, but I did not find anything. Using C# on .NET Framework 4.7.
Thanks.
Details on the following method that evenly (mostly) distributes the duplicates in your list. Duplicates can be anywhere in your list, they will be distributed.
Create a dictionary of all numbers and keep track of the number of times they appear in the list
Use a new list without any duplicates. For Each number that has duplicates, spread it over the size of this new list. Each time the distribution is even.
public static List<int> EvenlyDistribute(List<int> list)
{
List<int> original = list;
Dictionary<int, int> dict = new Dictionary<int, int>();
list.ForEach(x => dict[x] = dict.Keys.Contains(x) ? dict[x] + 1 : 1);
list = list.Where(x => dict[x] == 1).ToList();
foreach (int key in dict.Where(x => x.Value > 1).Select(x => x.Key))
{
int iterations = original.Where(x => x == key).Count();
for (int i = 0; i < iterations; i++)
list.Insert((int)Math.Ceiling((decimal)((list.Count + iterations) / iterations)) * i, key);
}
return list;
}
Usage in main:
List<int> test = new List<int>() {11,11,11,13,14,15,16,17,18,19,19,19,19};
List<int> newList = EvenlyDistribute(test);
Output
19,11,13,19,14,11,19,15,16,19,11,17,18
Here's how to do this.
var existing = new[] { 12, 13, 14, 15, 16 };
var additional = new [] { 19, 19, 19, 19 };
var lookup =
additional
.Select((x, n) => new { x, n })
.ToLookup(xn => xn.n * existing.Length / additional.Length, xn => xn.x);
var inserted =
existing
.SelectMany((x, n) => lookup[n].StartWith(x))
.ToArray();
This gives me results like 12, 19, 13, 19, 14, 19, 15, 19, 16.
The only thing that this won't do is insert a value in the first position, but otherwise it does evenly distribute the values.
In case random distribution is enough the following code is sufficient:
static void MixArray<T>(T[] array)
{
Random random = new Random();
int n = array.Length;
while (n > 1)
{
n--;
int k = random.Next(n + 1);
T value = array[k];
array[k] = array[n];
array[n] = value;
}
}
For instance:
int[] input = new int[]{12,13,14,15,16,19,19,19,19};
MixArray<int>(input);
In case you require precise evenly distribution while retaining the order of the elements, to following code will do the job:
public static T[] EvenlyDistribute<T>(T[] existing, T[] additional)
{
if (additional.Length == 0)
return existing;
if (additional.Length > existing.Length)
{
//switch arrays
T[] temp = additional;
additional = existing;
existing = temp;
}
T[] result = new T[existing.Length + additional.Length];
List<int> distribution = new List<int>(additional.Length);
double ratio = (double)(result.Length-1) / (additional.Length);
double correction = -1;
if (additional.Length == 1)
{
ratio = (double)result.Length / 2;
correction = 0;
}
double sum = 0;
for (int i = 0; i < additional.Length; i++)
{
sum += ratio;
distribution.Add(Math.Max(0, (int)(sum+correction)));
}
int existing_added = 0;
int additional_added = 0;
for (int i = 0; i < result.Length; i++)
{
if (additional_added == additional.Length)
result[i] = existing[existing_added++];
else
if (existing_added == existing.Length)
result[i] = additional[additional_added++];
else
{
if (distribution[additional_added] <= i)
result[i] = additional[additional_added++];
else
result[i] = existing[existing_added++];
}
}
return result;
}
For instance:
int[] existing = new int[] { 12, 13, 14, 15, 16};
int[] additional = new int[] { 101, 102, 103, 104};
int[] result = EvenlyDistribute<int>(existing, additional);
//result = 12, 101, 13, 102, 14, 103, 15, 104, 16
I have an array like this
int[] intnumber = new int[]{10,25,12,36,100,54,68,75,63,24,1,6,9,5};
I want to find the greatest number and make it In order from largest to smallest
like this
100,75,68,63,54,36,25,24,12,10,9,6,5,1
int[] intnumber = new int[] { 10, 25, 12, 36, 100, 54, 68, 75, 63, 24, 1, 6, 9, 5 };
int maxValue = intnumber.Max();
You can sort the array for viewing elements in ascending order
Array.Sort(intnumber);
Array.Reverse(intnumber);
foreach (var str in intnumber )
{
MessageBox.Show(str.ToString());
}
Try this,
int[] intnumber = new int[] { 10, 25, 12, 36, 100, 54, 68, 75, 63, 24, 1, 6, 9, 5 };
//Maximum Value
int maxValue = intnumber.Max();
//Maximum Index
int maxIndex = intnumber.ToList().IndexOf(maxValue);
You can use :
int[] intnumber = new int[]{10,25,12,36,100,54,68,75,63,24,1,6,9,5};
Array.Sort(intnumber );
Array.Reverse(intnumber );
int max = intnumber[0];
exactly output that you want.
int[] intnumber = new int[] { 10,25,12,36,100,54,68,75,63,24,1,6,9,5 };
Array.Sort<int>(intnumber ,
new Comparison<int>(
(i1, i2) => i2.CompareTo(i1)
));
intnumber .Dump();
P.S. To run this demo you need to follow these steps:
1.Download LINQPad.
2.Download the demo file, open it with LINQPad and hit F5.
I found my answer with your helps
Console.WriteLine("How many Numbers Do you want? ");
int counter = int.Parse(Console.ReadLine());
double[] numbers = new double[counter];
for (int i = 0; i < numbers.Length; i++)
{
Console.Write((i + 1) + " : ");
numbers[i] = Convert.ToDouble(Console.ReadLine());
}
Console.WriteLine("_______________________________________________");
Array.Sort(numbers);
Array.Reverse(numbers);
foreach (double item in numbers)
{
Console.WriteLine(item);
}
Console.WriteLine("_______________________________________________");
Console.WriteLine("The Greatest Number is " + numbers[0]);
Console.ReadKey();
Let intNumbers be the array that you are using, Then you can use the .Max() method of the Array Class to get the maximum value, that is the greatest number. If you want to Sort the Current array means You have to use the .Sort() method. The requirement is simply Printing the Array in descending order means you have to use the .OrderBy()
int[] inputNumbers = new int[] { 15, 12, 11, 23, 45, 21, 2, 6, 85, 1 };
Console.WriteLine("Input Array is : {0}\n",String.Join(",",inputNumbers.OrderByDescending(x=>x)));
Console.WriteLine("Max value in the array is : {0}\n",inputNumbers.Max());
Console.WriteLine("Array in descending order : {0}\n",String.Join(",",inputNumbers.OrderByDescending(x=>x)));
Here is a working Example
int max = Integer.MIN_VALUE;
for (int i =0; i < intnumber.length; i++)
{
int num = intnumber[i];
//Check to see if num > max. If yes, then max = num.
}
System.out.println(max);
I have data like
1 3 9 2 7 8 9
120 70 76 190 300 50 40
how can I sort the array based on the second row and return the value of the max number from the first row. I mean, the output become >
7 2 1 9 3 8 9
300 190 120 76 70 50 40
And I get the 7 as output.
First I would get your data out of the rectangular array into something a bit more usable. To do this, first convert the data into a List<Tuple<int, int>> because it is much easier to work with.
int[,] rawData = { { 1, 3, 9, 2, 7, 8, 9 }, { 120, 70, 76, 190, 300, 50, 40 } };
var data = new List<Tuple<int, int>>();
for(int i = 0; i < rawData.GetLength(1); i++)
{
data.Add(new Tuple<int, int>(rawData[0, i], rawData[1, i]));
}
Then it is just a matter of using a Linq query to get the data you want.
var result = data.OrderByDescending(x => x.Item2).First().Item1;
Fiddle
If you'd like to know the answer to 'what's the max number now' (or to put it differently, to keep the order rather then sort it post processing - beware it has a performance penalty!) then SortedList may come in handy:
int[] a = { 1, 3, 9, 2, 7, 8, 9 };
int[] b = { 120, 70, 76, 190, 300, 50, 40 };
var sortedList = new SortedList<int,int>();
for (int i = 0; i < a.Length; i++)
{
sortedList[b[i]] = a[i];
}
Console.WriteLine(sortedList.Last().Value);
(if you want to see what's current max value as you add data just move WriteLine to inside of the loop)
Hi I want to replace a byte[] where ever there is 10 by 10 10. here is my code.
if i have my data as "10 20 10 20 40 50 50 50 50 10 03" i want to replce it by
"10 20 10 10 20 40 50 50 50 50 10 10 03"
note: first byte is untouched
plse follow my comment, my idea is to push the byte array to nxt position and add another 10.
foreach (var b in command.ToBytes())
{
// var c = b;
transmitBuffer[count++] = b; data is formed here
addedbuffer[addall++] = b; duplication is made
}
if (addedbuffer[0] == 16 && addedbuffer[1] == 32 || addedbuffer[50] == 16 && addedbuffer[51] == 03) /
{
/condition on which to enter here
addedbuffer[0] = 0; //making 1st and 2nd value as null
addedbuffer[1] = 0;
for (int i = 0; i < addedbuffer.Length; i++) //till length i will chk
{
if (addedbuffer[i] == 10) //replace 10 by 10 10
addedbuffer[i] = 1010; // error,
}
}
You can't insert into array (you can do it with List<T>), so it looks that you have to create a new array; Linq solution:
Byte[] source = new Byte[] {
20, 10, 20, 40, 50, 50, 50, 50, 10, 03
};
var result = source
.SelectMany((item, index) =>
item == 10 && index != 0 ? new Byte[] { item, item } : new Byte[] { item })
.ToArray();
However, using List<Byte> (in order just to insert 10's) instead of Byte[] is a better way out:
List<Byte> list = List<Byte>() {
20, 10, 20, 40, 50, 50, 50, 50, 10, 03
};
// In order not to read inserted 10's we loop backward
// i >= 1: 1st byte should be preserved as is even if its == 10
for (int i = list.Count - 1; i >= 1; --i)
if (list[i] == 10)
list.Insert(i + 1, 10);
It helps to think of sequences like arrays (IEnumerable<T> in C#) as things that can be transformed into new sequences. Much like numbers can be transformed when you send them into a function, sequences can be, too.
Consider if I have a function that is defined as Add10If10(Byte b). It might looks like this:
public static Byte Add10If10(Byte b)
{
if (b == 10)
{
return b + 10;
}
return b;
}
Numbers which go into this are transformed based on the condition, and come out either 10 larger or the same. The same can be done with sequences, you can take a sequence with some number of elements, and transform it so it has more elements. The result is a new sequence:
public static IEnumerable<Byte> AddAdditional10If10(IEnumerable<Byte> values)
{
foreach (var b in values)
{
if (b == 10)
{
yield return 10;
}
yield return b;
}
}
This function returns an additional 10 for every 10 it encounters. Now that you have the right sequence, you can change how it is stored by changing it to an array:
AddAdditional10If10(addedbuffer).ToArray();
This works via conversion to strings, using String.Replace and converting back:
byte[] source = new Byte[] { 20, 10, 20, 40, 50, 50, 50, 50, 10, 03 };
string[] strArr = Array.ConvertAll(source, b => b.ToString());
string[] replArr = String.Join(" ", strArr).Replace("10", "10 10").Split();
byte[] newArr = Array.ConvertAll(replArr, str => Byte.Parse(str));
Edit:
Another approach with LINQ - elements at first and last indexes and all elements not equal to 10 are unchanged, for all remaining 10s it returns a sequence of 2 10s:
byte[] res = source.SelectMany((b, index) => index == 0
|| index == source.Length - 1
|| b != 10 ?
Enumerable.Repeat(b, 1) : Enumerable.Repeat(b, 2))
.ToArray();
This is a fairly efficient way to do it (requires two passes over the input array, but does not require any resizing of the output array):
public static byte[] Replace10With1010ExcludingFirstByte(byte[] input)
{
// Count 10s excluding first byte.
int count = input.Skip(1).Count(b => b == 10);
// Create output array of appropriate size.
byte[] result = new byte[input.Length + count];
// Copy input to output, duplicating all 10s that are not the first byte.
result[0] = input[0];
for (int i = 1, j = 1; i < input.Length; ++i, ++j)
{
result[j] = input[i];
if (input[i] == 10)
result[++j] = 10;
}
return result;
}
Call it with your original array, and use the returned array instead.
Test code (for use in a Console app):
byte[] input = {10, 20, 10, 20, 40, 50, 50, 50, 50, 10, 03};
var result = Replace10With1010ExcludingFirstByte(input);
Console.WriteLine(string.Join(", ", result));
[EDIT] It seems from one of your comments to another answer that you also want to also exclude the last byte from conversion too.
If so, use this code instead:
public static byte[] Replace10With1010ExcludingFirstAndLastByte(byte[] input)
{
// Count 10s excluding first and last byte.
int count = input.Skip(1).Take(input.Length-2).Count(b => b == 10);
// Create output array of appropriate size.
byte[] result = new byte[input.Length + count];
// Copy input to output, duplicating all 10s that are not the first byte.
result[0] = input[0];
for (int i = 1, j = 1; i < input.Length; ++i, ++j)
{
result[j] = input[i];
if ((input[i] == 10) && (i != (input.Length-1)))
result[++j] = 10;
}
return result;
}