Resolve a Perfect Sum with Predicate - c#

Hi everyone I'm trying to resolve this c# exercise but I couldn't find the way to do it. Even without doing with the suggested tip below.
Make a perfect sum with the following examples
Example 1:
input1: 5
input2: {9,6,3,12,7}
input3: 14
Output: 1
Explanation:
Here, the sum of elements 7+7=14. Hence, the number of perfect sums in
the given array is 1. Therefore, 1 is returned as the output.
Example 2:
input1: 5 input2: (4,7,8,2,3} input3: 12
Output: 2
Explanation:
Here, the sum of elements 8+4=12 and 7+3+2=12. Hence, the number of
perfect sums in the given array is 2. Therefore, 2 is returned as the
output
Tip: I rather like seeing Predicate in a function signature. It illustrates that the passed method makes a decision rather than just returns a success code or a different sort of bool.
Base Code:
class Program
{
static void Main(string[] args)
{
//Call the method here
Console.ReadKey();
}
static int PerfectSums(int input, int[] input2, int input3)
{
throw new NotImplementedException();
}
}

Related

C# Creating a list that takes user input and after prints the number from the list within a certain value range.(please explain how and why it works)

using System;
using System.Collections.Generic;
namespace exercise_69
{
class Program
{
public static void Main(string[] args)
{
List<int> numbers = new List<int>();
//creating a list called numbers
while (true)
{
int input = Convert.ToInt32(Console.ReadLine());
if (input == -1)
{
break;
}
numbers.Add(input);
}
//fills a list called numbers until user enters " -1 "
Console.WriteLine("from where");
int lownum = Convert.ToInt32(Console.ReadLine());
//lowest number to get printed
Console.WriteLine("where to");
int highnum = Convert.ToInt32(Console.ReadLine());
//highest number to get printed
foreach(int number in numbers)
{
if(lownum < number || highnum > number)
{
Console.WriteLine(numbers);
} //trying to filter the numbers and print them
}
}
}
}
Blockquote
the issue i am having is when i run the program the console just tells me this
"System.Collections.Generic.List`1[System.Int32]"
so my question is how do i properly filter or remove numbers from a list within a certain value ( not index )
the console just tells me this "System.Collections.Generic.List`1[System.Int32]"
That's because you did this:
Console.WriteLine(numbers);
numbers is a List<int>, it's a whole collection of numbers not just a single number. Console.WriteLine has many varaitions ("overloads") that know how to do all different kinds of things. It has a large quantity of specific variations for numbers, strings, etc and there is one variation that's like a "catch-all" - it accepts an object which means it can accept pretty much anything in the C# universe. The only thing it does with it, if you do manage to end up using this variation (overload), is call ToString() on whatever you passed in, and then print the string it gets back.
Because you passed a List<int> in, and Console.WriteLine doesn't have any variation that does anything cool with a List specifically, it means your passed-in List gets treated by the catch-all version of WriteLine; "call ToString on what was passed in and print the result". Because List doesn't have a very specific or interesting ToString() of its own, it just inherits a version of ToString() from object, the most simple root of all things in C#. Object's ToString() doesn't do very much - it just returns the type of the object which, in this case, is a "System.Collections.Generic.List`1[System.Int32]".. and that's why you see what you see in the console
Now that you know why your code is printing the type of the List, because you're passing in a List, can you see how to change it so you're passing in something else (like, e.g. an actual number you want to print) ?
Console.WriteLine(numbers);
^^^^^^^
this needs to be something else - can you work out what?

How do I add 1 number to a array? [duplicate]

This question already has answers here:
Add new item in existing array in c#.net
(20 answers)
Closed 1 year ago.
I do not have anything other than the normal
using System;
namespace TryStuff
{
class Program
{
static void Main(string[] args)
{
}
}
}
And I know that having nothing at the start and still asking questions isnt highly looked on but STILL...
Im trying to create a code that asks you for an integer, and if you answer anything over 0, it ADDS the given number to an array, once you stop giving numbers (example type some "stop") it prints out ALL the numbers given to the array.
I DO NOT need the full code for something like this, just an answer to how do I append to an array without making it insanely complicated (things ive found on the google are like 20 lines of code but im pretty sure its not that hard).
Sorry for the long post and in short, how do I append to an array? If you can provide me a code, please implement it in the C# code or give me a "explanation" how to do it. Thank you very much!
You probably don't want to use an array, you want a different data structure that allows easy expansion, like List<T>. For List<T>, you simply call .Add, like:
using System;
using System.Collections.Generic;
namespace TryStuff
{
class Program
{
static void Main(string[] args)
{
var myList = new List<int>();
while(int.TryParse(Console.ReadLine(), out int x))
{
if (x > 0)
{
myList.Add(x);
}
}
Console.WriteLine("You entered: " + string.Join(",", myList));
}
}
}
This should keep allowing you to enter integer numbers and add them to the list if the number is greater than 0. It ignores all numbers 0 or less than 0. If you type anything that is not a number, it will stop and print out the list you entered.

