Could you please give me vba code that can solve this problem:
I want remainder in Mod Function can become equal to divisor.
Example: In normal situation Mod(132,12)=0 but I want when remainder is equal to divisor, last step of dividing that is dividing 12 on 12 doesn't do and remainder becomes 12.
Example
I wrote this code but it seems something is wrong. What's the problem?
Function XLMod(a, b)
XLMod = Int(a - (b * Int(a / b)))
If XLMod(a / 10, b) = 1 And XLMod(a, 10) = 2 Then
XLMod = b
End If
End Function
You need a special exception of the standard modulo function.
If the result of a normal division (a / b) would result in a number ending with 1 (e. g. 1, 31, 10001, 12341, ...), then you want it to return b.
Function XLMod(a, b)
XLMod = a Mod b
If XLMod = 0 And (a / b) Mod 10 = 1 Then XLMod = b
End Function
Related
I am trying to implement a function to get the highest common divisor between two numbers, but I am getting an error Ambiguous variable occurrence "gcd".
gcd a 0 = 0
gcd 0 a = 0
gcd a b = if a > b
then (if mod a b == 0 then a else gcd a (b-1))
else (if mod b a == 0 then b else gcd (a-1) b)
How it will be executed:
1- find the greatest of two numbers
2- then the greatest mod smallest; if it equals zero then it will return the smallest, otherwise
it will call method again but with (smallest - 1) and the same value for the greatest
I have a problem where I have a string of length N, where (1 ≤ N ≤ 10^5). This string will only have lower case letters.
We have to rewrite the string so that it has a series of "streaks", where the same letter is included at least K (1 ≤ K ≤ N) times in a row.
It costs a_ij to change a single specific letter in the string from i to j. There are M different possible letters you can change each letter to.
Example: "abcde" is the input string. N = 5 (length of "abcde"), M = 5 (letters are A, B, C, D, E), and K = 2 (each letter must be repeated at least 2 times) Then we are given a M×M matrix of values a_ij, where a_ij is an integer in the range 0…1000 and a_ii = 0 for all i.
0 1 4 4 4
2 0 4 4 4
6 5 0 3 2
5 5 5 0 4
3 7 0 5 0
Here, it costs 0 to change from A to A, 1 to change from A to B, 4 to change from A to C, and so on. It costs 2 to change from B to A.
The optimal solution in this example is to change the a into b, change the d into e, and then change both e’s into c’s. This will take 1 + 4 + 0 + 0 = 5 moves, and the final combo string will be "bbccc".
It becomes complicated as it might take less time to switch from using button i to an intermediate button k and then from button k to button j rather than from i to j directly (or more generally, there may be a path of changes starting with i and ending with j that gives the best overall cost for switching from button i ultimately to button j).
To solve for this issue, I am treating the matrix as a graph, and then performing Floyd Warshall to find the fastest time to switch letters. This will take O(M^3) which is only 26^3.
My next step is to perform dynamic programming on each additional letter to find the answer. If someone could give me advice on how to do this, I would be thankful!
Here are some untested ideas. I'm not sure if this is efficient enough (or completely worked out) but it looks like 26 * 3 * 10^5. The recurrence could be converted to a table, although with higher Ks, memoisation might be more efficient because of reduced state possibilities.
Assume we've recorded 26 prefix arrays for conversion of the entire list to each of the characters using the best conversion schedule, using a path-finding method. This lets us calculate the cost of a conversion of a range in the string in O(1) time, using a function, cost.
A letter in the result can be one of three things: either it's the kth instance of character c, or it's before the kth, or it's after the kth. This leads to a general recurrence:
f(i, is_kth, c) ->
cost(i - k + 1, i, c) + A
where
A = min(
f(i - k, is_kth, c'),
f(i - k, is_after_kth, c')
) forall c'
A takes constant time since the alphabet is constant, assuming earlier calls to f have been tabled.
f(i, is_before_kth, c) ->
cost(i, i, c) + A
where
A = min(
f(i - 1, is_before_kth, c),
f(i - 1, is_kth, c'),
f(i - 1, is_after_kth, c')
) forall c'
Again A is constant time since the alphabet is constant.
f(i, is_after_kth, c) ->
cost(i, i, c) + A
where
A = min(
f(i - 1, is_after_kth, c),
f(i - 1, is_kth, c)
)
A is constant time in the latter. We would seek the best result of the recurrence applied to each character at the end of the string with either state is_kth or state is_after_kth.
What I currently have:
Option Explicit
Function Triangular(a As Double, b As Double, c As Double) As Double
Randomize
Application.Volatile
Dim d As Double
Dim uniform As Double
Dim retval as Double
d = (b - a) / (c - a)
uniform = Rnd()
If uniform <= d Then
Triangular = a + (c - a) * Sqr(d * uniform)
Else
Triangular = a + (c - a) * (1 - Sqr(1 - d) * (1 - uniform))
End If
End Function
I'm having trouble in regards to creating a triangular distribution function in VBA, which calculates a random number from arguments made from:
Calculate d = ( b - a )/( c - a )
Generate a uniformly distributed random number U between 0 and 1 with VBA's Rnd function.
If U <= d, return a + ( c - a ) × sqr(d×U) as the random number. (Sqr(x) is a VBA function which returns the square root of x.
If U > d , return a + ( c - a ) × (1 - sqr((1- d )×(1-U))) as the random number.
The parameters a and c are the minimum and maximum possible values respectively, and
the parameter b is the most likely value (where you see the high point in the triangle).
I'm unsure on how to create this function and was wondering if someone could lend a hand? In working on the function I realize I need to use randomize function in order to not generate similar results each time the function is called, as well as the application.volatile operation.
You have a bug in the code. Should be in second branch
Triangular = a + (c - a) * (1 - Sqr((1 - d) * (1 - uniform)))
Not sure of the correctness of your generating equations. Take a look Here for the correct equations; with the difference that b and c are switched with respect to your definition. Here's an implementation adapting the formulas of that page to your own definitions of a, b and c:
Function Triangular(a As Double, b As Double, c As Double) As Double
Application.Volatile
Dim U As Double: U = Rnd()
If U < (b - a) / (c - a) Then
Triangular = a + sqrt(U * (b - a) * (c - a))
Else
Triangular = c - sqrt(U * (c - b) * (c - a))
End If
End Function
To generate a sequence from the above distribution in a new Worksheet, you can
1- Create the new worksheet
2- Write your parameters in cells A1, B1 and C1
3- write this formula in A2: =Triangular($A$1, $B$1, $C$1)
4- Copy/Paste cell A2 down the column
Please notice (1-Prob) in the second case. The Wikipedia link shows the correct formula but it was not implemented correctly by A.S.H.
Function Triangular(ByVal Min As Single, ByVal ML As Single, ByVal Max As Single) As Single
Application.Volatile
Dim Prob As Single
Prob = Rnd
If Prob < (ML - Min) / (Max - Min) Then
Triangular = Min + Sqr(Prob * (ML - Min) * (Max - Min))
Else
Triangular = Max - Sqr((1 - Prob) * (Max - ML) * (Max - Min))
End If
End Function
I'm sure this is simple for all of you, but I'm new here. How do I create a formula or code that can output all of the potential scenarios for this type of array below? Basically, max is 60, min is 0, but I'm unsure how to make Excel spit out a table that represents this.
Solution:
Doing it with Excel formulas alone, while theoretically possible, is incredibly computationally demanding and crashed Excel when I was trying to do so. You can do this fairly easy with VBA though.
Create a VBA module, drop these two snippets in, press play, and wait for a few seconds to a minute while the code runs. The code is not the most efficient, but it is probably the simplest algorithm to understand.
Public Sub comb4()
Dim a, b, c, d, n, r, x As Integer
x = 60
a = x
Do While a >= n
b = x - a
Do While b >= n
c = x - a - b
Do While c >= n
d = x - a - b - c
Do While d >= n
If sumToZero(-x, a, b, c, d) Then
r = r + 1
Cells(r, 1).Value = a
Cells(r, 2).Value = b
Cells(r, 3).Value = c
Cells(r, 4).Value = d
End If
d = d - 1
Loop
c = c - 1
Loop
b = b - 1
Loop
a = a - 1
Loop
End Sub
Public Function sumToZero(ParamArray intNums())
For x = LBound(intNums) To UBound(intNums)
y = y + intNums(x)
Next x
If y = 0 Then sumToZero = True
End Function
Code explanation:
x is the max that you defined, while n is the min you defined.
r is a counter which helps us track what row to print to.
Since we always want to count down to 0 for each column's sub-permutations, each of our Do While loops will count from the theoretical maximum value down to 0.
The loop structure is nested so that each time we hit -1 in a column N we instead leave the loop, go into the loop one level higher, and decrease the value in column M by 1. The value in N is reset when we start the next instance of the loop for M.
Between each value change we need to check to see if the result is a valid solution. We pass the (negative) max and all 4 variables we are looping to a function which sums the values and returns true if the variables are equal to the max. When the function is true, we go to the next row in Excel and print the four values.
m = 0
for x in range (4,6):
for y in range (2,4):
m = m + x + y
print (m)
ANSWER: 28
not sure how this is? Excluding the last number in the range, I thought it should be 14. I add it up on paper and cannot understand what I am doing wrong.
That loop is equivalent to:
m = 4+2 + 4+3 + 5+2 + 5+3
And, that sum is 28.
(In the outer loop, x takes on the values 4 and 5. In the inner loop, y takes on values 2 and 3.)