Jump to content

Factorials


Recommended Posts

I was working on a tiny UDF when for some reason it wouldn't work anymore. It looks correct to me, if any of you Mathematicians out there want to do a once-over on it, I would appreciate it...

Func _MathFactorial($mfFactor, $mfStop = 0)
    If (Not StringIsInt($mfFactor)) OR Not (Int($mfFactor) < 0) Then
    ;Invalid text entered into parameters exit with error
        Return 0
        SetError(1)
    Else
    ;Make the parameter a number (was a string)
        $mfFactor = Int($mfFactor)
    EndIf
;0! is 1
    If $mfFactor = 0 Then Return 1
    
    Dim $return = 1
;$mfFactor * ($mfFactor - 1) * ($mfFactor - 2) * ... * 3 * 2 * 1
    While $mfFactor > $mfStop
        $return *= $mfFactor
        $mfFactor -= 1
    WEnd
    Return $return
EndFunc

Func _MathPermutation($mpN, $mpR)
    If (Not StringIsInt($mpN)) OR (Not (Int($mpN) < 0)) OR (Not StringIsInt($mpR)) OR (Not (Int($mpR) < 0)) OR (Int($mpN) < Int($mpR)) Then
    ;Invalid parameters, or N is less than R (not allowed)
        Return 0
        SetError(1)
    Else
    ;Make the parameters into numbers (was a string)
        $mpN = Int($mpN)
        $mpR = Int($mpR)
    EndIf
    
    Select
        Case $mpR = 1
            Return $mpN
        Case $mpN = $mpR
            _MathFactorial($mpN)
        Case Else
            _MathFactorial($mpN, $mpR)
        EndSelect
EndFunc

MsgBox(0, "4P2", _MathFactorial(4))

I had MathFactorial working on it, then I went and did permutations, and it FUBAR'ed

Writing AutoIt scripts since

_DateAdd("d", -2, _NowCalcDate())
Link to comment
Share on other sites

First I could find the problem...... in about a month, lol

but what is this

"*..."

???

8)

EDIT not sure again but you finish with this

MsgBox(0, "4P2", _MathFactorial(4)) ; has 1 number

but the function has 2 numbers

_MathFactorial($mfFactor, $mfStop = 0)

EDIT and

If (Not StringIsInt($mfFactor))

and

(Int($mfFactor) < 0) ; above states " $mfStop = 0 "

against

_MathFactorial(4))

????

hope (blind shot ) it helps

8)

Edited by Valuater

NEWHeader1.png

Link to comment
Share on other sites

* is a symbol for multiplication. I put it in a comment to show what a factorial is.

Here is a math site I used a while back for this kind of stuff.

_MathFactorial requires only 1 number, where the 2nd number is designed for the second function (permutations). When it is set to zero, it will multiply all numbers between the one set (4) and 1 (4 times 3 times 2 times 1) which will return 24 (it did at first).

If it is set to a negative number, you can't take negative positions of 8 (if its one position of 8, its 8, if its two, its 8*7).

As for that last part, the parameters are passed as strings, so it needs to be a String that is a valid integer, and then the Integer value has to be greater than zero (see last part).

Writing AutoIt scripts since

_DateAdd("d", -2, _NowCalcDate())
Link to comment
Share on other sites

OMFG! When I copied the string testing If Statement, I made the dumbest mistake ever

Func _MathFactorial($mfFactor, $mfStop = 0)
    If (Not StringIsInt($mfFactor)) OR Not (Int($mfFactor) < 0) Then

Should have been

If (Not StringIsInt($mfFactor)) OR (Int($mfFactor) < 0) Then

Writing AutoIt scripts since

_DateAdd("d", -2, _NowCalcDate())
Link to comment
Share on other sites

Now, just a problem with the permutations

Also, to help those who don't remember much from their algebra class...A combination is a set of numbers in any order, where a permutation is a set of numbers in a specific order.

Combinations: 123 and 124 are different, 123 and 321 are the same.

Permutations: 123 and 321 are different, they are in a different order.

In essence, those combination locks should be called permutation locks, as those numbers must be entered in a certain order...

AutoItSetOption("TrayIconDebug", 1)

