How can I price group? - c#

I am trying to price group. For example: a tutor costs 100 euro per 5 people; 6 people needs 2 tutors so it comes to 200 euro.
Basically I don't know how to go about this, this is what I tried. What I did works perfectly but let's say the user enters a bigger number and I didn't put an if statement how can I fix it? Thanks
int tutorprice;
int students;
Console.WriteLine("How many students");
students = Convert.ToInt32(Console.ReadLine());
if (students <= 1 && students <= 5)
{
tutorprice = 100;
}
else if (students > 5 && students <=10 )
{
tutorprice = 200;
}

You have 2 problems here.
First of all you need to learn basic implementation. For that you can search help other places.
To implement the best calculating function you should look at this topic :
Math Round to always upper integer

Related

How to get odd or even numbers in C# with a user input?

I am very new to C# and have been set a task to make a program that asks for a user input of a number and then says if that number is odd or even. How can I do that?
You need to figure how to check if a number is odd or even. How can do, you ask?
You may not have learned this yet, but modulus is the simplest way to do it. It uses the character % and it basically acts as a division, but instead of telling what value each parts of the division equals, it tells you what is left from the division. Coming from that, you know that if the number divided by % 2 is 0, your number is even because there is nothing left. 4 / 2 = 2 vs 4 % 2 = 0
My example here is not the shortest or fastest, but is easier to understand for a beginner
Console.WriteLine("Enter your number : ");
string number = Console.ReadLine();
Int32.Parse(number);
if(number % 2 == 0)
{
Console.WriteLine("Your number is even.");
}
else
{
Console.WriteLine("Your number is odd.");
}
Have a look at the remainder (modulus) operator.
An example:
int userInput = // get your input
bool isEven = userInput % 2 == 0;
An even number will have a remainder of 0 when divided by 2.
In one line
Console.WriteLine(int.Parse(Console.ReadLine()) % 2 == 0 ? "even":"odd");

Math.DivRem isn't counting how many times it's being divided correctly

