Confused about how to go about doing this program - vb.net

The question is as follows. A customer needs a specific amount of paper. The charges on the paper are:
.10 for single sheets.
.055 per sheet in multiples of 100.
.04 per sheet in multiples of 500.
.03 per sheet in multiples of 1000.
I know you have to use mod division somewhere. I'm not sure if my variables are set up correctly, and my brain is about to melt. Sad right? haha. I would greatly appreciate some help with this. Cheers :)
Option Explicit On
Imports system
Module paperp
Sub Main()
Dim papercost As Double
Dim onetpackage As Integer
Dim fivehpackages As Integer
Dim onehpackages As Integer
Dim singlesheets As Integer
Console.Writeline("Number of 1000 packages:")
onetpackage = convert.toint32(Console.Readline())
Console.Writeline("Number of 500 packages:")
fivehpackages = convert.toint32(Console.Readline())
Console.Writeline("Number of 100 packages:")
onehpackages = convert.toint32(Console.Readline())
Console.Writeline("Number of single sheets:")
singlesheets = convert.toint32(console.Readline())
Console.Out.Writeline("Number of 1000 packages:")
Console.Out.Writeline(onetpackage)
Console.Out.Writeline("Number of 500 packages:")
Console.Out.Writeline(fivehpackages)
Console.Out.Writeline("Number of 100 packages:")
Console.Out.Writeline(onehpackages)
Console.Out.Writeline("Number of single sheets:")
Console.Out.Writeline(singlesheets)
Console.Out.Writeline("Your total Cost is:")
Console.Out.Writeline(papercost)
End Sub
End Module

With that code you just have to add the price per package:
papercost = _
0.03 * 1000.0 * onetpackage + _
0.04 * 500 * fivehpackages + _
0.055 * 100 * onehpackages + _
0.1 * singlesheets
However, to make the assignment make sense, I think that you should really just input the total number of sheets, and then calculate the number of packages. You could use the modulo to calculate the remaining sheets after calculating the number of packages, but it's just as simple to use substraction:
onetpackage = Math.Floor(totalsheets / 1000)
totalsheets -= onetpackage * 1000

Why not loop through each amount (e.g. 1000, 500, 100, 1), and with the no of sheets the user specifies in a variable, the logic would be like so:
Predefined vars: no_of_sheets (the users input), working_amount = no_of_sheets, current_index = 0, count = 0, amounts (array) = (1000, 500, 100, 1), costs = (0.03, 0.04, 0.055, 0.1), total = (0, 0, 0, 0)
While (working_amount > 0)
if current_index < 4
if (working_amount - amounts[current_index]) >= 0
total[current_index]++
working_amount = working_amount - amounts[current_index]
else
current_index++
endif
endif
endwhile
Now you have an array with the amounts of each block, e.g. an array of (1, 2, 3, 4) means 1 x 1000 sheets, 2 x 500, 3 x 100, 4 x 1
Then you can just multiply each bit by their price.
HOpe that helps.

Your assignment question is an example of the Knapsack problem, but fortunately a very simple variant of it.
You don't necessarily need to use the modulo operator - you can do it iteratively. Start off with the most expensive product (which provides the best price-per-item ratio) then "buy" as many as you can with your starting money (keep subtracting from the money until you can't afford it), then move on to the next afforable product and repeat until you can't afford anything.

Related

The sum of the first natural 100 numbers