Func _MathFactorial($mfFactor, $mfStop = 0)
    If Not (StringIsInt($mfFactor)) OR (Int($mfFactor) < 0) Then
   ;Invalid text entered into parameters exit with error
        SetError(1)
        Return 0
    Else
   ;Make the parameter a number (was a string)
        $mfFactor = Int($mfFactor)
    EndIf
;0! is 1
    If $mfFactor = 0 Then Return 1
    
    Dim $return = 1
;$mfFactor * ($mfFactor - 1) * ($mfFactor - 2) * ... * 3 * 2 * 1
    While $mfFactor > $mfStop
        $return *= $mfFactor
        $mfFactor -= 1
    WEnd
    Return $return
EndFunc

Func _MathPermutation($mpN, $mpR)
    If (Not StringIsInt($mpN)) OR (Int($mpN) < 0) Then
   ;Invalid parameters, or N is less than R (not allowed)
        SetError(1)
        Return 0
    Else
   ;Make the parameters into numbers (was a string)
        $mpN = Int($mpN)
    EndIf
    
    If (Not StringIsInt($mpR)) OR (Int($mpR) < 0) Then
        SetError(2)
        Return 0
    Else
        $mpR = Int($mpR)
    EndIf
    
    If (Int($mpN) < Int($mpR)) Then
        SetError(4)
        Return 0
    EndIf
    
    Select
        Case $mpR = 0
            Return 1
        Case $mpR = 1
            Return $mpN
        Case $mpN = $mpR
            _MathFactorial($mpN)
        Case Else
            _MathFactorial($mpN, $mpR)
        EndSelect
EndFunc

MsgBox(0, "Factorial", _MathFactorial(4))
MsgBox(0, "Permutation", _MathPermutation(4, 4) & @CRLF & @error)
Edited by MSLx Fanboy

Writing AutoIt scripts since

_DateAdd("d", -2, _NowCalcDate())
Link to comment
Share on other sites

Func _MathFactorial($mfFactor, $mfStop = 0)
    If Not (StringIsInt($mfFactor)) OR (Int($mfFactor) < 0) Then
  ;Invalid text entered into parameters exit with error
        SetError(1)
        Return 0
    Else
  ;Make the parameter a number (was a string)
        $mfFactor = Int($mfFactor)
    EndIf
;0! is 1
    If $mfFactor = 0 Then Return 1
    
    Dim $return = 1
;$mfFactor * ($mfFactor - 1) * ($mfFactor - 2) * ... * 3 * 2 * 1
    While $mfFactor > $mfStop
        $return *= $mfFactor
        $mfFactor -= 1
    WEnd
    Return $return
EndFunc

Func _MathPermutation($mpN, $mpR)
    If (Not StringIsInt($mpN)) OR (Int($mpN) < 0) Then
  ;Invalid parameters, or N is less than R (not allowed)
        SetError(1)
        Return 0
    Else
  ;Make the parameters into numbers (was a string)
        $mpN = Int($mpN)
    EndIf
    
    If (Not StringIsInt($mpR)) OR (Int($mpR) < 0) Then
        SetError(2)
        Return 0
    Else
        $mpR = Int($mpR)
    EndIf
    
    If (Int($mpN) < Int($mpR)) Then
        SetError(4)
        Return 0
    EndIf
    
    Select
        Case $mpR = 0
            Return 1
        Case $mpR = 1
            Return $mpN
        Case $mpN = $mpR
            _MathFactorial($mpN)
        Case Else
            _MathFactorial($mpN, $mpR)
        EndSelect
EndFunc

<{POST_SNAPBACK}>

You need to Return the values from _MathFactorial for the calling function to see them.

Let's see. nPr is n!/(n-r)!. So 15P3 should be 15!/(15-3)! = 15!/12! = 15*14*13 = 2730.

Also, I would use a For loop for the factorial function, not the loop chosen. This should also be a little faster.

For $i = $mfFactor to $mfStop + 1 Step - 1
        $return *= $i
    Next

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

Thanks Nutster! I can't believe I didn't catch that I forgot the Return keyword. That For loop is much nicer too, thanks!

Yea! It's done and over with!!!!

:)

Writing AutoIt scripts since

_DateAdd("d", -2, _NowCalcDate())
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...