remove sequential numbers from int array / int list [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
im generating a list of numbers such as 100 101 102 103 110 111 112 130 131 132 and i want to remove numbers that are sequential till the next number but with a specific tolerance...
so with a tolerance of 3 for example my output will be
100 102
110 112
130 132
the tolerance value must be adjustable...
ADRS is my list of int's,
ADRSC is my list of strings after being cleaned
for (int v = 0; v <= ADRS.Count - 2; v++)
{
if (v == 0) //adds first number
ADRSC.Add(ADRS[v].ToString());
if (ADRS[v]-(int.Parse(ADRSC.Last())) > 3)
{
ADRSC.Add(ADRS[v].ToString());
}
}
in short:
i want to remove the numbers inbetween, that have a difference of under 3
This worked
adrCache = Nums.First();
for (int x=1; x < Nums.Count-2; x++)
{
if ((Nums[x+1] - adrCache) <= 4)
{
adrCache = Nums[x+1];
Nums[x] = 0; //ill then just remove all zeros
}
else {
adrCache = Nums[x];
}
}

Here's a shot at what you're looking for, but the question is a little unclear to me:
public static List<int> RemoveSequential(List<int> items, int tolerance)
{
if (items == null || items.Count < 2) return items;
var result = new List<int> {items.First()};
var sequenceCount = 0;
for(int i = 1; i < items.Count; i++)
{
if (Math.Abs(items[i] - items[i - 1]) == 1)
{
sequenceCount++;
if (sequenceCount == tolerance - 1)
{
result.Add(items[i]);
}
}
else
{
sequenceCount = 0;
result.Add(items[i]);
}
}
return result;
}
Usage would look like:
public static void Main(string[] args)
{
var input = new List<int> {100, 101, 102, 103, 110, 111, 112, 130, 131, 132};
var output = RemoveSequential(input, 3);
Console.WriteLine($"Input: {string.Join(", ", input)}");
Console.WriteLine($"Output: {string.Join(", ", output)}");
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output

Related

What causes IndexOutOfRangeException here? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I had a programming exam where at the end, I always had an IndexOutOfRangeException for the code below (for the if statement, exactly).
The task was to remove numbers in 21..32 range from the list then print out the new list. nums is a List<int> with exactly 6 numbers given by the user.
I've been programming for 4 years now and I can't find a single problem :D
Here's the code.
// nums is a List<int> with exactly 6 elements in it.
List<int> changedNums = new List<int>(nums);
for (int k = 0; k < 6; k++)
if (changedNums[k] >= 21 && changedNums[k] <= 32)
changedNums.RemoveAt(k);
I didn't put brackets here because it's a one-liner.
The issue here is that you modifying the length of the list while iterating. After you deleted at least one item from changedNums list, its length is less than the initial 6 (so you get IndexOutOfRangeException). Also, once you deleted k-th item, you should decrement k. I modified your sample code to work as follows:
static void Main()
{
List<int> nums = new List<int>() { 1, 22, 30, 4, 5, 6 };
List<int> changedNums = new List<int>(nums);
var currentLength = changedNums.Count;
for (int k = 0; k < currentLength; k++)
{
if (changedNums[k] >= 21 && changedNums[k] <= 32)
{
changedNums.RemoveAt(k);
--k;
--currentLength;
}
}
Console.WriteLine(string.Join(" ", changedNums));
}
This will print: 1 4 5 6
Edit:
As pointed by #derpirscher and #Jon Skeet in comments, index manipulations can be easily avoided by iterating the array from end to start:
List<int> nums = new List<int>() { 1, 22, 30, 4, 5, 6 };
List<int> changedNums = new List<int>(nums);
for (int k = changedNums.Count - 1; k >= 0 ; k--)
if (changedNums[k] >= 21 && changedNums[k] <= 32)
changedNums.RemoveAt(k);
Console.WriteLine(string.Join(" ", changedNums));
An even easier solution to your problem can be achieved using LINQ:
var changedNums = nums.Where(num => num < 21 || num > 32).ToList();
All the solutions will produce the same result 1 4 5 6

How to dynamically add indexes values of an array in C#?

I have an array where the first two smallest values have to be added, and consequently the result has to be added to next smallest and so on until it reaches the end of the array to give a final total.
However, how can I dynamically modify the method/function so if the values changes and I have 6 vehicles and 6 specs values in the array, the return of the method/function total is not restricted to just 4 indexes.
The array values are unsorted, so in order to add the first smallest, it has to be sorted. Once that's done it adds the values of the new array.
Here's what I've tried:
public static int vehicles = 4;
public static int[] specs = new int[] { 40, 8, 16, 6 };
public static int time(int vehicles, int[] specs)
{
int newValue = 0;
for (int i = 1; i < vehicles; i++)
{
newValue = specs[i];
int j = i;
while (j > 0 && specs[j - 1] > newValue)
{
specs[j] = specs[j - 1];
j--;
}
specs[j] = newValue;
}
// How can I dynamically change this below:
int result1 = specs[0] + specs[1];
int result2 = result1 + specs[2];
int result3 = result2 + specs[3];
int total = result1 + result2 + result3;
return total; // Returns 114
}
Here's the idea of how it works:
4, [40, 8, 16, 6] = 14 --> [40, 14, 16] = 30 --> [40, 30] = 70 ==>> 14 + 30 + 70 = 114
6, [62, 14, 2, 6, 28, 41 ] = 8 --> [62, 14, 8, 28, 41 ] --> 22 [62, 22, 28, 41 ] --> 50
[62, 50, 41 ] --> 91 [62, 91 ] --> 153 ==> 8 + 22 + 50 + 91 + 153 = 324
First off, if you are not restricted to arrays for some weird reason use List<int> and your life will be easier.
List<int> integers = { 14, 6, 12, 8 };
integers.Sort();
integers.Reverse();
while( integers.Count > 1 )
{
int i = integers[integers.Count - 1];
int j = integers[integers.Count - 2];
integers[integers.Count - 2] = i + j;
integers.RemoveAt(integers.Count - 1);
}
var result = integers[0];
P.S.: This can be easily modified to operate on the array version, you can't RemoveAt() from an array but can separately maintain a lastValidIndex.
I would go with the simplest version of a one line solution using LINQ:
Array.Sort(specs);
int total = specs.Select((n, i) => specs.Take(i + 1).Sum()).Sum() - (specs.Length > 1 ? specs[0] : 0);
I would use Linq.
Enumerable.Range(2, specs.Length - 1)
.Select(i => specs
.Take(i)
.Sum())
.Sum();
Explanation:
We take a range starting from 2 ending with specs.Length.
We sum the first i values of specs where i is the current value in the range.
After we have all those sums, we sum them up as well.
To learn more about linq, start here.
This code only works if the values have been sorted already.
If you want to sort the values using linq, you should use this:
IEnumerable<int> sorted = specs.OrderBy(x => x);
Enumerable.Range(2, sorted.Count() - 1)
.Select(i => sorted
.Take(i)
.Sum())
.Sum();
The OrderBy function needs to know how to get the value it should use to compare the array values. Because the array values are the values we want to compare we can just select them using x => x. This lamba takes the value and returns it again.
See comments in code for explanation.
using System;
using System.Linq;
class Program
{
static void Main()
{
//var inputs = new [] { 40, 8, 16, 6 }; // total = 114
var inputs = new[] { 62, 14, 2, 6, 28, 41 }; // total = 324
var total = 0;
var query = inputs.AsEnumerable();
while (query.Count() > 1)
{
// sort the numbers
var sorted = query.OrderBy(x => x).ToList();
// get sum of the first two smallest numbers
var sumTwoSmallest = sorted.Take(2).Sum();
// count total
total += sumTwoSmallest;
// remove the first two smallest numbers
query = sorted.Skip(2);
// add the sum of the two smallest numbers into the numbers
query = query.Append(sumTwoSmallest);
}
Console.WriteLine($"Total = {total}");
Console.WriteLine("Press any key...");
Console.ReadKey(true);
}
}
I benchmark my code and the result was bad when dealing with large dataset. I suspect it was because of the sorting in the loop. The sorting is needed because I need to find the 2 smallest numbers in each iteration. So I think I need a better way to solve this. I use a PriorityQueue (from visualstudiomagazine.com) because the elements are dequeued based on priority, smaller numbers have higher priority in this case.
long total = 0;
while (pq.Count() > 0)
{
// get two smallest numbers when the priority queue is not empty
int sum = (pq.Count() > 0 ? pq.Dequeue() : 0) + (pq.Count() > 0 ? pq.Dequeue() : 0);
total += sum;
// put the sum of two smallest numbers in the priority queue if the queue is not empty
if (pq.Count() > 0) pq.Enqueue(sum);
}
Here's some benchmark results of the new (priority queue) code and the old code in release build. Results are in milliseconds. I didn't test the 1 million data with the old code because it's too slow.
+---------+----------+-------------+
| Data | New | Old |
+---------+----------+-------------+
| 10000 | 3.9158 | 5125.9231 |
| 50000 | 16.8375 | 147219.4267 |
| 1000000 | 406.8693 | |
+---------+----------+-------------+
Full code:
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
class Program
{
static void Main()
{
const string fileName = #"numbers.txt";
using (var writer = new StreamWriter(fileName))
{
var random = new Random();
for (var i = 0; i < 10000; i++)
writer.WriteLine(random.Next(100));
writer.Close();
}
var sw = new Stopwatch();
var pq = new PriorityQueue<int>();
var numbers = File.ReadAllLines(fileName);
foreach (var number in numbers)
pq.Enqueue(Convert.ToInt32(number));
long total = 0;
sw.Start();
while (pq.Count() > 0)
{
// get two smallest numbers when the priority queue is not empty
int sum = (pq.Count() > 0 ? pq.Dequeue() : 0) + (pq.Count() > 0 ? pq.Dequeue() : 0);
total += sum;
// put the sum of two smallest numbers in the priority queue if the queue is not empty
if (pq.Count() > 0) pq.Enqueue(sum);
}
sw.Stop();
Console.WriteLine($"Total = {total}");
Console.WriteLine($"Time = {sw.Elapsed.TotalMilliseconds}");
total = 0;
var query = File.ReadAllLines(fileName).Select(x => Convert.ToInt32(x));
sw.Restart();
while (query.Count() > 0)
{
// sort the numbers
var sorted = query.OrderBy(x => x).ToList();
// get sum of the first two smallest numbers
var sumTwoSmallest = sorted.Take(2).Sum();
// count total
total += sumTwoSmallest;
// remove the first two smallest numbers
query = sorted.Skip(2);
// add the sum of the two smallest numbers into the numbers
if (query.Count() > 0)
query = query.Append(sumTwoSmallest);
}
sw.Stop();
Console.WriteLine($"Total = {total}");
Console.WriteLine($"Time = {sw.Elapsed.TotalMilliseconds}");
Console.WriteLine("Press any key...");
Console.ReadKey(true);
}
}
PriorityQueue code:
using System;
using System.Collections.Generic;
// From http://visualstudiomagazine.com/articles/2012/11/01/priority-queues-with-c.aspx
public class PriorityQueue<T> where T : IComparable<T>
{
private List<T> data;
public PriorityQueue()
{
this.data = new List<T>();
}
public void Enqueue(T item)
{
data.Add(item);
int ci = data.Count - 1; // child index; start at end
while (ci > 0)
{
int pi = (ci - 1) / 2; // parent index
if (data[ci].CompareTo(data[pi]) >= 0)
break; // child item is larger than (or equal) parent so we're done
T tmp = data[ci];
data[ci] = data[pi];
data[pi] = tmp;
ci = pi;
}
}
public T Dequeue()
{
// assumes pq is not empty; up to calling code
int li = data.Count - 1; // last index (before removal)
T frontItem = data[0]; // fetch the front
data[0] = data[li];
data.RemoveAt(li);
--li; // last index (after removal)
int pi = 0; // parent index. start at front of pq
while (true)
{
int ci = pi * 2 + 1; // left child index of parent
if (ci > li)
break; // no children so done
int rc = ci + 1; // right child
if (rc <= li && data[rc].CompareTo(data[ci]) < 0) // if there is a rc (ci + 1), and it is smaller than left child, use the rc instead
ci = rc;
if (data[pi].CompareTo(data[ci]) <= 0)
break; // parent is smaller than (or equal to) smallest child so done
T tmp = data[pi];
data[pi] = data[ci];
data[ci] = tmp; // swap parent and child
pi = ci;
}
return frontItem;
}
public T Peek()
{
T frontItem = data[0];
return frontItem;
}
public int Count()
{
return data.Count;
}
public override string ToString()
{
string s = "";
for (int i = 0; i < data.Count; ++i)
s += data[i].ToString() + " ";
s += "count = " + data.Count;
return s;
}
public bool IsConsistent()
{
// is the heap property true for all data?
if (data.Count == 0)
return true;
int li = data.Count - 1; // last index
for (int pi = 0; pi < data.Count; ++pi)
{ // each parent index
int lci = 2 * pi + 1; // left child index
int rci = 2 * pi + 2; // right child index
if (lci <= li && data[pi].CompareTo(data[lci]) > 0)
return false; // if lc exists and it's greater than parent then bad.
if (rci <= li && data[pi].CompareTo(data[rci]) > 0)
return false; // check the right child too.
}
return true; // passed all checks
}
// IsConsistent
}
// PriorityQueue
Reference:
https://visualstudiomagazine.com/articles/2012/11/01/priority-queues-with-c.aspx
https://en.wikipedia.org/wiki/Priority_queue
You can simply sort it using Array.Sort(), then get the sums in a new array which starts with the smallest value and add each next value to the most recent sum, the total will be the value of the last sum.
public static int time(int vehicles, int[] specs)
{
int i, total;
int[] sums = new int[vehicles];
Array.Sort(spec);
sums[0] = specs[0];
for (i = 1; i < vehicles; i++)
sums[i] = sums[i - 1] + spec[i];
total = sums[spec - 1];
}

What's wrong with my merge sort implementation [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm sure I'm making an incredibly silly mistake but I've been at this for hours and I just want my code to sort prettily... Something is going wrong with implementation when odd numbers come into the equation.
Below is my MergeSplit method:
static List<Motor> MergeSplit(List<int> ListX)
{
int n = ListX.Count;
if (n <= 1)
return ListX;
List<int> left = new List<int>();
List<int> right = new List<int>();
for (int i = 0; i < n; i++)
{
if (i < (n / 2))
left.Add(ListX[i]);
else
right.Add(ListX[i]);
}
left = MergeSplit(left);
right = MergeSplit(right);
return Merge(left, right);
}
And here is the Merge method:
static List<int> Merge(List<int> ListX, List<int> ListY)
{
List<int> result = new List<int>();
int i = 0;
while (ListX.Count > i && ListY.Count > i)
{
if (ListX[i] > ListY[i])
{
result.Add(ListY[i]);
result.Add(ListX[i]);
}
else
{
result.Add(ListX[i]);
result.Add(ListY[i]);
}
i++;
}
//If odd, add the rest to the result
if (ListX.Count > ListY.Count)
result.Add(ListX[ListX.Count - 1]);
else if (ListY.Count > ListX.Count)
result.Add(ListY[ListY.Count - 1]);
return result;
}
Thanks for your help!
Update
The algorithm just doesnt sort correctly with certain inputs
The problem is your Merge routine
You are comparing the left and right and adding them to the list respectively, where you should be comparing the heads, and adding the lowest to the result, and removing that head respectively for the next comparison
This is the pseudo code from wiki https://en.wikipedia.org/wiki/Merge_sort
while left is not empty and right is not empty do
if first(left) ≤ first(right) then
append first(left) to result
left := rest(left)
else
append first(right) to result
right := rest(right)
You can see why thats important here
As you can see its actually comparing the first left and first right, then adding them to the result and removing that item from the list. which is vastly different from what you are doing. you either need 2 index variables, or remove the items from the list
while (listX.Count > 0 && listY.Count > 0)
if (listX[0] > listY[0])
{
result.Add(listY[0]);
listY.RemoveAt(0);
}
else
{
result.Add(listX[0]);
listX.RemoveAt(0);
}
if (listX.Count > 0)
result.AddRange(listX);
else if (listY.Count > 0)
result.AddRange(listY);
Just for fun, i found this was easier to play with queues, they seem to like this sort of thing
private static Queue<int> Merge(Queue<int> left, Queue<int> right)
{
var result = new Queue<int>();
while (left.Count > 0 && right.Count > 0)
result.Enqueue(left.Peek() > right.Peek() ? right.Dequeue() : left.Dequeue());
foreach (var item in left)
result.Enqueue(item);
foreach (var item in right)
result.Enqueue(item);
return result;
}
private static Queue<int> MergeSplit(Queue<int> list)
{
var n = list.Count;
if (n <= 1)
return list;
var left = new Queue<int>();
var right = new Queue<int>();
for (var i = 0; i < n; i++)
if (i < n / 2)
left.Enqueue(list.Dequeue());
else
right.Enqueue(list.Dequeue());
left = MergeSplit(left);
right = MergeSplit(right);
return Merge(left, right);
}
Usage
var list = new List<int> { 8, 7, 6, 4, 43, 23, 435, 76, 7, 7877, 5, 421, 2 };
var results = MergeSplit(new Queue<int>(list));
Console.WriteLine(string.Join(", ", results));
Output
2, 4, 5, 6, 7, 7, 8, 23, 43, 76, 421, 435, 7877
Full Demo Here

Max average series in ordered list

I'm trying to get the greatest average values for different duration in a list.
Let's say I have the following data:
var randomList = new List<int>();
var random = new Random(1969);
for (var i = 0; i < 10; i++)
{
randomList.Add(random.Next(0, 500));
}
That produces the following list:
190
279
37
413
90
131
64
129
287
172
I'm trying to get the highest average values for the different sets 0-9.
Set 0 (one item in a row) = 413 (index 3)
Set 1 (two items in a row) = 252 (average index 3,4)
Set 9 (10 items in a row) = 179 (average of the entire list)
I've been beating my head on this a while. I'm trying to find an efficient way to write this so I have the least traversals as possible. In production, I'll have lists with 3500-6000 points.
How do I find the highest average values for the different sets 0-9?
This probably isn't the most efficient way to do it, but it works fine:
Basically, we use a stack to track the items we've traversed. Then to calculate the average for n last items, we peek at n items from the stack.
void Main()
{
var randomList = new List<int>();
var random = new Random(1969);
for (var i = 0; i < 10; i++)
{
randomList.Add(random.Next(0, 500));
}
// Use the values from the original post for validation
randomList = new List<int> { 190, 279, 37, 413, 90, 131, 64, 129, 287, 172 };
const int numSets = 9;
var avgDict = Enumerable.Range(1, numSets).ToDictionary(e => e, e => (double)0);
var s = new Stack<int>();
foreach (var item in randomList)
{
s.Push(item);
for (var i = 1; i <= numSets; i++)
{
if (s.Count >= i)
{
var avg = s.Take(i).Average();
if (avg > avgDict[i])
avgDict[i] = avg;
}
}
}
avgDict.Dump();
}
Yields the result:
1 413
2 251.5
3 243
4 229.75
5 201.8
6 190
7 183.714285714286
8 178.75
9 180
I'm unsure as to the implications of using a Stack for large lists, when we only need 9-10 items. Might be a good case for a custom limited size stack
In your comment, you mentioned Avg(items:0,1,2) vs Avg(items:1,2,3) vs Avg(items:2,3,4)
Not sure if this is what you want but I came up with this.
First, get random number, then get average of 3 numbers. Then, get the largest average value.
static void Main(string[] args)
{
var randomList = new List<int>();
var random = new Random(1969);
int TotalRandomNumber = 10; //Change this accordingly
for (var i = 0; i < TotalRandomNumber ; i++)
{
randomList.Add(random.Next(0, 500));
}
foreach (var item in randomList)
{
Console.WriteLine("Random Number: " + item);
}
var AveNum = new List<double>();
int range = 3; //Change this for different range
for (int i = 1; i < TotalRandomNumber - range; i++)
{
var three = randomList.GetRange(i, range);
double result = three.Average();
Console.WriteLine("Average Number: " + result);
AveNum.Add(result);
}
Console.WriteLine("Largest: " + AveNum.Max());
}

Logic to generate an alphabetical sequence in C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
The sequence should go like this.
A-Z,AA-AZ,BA-BZ,CA-CZ,.......,ZA-ZZ
After ZZ it should start from AAA.
Then AAA to ZZZ and then AAAA to ZZZZ and so on.
This sequence is pretty much like that of an Excel sheet.
Edit: Added my code
private void SequenceGenerator()
{
var numAlpha = new Regex("(?<Numeric>[0-9]*)(?<Alpha>[a-zA-Z]*)");
var match = numAlpha.Match(txtBNo.Text);
var alpha = match.Groups["Alpha"].Value;
var num = Convert.ToInt32(match.Groups["Numeric"].Value);
lastChar = alpha.Substring(alpha.Length - 1);
if (lastChar=="Z")
{
lastChar = "A";
txtBNo.Text = num.ToString() + "A" + alpha.Substring(0, alpha.Length - 1) + lastChar;
}
else
{
txtBNo.Text = num.ToString() + alpha.Substring(0, alpha.Length - 1) + Convert.ToChar(Convert.ToInt32(Convert.ToChar(lastChar)) + 1);
}
}
This is what I've done. But, I know that is a wrong logic.
Thanks.
As I've wrote in the comment, it's a base-conversion problem, where your output is in base-26, with symbols A-Z
static string NumToLetters(int num)
{
string str = string.Empty;
// We need to do at least a "round" of division
// to handle num == 0
do
{
// We have to "prepend" the new digit
str = (char)('A' + (num % 26)) + str;
num /= 26;
}
while (num != 0);
return str;
}
Lucky for you, I've done this once before. the problems I've encountered is that in the Excel sheet there is no 0, not even in double 'digit' 'numbers'. meaning you start with a (that's 1) and then from z (that's 26) you go straight to aa (27). This is why is't not a simple base conversion problem, and you need some extra code to handle this.
Testing the function suggested by xanatos results with the following:
NumToLetters(0) --> A
NumToLetters(25) --> Z
NumToLetters(26) --> BA
My solution has more code but it has been tested against Excel and is fully compatible, except it starts with 0 and not 1, meaning that a is 0, z is 25, aa is 26, zz 701, aaa is 702 and so on). you can change it to start from 1 if you want, it's fairly easy.
private static string mColumnLetters = "zabcdefghijklmnopqrstuvwxyz";
// Convert Column name to 0 based index
public static int ColumnIndexByName(string ColumnName)
{
string CurrentLetter;
int ColumnIndex, LetterValue, ColumnNameLength;
ColumnIndex = -1; // A is the first column, but for calculation it's number is 1 and not 0. however, Index is alsways zero-based.
ColumnNameLength = ColumnName.Length;
for (int i = 0; i < ColumnNameLength; i++)
{
CurrentLetter = ColumnName.Substring(i, 1).ToLower();
LetterValue = mColumnLetters.IndexOf(CurrentLetter);
ColumnIndex += LetterValue * (int)Math.Pow(26, (ColumnNameLength - (i + 1)));
}
return ColumnIndex;
}
// Convert 0 based index to Column name
public static string ColumnNameByIndex(int ColumnIndex)
{
int ModOf26, Subtract;
StringBuilder NumberInLetters = new StringBuilder();
ColumnIndex += 1; // A is the first column, but for calculation it's number is 1 and not 0. however, Index is alsways zero-based.
while (ColumnIndex > 0)
{
if (ColumnIndex <= 26)
{
ModOf26 = ColumnIndex;
NumberInLetters.Insert(0, mColumnLetters.Substring(ModOf26, 1));
ColumnIndex = 0;
}
else
{
ModOf26 = ColumnIndex % 26;
Subtract = (ModOf26 == 0) ? 26 : ModOf26;
ColumnIndex = (ColumnIndex - Subtract) / 26;
NumberInLetters.Insert(0, mColumnLetters.Substring(ModOf26, 1));
}
}
return NumberInLetters.ToString().ToUpper();
}
Try this method:
public static IEnumerable<string> GenerateItems()
{
var buffer = new[] { '#' };
var maxIdx = 0;
while(true)
{
var i = maxIdx;
while (true)
{
if (buffer[i] < 'Z')
{
buffer[i]++;
break;
}
if (i == 0)
{
buffer = Enumerable.Range(0, ++maxIdx + 1).Select(c => 'A').ToArray();
break;
}
buffer[i] = 'A';
i--;
}
yield return new string(buffer);
}
// ReSharper disable once FunctionNeverReturns
}
This is infinite generator of alphabetical sequence you need, you must restrict count of items like this:
var sequence = GenerateItems().Take(10000).ToArray();
Do not call it like this (it cause infinite loop):
foreach (var i in GenerateItems())
Console.WriteLine(i);

Categories