Choosing the two biggest pairs in a yatzhee game - vb.net

So hello again, I were wondering how we could get 2 of the biggest pairs in a yatzee game.
From a previous question i got help by finding one pair but now i dont even know. It would seem we just need to double the amount in the 1 pair code, but doing that i just got no result or just x4 of the dice
Public Function parVerdier1(ByVal regel As Integer, tall As Object)
Dim sum As Integer = 0
For i As Integer = 0 To 4
For j As Integer = (i + 1) To 4
If tall(i) = tall(j) Then
If tall(i) + tall(j) > sum Then
sum = tall(i) + tall(j)
End If
End If
Next
Next
Return sum
End Function
This is the 1 pair code if ayone were wondering, help pls and thank you :)
Also the regel is used futher down the rest of the code.
yatzee is a game where you throw 5 dices, the eyes = points (you can combo it for more points etc). lets pretend you threw (3 3 4 4 5), by selecting it as a pair you get 8points (4+4), if you select it as two pairs you get 14points (4+4+3+3) you can read more here if you want to learn all the rules http://en.wikipedia.org/wiki/Yahtzee its a pretty easy game and fun to play if you're bored.
My lates code with a lot of help thank you :) still got some problems like http://imgur.com/ExpBb2Q when i get these dices i get 40 points...
Public Function parVerdier2(ByVal regel As Integer, tall As Object)
Dim sum As Integer = 0
Dim sum2 As Integer = 0
For o As Integer = 0 To 4
For l As Integer = (o + 1) To 4
For i As Integer = (l + 1) To 4
For j As Integer = (i + 1) To 4
If tall(i) = tall(j) And tall(o) = tall(l) Or tall(i) = tall(o) And tall(j) = tall(l) Or tall(i) = tall(l) And tall(j) = tall(o) Then
If tall(i) + tall(j) + tall(o) + tall(l) > sum Then
sum2 = sum
sum = tall(i) + tall(j) + tall(o) + tall(l)
ElseIf tall(i) + tall(j) + tall(o) + tall(l) > sum2 Then
sum2 = tall(i) + tall(j) + tall(o) + tall(l)
End If
End If
Next
Next
Next
Next
sum += sum2
Return sum
End Function

you would just need another variable for the second biggest sum:
Public Function parVerdier1(ByVal regel As Integer, tall As Object)
Dim sum As Integer = 0
Dim sum2 As Integer = 0
For i As Integer = 0 To 4
For j As Integer = (i + 1) To 4
If tall(i) = tall(j) Then
If tall(i) + tall(j) > sum Then
sum2 = sum
sum = tall(i) + tall(j)
Else If tall(i) + tall(j) > sum2 Then
sum2 = tall(i) + tall(j)
End If
End If
Next
Next
Return sum + sum2
End Function

You can use Linq to get the two pairs with the greatest sum:
Public Shared Sub Main()
Dim dieValues() As Integer = {3, 3, 4, 4, 5}
Dim pairs = dieValues.GroupBy(Function(i) i).
Where(Function(g) g.Count() = 2).
OrderByDescending(Function(g) g.Sum()).
Select(Function(g) New With {.Value = g.Key, .Sum = g.Sum()}).
Take(2)
For Each g In pairs
Console.WriteLine("{0}: {1}", g.Key, g.Sum)
Next
Console.ReadLine()
End Sub
Output:
4: 8
3: 6

Related

Randomly find numbers from 1-12 without repeat [duplicate]

This question already has an answer here:
Pick unique Random numbers
(1 answer)
Closed 5 years ago.
I have three variable integers, and I have the following code that randomizes their value:
Randomize()
number = Int(Rnd() * 12) + 1
AssignImagesToSquares()
number2 = Int(Rnd() * 12) + 1
AssignImagesToSquares()
number3 = Int(Rnd() * 12) + 1
AssignImagesToSquares()
And AssignImagesToSquares is a Private Sub where I use them.
However, the problem that I am facing is that numbers can be repeated. I could not figure out how to do it, but in psuedocode,
'Randomize the integer "number"
'Randomize the integer "number2" where number2 <> number
'Randomize the integer "number3" where number3 <> number2 <> number.
I thought of maybe using a loop to repeat the process until a match is found but how exactly can that be done?
As a simple solution you could just use a Do..Loop until the numbers do not match, for example
Randomize()
number = Int(Rnd() * 12) + 1
AssignImagesToSquares()
Do
number2 = Int(Rnd() * 12) + 1
If number2 <> number Then
AssignImagesToSquares()
Exit Do
End If
Loop
Do
number3 = Int(Rnd() * 12) + 1
If number3 <> number AndAlso number3 <> number2 Then
AssignImagesToSquares()
Exit Do
End If
Loop
Yes you could use loops, but alternatively given your situation you could store your values in array, and take values from this array, and as soon as you pick a value from array you remove it. Then you could use it again. Simple code provided (of course it would be better wrapped in a function):
Dim number1, number2, number3 as Integer
Dim numbers = New Integer() {1,2,3,4,5,6,7,8,9,10,11,12}
Dim indx As Integer = Int(Rnd() * numbers.Length)
number1=numbers(indx)
Console.WriteLine(number1)
System.Array.Clear(numbers, indx, 1)
indx=Int(Rnd() * numbers.Length) 'wrap in function
number2=numbers(indx) '
Console.WriteLine(number2) 'AssignImagesToSquares()
System.Array.Clear(numbers, indx, 1) '
MAYBE a little overkill ;) , but you can extend this for any number of numbers wanted:
Dim temp As New ConcurrentDictionary(Of Integer, Integer)
Dim count_actual As Integer = 0
Dim count_wanted As Integer = 3
Do
Dim number = Int(Rnd() * 12) + 1 'or whatever random function
If temp.TryAdd(number, count_actual) Then
count_actual += 1
End If
Loop While count_actual < count_wanted
Dim yourNumbers = temp.OrderBy(Function(v) v.Value).Select(Of Integer)(Function(v) v.Key).ToArray()
Now there are your wanted random different numbers in the yourNumbers array. Just use them.

