Help needed to perform an output in C# console application.
I have a maximum number
int maxNr = 10;
int myValue = 1;
public void myMethod(){
int choice = int.Parse(Console.ReadLine()); // only 1 or 2 accepted.
//Only choice = 1 in displayed here.
if(choice == 1){
while(myValue <= maxNr){
Console.WriteLine(myValue);
myValue = myValue + 3;
}
}
}
Expected output:
1, 4, 7, 10
Next time the function is called the output should be:
3, 6, 9
2, 5, 8
myValue is stuck at 13 after the first call, so the code does not enter the loop the second time
Add this before the while loop:
if (myValue >= 10)
myValue -= 10;
Edit:
1.If I understood you correctly, the expected output is:
1st call 1, 4, 7, 10.
2nd call: 3, 6, 9.
3rd call 2, 5, 8.
2.As some suggested, you should use for loop instead of while loops:
if (myValue >= maxNr)
myValue -= maxNr;
for (; myValue <= maxNr; myValue += 3)
{
Console.WriteLine(myValue);
}
for (i=0; i<n; i+=3) don't work for you?
Why not just use this?
for (int i = n; i <= maxNr; i = i+3) {
Console.WriteLine(i);
}
myValue is not defined locally, so you need to set it to 0, when calling the method again, otherwise it would still be 10 and you do not enter the loop.
public void myMethod(){
int choice = int.Parse(Console.ReadLine()); // only 1 or 2 accepted.
int maxNr = 10;
int myValue = choice;
//Only choice = 1 in displayed here.
if(choice == 1){
while(myValue <= maxNr){
Console.WriteLine(myValue);
myValue = myValue + 3;
}
}
}
Reset your starting value each time.
You need to store myValue in a temporary variable and update it before exiting the method. As I understand your requirements the code to achieve the output is as given below,
static int maxNr = 10;
static int myValue = 1;
private static void Test()
{
int lastValue = myValue;
int choice = int.Parse(Console.ReadLine()); // only 1 or 2 accepted.
//Only choice = 1 in displayed here.
if (choice == 1)
{
while (myValue <= maxNr)
{
Console.WriteLine(myValue);
myValue = myValue + 3;
}
}
if (lastValue == 1)
{
myValue = lastValue + 3 - 1;
}
else
{
myValue = lastValue - 1;
}
}
Method Call
static void Main(string[] args)
{
Test();
Test();
Test();
Console.ReadLine();
}
Output
1
4
7
10
3
6
9
2
5
8
Note that the user needs to enter the value 1 at every function call.
Related
I have one dll application. In this application I am extacting some values.There in information about extraction.
.
and I wrote c# code from this link guide to calculate digit number. and I will compare it. Below code I wrote for c# to calculate
private static int[] _weights = { 7, 3, 1 };
private static SortedDictionary<char, int> GetMappedDictionary()
{
string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
SortedDictionary<char, int> mappedValues = new SortedDictionary<char, int>();
char[] charArr = charset.ToCharArray();
for (int i = 0; i < charArr.Length; ++i)
{
mappedValues[charArr[i]] = i;
}
mappedValues['<'] = 0;
return mappedValues;
}
private static int MrzComputeWeight(string line, int start, int end)
{
int sum = 0;
SortedDictionary<char, int> mappedValues = GetMappedDictionary();
for (int i = start, j = 0; i <= end; ++i, ++j)
{
var a = mappedValues[(line)[i]];
var b = _weights[j % 3];
sum += a *b;
}
return sum;
}
private static bool MrzCheckValidty(string line, int start, int end,int indexDigit)
{
int weight = MrzComputeWeight(line, start, end);
return (weight % 10) == Int32.Parse(line.Substring(indexDigit, 1));
}
Now It works for all test examples but It doesn't work for
IDUTOBE01124128TEST1234V<<<<<<
here document id is BE0112412 and when I calculate it , it gives me 4 as result but in mrz check digit is 8 . And this mrz is real mrz so 8 must be correct. Why this is not working for this MRZ even it works for anothers I tried?
Thanks in advance
I check your case and it gave 8 when you have letter O and it gave 4 when you have number 0.
Here is complete python code checkdigit.py:
#!/usr/bin/python3
import sys
def getcharvalue(c):
if c >= '0' and c <= '9':
return ord(c) - ord('0')
if c >= 'A' and c <= 'Z':
return ord(c) - ord('A') + 10
if c == '<':
return 0
def calc_checkdigit(data):
multipliers = [7, 3, 1]
s = 0
for idx,digit in enumerate(data):
n = getcharvalue(digit) * multipliers[idx % len(multipliers)]
s += n
cdigit = s % 10
return cdigit
data = sys.argv[1]
cdigit = calc_checkdigit(data)
print(cdigit)
Test run:
./checkdigit.py "BEO112412" # this prints 8
./checkdigit.py "BE0112412" # this prints 4
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Question:
Have the function ClosestEnemy(arr) take the array of numbers stored in arr and from the position in the array where a 1 is, return the number of spaces either left or right you must move to reach an enemy which is represented by a 2. For example: if arr is [0, 0, 1, 0, 0, 2, 0, 2] then your program should return 3 because the closest enemy (2) is 3 spaces away from the 1. The array will contain any number of 0's and 2's, but only a single 1. It may not contain any 2's at all as well, where in that case your program should return a 0.
My problem Console.Readline() and return.I dont know proper use.
I get to this errors, I put a comment line on the code
CS1503 C# Argument 1: cannot convert from 'int' to 'int[]'
CS0165 C# Use of unassigned local variable 'result'
examples:
Input: new int[] {1, 0, 0, 0, 2, 2, 2}
Output: 4
Input: new int[] {2, 0, 0, 0, 2, 2, 1, 0}
Output: 1
public static int ClosestEnemy1(int[] arr)
{
int result;
int counterright = 0;
int counterleft = 0;
int locationleft = 0;
int location1 = 0;
int locationright = 0;
int rightclosest;
int leftclosest;
int i;
// code goes here
for(i = 0; i < arr.Length; i++)
{
if (arr[i] == 1)
{
location1 = i;//1'in konumu belirlendi
}
}
//sağa kontrol et
while (arr[i]!= '\0' )//saga bak
{
i = location1;
i++;
if (arr[i] == 2)
{
counterright = 1;
locationright = i;
break;
}
}
for (i = location1; i >= 0; i--)
{
if (arr[i] == 2)
{
counterleft = 1;
locationleft = i;
break;
}
}
if(counterright == 0 && counterleft == 0)
{
result=0;
}
if(counterright == 0 && counterleft == 1)
{
result = location1 - locationleft;
}
if(counterright == 1 && counterleft == 0)
{
result = locationright - location1;
}
if(counterright == 1 && counterleft == 1)
{
leftclosest = location1 - locationleft;
rightclosest = locationright - location1;
if (leftclosest > rightclosest)
{
result = leftclosest;
}
else
{
result= rightclosest;
}
}
return result; //it's error!!!!!!!
}
static void Main()
{
// keep this function call here
Console.WriteLine(ClosestEnemy1(Convert.ToInt32(Console.ReadLine())));//it's errorr!!!!
}
Try these corrections in your code:
1) chnage input type to string : public static int ClosestEnemy1(string inputString)
, make sure you leave the comment for user to enter input like this: 1, 0, 0, 0, 2, 2, 2
2) inside the function make int arr[] by String.Split():
string[] stringNumbers = inputString .Split(',');
int[] arr = Array.ConvertAll(stringNumbers, s => int.Parse(s));
3) change this line :
int result=0; to assign the default value to result .
4) assign i=0 or what you think better before while, becuse the last assigned value for i is 7 and it will has an error.
//sağa kontrol et
i = 0;
while (arr[i] != '\0')//saga bak
5) in the main() function after you get console result, put a Console.ReadKey(); to you see the result.
So my homework is I have to take two numbers from the user then I have to write out the odd numbers in that interval.But the code under doesn't work. It writes out "TrueFalseTrueFalse".
int szam;
int szam2=0;
int szam3=0;
int szam4=0;
Console.Write("Please give a number:");
szam = Convert.ToInt32(Console.ReadLine());
Console.Write("Please give another number:");
szam2 = Convert.ToInt32(Console.ReadLine());
if (szam>szam2)
{
for (szam3=szam, szam4 = szam2; szam4 < szam3; szam4++)
{
Console.Write(szam2 % 2==1);
}
}
else
{
for (szam3 = szam, szam4 = szam2; szam3 < szam4; szam3++)
{
Console.Write(szam3 % 2 ==1);
}
}
So if the two numbers would be 0 and 10, the program has to write out 1, 3, 5, 7, and 9
I would be careful when naming your variables yes its a small piece of code but it gets confusing to people trying to read it.
Based on the requirement, I would guess you want all the odd numbers given a certain range.
const string comma = ",";
static void Main(string[] args)
{
int start = getNumber();
int end = getNumber();
if(start > end)
{
int placeHolder = end;
end = start;
start = placeHolder;
}
string delimiter = string.Empty;
for(int i = start; i < end; i++)
{
if(i % 2 == 1)
{
Console.Write(string.Concat(delimiter,i.ToString()));
delimiter = comma;
}
}
Console.ReadLine();//otherwise you wont see the result
}
static int getNumber()
{
Console.Write("Please enter a number:");
string placeHolder = Console.ReadLine();
int toReturn = -1;
if (int.TryParse(placeHolder, out toReturn))
return toReturn;
return getNumber();
}
as Juharr mentioned in the comments, you need to check the result to print the actual number.
Width Linq you can write:
int szam = 20;
int szam2= 30;
var odds = Enumerable.Range(szam2 > szam ? szam : szam2, Math.Abs(szam-szam2))
.Where(x=>x % 2 != 0);
outputs:
21
23
25
27
29
// so we create a range from low to high (Enumerable.Range(..)
// take only the odd values (x % 2 != 0)
simply wrap it in string.Join to make a single string:
string text = String.Join(",",Enumerable.Range(szam2 > szam ? szam :
szam2,Math.Abs(szam-szam2))
.Where(x=>x % 2 != 0));
I have a situation where I need to evenly distribute N items across M slots. Each item has its own distribution %. For discussion purposes say there are three items (a,b,c) with respective percentages of (50,25,25) to be distributed evenly across 20 slots. Hence 10 X a,5 X b & 5 X c need to be distributed. The outcome would be as follows:
1. a
2. a
3. c
4. b
5. a
6. a
7. c
8. b
9. a
10. a
11. c
12. b
13. a
14. a
15. c
16. b
17. a
18. a
19. c
20. b
The part that I am struggling with is that the number of slots, number of items and percentages can all vary, of course the percentage would always total up to 100%. The code that I wrote resulted in following output, which is always back weighted in favour of item with highest percentage. Any ideas would be great.
1. a
2. b
3. c
4. a
5. b
6. c
7. a
8. b
9. c
10. a
11. c
12. b
13. a
14. b
15. c
16. a
17. a
18. a
19. a
20. a
Edit
This is what my code currently looks like. Results in back weighted distribution as I mentioned earlier. For a little context, I am trying to evenly assign commercials across programs. Hence every run with same inputs has to result in exactly the same output. This is what rules out the use of random numbers.
foreach (ListRecord spl in lstRecords){
string key = spl.AdvertiserName + spl.ContractNumber + spl.AgencyAssignmentCode;
if (!dictCodesheets.ContainsKey(key)){
int maxAssignmentForCurrentContract = weeklyList.Count(c => (c.AdvertiserName == spl.AdvertiserName) && (c.AgencyAssignmentCode == spl.AgencyAssignmentCode)
&& (c.ContractNumber == spl.ContractNumber) && (c.WeekOf == spl.WeekOf));
int tmpAssignmentCount = 0;
for (int i = 0; i < tmpLstGridData.Count; i++)
{
GridData gData = tmpLstGridData[i];
RotationCalculation commIDRotationCalc = new RotationCalculation();
commIDRotationCalc.commercialID = gData.commercialID;
commIDRotationCalc.maxAllowed = (int)Math.Round(((double)(maxAssignmentForCurrentContract * gData.rotationPercentage) / 100), MidpointRounding.AwayFromZero);
tmpAssignmentCount += commIDRotationCalc.maxAllowed;
if (tmpAssignmentCount > maxAssignmentForCurrentContract)
{
commIDRotationCalc.maxAllowed -= 1;
}
if (i == 0)
{
commIDRotationCalc.maxAllowed -= 1;
gridData = gData;
}
commIDRotationCalc.frequency = (int)Math.Round((double)(100/gData.rotationPercentage));
if (i == 1)
{
commIDRotationCalc.isNextToBeAssigned = true;
}
lstCommIDRotCalc.Add(commIDRotationCalc);
}
dictCodesheets.Add(key, lstCommIDRotCalc);
}else{
List<RotationCalculation> lstRotCalc = dictCodesheets[key];
for (int i = 0; i < lstRotCalc.Count; i++)
{
if (lstRotCalc[i].isNextToBeAssigned)
{
gridData = tmpLstGridData.Where(c => c.commercialID == lstRotCalc[i].commercialID).FirstOrDefault();
lstRotCalc[i].maxAllowed -= 1;
if (lstRotCalc.Count != 1)
{
if (i == lstRotCalc.Count - 1 && lstRotCalc[0].maxAllowed > 0)
{
//Debug.Print("In IF");
lstRotCalc[0].isNextToBeAssigned = true;
lstRotCalc[i].isNextToBeAssigned = false;
if (lstRotCalc[i].maxAllowed == 0)
{
lstRotCalc.RemoveAt(i);
}
break;
}
else
{
if (lstRotCalc[i + 1].maxAllowed > 0)
{
//Debug.Print("In ELSE");
lstRotCalc[i + 1].isNextToBeAssigned = true;
lstRotCalc[i].isNextToBeAssigned = false;
if (lstRotCalc[i].maxAllowed == 0)
{
lstRotCalc.RemoveAt(i);
}
break;
}
}
}
}
}
}
}
Edit 2
Trying to clear up my requirement here. Currently, because item 'a' is to be assigned 10 times which is the highest among all three items, towards the end of distribution, items 16 - 20 all have been assigned only 'a'. As has been asked in comments, I am trying to achieve a distribution that "looks" more even.
One way to look at this problem is as a multi-dimensional line drawing problem. So I used Bresenham's line algorithm to create the distribution:
public static IEnumerable<T> GetDistribution<T>( IEnumerable<Tuple<T, int>> itemCounts )
{
var groupCounts = itemCounts.GroupBy( pair => pair.Item1 )
.Select( g => new { Item = g.Key, Count = g.Sum( pair => pair.Item2 ) } )
.OrderByDescending( g => g.Count )
.ToList();
int maxCount = groupCounts[0].Count;
var errorValues = new int[groupCounts.Count];
for( int i = 1; i < errorValues.Length; ++i )
{
var item = groupCounts[i];
errorValues[i] = 2 * groupCounts[i].Count - maxCount;
}
for( int i = 0; i < maxCount; ++i )
{
yield return groupCounts[0].Item;
for( int j = 1; j < errorValues.Length; ++j )
{
if( errorValues[j] > 0 )
{
yield return groupCounts[j].Item;
errorValues[j] -= 2 * maxCount;
}
errorValues[j] += 2 * groupCounts[j].Count;
}
}
}
The input is the actual number of each item you want. This has a couple advantages. First it can use integer arithmetic, which avoids any rounding issues. Also it gets rid of any ambiguity if you ask for 10 items and want 3 items evenly distributed (which is basically just the rounding issue again).
Here's one with no random number that gives the required output.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// name, percentage
Dictionary<string, double> distribution = new Dictionary<string,double>();
// name, amount if one more were to be distributed
Dictionary<string, int> dishedOut = new Dictionary<string, int>();
//Initialize
int numToGive = 20;
distribution.Add("a", 0.50);
distribution.Add("b", 0.25);
distribution.Add("c", 0.25);
foreach (string name in distribution.Keys)
dishedOut.Add(name, 1);
for (int i = 0; i < numToGive; i++)
{
//find the type with the lowest weighted distribution
string nextUp = null;
double lowestRatio = double.MaxValue;
foreach (string name in distribution.Keys)
if (dishedOut[name] / distribution[name] < lowestRatio)
{
lowestRatio = dishedOut[name] / distribution[name];
nextUp = name;
}
//distribute it
dishedOut[nextUp] += 1;
Console.WriteLine(nextUp);
}
Console.ReadLine();
}
}
Instead of a truly random number generator, use a fixed seed, so that the program has the same output every time you run it (for the same input). In the code below, the '0' is the seed, which means the 'random' numbers generated will always be the same each time the program is run.
Random r = new Random(0);
//AABC AABC…
int totalA = 10
int totalB = 5
int totalC = 5
int totalItems = 20 //A+B+C
double frequencyA = totalA / totalItems; //0.5
double frequencyB = totalB / totalItems; //0.25
double frequencyC = totalC / totalItems; //0.25
double filledA = frequencyA;
double filledB = frequencyB;
double filledC = frequencyC;
string output = String.Empty;
while(output.Length < totalItems)
{
filledA += frequencyA;
filledB += frequencyB;
filledC += frequencyC;
if(filledA >= 1)
{
filledA -= 1;
output += "A";
if(output.Length == totalItems){break;}
}
if(filledB >= 1)
{
filledB -= 1
output += "B";
if(output.Length == totalItems){break;}
}
if(filledC >= 1)
{
filledC -= 1
output += "C";
if(output.Length == totalItems){break;}
}
}
This answer was mostly stolen and lightly adapted for your use from here
My idea is that you distribute your items in the simplest way possible without care of order, then shuffle the list.
public static void ShuffleTheSameWay<T>(this IList<T> list)
{
Random rng = new Random(0);
int n = list.Count;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
Fiddle here
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);