new to coding,
Quick Homework problem Im having trouble on.
I must find the sum of the first 100 natural numbers. 1+2+3+4, and so on. While using "while loops".
This is what I have so far.
Dim sum, count As Integer
Const num As Integer = 1
Console.WriteLine("The Sum of the first 100 natural numbers is:")
count = num + 1
While count <= 100
Count = num + count
End While
Sum = count
Console.WriteLine("{0}", sum)
Console.ReadLine()
I know for a fact the math and while loop is incorrect, but Im not sure how to fix it. I keep getting 101 as my answer.
You do not need the num constant and the line: count = num + 1
While count <= 100
sum += count
count += 1
End While
I know you are learning and the solution must use a While loop but for fun see what you can do in 2 lines of code.
Dim arrNumbers = Enumerable.Range(1, 100).ToArray
Console.WriteLine(arrNumbers.Sum)
Since your question title asked for sums of all [1 - 100] as well as the evens and odds, here is some LINQ for each one
Dim sum = Enumerable.Range(1, 100).Sum()
Dim sumEvens = Enumerable.Range(1, 100).Sum(Function(i) If(i Mod 2 = 0, i, 0))
Dim sumOdds = Enumerable.Range(1, 100).Sum(Function(i) If(i Mod 2 = 0, 0, i))
Console.WriteLine($"Sum: {sum}, Sum evens: {sumEvens}, Sum odds: {sumOdds}")
Sum: 5050, Sum evens: 2550, Sum odds: 2500
Enumerable.Range(1, 100) creates your sequence of all [1 - 100]. Call the LINQ function Sum to simply get the sum, or you can pass a lambda function to Sum to transform the numbers. Use Mod to select evens or odds. The method above sets odds to 0 for the evens, and vice-versa for the odds.
An alternative to this method of transforming the sequence is to use Where to select only even numbers then Sum, which may be more readable.
Dim sumEvens = Enumerable.Range(1, 100).Where(Function(i) i Mod 2 = 0).Sum()
With your code you've done a few things in a weird way.
Let's simplify the code and see what's going wrong.
To start with you are setting num as a constant to the value of 1. Since it's not changing, we'll put the value in directly.
You'd then have this:
count = 1 + 1
While count <= 100
count = 1 + count
End While
sum = count
So that means count will start at 2 and goes up by one until the value of count is greater than 100 - and that's when it is 101.
Then you set sum to count and you get 101.
What you needed to do was start count as 1 and sum up the values inside the loop.
count = 1
While count <= 100
sum = sum + count
count = count + 1
End While
And that gives the correct result of 5050.
While count <= 100
num += count
count += 1
End While
Sum = num

Is there a better way to set the odds to generating a random number and controling the limits?

I am trying to do a game that has 20 rounds of play. I have assigned 0 thru 8 to represent the items in the game. I need the random number to be 90 percent of the time to be any number 0 thru 5. I need the numbers 6 and 7 to be 4 percent of the time. And, I need the 8 to be only 2 percent of the time. Below is the code I have and it works sometimes but often it generates way too many of the 6s, 7s, and 8's. The way I see the code is that it should be working most of the time correctly but does not. Is there a better way to control the random to get the percents I need to be more consistently?
' Get the random number position into array
Public Sub GetNumPositions(ByVal positions() As Integer)
' 20 rounds, each round 5 numbers
' we want 2 times (8), 4 times (6 and 7)
' 2% 8, 4% 6, 4% 7, and 90% times 0 thru 5
For i As Integer = 0 To positions.Length - 1
Dim p As Integer = rndNums.Next(100)
If p < 90 Then
positions(i) = p \ 15
ElseIf p < 94 Then
positions(i) = 6
ElseIf p < 98 Then
positions(i) = 7
Else
positions(i) = 8
End If
Next
End Sub
Your code is just fine. Here is a method to test it. It gathers some numbers and calculates their frequency:
Sub Main()
Dim count = 100000000
Dim positions(count) As Integer
Dim frequencies(9) As Integer
GetNumPositions(positions)
For Each num In positions
frequencies(num) += 1
Next
For i As Integer = 0 To 8
Console.WriteLine(i & ": " & (100.0 * frequencies(i) / count) & " %")
Next
End Sub
The result is:
0: 14.994567 %
1: 15.000016 %
2: 15.01366 %
3: 14.996542 %
4: 15.002074 %
5: 15.00325 %
6: 4.002246 %
7: 3.999337 %
8: 2.000603 %
As you can see, the frequencies match your input distribution very closely.

VB.net: How to have an unknown algebra for a equation