C# - Creating a recursive function to calculate the sum of a list. Is it possible using only the list as the only parameter?

So in my attempt to start learning c# one challenge I've come across is to create a recursive function that will calculate the sum of a list. I'm wondering if it's possible to do this using a list as the only argument of the function? Or would I need to apply an index size as well to work through the list?
int addRecursively(List<int> numList)
{
int total = numList[0];
if (numList.Count > 1)
{
numList.RemoveAt(0);
return total += addRecursively(numList);
}
Console.WriteLine(total);
return total;
}
List<int> numbers = new<List<int> {1,2,3,4,5,6,7,8};
addRecursively(numbers); //returns only the last element of whichever list I enter.
I was hoping by assigning the total to the first index of the list before deleting the first index of the list that when passed into the next instance of the function the index of each element in the list would move down one, allowing me to get each value in the list and totalling them up. However using the function will only ever return the last element of whichever list of integers I enter.
My thought process came from arrays and the idea of the shift method on an array in JS, removing the first element and bringing the whole thing down.
Am I attempting something stupid here? Is there another similar method I should be using or would I be better off simply including a list size as another parameter?
Thanks for your time
So in my attempt to start learning c# one challenge I've come across is to create a recursive function that will calculate the sum of a list. I'm wondering if it's possible to do this using a list as the only argument of the function? Or would I need to apply an index size as well to work through the list?
That's a great exercise for a beginner. However, you would never, ever do this with a List<int> in a realistic program. First, because you'd simply call .Sum() on it. But that's a cop-out; someone had to write Sum, and that person could be you.
The reason you would never do this recursively is List<T> is not a recursive data structure. As you note, every time you recurse there has to be something different. If there is not something different then you have an unbounded recursion!
That means you have to change one of the arguments, either by mutating it, if it is a reference type, or passing a different argument. Neither is correct in this case where the argument is a list.
For a list, you never want to mutate the list, by removing items, say. You don't own that list. The caller owns the list and it is rude to mutate it on them. When I call your method to sum a list, I don't want the list to be emptied; I might want to use it for something else.
And for a list, you never want to pass a different list in a recursion because constructing the new list from the old list is very expensive.
(There is also the issue of deep recursion; presumably we wish to sum lists of more than a thousand numbers, but that will eat up all the stack space if you go with a recursive solution; C# is not a guaranteed-tail-recursive language like F# is. However, for learning purposes let's ignore this issue and assume we are dealing with only small lists.)
Since both of the techniques for avoiding unbounded recursions are inapplicable, you must not write recursive algorithms on List<T> (or, as you note, you must pass an auxiliary parameter such as an index, and that's the thing you change). But your exercise is still valid; we just have to make it a better exercise by asking "what would we have to change to make a list that is amenable to recursion?"
We need to change two things: (1) make the list immutable, and (2) make it a recursively defined data structure. If it is immutable then you cannot change the caller's data by accident; it's unchangeable. And if it is a recursively defined data structure then there is a natural way to do recursion on it that is cheap.
So this is your new exercise:
An ImmutableList is either (1) empty, or (2) a single integer, called the "head", and an immutable list, called the "tail". Implement these in the manner of your choosing. (Abstract base class, interface implemented by multiple classes, single class that does the whole thing, whatever you think is best. Pay particular attention to the constructors.)
ImmutableList has three public read-only properties: bool IsEmpty, int Head and ImmutableList Tail. Implement them.
Now we can define int Sum(ImmutableList) as a recursive method: the base case is the sum of an empty list is zero; the inductive case is the sum of a non-empty list is the head plus the sum of the tail. Implement it; can you do it as a single line of code?
You will learn much more about C# and programming in a functional style with this exercise. Use iterative algorithms on List<T>, always; that is what it was designed for. Use recursion on data structures that are designed for recursion.
Bonus exercises:
Write Sum as an extension method, so that you can call myImmutableList.Sum().
Sum is a special case of an operation called Aggregate. It returns an integer, and takes three parameters: an immutable list, an integer called the accumulator, and a Func<int, int, int>. If the list is empty, the result is the accumulator. Otherwise, the result is the recursion on the tail and calling the function on the head and the accumulator. Write a recursive Aggregate; if you've done it correctly then int Sum(ImmutableList items) => Aggregate(items, 0, (acc, item) => acc + item); should be a correct implementation of Sum.
Genericize ImmutableList to ImmutableList<T>; genericize Aggregate to Aggregate<T, R> where T is the list element type and R is the accumulator type.
Try this way:
int addRecursively(List<int> lst)
{
if(lst.Count() == 0) return 0;
return lst.Take(1).First() + addRecursively(lst.Skip(1).ToList());
}
one more example:
static public int RecursiveSum(List<int> ints)
{
int nextIndex = 0;
if(ints.Count == 0)
return 0;
return ints[0] + RecursiveSum(ints.GetRange(++nextIndex, ints.Count - 1));
}
These are some ways to get the sum of integers in a list.
You don't need a recursive method, it spends more system resources when it isn't needed.
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
int sum1 = numbers.Sum();
int sum2 = GetSum2(numbers);
int sum3 = GetSum3(numbers);
int sum4 = GetSum4(numbers);
}
private static int GetSum2(List<int> numbers)
{
int total = 0;
foreach (int number in numbers)
{
total += number;
}
return total;
}
private static int GetSum3(List<int> numbers)
{
int total = 0;
for (int i = 0; i < numbers.Count; i++)
{
total += numbers[i];
}
return total;
}
private static int GetSum4(List<int> numbers)
{
int total = 0;
numbers.ForEach((number) =>
{
total += number;
});
return total;
}
}

