I am trying to improve a list collection that i have to replace values that are divisible by two and 10 and replace everything that is divisible by two with dTwo and ten with dTen?
My code works with one divisible statment but not two.
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
num.Add(n % 10 == 0 ? "dTen" : n.ToString());
}
Since any number that is divisible by 10 is also divisible by 2 you have to switch your addition statements, and continue with the next number if you have a number divisible by 10:
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
if( n % 10 == 0)
{
num.Add("dTen");
}
else num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
}
If I can I try avoid using loop controls out side of the defined construct of the actual loop, ie. I prefer to avoid using continue if I can, it sort of feels like using goto statements. For this case, I would go for the plain and simple approach which I believe is readable, maintainable and simple albeit a little more verbose.
You can switch the order of the if/else if statements to change the priority if required, in this case the n % 10 has priority
var num = new List<string>();
for (int n = 0; n < 101; ++n)
{
if (n % 10 == 0)
{
num.Add("dTen");
}
else if (n % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(n.ToString());
}
}
There are two approaches I would take here, the first is verbose, but conveys what you're trying to do in a very readable manner:
var num = new List<string>(101);
for (int i = 0; i < 101 ; i++)
{
if (i == 0)
{
num.Add(i.ToString());
}
else if (i % 10 == 0)
{
num.Add("dTen");
}
else if (i % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(i.ToString());
}
}
The second uses a more concise LINQ-y type approach, like this.
var num = Enumerable.Range(0, 101)
.Select(
n => n == 0 ? n.ToString() :
n % 10 == 0 ? "dTen" :
n % 2 == 0 ? "dTwo" :
n.ToString())
.ToList();
Note that I've also taken into account the 0 edge case, where 0 would otherwise get reported as being divisible by 10.
Which one you go for is largely up to your taste. Personally I'd go for the latter implementation, as it's concise but still conveys the intent of the code. Some very rudimentary tests I've just done shows that it'll execute faster as well.
Related
I have a class RekenReeks which returns numbers starting from 2, multiplied by 2. So {2,4,8,16,32,64}
Now I learned about the TakeWhile and SkipWhile methods as well as LINQ.
So I have created 3 variables which should store exactly the same but my Console.WriteLine only prints selection1 and not 2 and 3.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
RekenReeks reeks = new RekenReeks(2, n => n * 2);
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);
var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);
foreach (int i in selection)
{
Console.WriteLine("selection1 {0}",i);
}
foreach (int i in selection2)
{
Console.WriteLine("selection2 {0}", i);
}
foreach (int i in selection3)
{
Console.WriteLine("selection3 {0}", i);
}
Console.ReadLine();
}
}
public class RekenReeks : IEnumerable<int>
{
Func<int, int> getNew;
int number;
public RekenReeks(int starton, Func<int, int> getNewThing)
{
getNew = getNewThing;
number = starton;
}
public IEnumerator<int> GetEnumerator()
{
yield return number;
for (; ; )
{
yield return getNew(number);
number = getNew(number);
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
Your sequence is unlimited (theoretically). You assume too much. The functionality of your program cannot possibly know that your sequence is strictly monotonic increasing.
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
This will never stop. Because the where will always pull the next value, it does not know it's condition will be satisfied, it always has to check the next value.
var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);
This will take values, while they are between 11 and 999. As your sequence starts with 2, it will stop right on the first value.
var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);
This will skip values while they are between 11 and 999. As the first is 2, it will skip none and therefore yield all.
Both TakeWhile() and SkipWhile() start from very beginning of the sequence and stop taking/skipping when condition doesn't meet.
// I've redesigned your ReekenReeks
// [2, 4, 8, 16, 32, 64, ..., 2**30]
var reeks = Enumerable
.Range(1, 30)
.Select(index => 1 << index);
For instance, if you put
var selection2 = reeks
.TakeWhile(n => n < 1000 && n > 10);
since the 1st item of the reeks is 2 the condition n < 1000 && n > 10 doesn't meet TakeWhile stops and returns an empty sequence. The right implemenation is
var selection2 = reeks
.SkipWhile(n => n <= 10)
.TakeWhile(n => n < 1000);
If you want to cut off values from the middle of the sequence (selection3) you have to use Where:
var selection3 = reeks
.Where(n => !(n > 1000 && n < 10)); // cut theses items off
Be careful when printing out an infinine sequence, .Take() is a good choice here:
var selection3 = reeks
.Where(n => n > 1000 && n < 10)
.Take(100); // First 100 items in case the sequence is too long
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
There's no reason for this to ever end. When i is 1024 it won't be yielded, but it will still check then if 2048 is less than 1000, or 4096 is less than 1000, or 8192 is less than 1000 and so on forever (eventually either overflow exception happens or n wraps around to 0 which then keeps being set to 0 * 2 which is still 0).
reeks.TakeWhile(n => n < 1000 && n > 10)
The first value tried is 2. This does not satisfy the predicate n < 1000 && n > 10 because it is not true that 2 > 10. Therefore the taking stops.
reeks.SkipWhile(n => n > 1000 && n < 10)
There is no value of n for which n > 1000 && n < 10. Therefore this is the same as having no SkipWhile at all.
It seems like what you want is:
reeks.SkipWhile(n => n >= 1000 || n <= 10).TakeWhile(n => n < 1000 && n > 10)
Which skips until the first number that meets the criteria is found, then takes all that meet it until the first that does not.
for (int k = 0; k < proc.Count; k++){
for (int i = k + 1; i < proc.Count; i++){
if (proc[k].arrivalTime >= proc[i].arrivalTime && proc[k].priority >= proc[i].priority && proc[k].brust > proc[i].brust){
temp = proc[i];
proc[i] = proc[k];
proc[k] = temp;
}
}
}
Input
Process Arrival Brust Priority
P0 0 10 5
P1 1 3 1
P2 1 2 1
P3 5 1 5
P4 5 8 2
I want to sort these processes following these rules
1) If the process arrived alone it'll work no matter what.
2) If 2 processes arrived in the same time, we gonna check the priority if the first one has higher priority(lower number) it'll work first, and if they have the same priority we gonna let the one who has lower Brust work first.
There's problem with last 2 processes where's the problem?
P3 5 1 5
P4 5 8 2
process 4 should work because it has higher priority
Rather than bubble sorting (which is the one of the least efficient ways to sort collections), why not just sort the collection using LINQ's OrderBy(), e.g.
var sorted = proc.OrderBy(x => x.arrivalTime)
.ThenBy(x => x.priority)
.ThenBy(x => x.brust)
.ToList(); // or .ToArray() or whatever collection you need
You provided very clear explanation of the rules.
Now check this line
if (proc[k].arrivalTime >= proc[i].arrivalTime && proc[k].priority >= proc[i].priority && proc[k].brust > proc[i].brust)
Is it doing what the rules say? Definitely no. The direct translation of the rules would be something like this
if (proc[k].arrivalTime > proc[i].arrivalTime ||
(proc[k].arrivalTime == proc[i].arrivalTime &&
(proc[k].priority > proc[i].priority ||
(proc[k].priority == proc[i].priority && proc[k].brust > proc[i].brust))))
Better and more readable would be
int compare = proc[k].arrivalTime.CompareTo(proc[i].arrivalTime);
if (compare == 0)
compare = proc[k].priority.CompareTo(proc[i].priority);
if (compare == 0)
compare = proc[k].brust.CompareTo(proc[i].brust);
if (compare > 0)
{
// ...
}
which is the standard way of doing multi key comparison.
Mahmoud, your if-statment is incorrect because it will evaluate to true if ALL conditions are met, your statement should cascade the conditions.
for (int k = 0; k < proc.Count; k++){
for (int i = k + 1; i < proc.Count; i++){
bool doSwap = false;
if (proc[k].arrivalTime > proc[i].arrivalTime)
{
doSwap = true;
}
else if (proc[k].arrivalTime == proc[i].arrivalTime)
{
if(proc[k].priority > proc[i].priority)
{
doSwap = true;
}
else if (proc[k].priority == proc[i].priority )
{
if(proc[k].brust > proc[i].brust)
{
doSwap = true;
}
}
}
if(doSwap)
{
temp = proc[i];
proc[i] = proc[k];
proc[k] = temp;
}
}
}
I need help with a simple C# program. Simpley yet I don't know the solution. The problem is here: I need to loop (or print on the screen) all numbers in this order: 2, -3, 4, -5, 6, -7, etc. until they reach 100.
Do you have any ideas how to do that? For now I've done something like that:
for (int i = -2; i <= 100; i += 1)
{
Console.WriteLine(i);
}
But I can't get it to work like the order I want, I know I'm doing something wrong in the i += 1 section but I can't figure out how to do that! Thank you for your support.
You can multiple with -1 on odd numbers, therefore use the % operator:
for (int i = 2; i <= 100; i++)
{
int val = i % 2 == 1 ? i * -1 : i;
Console.WriteLine(val);
}
Demo
for(int i=2;i<=100;++i){
Console.WriteLine(i % 2 == 1 ? -i : i);
}
Pretty simple if we use modulo
The steps are faily straight forward. If we will notice the it's the same solution as printing 2-100 but with 1 little twist, for the odd places the number i should be at his negative sign. So the solution will be the same.
Steps:
Loop i to 100
For every iteration we will decide if it's odd or even.
If i is even will multiply it by 1 that will result with i of course. else, that means it's odd and thus, resulting in
multiplying with -1, resulting with minus i.
Code
for (int i = 2; i <= 100; i++)
{
Console.WriteLine(i * (i%2 == 0 ? 1 : -1));
}
You should iterate from 2 to 100 one by one (yes, all are positive values)
Then in loop body you should invert sign on each iteration (by multiplying on "-1") and print the result on screen.
Using bitwise and to spot the odd numbers:
for (int i = 2; i <= 100; i += 1)
{
int toPrint = i
if((i & 1)==1)
{
// It's odd
toPrint = -toPrint;
}
Console.WriteLine(toPrint);
}
static void Main(string[] args)
{
for (int i = 2; i <= 100; i++)
{
if (i % 2 == 1)
{
int j = -i;
Console.WriteLine(j);
}
else
Console.WriteLine(i);
}
Console.ReadLine();
}
As we all did this task in school:
Enumerable.Range(2, Int32.MaxValue - 1)
.TakeWhile(i => i <= 100)
.Select(i => i % 2 == 0 ? i : -i)
.ToList()
.ForEach(Console.WriteLine);
In my program, I think my count variable is not holding the value. What do I do so that it can hold? here`s my code.
static void Main(string[] args)
{
double a;
double count = 0;
Console.WriteLine("Enter the Numbers : ");
for (double i = 1; i <= 10; i++)
{
a = Convert.ToDouble(Console.ReadLine());
if (a % 2 != 0 || a % 3 != 0 || a % 5 != 0)
{
count = count++;
}
//else
//{
// }
Console.ReadLine();
}
Console.WriteLine("The Numbers That Are divisible by 2,3,5 are : " + count);
Console.ReadLine();
}
Your mistake is the line count = count++;. This does not increase count by one. You need to use just count++;.
The expression count++ will increment the value of count by one and then return as the expression's value the original value of count. In this case the increment of count++ happens before the assignment, so count is first incremented by one, but then you assign the value of count++, that is, the original value, to count again, so it does not increase at all.
Your program lists numbers that are not divisible by any of those numbers. If you want to count numbers which aren't divisible by all of them then you need to use if (a % 2 != 0 && a % 3 != 0 && a % 5 != 0) instead. I would also suggest using integers instead of doubles if possible.
Finally, your print statement says numbers that are divisible by 2,3,5, but count is the number of numbers which are not divisible by those numbers.
Edit: Are you entering 10 numbers each time you test? I'm not sure what kind of result you will get if you give a blank input.
Not to add to what jk and David Kanarek said in their answers or what the others the comments on those answers, As pointed out by jk use count+1 instead of count ++ , also a few notes:
1) Your using console.Readline() twice in the loop, so the user will enter 20 inputs but only 10 will be read..
2) Just alittle extra thought on Anton's comment, in your if clause , if you use || your trying to catch any of the conditions being true, in other words:
// a=2
if (a % 2 != 0 || a % 3 != 0 || a % 5 != 0) // False || True || True = True
{
count = count + 1 ;// count will increase
}
on the other hand, using && :
// a=2
if (a % 2 != 0 && a % 3 != 0 && a % 5 != 0) // False && True && True = false
{
count = count + 1 ; //count will not increase
}
A useful Link explaining operators
So after pulling my hair out for 30 minutes, I have decided to come to SO for some help on this problem:
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
Now, I don't want to know how to do the problem - that's easy - and especially not the answer. I would like to know why my code isn't giving me the correct answer when I run it (C#):
using System;
using System.Collections.Generic;
public class Euler010 {
public static bool isPrime(Int64 n) {
if (n <= 1)
return false;
if (n < 4)
return true;
if (n % 2 == 0)
return false;
if (n < 9)
return true;
if (n % 3 == 0)
return false;
Int64 r = (Int64)Math.Floor(Math.Sqrt((double)n));
Int64 f = 5;
while (f <= 4) {
if (n % f == 0)
return false;
if (n % (f + 2) == 0)
return false;
f += 6;
}
return true;
}
public static void Main() {
Int64 sum = 2;
for (Int64 n = 3; n <= 2000000; n+=2) {
if (isPrime(n)) {
sum += n;
}
}
Console.WriteLine(sum);
Console.ReadLine();
}
}
When run to n <= 10, it outputs 17, like it should. When run to anything that's easy to compute by hand, it outputs the correct answer (like n <= 20 -> 77).
However, when I run this, it outputs 666667333337 which is wrong.
Any ideas?
Int64 f = 5;
while (f <= 4) {
Maybe I'm missing something here but these two lines don't seem to make sense. I'm fairly certain that the code posted above will never execute the body of the while loop.
Perhaps you meant to check if f is less than the square root of r?
You're not using the variable r in your loop, I assume you probably want to loop while f<=r?
Not what you are looking for, but you should probably use something like Sieve of Eratosthenes to generate your primes.
Plus the existing tests catch all non-primes below 20 (divisible by 2, 3, etc).