I am creating a calculator to cover the tax of an input.
How do I have an unknown integer "m" as something like an algebra for my equation?
b = m - tm
"b" is money after tax. "m" is money before being taxed and "t" is Tax Rate in decimal
-
Example 1 - Money to cover tax [To find unknown variable 'm'] [t=0.06/6%]
100000000 = m - 0.06m ~ Plug-in all available numbers
100000000 = 0.94m ~ Subtraction
106382978 = m ~ Division
-
What is the code so that I can make m a unknown variable to be solved? VB.net Please help!
From what I understand, you want to solve for m. This means given a value for b and t, you want to find m.
Algebraically:
m = b/ (1-t)
The above equation is what you need to put in your program. Be aware that t=1 will cause an error, so make an 'IF' statement before you execute the equation.
It based on previous solution and it's pretty dirty
Dim restCash = 4500
Dim taxRate = 0.1 ' e.x 10%
Dim initialCash = 0 ' That's what we looking for
If (taxRate = 1) Then ' It means that taxRate = 100%
MsgBox("Tax rate cannot be 100%")
Return
Else
initialCash = restCash / (1 - taxRate)
End If

Penny calculator mod division

I have an assignment for a beginners VB class, and I have looked for examples for a penny calculator and have read them and tried to figure out where I am going wrong. I have a text box that takes the number of pennies you want to figure out. If you input 101 pennies it comes back with 1 dollar and 1 penny.
Strangely it works for up to 137 pennies. That comes back with 1 dollar 1 quarter 1 dime 2 pennies. If it goes to 138 or higher it just screws up. If I input 138 I get 1 dollar, 2 quarters, 1 dime, 1 nickel, 3 pennies. If I use 17 I get 1 quarter, 2 dimes, 1 nickel, 2 pennies.
Here is the arithmetic portion of my code.
DolBack = intLeftOver / 100
intLeftOver = intLeftOver Mod 100
LblDolRes.Text = DolBack.ToString
QrtBack = intLeftOver / 25
intLeftOver = intLeftOver Mod 25
LblQrtRes.Text = QrtBack.ToString
DimBack = intLeftOver / 10
intLeftOver = intLeftOver Mod 10
LblDimRes.Text = DimBack.ToString
NicBack = intLeftOver / 5
intLeftOver = intLeftOver Mod 5
LblNicRes.Text = NicBack.ToString
PenBack = intLeftOver
LblPenRes.Text = PenBack.ToString
I have tried to look my code over and look at other examples, but apparently I'm doing it a little differently. If anyone could point out the apparent major flaw in my code or my way of doing it I would appreciate it.
Further clarifying I have looked at the post at
Penny Calculator
Obviously there are a few differences with the actual arithmetic. In the link given is that because that is the only way to do it without rounding issues?
there are 100 pennies in a dollar, 25 pennies in a quarter, 10 pennies in a dime, 5 pennies in a nickel.
EDIT: Thanks for the help and pointing out my error. It's appreciated.
You're right that it's a rounding error. Use
DolBack = intLeftOver \ 100
instead of
DolBack = intLeftOver / 100
(and the same for the other ones) and you'll see a very different result.
The reason is that the / operator will do floating point division, regardless of the values either side of it, so 38/25 will yield an answer of 1.52, which rounds upwards (as you suspected) when assigned back to the variable, which is defined as an Integer. On the other hand, the \ operator will do integer division, truncating rather than rounding.
The Math.DivRem method is helpful for this kind of problem.
Dim dollars As Integer
Dim fifty As Integer
Dim quarter As Integer
Dim dime As Integer
Dim nickel As Integer
Dim pennies As Integer = 137
dollars = Math.DivRem(pennies, 100, pennies)
fifty = Math.DivRem(pennies, 50, pennies)
quarter = Math.DivRem(pennies, 25, pennies)
dime = Math.DivRem(pennies, 10, pennies)
nickel = Math.DivRem(pennies, 5, pennies)

Rounding a number to the nearest 5 or 10 or X

