Jump to content

Bug with number 3


Go to solution Solved by Nine,

Recommended Posts

#cs ----------------------------------------------------------------------------

 AutoIt Version: Last stable version
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

#include <Array.au3>
#include <Math.au3>
#include <MsgBoxConstants.au3>

Global $g_aiOrden = [0, 2, 200, 1, -1, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Global $eCount = 38
Orden($g_aiOrden)
_ArrayDisplay($g_aiOrden)

Func Orden(ByRef $aArray)
    Local $i = 0, $iMax = UBound($aArray)
    Local $oOrden = ObjCreate("Scripting.Dictionary")
    If @error Then Logs("Error creating the dictionary object $oOrden")

    For $i = 0 To $iMax - 1
        If ($aArray[$i] < 0 Or $aArray[$i] > $iMax Or StringIsDigit($aArray[$i]) = 0) = True Then
            $aArray[$i] = -1
        EndIf
        For $i3 = 0 To $iMax - 1
            Local $located = -1
            $located = _ArrayFindAll($aArray, $i3)
            If UBound($located) <> 1 And Not @error Then
                For $i2 = 1 To UBound($located) - 1
                    $aArray[$located[$i2]] = -1
                    $i = 0
                Next
            EndIf
        Next
    Next

    For $i = 0 To $iMax - 1
        $oOrden.Item($i) = Number($aArray[$i]) <> -1
    Next

    Local $iC = 0
    For $i2 = $oOrden.Count -1 To 0 Step - 1
        If $oOrden.Item($i2) = True Then ContinueLoop
        $iC -= 1
        $aArray[$i2] = $i + $iC
        $oOrden.Item($i2) = True
    Next

 EndFunc   ;==>Orden

Func Logs($s, $a = 1)
   ConsoleWrite($s & @CRLF)
EndFunc

I made this code in multiple ways and it has some mania with the number 3, it never shows it no matter what I do, it's diabolical but I always have problems with that number instead it doubles 15. It is the latest official stable version of autoit.

The script should fix the array and instead of duplicating the number 15 it should show 3 instead of 200, what it does is mark the numbers out of range and replace them with clean numbers that have not been used elsewhere within the same range .

I've been trying to get it to work for days and I can't.

Edited by boludoz
Link to comment
Share on other sites

  • Solution

Your two last loops seem to be the one defective :

#include <Array.au3>
#include <Math.au3>
#include <MsgBoxConstants.au3>

Global $g_aiOrden = [0, 2, 200, 1, -1, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Global $eCount = 38
Orden($g_aiOrden)
_ArrayDisplay($g_aiOrden)

Func Orden(ByRef $aArray)
    Local $i = 0, $iMax = UBound($aArray)
    Local $oOrden = ObjCreate("Scripting.Dictionary")
    If @error Then Logs("Error creating the dictionary object $oOrden")

    For $i = 0 To $iMax - 1
        If ($aArray[$i] < 0 Or $aArray[$i] > $iMax Or StringIsDigit($aArray[$i]) = 0) = True Then
            $aArray[$i] = -1
        EndIf
        For $i3 = 0 To $iMax - 1
            Local $located = -1
            $located = _ArrayFindAll($aArray, $i3)
            If UBound($located) <> 1 And Not @error Then
                For $i2 = 1 To UBound($located) - 1
                    $aArray[$located[$i2]] = -1
;                    $i = 0
                Next
            EndIf
        Next
    Next

    ; _ArrayDisplay($aArray)

    For $i = 0 To $iMax - 1
        $oOrden.Item($i) = _ArraySearch($aArray, $i) >= 0
    Next

    $IC = -1
    For $i = 0 To $iMax - 1
      If $aArray[$i] < 0 Then
        Do
          $IC += 1
        Until Not $oOrden.Item($IC)
        $aArray[$i] = $IC
      EndIf
    Next

 EndFunc   ;==>Orden

Func Logs($s, $a = 1)
   ConsoleWrite($s & @CRLF)
EndFunc

Notice, I did not try to change your algorithm too much, although I believe it could be optimized :

Func Order(ByRef $aArray)
  Local Const $iMax = UBound($aArray) - 1
  Local $iNum = -1
  For $i = 0 To $iMax
    If $aArray[$i] > $iMax Or $aArray[$i] < 0 Or Not StringIsDigit($aArray[$i]) Or _
      ($i > 1 And _ArraySearch($aArray, $aArray[$i], 0, $i-1) >= 0) Or ($i = 1 And $aArray[0] = $aArray[1]) Then
      Do
        $iNum += 1
      Until _ArraySearch($aArray, $iNum) < 0
      $aArray[$i] = $iNum
    EndIf
  Next
EndFunc

 

Edited by Nine
Link to comment
Share on other sites

6 hours ago, Nine said:

Your two last loops seem to be the one defective :

#include <Array.au3>
#include <Math.au3>
#include <MsgBoxConstants.au3>

Global $g_aiOrden = [0, 2, 200, 1, -1, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Global $eCount = 38
Orden($g_aiOrden)
_ArrayDisplay($g_aiOrden)

Func Orden(ByRef $aArray)
    Local $i = 0, $iMax = UBound($aArray)
    Local $oOrden = ObjCreate("Scripting.Dictionary")
    If @error Then Logs("Error creating the dictionary object $oOrden")

    For $i = 0 To $iMax - 1
        If ($aArray[$i] < 0 Or $aArray[$i] > $iMax Or StringIsDigit($aArray[$i]) = 0) = True Then
            $aArray[$i] = -1
        EndIf
        For $i3 = 0 To $iMax - 1
            Local $located = -1
            $located = _ArrayFindAll($aArray, $i3)
            If UBound($located) <> 1 And Not @error Then
                For $i2 = 1 To UBound($located) - 1
                    $aArray[$located[$i2]] = -1
;                    $i = 0
                Next
            EndIf
        Next
    Next

    ; _ArrayDisplay($aArray)

    For $i = 0 To $iMax - 1
        $oOrden.Item($i) = _ArraySearch($aArray, $i) >= 0
    Next

    $IC = -1
    For $i = 0 To $iMax - 1
      If $aArray[$i] < 0 Then
        Do
          $IC += 1
        Until Not $oOrden.Item($IC)
        $aArray[$i] = $IC
      EndIf
    Next

 EndFunc   ;==>Orden

Func Logs($s, $a = 1)
   ConsoleWrite($s & @CRLF)
EndFunc

Notice, I did not try to change your algorithm too much, although I believe it could be optimized :

Func Order(ByRef $aArray)
  Local Const $iMax = UBound($aArray) - 1
  Local $iNum = -1
  For $i = 0 To $iMax
    If $aArray[$i] > $iMax Or $aArray[$i] < 0 Or Not StringIsDigit($aArray[$i]) Or _
      ($i > 1 And _ArraySearch($aArray, $aArray[$i], 0, $i-1) >= 0) Or ($i = 1 And $aArray[0] = $aArray[1]) Then
      Do
        $iNum += 1
      Until _ArraySearch($aArray, $iNum) < 0
      $aArray[$i] = $iNum
    EndIf
  Next
EndFunc

 

Thank you, your code is excellent and fast, I was already exhausted trying to use objects.

Link to comment
Share on other sites

@boludoz and @Nine

can check if is correct.....

#include <Array.au3>
#include <Math.au3>
#include <MsgBoxConstants.au3>

Global $g_aiOrden = [0, 2, 200, 1, -1, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Global $eCount = 38

Order3($g_aiOrden)
_ArrayDisplay($g_aiOrden)

Func Order3(ByRef $aArray)
    Local $oTemp = ''
    Local $oRow = ''
    Local $oNumber = ''
    Local Const $iMax = UBound($aArray) - 1
    Local $iNum = -1
        For $i = 0 To $iMax
            $oNumber &= $i & ';'
            If $aArray[$i] > $iMax Or $aArray[$i] < 0 Or Not StringIsDigit($aArray[$i]) Then
                $oRow &= $i & '|'
            Else
                If Not StringRegExp($oTemp, '\b'& $aArray[$i] &'\b') Then
                    $oTemp &= $aArray[$i] & '|'
                Else
                    $oRow &= $i & '|'
                Endif
            Endif
        Next
    $oTemp = StringTrimRight($oTemp, 1)
    $oNumber = StringRegExpReplace($oNumber, '\b('& $oTemp &');\b', '')

    Local $oRowSplit = StringSplit(StringTrimRight($oRow, 1), '|', 2)
    Local $oNumberSplit = StringSplit(StringTrimRight($oNumber, 1), ';', 2)
    For $i = 0 To UBound($oRowSplit) - 1
        $aArray[$oRowSplit[$i]] = $oNumberSplit[$i]
    Next
EndFunc

 

Link to comment
Share on other sites

On 3/10/2022 at 3:53 PM, jugador said:

@boludoz and @Nine

can check if is correct.....

#include <Array.au3>
#include <Math.au3>
#include <MsgBoxConstants.au3>

Global $g_aiOrden = [0, 2, 200, 1, -1, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Global $eCount = 38

Order3($g_aiOrden)
_ArrayDisplay($g_aiOrden)

Func Order3(ByRef $aArray)
    Local $oTemp = ''
    Local $oRow = ''
    Local $oNumber = ''
    Local Const $iMax = UBound($aArray) - 1
    Local $iNum = -1
        For $i = 0 To $iMax
            $oNumber &= $i & ';'
            If $aArray[$i] > $iMax Or $aArray[$i] < 0 Or Not StringIsDigit($aArray[$i]) Then
                $oRow &= $i & '|'
            Else
                If Not StringRegExp($oTemp, '\b'& $aArray[$i] &'\b') Then
                    $oTemp &= $aArray[$i] & '|'
                Else
                    $oRow &= $i & '|'
                Endif
            Endif
        Next
    $oTemp = StringTrimRight($oTemp, 1)
    $oNumber = StringRegExpReplace($oNumber, '\b('& $oTemp &');\b', '')

    Local $oRowSplit = StringSplit(StringTrimRight($oRow, 1), '|', 2)
    Local $oNumberSplit = StringSplit(StringTrimRight($oNumber, 1), ';', 2)
    For $i = 0 To UBound($oRowSplit) - 1
        $aArray[$oRowSplit[$i]] = $oNumberSplit[$i]
    Next
EndFunc

 

It works fine too, thanks.

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...