How to create an excel VBA function for this particular purpose?

I am trying to create the function for this purpose: I have a year of birth list, I want to take out the last two numbers of that year and make a sum of them. If this sum is less than 10, it will be the result I need. If the result is more than 10 (ex: 9+9 = 18), I will separate this two digits (1 and 8) and make a sum of them (1+8=9. This is less than 10, so it will be my result)
This is my code, but it only give me the result of the first split and sum (18 in this example):
Function test(yob as range) as integer
Dim sum, i, j, i2, j2 as integer
i = mid(yob, 3, 1)
j = right(yob, 1)
sum = i + j
If sum < 10 then
test = sum
Else:
i2 = left(sum, 1)
j2 = right(sum, 1)
test = i2 + j2
End If
End function
Sub test()
Debug.Print getSum(9, 9)
'/ Prints 9
Debug.Print getSumShort(7, 7)
'/ Prints 5
End Sub
Public Function getSum(x As Long, y As Long)
Dim res As Long
res = x + y
Do While res > 10 '/ Keep repeating till its greater than 10
res = (res \ 10) + (res Mod 10)
Loop
getSum = res
End Function
'/ Another way using 9 as divider.
Public Function getSumShort(x As Long, y As Long)
Dim res As Long
res = (x + y) Mod 9
getSum = IIf(res = 0, 9, res)
End Function
Function sum2d(year)
sum2d=IIf(year mod 100, (year - 1) Mod 9 + 1, 0)
End Function
Sub Test
For Each v in Array(1980, 2001, 2017)
Debug.Print v; "=>"; sum2d(v)
Next
Next

Longest common substring large strings?

I need some help with this function. I am trying to find the longest common string between 2 strings. Here is the function that I am currently using:
Public Shared Function LCS(str1 As Char(), str2 As Char())
Dim l As Integer(,) = New Integer(str1.Length - 1, str2.Length - 1) {}
Dim lcs__1 As Integer = -1
Dim substr As String = String.Empty
Dim [end] As Integer = -1
For i As Integer = 0 To str1.Length - 1
For j As Integer = 0 To str2.Length - 1
If str1(i) = str2(j) Then
If i = 0 OrElse j = 0 Then
l(i, j) = 1
Else
l(i, j) = l(i - 1, j - 1) + 1
End If
If l(i, j) > lcs__1 Then
lcs__1 = l(i, j)
[end] = i
End If
Else
l(i, j) = 0
End If
Next
Next
For i As Integer = [end] - lcs__1 + 1 To [end]
substr += str1(i)
Next
Return substr
End Function
This works great on strings of up to around 600 words or so. If I try to compare strings with a larger word count than that it starts to throw system.outofmemoryexception. Obviously, this is hitting the memory pretty hard. Is there any way to fine tune this function or is there possibly another way of doing this that is more streamlined?

How to compare Strings for Percentage Match using vb.net?