Given numbers like 499, 73433, 2348 what VBA can I use to round to the nearest 5 or 10? or an arbitrary number?
By 5:
499 -> 500
2348 -> 2350
7343 -> 7345
By 10:
499 -> 500
2348 -> 2350
7343 -> 7340
etc.
It's simple math. Given a number X and a rounding factor N, the formula would be:
round(X / N)*N
Integrated Answer
X = 1234 'number to round
N = 5 'rounding factor
round(X/N)*N 'result is 1235
For floating point to integer, 1234.564 to 1235, (this is VB specific, most other languages simply truncate) do:
int(1234.564) 'result is 1235
Beware: VB uses Bankers Rounding, to the nearest even number, which can be surprising if you're not aware of it:
msgbox round(1.5) 'result to 2
msgbox round(2.5) 'yes, result to 2 too
Thank you everyone.
To round to the nearest X (without being VBA specific)
N = X * int(N / X + 0.5)
Where int(...) returns the next lowest whole number.
If your available rounding function already rounds to the nearest whole number then omit the addition of 0.5
In VB, math.round has additional arguments to specify number of decimal places and rounding method. Math.Round(10.665, 2, MidpointRounding.AwayFromZero) will return 10.67 . If the number is a decimal or single data type, math.round returns a decimal data type. If it is double, it returns double data type. That might be important if option strict is on.
The result of (10.665).ToString("n2") rounds away from zero to give "10.67". without additional arguments math.round returns 10.66, which could lead to unwanted discrepancies.
'Example: Round 499 to nearest 5. You would use the ROUND() FUNCTION.
a = inputbox("number to be rounded")
b = inputbox("Round to nearest _______ ")
strc = Round(A/B)
strd = strc*B
msgbox( a & ", Rounded to the nearest " & b & ", is" & vbnewline & strd)
For a strict Visual Basic approach, you can convert the floating-point value to an integer to round to said integer. VB is one of the rare languages that rounds on type conversion (most others simply truncate.)
Multiples of 5 or x can be done simply by dividing before and multiplying after the round.
If you want to round and keep decimal places, Math.round(n, d) would work.
Here is our solution:
Public Enum RoundingDirection
Nearest
Up
Down
End Enum
Public Shared Function GetRoundedNumber(ByVal number As Decimal, ByVal multiplier As Decimal, ByVal direction As RoundingDirection) As Decimal
Dim nearestValue As Decimal = (CInt(number / multiplier) * multiplier)
Select Case direction
Case RoundingDirection.Nearest
Return nearestValue
Case RoundingDirection.Up
If nearestValue >= number Then
Return nearestValue
Else
Return nearestValue + multiplier
End If
Case RoundingDirection.Down
If nearestValue <= number Then
Return nearestValue
Else
Return nearestValue - multiplier
End If
End Select
End Function
Usage:
dim decTotal as Decimal = GetRoundedNumber(CDec(499), CDec(0.05), RoundingDirection.Up)
Simply ROUND(x/5)*5 should do the job.
I cannot add comment so I will use this
in a vbs run that and have fun figuring out why the 2 give a result of 2
you can't trust round
msgbox round(1.5) 'result to 2
msgbox round(2.5) 'yes, result to 2 too
something like that?
'nearest
n = 5
'n = 10
'value
v = 496
'v = 499
'v = 2348
'v = 7343
'mod
m = (v \ n) * n
'diff between mod and the val
i = v-m
if i >= (n/2) then
msgbox m+n
else
msgbox m
end if
Try this function
--------------start----------------
Function Round_Up(ByVal d As Double) As Integer
Dim result As Integer
result = Math.Round(d)
If result >= d Then
Round_Up = result
Else
Round_Up = result + 1
End If
End Function
-------------end ------------
I slightly updated the function provided by the "community wiki" (the best answer), just to round to the nearest 5 (or anything you like), with this exception : the rounded number will NEVER be superior to the original number.
This is useful in cases when it is needed to say that "a company is alive for 47 years" : I want the web page to display "is alive for more than 45 years", while avoiding lying in stating "is alive for more than 50 years".
So when you feed this function with 47, it will not return 50, but will return 45 instead.
'Rounds a number to the nearest unit, never exceeding the actual value
function RoundToNearestOrBelow(num, r)
'#param num Long/Integer/Double The number to be rounded
'#param r Long The rounding value
'#return OUT Long The rounded value
'Example usage :
' Round 47 to the nearest 5 : it will return 45
' Response.Write RoundToNearestBelow(47, 5)
Dim OUT : OUT = num
Dim rounded : rounded = Round((((num)) / r), 0) * r
if (rounded =< num) then
OUT = rounded
else
OUT = rounded - r
end if
'Return
RoundToNearestOrBelow = OUT
end function 'RoundToNearestOrBelow
To mimic in Visual Basic the way the round function works in Excel, you just have to use:
WorksheetFunction.Round(number, decimals)
This way the banking or accounting rounding don't do the rounding.