This question already has answers here:
how can read values and put them in Array C#
(3 answers)
Closed 3 years ago.
I have been messing around with Lambda expressions in C#, teaching myself, and trying to test myself here. The problem with my code is not in evaluating the array for these set conditions, but rather I am having a difficult time capturing user input to build out the array. Have tried a few different methods, some mentioned here, but seem to have trouble adapting them to my code. Also any input on simplifying my expressions for checking if it has odd only or even only would be appreciated! I feel they are slightly bloated. Thanks!
using System;
namespace BuildingArrays
{
class Program
{
static void Main(string[] args)
{
int[] numbers = {Int32.TryParse(string, Console.ReadLine())};
bool hasOddOnly = Array.Exists(numbers, (int num) =>
{
bool hasEven = num % 2 == 0;
return hasEven;
});
hasOddOnly = !hasOddOnly;
bool hasEvenOnly = Array.Exists(numbers, (int num) =>
{
bool hasOdd = num % 2 != 0;
return hasOdd;
});
hasEvenOnly = !hasEvenOnly;
bool hasOddAnd4 = Array.Exists(numbers, (int num) =>
{
bool hasOdd = num % 2 != 0;
bool is4 = num == 4;
return is4 && hasOdd;
});
bool multipleOf4 = Array.Exists(numbers, (int num)=>
{
bool multiple = num % 4 == 0;
bool multiple2 = num % 3 == 0;
return multiple || multiple2;
});
bool multipleOf4and3 = Array.Exists(numbers, (int num)=>
{
bool multipleBoth = num % 4 == 0 && num % 3 == 0;
return multipleBoth;
});
Console.WriteLine($"This array contains odd numbers and 4 is {hasOddAnd4}");
Console.WriteLine($"This array contains ONLY odd numbers is {hasOddOnly}.");
Console.WriteLine($"This array contains ONLY even numbers is {hasEvenOnly}.");
Console.WriteLine($"This array contains either a multiple of 4, or a multiple of 3 is {multipleOf4}.");
Console.WriteLine($"This array contains a number which is both a multiple of 4 and 3 is {multipleOf4and3}");
}
}
}
Array.Exists takes a Predicate<T> as the second parameter. That should look like this:
bool hasEven = Array.Exists(numbers, x => x % 2 == 0);
To fill your array, you're going to need something like this:
for (int i=0; i< numbers.Length; i++)
numbers[i] = Int32.Parse(Console.ReadLine());
Further Reading
Array.Exists on MSDN
How to fill an array from user input in C#
Related
I was doing a LeetCode exercise for c# and made my own solution for the following prompt:
"Given a binary array nums, return the maximum number of consecutive 1's in the array."
"Input: nums = [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3."
My solution had a hardcoded array value, and i found a solution online that worked and ran fine. However, im having a really hard time understanding what the isStart and isEnd bools do. The code is below:
public class Solution {
public int FindMaxConsecutiveOnes(int[] nums)
{
if(nums == null || nums.Length == 0)
{
return 0;
}
var start = 0;
var length = nums.Length;
var maxLength = 0;
for(int i = 0; i < length; i++)
{
var current = nums[i];
bool isStart = current == 1 && (i == 0 || nums[i - 1] == 0);
bool isEnd = current == 1 && (i == length - 1 || nums[i + 1] == 0);
if (isStart)
{
start = i;
}
if(isEnd)
{
var currentOnes = i - start + 1;
maxLength = currentOnes > maxLength ? currentOnes : maxLength;
}
}
return maxLength;
}
I assume isStart and isEnd determine if we are at the Start or End of the array? I dont really understand what the operators do either. Any help could be appreciated. Thanks :)
This question already has answers here:
Best way to find all factors of a given number
(14 answers)
Closed 4 years ago.
I'm trying to get all the factors of a number provided by a user and after a button click displaying all the factors on a MessageBox.
This is what my code code taken from Getting Factors of a Number answer by Mark Byers looks like, I thought I was pretty close, but I'm displaying the number of factors not the actual factor numbers.
For example if the user types in 10 and uses a button click, the MessageBox displays the number 4, but i'm wanting it to display the actual factors of 10 which should be 1,2,5,10.
*how can I display the factors?
public int Divisors(int fact)
{
int number = int.Parse(textBox2.Text);
int factorCount = 0;
int sqrt = (int)Math.Ceiling(Math.Sqrt(number));
for (int i = 1; i < sqrt; i++)
{
if (number % i == 0)
{
factorCount += 2; // We found a pair of factors.
}
}
// Check if our number is an exact square.
if (sqrt * sqrt == number)
{
factorCount++;
}
return factorCount;
}
private void ShowallButton_Click(object sender, EventArgs e)
{
int input = int.Parse(textBox2.Text);
double output = Divisors(input);
MessageBox.Show(+output + "");
}
public List<int> Divisors(int fact)
{
List<int> factors = new List<int>();
int number = int.Parse(textBox2.Text);
int factorCount = 0;
int sqrt = (int)Math.Ceiling(Math.Sqrt(number));
for (int i = 1; i < sqrt; i++)
{
if (number % i == 0)
{
factors.Add(i);
factorCount += 2; // We found a pair of factors.
}
}
// Check if our number is an exact square.
if (sqrt * sqrt == number)
{
factorCount++;
}
// return factorCount;
return factors;
}
private void ShowallButton_Click(object sender, EventArgs e)
{
int input = int.Parse(textBox2.Text);
List<int> factors = Divisors(input);
string message = $"The Divisors are {string.Join(",", factors)}";
MessageBox.Show(message);
}
This is not very close at all.
Lets look at the factorisation first
% Operator (C# Reference)
The remainder operator % computes the remainder after dividing its
first operand by its second operand.
public static void Divisors(int number )
{
for (var x = 1; x <= number; x++)
if (number % x == 0) // no remainder it must be a factor
Console.WriteLine(x);
}
usage
Divisors(10);
Output
1
2
5
10
Now Lets return an Enumerable using yield
public static IEnumerable<int> Divisors(int number )
{
for (var x = 1; x <= number; x++)
if (number % x == 0) // no remainder it must be a factor
yield return x;
}
Usage
var results = Divisors(10);
Console.WriteLine(string.Join(", ", results));
Output
1, 2, 5, 10
Additional resources
yield (C# Reference)
When you use the yield contextual keyword in a statement, you indicate
that the method, operator, or get accessor in which it appears is an
iterator. Using yield to define an iterator removes the need for an
explicit extra class (the class that holds the state for an
enumeration, see IEnumerator for an example) when you implement the
IEnumerable and IEnumerator pattern for a custom collection type.
String.Join Method
Concatenates the elements of a specified array or the members of a
collection, using the specified separator between each element or
member.
private void ShowallButton_Click(object sender, EventArgs e)
{
var input = int.Parse(textBox2.Text);
var output = Divisors(input);
var message = string.Join(Environment.NewLine, output);
MessageBox.Show(message);
}
public List<int> Divisors(int number)
{
var factors = new List<int>();
for (var i = 1; i <= number; i++)
{
if (number % i == 0)
{
factors.Add(i);
}
}
return factors;
}
This question already has answers here:
Is there an easy way to turn an int into an array of ints of each digit?
(11 answers)
Closed 5 years ago.
To sort through 16 million combinations in the 8 Queens problem, I use an 8-digit number in which each digit represents a column, and the value of the digit is the row. No digit may repeat. My function accepts a number, converts it to a string, then to a char array, and then to an int array. Is there a simpler way to arrive at an int array?
Also, are any optimizations available in this code:
private bool IsValidSolution(int MyInt)
{
string sNum = MyInt.ToString();
int iVal = 0;
int i, k, j;
// Eliminate row and column conflicts.
char[] aChars = sNum.ToCharArray();
int[] aInt = Array.ConvertAll(aChars, c => (int)Char.GetNumericValue(c));
// The first false in the array is just a placeholder. Of interest are positions 1 - 8).
bool[] aCheck = new bool[] { false, false, false, false, false, false, false, false, false, false };
for (i = 0; i < 8; i++)
{
iVal = aInt[i];
if (iVal == 0 || iVal == 9) return false;
if (aCheck[iVal] == false)
{
aCheck[iVal] = true;
} else {
return false;
}
}
// Eliminate diagonal conflicts.
for (k = 0; k < 7; k++)
{
j = k + 1;
for (i = j; i < 8; i++)
{
if (Math.Abs(aInt[k] - aInt[i]) == Math.Abs(k - i)) return false;
}
}
return true;
}
Yes you can, using some arithmetic on the number let's say n = 4,732
To get the thousands digit you can do (int) n/1000.
To get the hundreds digit you do: ((int) n/100) % 10
The tens digit (3) you do: ((int) n/10) %10
and so on... and place each value in a block of the array of ints
Can be done in a loop
I try to write program that check the ratio between odd and even
digits in a given number. I've had some problems with this code:
static void Main(string[] args)
{
int countEven = 0 ;
int countOdd = 0 ;
Console.WriteLine("insert a number");
int num = int.Parse(Console.ReadLine());
int length = num.GetLength;
for (int i = 0;i<length ; i++)
{
if((num/10)%2) == 0)
int countEven++;
}
}
any ideas?
The problem is that int does not have a length, only the string representation of it has one.As an alternative to m.rogalski answer, you can treat the input as a string to get all the digits one by one. Once you have a digit, then parsing it to int and checking if it is even or odd is trivial.Would be something like this:
int countEven = 0;
int countOdd = 0;
Console.WriteLine("insert a number");
string inputString = Console.ReadLine();
for (int i = 0; i < inputString.Length; i++)
{
if ((int.Parse(inputString[i].ToString()) % 2) == 0)
countEven++;
else
countOdd++;
}
Linq approach
Console.WriteLine("insert a number");
string num = Console.ReadLine(); // check for valid number here?
int countEven = num.Select(x => x - '0').Count(x => x % 2 == 0);
int countOdd = num.Select(x => x - '0').Count(x => x % 2 != 0);
Let's assume your input is : 123456
Now all you have to do is to get the modulo from the division by ten : int m = num % 10;
After that just check if bool isEven = m % 2 == 0;
On the end you have to just divide your input number by 10 and repeat the whole process till the end of numbers.
int a = 123456, oddCounter = 0, evenCounter = 0;
do
{
int m = a % 10;
switch(m % 2)
{
case 0:
evenCounter++;
break;
default: // case 1:
oddCounter++;
break;
}
//bool isEven = m % 2 == 0;
}while( ( a /= 10 ) != 0 );
Online example
Made a small change to your code and it works perfectly
int countEven = 0;
int countOdd = 0;
Console.WriteLine( "insert a number" );
char[] nums = Console.ReadLine().ToCharArray();
for ( int i = 0; i < nums.Length; i++ )
{
if ( int.Parse( nums[i].ToString() ) % 2 == 0 )
{
countEven++;
}
else
{
countOdd++;
}
}
Console.WriteLine($"{countEven} even numbers \n{countOdd} odd numbers");
Console.ReadKey();
What I do is get each number as a a character in an array char[] and I loop through this array and check if its even or not.
If the Input number is a 32-bit integer (user pick the length of the number)
if asked:
The number of even digits in the input number
Product of odd digits in the input number
The sum of all digits of the input number
private void button1_Click(object sender, EventArgs e) {
int num = ConvertToInt32(textBox1.Text);
int len_num = textBox1.Text.Length;
int[] arn = new int[len_num];
int cEv = 0; pOd = 0; s = 0;
for (int i = len_num-1; i >= 0; i--) { // loop until integer length is got down to 1
arn[i] = broj % 10; //using the mod we put the last digit into a declared array
if (arn[i] % 2 == 0) { // then check, is current digit even or odd
cEv++; // count even digits
} else { // or odd
if (pOd == 0) pOd++; // avoid product with zero
pOd *= arn [i]; // and multiply odd digits
}
num /= 10; // we divide by 10 until it's length is get to 1(len_num-1)
s += arn [i]; // sum of all digits
}
// and at last showing it in labels...
label2.Text = "a) The even digits count is: " + Convert.ToString(cEv);
label3.Text = "b) The product of odd digits is: " + Convert.ToString(pOd);
label4.Text = "c) The sum of all digits in this number is: " + Convert.ToString(s);
}
All we need in the interface is the textbox for entering the number, the button for the tasks, and labels to show obtained results. Of course, we have the same result if we use a classic form for the for loop like for (int i = 0; and <= len_num-1; i++) - because the essence is to count the even or odd digits rather than the sequence of the digits entry into the array
static void Main(string args[]) {
WriteLine("Please enter a number...");
var num = ReadLine();
// Check if input is a number
if (!long.TryParse(num, out _)) {
WriteLine("NaN!");
return;
}
var evenChars = 0;
var oddChars = 0;
// Convert string to char array, rid of any non-numeric characters (e.g.: -)
num.ToCharArray().Where(c => char.IsDigit(c)).ToList().ForEach(c => {
byte.TryParse(c.ToString(), out var b);
if (b % 2 == 0)
evenChars++;
else
oddChars++;
});
// Continue with code
}
EDIT:
You could also do this with a helper (local) function within the method body:
static void Main(string args[]) {
WriteLine("Please enter a number...");
var num = ReadLine();
// Check if input is a number
if (!long.TryParse(num, out _)) {
WriteLine("NaN!");
return;
}
var evenChars = 0;
var oddChars = 0;
// Convert string to char array, rid of any non-numeric characters (e.g.: -)
num.ToCharArray().Where(c => char.IsDigit(c)).ToList().ForEach(c => {
byte.TryParse(c.ToString(), out var b);
if (b % 2 == 0)
evenChars++;
else
oddChars++;
// Alternative method:
IsEven(b) ? evenChars++ : oddChars++;
});
// Continue with code
bool IsEven(byte b) => b % 2 == 0;
}
Why am I using a byte?
Dealing with numbers, it is ideal to use datatypes that don't take up as much RAM.
Granted, not as much an issue nowadays with multiple 100s of gigabytes possible, however, it is something not to be neglected.
An integer takes up 32 bits (4 bytes) of RAM, whereas a byte takes up a single byte (8 bits).
Imagine you're processing 1 mio. single-digit numbers, and assigning them each to integers. You're using 4 MiB of RAM, whereas the byte would only use up 1 MiB for 1 mio. numbers.
And seeming as a single-digit number (as is used in this case) can only go up to 9 (0-9), you're wasting a potential of 28 bits of memory (2^28) - whereas a byte can only go up to 255 (0-255), you're only wasting a measly four bits (2^4) of memory.
can you help me with the following exercise pls? (it's not homework, just an exercise in the book I'm using.)
"An integer is said to be a perfect number if its factors, including one (but not the number itself), sum to the number. For example, 6 is a perfect number, because 6 = 1 + 2 + 3. Write method Perfect that determines whether parameter value is a perfect number. Use this method in an app that determines and displays all the perfect numbers between 2 and 1000. Display the factors of each perfect number to confirm that the number is indeed perfect."
so here's what i got so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perfect_Numbers2
{
class Program
{
static bool IsItPerfect(int value)
{
int x = 0;
int counter = 0;
bool IsPerfect = false;
List<int> myList = new List<int>();
for (int i = value; i <= value; i++)
{
for (int j = 1; j < value; j++)
{
// if the remainder of i divided by j is zero, then j is a factor of i
if (i%j == 0) {
myList[counter] = j; //add j to the list
counter++;
}
for (int k = 0; k < counter; k++)
{
// add all the numbers in the list together, then
x = myList[k] + myList[k + 1];
}
// test if the sum of the factors equals the number itself (in which case it is a perfect number)
if (x == i) {
IsPerfect = true;
}
}
Console.WriteLine(i);
}
return IsPerfect;
}
static void Main(string[] args)
{
bool IsItAPerfectNum = false;
for (int i = 2; i < 1001; i++)
{
IsItAPerfectNum = IsItPerfect(i);
}
}
}
}
how would you do it? is my code fixable? how would you fix it? thanks!
im getting an error at line myList[counter] = j; (index was out of range) and besides it's not displaying the perfect numbers like it's supposed to....
EDIT = I made some changes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perfect_Numbers2
{
class Program
{
static bool IsItPerfect(int value)
{
int x = 0;
int counter = 0;
bool IsPerfect = false;
List<int> myList = new List<int>();
for (int i = value; i <= value; i++)
{
for (int j = 1; j < i; j++)
{
if (i%j == 0) // if the remainder of i divided by j is zero, then j is a factor of i
{
myList.Add(j); //add j to the list
}
x = myList.Sum();
if (x == i) // test if the sum of the factors equals the number itself (in which case it is a perfect number)
{
IsPerfect = true;
}
}
Console.WriteLine(i);
}
return IsPerfect;
}
static void Main(string[] args)
{
bool IsItAPerfectNum = false;
for (int i = 2; i < 1001; i++)
{
IsItAPerfectNum = IsItPerfect(i);
Console.WriteLine(IsItAPerfectNum);
Console.ReadKey(true);
}
}
}
}
now i can cycle through all the numbers until 1000 and it displays if it's perfect or not (true or false) [which isn't what the exercise called for, but it's a step in the right direction (the exercise says that it should display only the perfect numbers)].
In any case, what's strange is that it says true at number 24, which isn't a perfect number.... http://en.wikipedia.org/wiki/Perfect_numbers#Examples
why is 24 different?
thanks very much
can you help me with the following exercise please?
Yes. Rather than showing you where your error is, I'll teach you how to find your error. Even better, the same technique will lower the chances of you causing the error in the first place.
The key here is to break the problem down into small parts where each small part can be tested independently. You have already started to do this! You have two methods: Main and IsItPerfect. You should have at least three more methods. The methods you should have are:
IsDivisor -- takes two integers, returns true if the first divides the second.
GetAllDivisors -- takes an integer, returns a list of all the divisors
Sum -- takes a list of integers, returns the sum
Your method IsPerfect should be calling GetAllDivisors and Sum and comparing the sum to the original number, and that's all it should be doing. Your method GetAllDivisors should be calling IsDivisor, and so on.
You can't find the bug easily because your method is doing too much. If you're not getting the correct result out and you have four methods instead of one then you can test each method independently to make sure that it works, or fix it if it does not.
Your first for loop will be executed exactly once.
for (int i = value; i <= value; i++)
For example for value = 6
for (int i = 6; i <= 6; i++)
Some help with the 24 issue you are having: 24 is returning true as you are actually checking if it is perfect on every additional factor. So 24 gets flipped to true here:
Factors of 24 | Total so far
1 1
2 3
3 6
4 10
6 16
8 24 <-- returns true
12 36 <-- should be false, but flag is never reset
I have just now completed the same exercise which is from a really great book called visual c# 2012 by Mr Deitel.
The way i started to tackle is, i started off with figuring out how to work out the factorials of numbers and then slowly kept building on from there.
Since you are following the same book, i would suggest you not to use things that are not covered up to that chapters exercise, like list collections which you have used, As this will make the exercise unnecessarily difficult. and negates the learning methodology set out by of the author.
here is my code which i hope can help you in some way.
class Program
{
static int factorTotal = 1;
static void Main(string[] args)
{
int count = 1;
while (count <= 10000)
{
bool isPerfect = IsPerfectNumber(count);
if (isPerfect && (factorTotal >1))
{
Console.WriteLine("Is Perfect: {0}", factorTotal);
}
factorTotal = 1;
count++;
}
} // end main
static bool IsPerfectNumber(int n)
{
int temp;
int counter = 2;
bool IsPerfect = false;
while (counter <= (n - 1))
{
temp = n % counter;
if (temp == 0) // if true than factor found
{
factorTotal = factorTotal + counter;
}
counter++;
}
if ((factorTotal) == n)
IsPerfect = true;
else
IsPerfect = false;
return IsPerfect;
}
}//end class
under the Main method of you console application copy and paste below code.
I explained few things at the end of the code...
=====================================================================
{
Console.WriteLine("perfect numbers/n");
Console.Write("Enter upper limit: ");
int iUpperLimit = int.Parse(Console.ReadLine());
string sNumbers = "";
List<int> lstFactor = new List<int>();
for(int i = 1;i<=iUpperLimit;i++)
{
for(int k = 1;k<i;k++)
{
if (i % k == 0)
{
lstFactor.Add(k); //this collect all factors
}
if (k == i-1)
{
if (lstFactor.Sum() == i) //explain1
{
sNumbers += " " + i;
lstFactor.Clear(); //explain2
break;
}
else
{
lstFactor.Clear(); //explain2
}
}
}
}
Console.WriteLine("\nperfect numbers are: " + sNumbers);
Console.ReadKey();
}
}
=======================================================================
note that i is a number that we test and k is its factors.
explain1 => we add all factors collected and check if they are equal to i (we simply check if i is perfect number)
explain2 => we have to clear our list before we can check if the next number i is a perfect number or not so that factors of the previous number does not interfere with factors of the current number.
int start=1;
int end=50;
for(int a=end ; a > start ;a--)
{
int b=1;
int c=0;
bool x=false;
for(int i=1 ; i < a ;i++)
{
b=a/i;
if(b*i==a)
{
c+=i;
}
if(c==a & i==a/2)
{
x=true;
}
}
if(x==true)
Console.Write("{0} is : {1}",a,x);
}