I am banging my head against the wall for a while now trying different techniques.
None of them are working well.
I have two strings.
I need to compare them and get an exact percentage of match,
ie. "four score and seven years ago" TO "for scor and sevn yeres ago"
Well, I first started by comparing every word to every word, tracking every hit, and percentage = count \ numOfWords. Nope, didn't take into account misspelled words.
("four" <> "for" even though it is close)
Then I started by trying to compare every char in each char, incrementing the string char if not a match (to count for misspellings). But, I would get false hits because the first string could have every char in the second but not in the exact order of the second. ("stuff avail" <> "stu vail" (but it would come back as such, low percentage, but a hit. 9 \ 11 = 81%))
SO, I then tried comparing PAIRS of chars in each string. If string1[i] = string2[k] AND string1[i+1] = string2[k+1], increment the count, and increment the "k" when it doesn't match (to track mispellings. "for" and "four" should come back with a 75% hit.) That doesn't seem to work either. It is getting closer, but even with an exact match it is only returns 94%. And then it really gets screwed up when something is really misspelled. (Code at the bottom)
Any ideas or directions to go?
Code
count = 0
j = 0
k = 0
While j < strTempName.Length - 2 And k < strTempFile.Length - 2
' To ignore non letters or digits '
If Not strTempName(j).IsLetter(strTempName(j)) Then
j += 1
End If
' To ignore non letters or digits '
If Not strTempFile(k).IsLetter(strTempFile(k)) Then
k += 1
End If
' compare pair of chars '
While (strTempName(j) <> strTempFile(k) And _
strTempName(j + 1) <> strTempFile(k + 1) And _
k < strTempFile.Length - 2)
k += 1
End While
count += 1
j += 1
k += 1
End While
perc = count / (strTempName.Length - 1)
Edit: I have been doing some research and I think I initially found the code from here and translated it to vbnet years ago. It uses the Levenshtein string matching algorithm.
Here is the code I use for that, hope it helps:
Sub Main()
Dim string1 As String = "four score and seven years ago"
Dim string2 As String = "for scor and sevn yeres ago"
Dim similarity As Single =
GetSimilarity(string1, string2)
' RESULT : 0.8
End Sub
Public Function GetSimilarity(string1 As String, string2 As String) As Single
Dim dis As Single = ComputeDistance(string1, string2)
Dim maxLen As Single = string1.Length
If maxLen < string2.Length Then
maxLen = string2.Length
End If
If maxLen = 0.0F Then
Return 1.0F
Else
Return 1.0F - dis / maxLen
End If
End Function
Private Function ComputeDistance(s As String, t As String) As Integer
Dim n As Integer = s.Length
Dim m As Integer = t.Length
Dim distance As Integer(,) = New Integer(n, m) {}
' matrix
Dim cost As Integer = 0
If n = 0 Then
Return m
End If
If m = 0 Then
Return n
End If
'init1
Dim i As Integer = 0
While i <= n
distance(i, 0) = System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
End While
Dim j As Integer = 0
While j <= m
distance(0, j) = System.Math.Max(System.Threading.Interlocked.Increment(j), j - 1)
End While
'find min distance
For i = 1 To n
For j = 1 To m
cost = (If(t.Substring(j - 1, 1) = s.Substring(i - 1, 1), 0, 1))
distance(i, j) = Math.Min(distance(i - 1, j) + 1, Math.Min(distance(i, j - 1) + 1, distance(i - 1, j - 1) + cost))
Next
Next
Return distance(n, m)
End Function
Did not work for me unless one (or both) of following are done:
1) use option compare statement "Option Compare Text" before any Import declarations and before Class definition (i.e. the very, very first line)
2) convert both strings to lowercase using .tolower
Xavier's code must be correct to:
While i <= n
distance(i, 0) = System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)
End While
Dim j As Integer = 0
While j <= m
distance(0, j) = System.Math.Min(System.Threading.Interlocked.Increment(j), j - 1)
End While

I need to design a program which output the specific day of the week given the date using vb console(VB net)

Module Module1
Sub Main()
Dim N, d, m, y, T As Integer
Console.Write("Enter the date(DD): ")
Console.ReadLine()
Console.Write("Enter the month(MM): ")
Console.ReadLine()
Console.Write("Enter the year(YY): ")
Console.ReadLine()
N = d + 2 * m + (3 * (m + 1) / 5) + y + (y / 4) - (y / 100) + (y / 400) + 2
T = N Mod 7 - 1
If T = 1 Then
Console.Write("The day is Monday")
Console.ReadLine()
ElseIf T = 2 Then
Console.Write("The day is Tuesday")
Console.ReadLine()
ElseIf T = 3 Then
Console.Write("The day is Wednesday")
Console.ReadLine()
ElseIf T = 4 Then
Console.Write("The day is Thursday")
Console.ReadLine()
ElseIf T = 5 Then
Console.Write("The day is Friday")
Console.ReadLine()
ElseIf T = 6 Then
Console.Write("The day is Saturday")
Console.ReadLine()
ElseIf T = 7 Then
Console.Write("The day is Sunday")
Console.ReadLine()
End If
End Sub
End Module
Depending on the formula, i suppose that it should work but it's not. It's not giving me the right day. Maybe because we also need to calculate the leap year in it? I need simple vb net code.
To me the formula you showed is unnecessary complex as there is a built in way to achieve what you want.
What about just:
Dim dt As New DateTime(2003, 5, 1)
Console.WriteLine("The day of the week for {0:d} is {1}.", dt, dt.DayOfWeek)