Whenever I do this piece of code, it's not counting correctly how many times I'm dividing it. I'm trying to calculate octal to denary number but require how many times it was divided by hence the 8.
Maybe a silly mistake or I've just completely missed the concept but I'm not too sure. Sorry if this sounds like a stupid question.
I type in 123 and its count for how many times it was divided is 2, I'm honestly quite clueless on how to solve this. Some guidance points would be much appreciated! Thanks
private void OctalToDen()
{
string input = txtInputValue.Text;
int count = 0;
int input32 = Convert.ToInt32(input);
while (input32 > 7)
{
input32 = Math.DivRem(input32, 8, out remainder);
count = count + 1;
}
string countString = Convert.ToString(count);
rtbResultAnswer.AppendText(countString);

Divide between two rows of the same column and store the answer in a already existing column

I have a table in my database that has columns 'price', 'percentage' and 'ID'.
Percentage column needs to be calculated using colum 'price' and 'id'. There is an initial price, followed by three increased prices, all of them having the same ID. I need to find a method that calculates the percentage column in my database using C#.
I attach a picture for better understanding how it should be.
I am writing an import system using Linq and I have already imported all the columns, but now I need to calculate percentage for the increasing prices and I am really struggeling with this. Maybe someone have some god suggestions of how I can solve this.
UPDATE:
public static void calculateProcentage(string id, double price, double, double percentage)
{
var percentageQuery = from l in db.Table
where l.ID == id
&& l.Price == price && l.Percentage != percentage
select l;
foreach (Table l in percentageQuery)
{
//double newPercentage = (double) l.Percentage;
//DataTable table = new DataTable();
// int rowCount = table.Rows.Count;
DataGridView dataGridView = new DataGridView();
for (int i = 0; i < dataGridView.Rows.Count; i++)
{
if (l.Building_vigor_ID == building_vigor_id)
{
//var priceRows = db.V_Leases.Select(x => x.Price_sqm).ToList();
// get a list of the rows of the price column
// get a list of the rows of the price column
var priceRows = (from r in db.Table
select r.Price).ToList();
percentage = (double)(priceRows[i] / priceRows[i + 1]);
}
}
}
try
{
db.SubmitChanges();
Console.Write("Percentage updated");
//Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.Write("Could not update percentage");
//Console.ReadKey();
}
}
That is what I have tried. I bassicaly wanted to make it like an update method with only updating column percentage. But did not actualy work. I am pretty new with Linq sow it may be some bad code written here.
The disclaimer
I am pretty new with Linq sow it may be some bad code written here.
Your question, and the way you've attempted to solve this, are fraught with inconsistencies and seemingly contradictory expectations.
As it stands, the question you've asked is not answerable due to lack of information. However, I do think I understand what the actual problem is that you're trying to solve, so I'll give you that answer. But first, let me explain how I've interpreted your question.
My assumptions about your actual question
As I understand it, you're trying to calculate the percentage based on the previous value.
A more generalized example:
PRICE % ID
------------------------
100 A 1
103 B 1
100 C 2
150 D 2
A and C should both be 0 as they are the "base" price of their respective ID value.
B should be 3% because its price is 103% of A's price.
D should be 50% because its price is 150% of C's price.
My below answer will assume that this is correct.
There is also a problem with your expected values. In your example, you have listed the percentage of 19.79 (compared to 19.21) as 0.3.
This does not make sense. The difference is 3%. There are two different (acceptable) ways to denote this in the percentage column:
3, because it is expressed as a percentage (3%)
0.03, because it is expressed as a decimal value (3% = 0.03)
Your usage of 0.3 makes no sense, as I would interpret this as either 0.3% (option 1) or 30% (option 2).
In order to maintain consistency, my answer will assume that you want the decimal value (0.03 in the above example)
I assume your data class is constructed as follows:
public class Foo
{
public decimal Price { get; set; }
public decimal Percentage { get; set; }
public int ID { get; set; }
}
I don't quite understand how you're using the method. You supply three parameters (string id, double price, double, double percentage), but then you go on to select your data as follows:
var percentageQuery = from l in db.Table
where l.ID == id
&& l.Price == price && l.Percentage != percentage
select l;
It makes little sense to supply a percentage, and then pick everything that's different from that percentage. You have no idea of knowing what data you're going to get, in what order, and whether or not the found entries are "before" or "after" your mentioned percentage.
Instead, my answer will be a method that recalculates all percentages of a given ID. This seems like a much clearer algorithm.
The assumed answer
Retrieving the data
Your attempt is a weird mix of new and old technologies (LINQ, DataTable), I'm going to use LINQ near exclusively, as I feel the use of DataTable is unwarranted here.
public static void CalculatePercentagesForID(int id)
{
Foo[] rows = db.Table.Where(x => x.ID == id).ToArray();
//... (see the next code block)
}
This is much simpler. Note that I am assuming that you wish to process the entries based on the order that they appear in the database. If you need to order them based on something else (e.g. a date value in your Foo objects), then you will have to use an additional OrderBy, e.g. :
Foo[] rows = db.Table.Where(x => x.ID == id).Orderby(x => x.DateCreated).ToArray();
Processing the data
It's important to notice here that a percentage is calculated off of two (subsequent) rows.
//The first entry is always the "base" price, therefore always 0.
rows[0].Percentage = 0;
for(int i = 1; i < rows.Length; i++)
{
var previous = rows[i-1];
var current = rows[i];
current.Percentage = CalculateDifferenceInPercentage(previous.Price, current.Price);
}
//TODO: save all the objects in "rows" back to the database!
Notice how the for loop starts at 1, not at 0. We skip step 0 because the first element is automatically 0 anyway. The for loop will only process every row after the first.
Calculating the percentage
public static Decimal CalculateDifferenceInPercentage(decimal oldPrice, decimal newPrice)
{
//1.The elaborate calculation
//The comments are example output when oldPrice = 19.21, newPrice = 19.79
var theRatio = newPrice / oldPrice;
// = 1.0301...
var theRatioRounded = Math.Round(theRatio,2);
// = 1.03
var thePercentageDifference = theRatioRounded - 1;
// = 0.03
return thePercentageDifference;
}
Or, if you want a shorter (but harder to read) version:
public static Decimal CalculateDifferenceInPercentage(decimal oldPrice, decimal newPrice)
{
return Math.Round(newPrice / oldPrice , 2) - 1;
}
Some caveats
I've omitted some null-checks for the sake of simplicity, e.g. checking if any rows are returned.
I've omitted how to save the updated entities in the database as it is not pertinent to your actual question about calculating the percentages.
This works both for negative and positive percentages.

How to obtain a list sorted in a pyramidal way using SQL Orm Lite?

One of our clients solicited us to display the scores from a user's friends list following the next criteria:
If my score is 1100, I need to get a list of my friends sorted by those who are closest to me in score first. If my friends are Gonzalo 1250, Marilda 1100 and Marco 950, the list should be ordered as follows:
Marilda 1100
Gonzalo 1250
Marco 950
Since Marilda and me have the same score, the difference in score is 0, so she is closest to me. Gonzalo is 150 points away from me, just like Marco is, but Gonzalo's score is higher than Marco, so he comes first, then Marco.
We spent some time thinking how to perform this query with no clue so far, we are using Service Stack free version, which makes all of its queries with SQL Orm Lite.
The way to do this is probably some variation of:
select UserName, ABS(Score - #MyScore) as ScoreDelta, Score > #MyScore ? 0 : 1 as HigherOrLower
from ScoreTable
order by ScoreDelta, HigherOrLower
Where UserName and Score are columns in the ScoreTable. MyScore is a scalar value.
Most of the entries will be ranked based on their difference from your score. If there's a tie (Like Gonzalo and Marco) then the one that's higher than your score will be sorted first.
Sorry - I don't think the SQL isn't exactly right (syntax) - It's been a few years since I've touched a database. I'm fairly certain that the ternary conditional operator in the select statement isn't valid SQL - but you get the idea
Alternatively, if you have user/score pairs from the database and want to sort in the application then:
public class UserScore
{
public string Name { get; private set; }
public int Score { get; private set; }
//. . .
}
var sortedScores = from userScore in MyFriendScores
orderby Math.Abs(userScore.Score - myScore), userScore.Score > myScore ? -1 : +1
select userScore;
or
var sortedScores = MyFriendScores
.OrderBy(o => Math.Abs(o.Score - myScore))
.ThenBy(o => o.Score > myScore ? -1 : +1);
The concept is identical - sort first on the ABS of the difference, then as a tie-breaker sort on whether it's higher or lower than your score.

Help with maths/coding on possible combinations of a set to make up a total - C#

I have a coding/maths problem that I need help translating into C#. It's a poker chip calculator that takes in the BuyIn, the number of players and the total amount of chips for each colour (there are x amount of colours) and their value.
It then shows you every possible combination of chips per person to equal the Buy In. The user can then pick the chipset distribution they would like to use. It's best illustrated with a simple example.
BuyIn: $10
Number of Players: 1
10 Red Chips, $1 value
10 Blue Chips, $2 value
10 Green Chips, $5 value
So, the possible combinations are:
R/B/G
10/0/0
8/1/0
6/2/0
5/0/1
4/3/0
2/4/0
1/2/1
etc.
I have spent a lot of time trying to come up with an algorithm in C#/.NET to work this out. I am stumbling on the variable factor - there's usually only 3 or 4 different chips colours in a set, but there could be any amount. If you have more than one player than you have to count up until TotalChips / NumberOfPlayers.
I started off with a loop through all the chips and then looping from 0 up to NumberOfChips for that colour. And this is pretty much where I have spent the last 4 hours... how do I write the code to loop through x amount of chips and check the value of the sum of the chips and add it to a collection if it equals the BuyIn? I need to change my approach radically methinks...
Can anyone put me on the right track on how to solve this please? Pseudo code would work - thank you for any advice!
The below is my attempt so far - it's hopeless (and wont compile, just an example to show you my thought process so far) - Might be better not to look at it as it might biased you on a solution...
private void SplitChips(List<ChipSuggestion> suggestions)
{
decimal valueRequired = (decimal)txtBuyIn.Value;
decimal checkTotal = 0;
ChipSuggestion suggestion;
//loop through each colour
foreach (Chip chip in (PagedCollectionView)gridChips.ItemsSource)
{
//for each value, loop through them all again
foreach (Chip currentChip in (PagedCollectionView)gridChips.ItemsSource)
{
//start at 0 and go all the way up
for (int i = 0; i < chip.TotalChipsInChipset; i++)
{
checkTotal = currentChip.ChipValue * i;
//if it is greater than than ignore and stop
if (checkTotal > valueRequired)
{
break;
}
else
{
//if it is equal to then this is a match
if (checkTotal == valueRequired)
{
suggestion = new ChipSuggestion();
suggestion.SuggestionName = "Suggestion";
chipRed.NumberPerPlayer = i;
suggestion.Chips.Add(chipRed);
chipBlue.NumberPerPlayer = y;
suggestion.Chips.Add(chipBlue);
chipGreen.NumberPerPlayer = 0;
suggestion.Chips.Add(chipGreen);
//add this to the Suggestion
suggestions.Add(suggestion);
break;
}
}
}
}
}
}
Here's an implementation that reads the number of chips, the chips (their worth and amount) and the buyin and displays the results in your example format. I have explained it through comments, let me know if you have any questions.
class Test
{
static int buyIn;
static int numChips;
static List<int> chips = new List<int>(); // chips[i] = value of chips of color i
static List<int> amountOfChips = new List<int>(); // amountOfChips[i] = number of chips of color i
static void generateSolutions(int sum, int[] solutions, int last)
{
if (sum > buyIn) // our sum is too big, return
return;
if (sum == buyIn) // our sum is just right, print the solution
{
for (int i = 0; i < chips.Count; ++i)
Console.Write("{0}/", solutions[i]);
Console.WriteLine();
return; // and return
}
for (int i = last; i < chips.Count; ++i) // try adding another chip with the same value as the one added at the last step.
// this ensures that no duplicate solutions will be generated, since we impose an order of generation
if (amountOfChips[i] != 0)
{
--amountOfChips[i]; // decrease the amount of chips
++solutions[i]; // increase the number of times chip i has been used
generateSolutions(sum + chips[i], solutions, i); // recursive call
++amountOfChips[i]; // (one of) chip i is no longer used
--solutions[i]; // so it's no longer part of the solution either
}
}
static void Main()
{
Console.WriteLine("Enter the buyin:");
buyIn = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the number of chips types:");
numChips = int.Parse(Console.ReadLine());
Console.WriteLine("Enter {0} chips values:", numChips);
for (int i = 0; i < numChips; ++i)
chips.Add(int.Parse(Console.ReadLine()));
Console.WriteLine("Enter {0} chips amounts:", numChips);
for (int i = 0; i < numChips; ++i)
amountOfChips.Add(int.Parse(Console.ReadLine()));
int[] solutions = new int[numChips];
generateSolutions(0, solutions, 0);
}
}
Enter the buyin:
10
Enter the number of chips types:
3
Enter 3 chips values:
1
2
5
Enter 3 chips amounts:
10
10
10
10/0/0/
8/1/0/
6/2/0/
5/0/1/
4/3/0/
3/1/1/
2/4/0/
1/2/1/
0/5/0/
0/0/2/
Break the problem down recursively by the number of kinds of chips.
For the base case, how many ways are there to make an $X buy-in with zero chips? If X is zero, there is one way: no chips. If X is more than zero, there are no ways to do it.
Now we need to solve the problem for N kinds of chips, given the solution for N - 1. We can take one kind of chip, and consider every possible number of that chip up to the buy-in. For example, if the chip is $2, and the buy-in is $5, try using 0, 1, or 2 of them. For each of these tries, we have to use only the remaining N - 1 chips to make up the remaining value. We can solve that by doing a recursive call, and then adding our current chip to each solution it returns.
private static IEnumerable<IEnumerable<Tuple<Chip, int>>> GetAllChipSuggestions(List<Chip> chips, int players, int totalValue)
{
return GetAllChipSuggestions(chips, players, totalValue, 0);
}
private static IEnumerable<IEnumerable<Tuple<Chip, int>>> GetAllChipSuggestions(List<Chip> chips, int players, int totalValue, int firstChipIndex)
{
if (firstChipIndex == chips.Count)
{
// Base case: we have no chip types remaining
if (totalValue == 0)
{
// One way to make 0 with no chip types
return new[] { Enumerable.Empty<Tuple<Chip, int>>() };
}
else
{
// No ways to make more than 0 with no chip types
return Enumerable.Empty<IEnumerable<Tuple<Chip, int>>>();
}
}
else
{
// Recursive case: try each possible number of this chip type
var allSuggestions = new List<IEnumerable<Tuple<Chip, int>>>();
var currentChip = chips[firstChipIndex];
var maxChips = Math.Min(currentChip.TotalChipsInChipset / players, totalValue / currentChip.ChipValue);
for (var chipCount = 0; chipCount <= maxChips; chipCount++)
{
var currentChipSuggestion = new[] { Tuple.Create(currentChip, chipCount) };
var remainingValue = totalValue - currentChip.ChipValue * chipCount;
// Get all combinations of chips after this one that make up the rest of the value
foreach (var suggestion in GetAllChipSuggestions(chips, players, remainingValue, firstChipIndex + 1))
{
allSuggestions.Add(suggestion.Concat(currentChipSuggestion));
}
}
return allSuggestions;
}
}
For some large combinations this is propably not solvable in finite time.
(It is a NP problem)
http://en.wikipedia.org/wiki/Knapsack_problem
There are also links with Code? that could help you.
Hope this helps a bit.

Categories