How can I modify a function's behavior based on if it is being assigned to a variable?

As in the title.
I know this is possible in other languages - is it in C#?
If the question title isn't clear, i would like something that does (something like) this:
MyClass exampleObject1 = new MyClass(...)
exampleObject1.sort() //sort method detects that value is not being assigned and performs sort in place.
MyClass exampleObject2 = exampleObject1.sort() //method detects assignment and returns new sorted object leaving original untouched.
is this something that's possible without resorting to magic? If it is possible, but in some nasty way, what is that way?
EDIT: for those wanting to see an example where you can do this (in python): here. Note that i caveat it with the issue that it does not always work - but this is only in relation to the way i did it when i answered the question. Now i know more about inspect, and you can get all the information you need from the stack to work out if it is being assigned anywhere or not.
Of course, you definitely shouldn't be doing this, but since the OP is more interested if it could be done for curiosity sake, then here is a snippet of code that demonstrates this capability:
class SomeWeirdClass
{
private bool sortApplied = false;
private List<int> elements;
public IList<int> Elements
{
get
{
if(sortApplied)
{
elements.Sort();
sortApplied = false;
}
return elements;
}
}
public SomeWeirdClass(IEnumerable<int> elements)
{
this.elements = elements.ToList();
}
public SortedWeirdClass Sort()
{
sortApplied = true;
return new SortedWeirdClass(this);
}
public class SortedWeirdClass
{
SomeWeirdClass parent;
internal SortedWeirdClass(SomeWeirdClass parent)
{
this.parent = parent;
}
public static implicit operator SomeWeirdClass(SortedWeirdClass sorted)
{
sorted.parent.sortApplied = false;
var elementCopy = new int[sorted.parent.elements.Count];
sorted.parent.elements.CopyTo(elementCopy);
var result = new SomeWeirdClass(elementCopy);
result.Sort();
return result;
}
}
}
Now using it in a program:
static void Main(string[] args)
{
SomeWeirdClass original = new SomeWeirdClass(new[] { 5, 1, 4, 3, 2 });
Console.WriteLine("Original Data: ");
Console.WriteLine(string.Join(" ", original.Elements));
SomeWeirdClass copy = original.Sort();
Console.WriteLine("Original Data after Sort and Assignment: ");
Console.WriteLine(string.Join(" ", original.Elements));
Console.WriteLine("Sorted Copy:");
Console.WriteLine(string.Join(" ", copy.Elements));
original.Sort();
Console.WriteLine("Original Data after Sort without Assignment: ");
Console.WriteLine(string.Join(" ", original.Elements));
}
The program outputs:
Original Data:
5 1 4 3 2
Original Data after Sort and Assignment:
5 1 4 3 2
Sorted Copy:
1 2 3 4 5
Original Data after Sort without Assignment:
1 2 3 4 5
The hack here is that sorting actually creates a temporary class which wraps the original. Unless that result is implicitly cast to the original type via assignment, the sorting effects will be applied to the original dataset. If assignment is made, the sorting is cancelled, and a copy is made for the new variable.
It is not possible in a reliable way. The compiler can optimize
MyClass exampleObject2 = exampleObject1.sort(); to exampleObject1.sort(); if exampleObject2 is not used.
To answer a slightly different question: you could return a Lazy<MyClass>. So you can do the sort only if the result is actually used.
Split the Copy and Sort methods into two distinct methods. If I want to sort a copy, I should be responsible for copying before I sort. For example:
var copy = myCollection.Copy();
copy.Sort();
The goal should be making it clear what your function is doing to any calling code. Different behavior based on usage is only going to lead to bugs, at least in the C# world.

C# Console Application - Using Methods to Pass Arguments

I have an application assignment from school that I have been working on and have gotten stuck on. I am not understanding some of the concepts to complete my program. It is simple and I have the basic structure down. Could someone assist me in understanding and completing my program? Below is the listed information:
The following is the overall application assignment:
Write a program to display the average of some numbers. Your program will consist of three user defined methods named GetNums(), CalcAvg(), and DspAvg(). In GetNums() prompt for and read in 3 real numbers from the keyboard. After reading in the numbers, call CalcAvg() passing the three numbers as input. CalcAvg() must RETURN (use the return statement) the average of the 3 numbers. After calling CalcAvg(), call DspAvg() to display the average and the three numbers entered. Your program must not contain any variables with class-wide scope (all variables must be declared inside a method). All method calls (GetNums(), CalcAvg(), and DspAvg() must be called from main()). Using proper passing is important.
Your output should closely resemble the following.
The average of 10.20, 89.50, and 17.60 is 39.10.
Round the average to two decimal places. Display all values with two decimal places.
GetNums() will have three arguments, all pass by out. CalcAvg() will have three arguments, all pass by copy. Do not use four! DspAvg() will have four arguments, all pass by copy.
Below is the following code I have written, but have gotten stuck, based on the requirements above.
static void Main(string[] args)
{
int nu1, nu2, nu3, cavg;
GetNums();
CalcAvg();
DspAvg();
}
static void GetNums()
{
Console.Write("Please enter nu1: ");
nu1 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu2: ");
nu2 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu3: ");
nu3 = int.Parse(Console.ReadLine());
CalcAvg(DspAvg);
}
static void CalcAvg()
{
}
static void DspAvg()
{
}
}
}
You can't declare variables in one method and use them in another method. the second method doesn't know the variables in the first method.
As the specification said you need your GetNums() to have 3 parameters passed by out
static void GetNums(out decimal num1, out decimal num2, out decimal num3)
Start from here. If you need more help please let me know :)
Well, we won't do your homework for you, but I can give you a few pointers. Your Main should only call GetNums(). GetNums() should call CalcAvg() passing in the numbers read from the console not the DspAvg() function. Finally pass the returned value from CalcAvg() to DspAvg() to display the result to the console.
Start writing some code and if you are getting errors, then we will be able to help you more.
You are not using parameters as described in the assignment. Here is an example of using an out parameter with one method and sending it into another method and returning a value:
double parameter, result;
methodOne(out parameter);
result = methodTwo(parameter);
The methods:
static void methodOne(out double x) {
x = 42;
}
static double methodTwo(double x) {
return x;
}
That should get you started on how you need to modify your methods.
I will provide some suggestions, but this a very good introductory programming problem. I would very much recommend trying to solve this problem on your own as it uses basic programming concepts that you will use in the future.
Your variables nu1, nu2, nu3, and cavg should be double values. An int can not be used to store decimal values. (Note: to get a value with 2 decimal places, you should use the Math.Round method)
double nu1, nu2, nu3, cavg;
You seem to be stuck on how to pass paramaters to a method. For example, when you call the CalcAvg method in your main method, you should be passing the 3 values you read from the console into the method.
static void Main(string[] args){
CalcAvg(nu1,nu2,nu3);
}
static void CalcAvg(double nu1, double nu2, double nu3){
}
By doing this, you can now manipulate the values within your CalcAvg method.
Finally, once you have passed values into a method and manipulated them, you will want to return these values from the method. This can be done with the return statement. You can then call this method by passing in your paramaters and storing the returned value in another variable.
static void Main(string[] args){
double cavg;
cavg = CalcAvg(nu1,nu2,nu3);
}
static double CalcAvg(double nu1, double nu2, double nu3){
double cavg;
return cavg;
}
These three principles should help you complete this assignment. I STRONGLY recommend you do this assignment on your own and not copy the complete answer off of this or any other website. Learning these principles correctly will help you further down the road in your academic career. Good luck :)
I've made a few assumptions here. But I've gone ahead to give you a "working" app for you to consider
static void Main(string[] args)
{
int nu1, nu2, nu3, cavg;
GetNums(out nu1, out nu2, out nu3);
double average = CalcAvg(nu1, nu2, nu3);
DspAvg(average);
}
static void GetNums(out int nu1, out int nu2, out int nu3)
{
Console.Write("Please enter nu1: ");
nu1 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu2: ");
nu2 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu3: ");
nu3 = int.Parse(Console.ReadLine());
}
static double CalcAvg(int nu1, int nu2, int nu3)
{
return (nu1 + nu2 + nu3) / 3;
}
static void DspAvg(double average)
{
Console.WriteLine(Math.Round(average, 2));
}

Categories

Resources