• Moin,

    Ich hab' anlässlich zu dem Thema hier Klick! mal was gebastelt.;)
    Ich selbst habe nicht die geringste Ahnung, wie BrainFuck funktioniert, deswegen arbeite ich mit einem anderen System:

    i
    Inkrementiert den aktuellen Wert um 1. (+1)

    d
    Dekrementiert den aktuellen Wert um 1. (-1)

    I
    Inkrementiert den aktuellen Wert um 10. (+10)

    D
    Dekrementiert den aktuellen Wert um 10. (-10)

    R
    Setzt den aktuellen Wert auf 65 (ASCII-Code für "A").

    r
    Setzt den aktuellen Wert auf 97 (ASCII-Code für "a").

    O oder o (Groß-Klein-Schreibung wird hier nicht beachtet)
    Gibt den aktuellen Wert als ASCII-Zeichen aus.

    So, hier dann mal das Script. ;)

    IDO-Interpreter (Version 1.0)
    [autoit]


    #include <EditConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sFile = "test.txt"
    $fDebug = True

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("IDO-Interpreter", 500, 250)
    $hCodeInput = GUICtrlCreateEdit("Input", 0, 0, 250, 100)
    $hCodeOutput = GUICtrlCreateEdit("Output", 0, 150, 250, 100, $ES_READONLY)
    $hDebugOutput = GUICtrlCreateEdit("Debug", 250, 0, 250, 250)
    GUICtrlSetBkColor(-1, 0x999999)
    GUICtrlSetColor(-1, 0xFFFFFF)
    $hRunButton = GUICtrlCreateButton("Execute", 0, 100, 250, 50)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()
    While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
    Case -3
    Exit
    Case $hRunButton
    _Run()
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Run()
    GUICtrlSetData($hDebugOutput, "")
    GUICtrlSetData($hCodeOutput, "")

    [/autoit] [autoit][/autoit] [autoit]

    $hTimer = TimerInit()

    [/autoit] [autoit][/autoit] [autoit]

    _Debug("Program started!" & @CRLF & @CRLF)
    Dim $asCmd
    $asCmd = _InputReadToCommands($sFile)

    [/autoit] [autoit][/autoit] [autoit]

    $iCell = 65
    For $i = 1 To $asCmd[0]
    _Debug("Read Char: " & $asCmd[$i] & @CRLF & " Action: ")
    $fMatch = False

    [/autoit] [autoit][/autoit] [autoit]

    Switch $asCmd[$i]
    Case "I"
    $fMatch = True
    If $asCmd[$i] == "i" Then
    $iCell += 1
    _Debug("Increment Cell from " & $iCell - 1 & " to " & $iCell & @CRLF)
    ElseIf $asCmd[$i] == "I" Then
    $iCell += 10
    _Debug("Increment Cell from " & $iCell - 10 & " to " & $iCell & @CRLF)
    EndIf
    Case "D"
    $fMatch = True
    If $asCmd[$i] == "d" Then
    $iCell -= 1
    _Debug("Decrement Cell from " & $iCell + 1 & " to " & $iCell & @CRLF)
    ElseIf $asCmd[$i] == "D" Then
    $iCell -= 10
    _Debug("Decrement Cell from " & $iCell + 10 & " to " & $iCell & @CRLF)
    EndIf
    Case "O"
    $fMatch = True
    _Debug("Output Cell as ASCII-Char from " & $iCell & " to '" & Chr($iCell) & "'" & @CRLF)
    _Output(Chr($iCell))
    Case "R"
    $fMatch = True
    If $asCmd[$i] == "R" Then
    _Debug("Resetting Cell from " & $iCell & " (" & Chr($iCell) & ") to 65 (A)" & @CRLF)
    $iCell = 65
    ElseIf $asCmd[$i] == "r" Then
    _Debug("Resetting Cell from " & $iCell & " (" & Chr($iCell) & ") to 97 (a)" & @CRLF)
    $iCell = 97
    EndIf
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    If $fMatch = False Then
    _Debug("None. Character is unknown." & @CRLF)
    EndIf
    Next
    _Debug(@CRLF & "Program ended. Time: " & Round(TimerDiff($hTimer) / 1000, 1) & " Seconds")
    EndFunc ;==>_Run

    [/autoit] [autoit][/autoit] [autoit]

    Func _InputReadToCommands($sFile)
    $sCommands = GUICtrlRead($hCodeInput)
    $asCommands = StringSplit($sCommands, "")
    Return $asCommands
    EndFunc ;==>_InputReadToCommands

    [/autoit] [autoit][/autoit] [autoit]

    Func _Debug($sDebugInfo)
    GUICtrlSetData($hDebugOutput, GUICtrlRead($hDebugOutput) & $sDebugInfo)
    EndFunc ;==>_Debug

    [/autoit] [autoit][/autoit] [autoit]

    Func _Output($sOutput)
    GUICtrlSetData($hCodeOutput, GUICtrlRead($hCodeOutput) & $sOutput)
    EndFunc ;==>_Output

    [/autoit]

    Update:

    IDO-Interpreter (Version 1.1)


    Changelog:
    -2 Engines:
    -Chesstiger-Engine (Von mir)
    -Marsi-Engine (Von Marsi [Nochmal danke!])

    [autoit]


    #include <EditConstants.au3>
    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <GUIEdit.au3>
    $sFile = "test.txt"
    $fDebug = True

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("IDO-Interpreter", 500, 250)
    $hCodeInput = GUICtrlCreateEdit("Input", 0, 0, 250, 100, $WS_VSCROLL + $ES_AUTOVSCROLL)
    $hCodeOutput = GUICtrlCreateEdit("Output", 0, 150, 250, 100, $ES_READONLY + $WS_VSCROLL + $ES_AUTOVSCROLL)
    $hDebugOutput = GUICtrlCreateEdit("Debug", 250, 0, 250, 250, $ES_READONLY + $WS_VSCROLL + $ES_AUTOVSCROLL)
    GUICtrlSetBkColor(-1, 0x999999)
    GUICtrlSetColor(-1, 0xFFFFFF)
    $hRunButton = GUICtrlCreateButton("Execute", 0, 100, 150, 50)
    $hCtEngineRadio = GUICtrlCreateRadio("Chesstiger-Engine",150,100)
    GUICtrlSetState($hCtEngineRadio, $GUI_CHECKED)
    $hMarsiEngineRadio = GUICtrlCreateRadio("Marsi-Engine",150,120)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()
    While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
    Case -3
    Exit
    Case $hRunButton
    If BitAND(GUICtrlRead($hCtEngineRadio), $GUI_CHECKED) = $GUI_CHECKED Then _Run_CtEngine()
    If BitAND(GUICtrlRead($hMarsiEngineRadio), $GUI_CHECKED) = $GUI_CHECKED Then _Run_MarsiEngine()
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    #region Chesstiger-Engine
    Func _Run_CtEngine()
    GUICtrlSetData($hDebugOutput, "")
    GUICtrlSetData($hCodeOutput, "")

    [/autoit] [autoit][/autoit] [autoit]

    $hTimer = TimerInit()

    [/autoit] [autoit][/autoit] [autoit]

    _Debug("Program started!" & @CRLF & @CRLF)
    Dim $asCmd
    $asCmd = _InputReadToCommands($sFile)

    [/autoit] [autoit][/autoit] [autoit]

    $iCell = 65
    For $i = 1 To $asCmd[0]
    _Debug("Read Char: " & $asCmd[$i] & @CRLF & " Action: ")
    $fMatch = False

    [/autoit] [autoit][/autoit] [autoit]

    $sChar = $asCmd[$i]
    Select
    Case $sChar == "I"
    $fMatch = True
    $iCell += 10
    _Debug("Increment Cell from " & $iCell - 10 & " to " & $iCell & @CRLF)
    Case $sChar == "i"
    $fMatch = True
    $iCell += 1
    _Debug("Increment Cell from " & $iCell - 1 & " to " & $iCell & @CRLF)
    Case $sChar == "D"
    $fMatch = True
    $iCell -= 10
    _Debug("Decrement Cell from " & $iCell + 10 & " to " & $iCell & @CRLF)
    Case $sChar == "d"
    $fMatch = True
    $iCell -= 1
    _Debug("Decrement Cell from " & $iCell + 1 & " to " & $iCell & @CRLF)
    Case $sChar = "O"
    $fMatch = True
    _Debug("Output Cell as ASCII-Char from " & $iCell & " to '" & Chr($iCell) & "'" & @CRLF)
    _Output(Chr($iCell))
    Case $sChar == "R"
    $fMatch = True
    _Debug("Resetting Cell from " & $iCell & " (" & Chr($iCell) & ") to 65 (A)" & @CRLF)
    $iCell = 65
    Case $sChar == "r"
    $fMatch = True
    _Debug("Resetting Cell from " & $iCell & " (" & Chr($iCell) & ") to 97 (a)" & @CRLF)
    $iCell = 97
    EndSelect

    [/autoit] [autoit][/autoit] [autoit]

    If $fMatch = False Then
    _Debug("None. Character is unknown." & @CRLF)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Next
    _Debug(@CRLF & "Program ended. Time: " & Round(TimerDiff($hTimer), 2) & " ms")
    EndFunc ;==>_Run

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _InputReadToCommands($sFile)
    $sCommands = GUICtrlRead($hCodeInput)
    $asCommands = StringSplit($sCommands, "")
    Return $asCommands
    EndFunc ;==>_InputReadToCommands
    #endregion

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Output & Debug
    Func _Debug($sDebugInfo)
    GUICtrlSetData($hDebugOutput, GUICtrlRead($hDebugOutput) & $sDebugInfo)
    EndFunc ;==>_Debug

    [/autoit] [autoit][/autoit] [autoit]

    Func _Output($sOutput)
    GUICtrlSetData($hCodeOutput, GUICtrlRead($hCodeOutput) & $sOutput)
    EndFunc ;==>_Output
    #endregion
    #region Marsi-Engine
    Func _Run_MarsiEngine() ;By Marsi
    GUICtrlSetData($hCodeOutput,"")
    GUICtrlSetData($hDebugOutput,"")
    _Debug("Program started." & @CRLF & "The Marsi-engine does not support debugging." & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    Local $Timer, $Interpretiert

    [/autoit] [autoit][/autoit] [autoit]

    $Timer = TimerInit()
    $Interpretiert = _Ido2Asc(GUICtrlRead($hCodeInput))
    $Timer = TimerDiff($Timer)
    _Debug('Program ended. Time: ' & Round($Timer, 2) & ' ms' & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _Output($Interpretiert)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Ido2Asc($s)
    Local $n = 65, $o = ''
    For $i = 1 To StringLen($s) Step 1
    Switch Asc(StringMid($s, $i, 1))
    Case 105
    $n += 1
    Case 73
    $n += 10
    Case 100
    $n -= 1
    case 68
    $n -= 10
    Case 82
    $n = 65
    Case 114
    $n = 97
    Case 111
    $o &= Chr($n)
    Case 79
    $o &= Chr($n)
    EndSwitch
    Next
    Return $o
    EndFunc ;==>_Ido2Asc
    #endregion

    [/autoit]

    Nebenbei, IDO kommt von den drei Grundbefehlen: Increment Decrement Output
    Zeilenumbrüche werden einfach ignoriert.

    Ach, hier noch mal ein Beispiel:

    Code
    IdddOriiiiOiiiiiiiOOiiiORDDDdddOrDOIIiiiiOiiiOddddddOddddddddODDDDDDDiiiO

    lg chess;)

    Edit: Englisch ( :S ) korrigiert.

  • Zumindest "Readed Char:" würde ich auf "Read Char:" ändern.
    Ich würde mich auch auf eine Sprache festlegen. Entweder Englisch oder Deutsch.

  • Sehr schön und leicht zu verstehen.

    Hab direkt mal einen kleinen interpreter gebastelt, der den Kram rasend schnell verarbeiten kann.

    [autoit]

    Local $HalloWelt = 'IdddOriiiiOiiiiiiiOOiiiORDDDdddOrDOIIiiiiOiiiOddddddOddddddddODDDDDDDiiiO'
    Local $Timer, $Interpretiert

    [/autoit][autoit][/autoit][autoit]

    $Timer = TimerInit()
    $Interpretiert = _Ido2Asc($HalloWelt)
    $Timer = TimerDiff($Timer)
    ConsoleWrite('Dauer: ' & Round($Timer,2) & ' ms' & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite($Interpretiert & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Func _Ido2Asc($sIdo) ; lol hier steht Sido^^

    [/autoit][autoit][/autoit][autoit]

    Local $iNr = 65 ; Startwert
    Local $sOut = '', $sMid
    Local $iLen = StringLen($sIdo)

    [/autoit][autoit][/autoit][autoit]

    For $i = 1 To $iLen Step 1
    $sMid = StringMid($sIdo, $i, 1)
    $iNr += ($sMid == 'i') * 1 + ($sMid == 'I') * 10 - ($sMid == 'd') * 1 - ($sMid == 'D') * 10 - ($iNr - 65) * ($sMid == 'R') - ($iNr - 97) * ($sMid == 'r')
    If $sMid = 'o' Then $sOut &= Chr($iNr)
    Next

    [/autoit][autoit][/autoit][autoit]

    Return $sOut

    [/autoit][autoit][/autoit][autoit]

    EndFunc

    [/autoit]
  • Nunja, du benutzt doppelte Abfragen (erst Case und dann nochmal das gleiche für groß/klein), du könntest das Case einfach weglassen. Das _Debug ausgeben verbraucht auch viel Zeit. Marsi gibt nur einmal aus und spart sich somit die Zeit

  • Ja, weil das Sprachmodell zuerst nur auf I, D & O basiert hat.
    Am Anfang gab's nur +1, nicht +10.
    Und ich hab's so gelassen, weil ich es so übersichtlicher finde und weil es hier eigentlich nicht auf Geschwindigkeit ankommt.
    Wenn müsste man hier mit Select arbeiten, das wäre wohl das praktischste.

    Und das Debug finde ich ganz nützlich, um Fehler zu finden. ;)

    lg chess

  • Habe gerade entdeckt wie man es nochmals beschleunigen kann.
    AutoIt mag Stringvergleiche überhaupt nicht. Und schon garnicht, wenn auch noch auf Groß/Kleinschreibung geachtet werden muss.

    Also kann man den einen Buchstaben direkt als Zahl speichern und anschließend nur noch die Asc Werte vergleichen.
    Dadurch entfallen sämtliche Strings aus den Vergleichen und Variablen.

    Bei mir dauerts jetzt noch 0,41ms. Ist also etwa 1,5Mal so schnell.

    Spoiler anzeigen
    [autoit]

    Local $HalloWelt = 'IdddOriiiiOiiiiiiiOOiiiORDDDdddOrDOIIiiiiOiiiOddddddOddddddddODDDDDDDiiiO'
    Local $Timer, $Interpretiert

    [/autoit] [autoit][/autoit] [autoit]

    $Timer = TimerInit()
    $Interpretiert = _Ido2Asc($HalloWelt)
    $Timer = TimerDiff($Timer)
    ConsoleWrite('Dauer: ' & Round($Timer, 2) & ' ms' & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite($Interpretiert & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    Func _Asc2Ido($s)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Ido2Asc($sIdo) ; lol hier steht Sido^^

    [/autoit] [autoit][/autoit] [autoit]

    Local $iNr = 65 ; Startwert
    Local $sOut = '', $iMid
    Local $iLen = StringLen($sIdo)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iLen Step 1
    $iMid = Asc(StringMid($sIdo, $i, 1))
    $iNr += ($iMid = 105) * 1 + ($iMid = 73) * 10 - ($iMid = 100) * 1 - ($iMid = 68) * 10 - ($iNr - 65) * ($iMid = 82) - ($iNr - 97) * ($iMid = 114)
    If $iMid = 111 Or $iMid = 79 Then $sOut &= Chr($iNr)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $sOut

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Ido2Asc

    [/autoit]
  • Edit: Komplett geändert. Man konnte nix lesen.

    Nur einfaches i oder d zusammen mit O: [2114 Zeichen]

    Code
    'iiiiiiiOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOddddOiiiiiiiiiiiiiOddddddddddddddddddddddddddddddddddddddd' & @CRLF & _'dddddddddddddddddddddddddddddddddddddddddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii' & @CRLF & _'iiiiiiiiiiiiiiiiiOiiiiiiiiiiOiOddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' & @CRLF & _'dddddddddddddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOiiiiOiiiiiOddd' & @CRLF & _'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddOiiiiiiiiiiiiiiiiiiiiiiii' & @CRLF & _'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOiOdddddddOiiiiOiiiiiOdddddddddOiiiiiiiiiiiiiOddd' & @CRLF & _'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddOiiiiiiiiiiiiiiiiiiii' & @CRLF & _'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOiiiiiiiiiiiiiiiiiOiiiiiiiiiiiiiiiiiiiOddddOdddddddddddddddddddddddd' & @CRLF & _'ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii' & @CRLF & _'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOdddddOdddOdddddddddddddddddddddddddddddddddddddd' & @CRLF & _'ddddddddddddddddddddddddddddddddddddddddddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOiiiiiiiiiiiiiiiii' & @CRLF & _'iiiiiiiiiiiiiiiiiiiOiiiiiOiiiiiOiOdddddddddddOiiiiOOiiiiiiiiOdddddddOdddddddOddddddddddddddddddddddd' & @CRLF & _'ddddddddddddddddddddddddddddddddddOddddddddddddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOiiii' & @CRLF & _'iiiiiiiiiiiiiiiiOiiiiiiiiiiiOddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' & @CRLF & _'dddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOdddddddddd' & @CRLF & _'ddddddOiiiiiOdddddddOiiiiiiiiiiiiiiiiiiiiOddddddddddddddddOiiiiiiiiiOddddddddddddddddddddddddddddddd' & @CRLF & _'dddddddddddddddddddddddddddddddddddddddddddddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii' & @CRLF & _'iiiiiiiiiiiiiiiiiiiiiiiiiiiOdddddddddddddOdddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' & @CRLF & _'ddddddddOiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOiiiiiiiiiiiiiiOdddddd' & @CRLF & _'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddOiiiiiiiiiiiiiiiiiiiiii' & @CRLF & _'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiOiOdddddddddddOiiiiiiiiiiiiiiiOOiiiiOdddddddddd' & @CRLF & _'ddddddddddddOO'

    Einbeziehung von D und I: [539 Zeichen]

    Code
    'iiiiiiiOIIIiiiOddddOIiiiODDDDDDDDddOIIIIIIIiiiOIOiODDDDDDDDddddOIIIIIIiiiiiiiiiOiiiiOiiiiiODDDDDDDdd' & @CRLF & _'ddddddOIIIIIIIiiiiiOiOdddddddOiiiiOiiiiiOdddddddddOIiiiODDDDDDDDddOIIIIIiiOIiiiiiiiOIiiiiiiiiiOddddO' & @CRLF & _'DDDDDDDDddddOIIIIIIIIIOdddddOdddODDDDDDDDddOIIIiiiiiiiOIIIiiiiiiOiiiiiOiiiiiOiODdOiiiiOOiiiiiiiiOddd' & @CRLF & _'ddddOdddddddODDDDDdddddddODddddOIIIIiiiiiOIIOIiODDDDDDDddddddOIIIIIIIIiiiODddddddOiiiiiOdddddddOIIOD' & @CRLF & _'ddddddOiiiiiiiiiODDDDDDDddddddddOIIIIIIIiiiiiiiiiODdddODDDDDDddddddOIIIIIIiiiiiiiiiOIiiiiODDDDDDDDdd' & @CRLF & _'dOIIIIIIIiiiiiOiODdOIiiiiiOOiiiiODDddOO'
  • Ich versuche einen Umwandler zu schreiben der immer den kürzest möglichen Weg nimmt.

    Ist aber schwieriger als ich zuerst dachte, da man immer von der Aktuellen Pos, R oder r ausgehen kann.
    Und man kann über das Ziel hinaus schießen und anschließend per i oder d schneller sein.

    Der Zweite müsste bei dir auch wesentlich schneller gehen.

  • Dann hast du zwischendrin irgendwelche Zeichen kaputt gemacht.

    Hier nochmal als eine Zeile. Damit müsste es gehen.

    Code
    iiiiiiiOIIIiiiOddddOIiiiODDDDDDDDddOIIIIIIIiiiOIOiODDDDDDDDddddOIIIIIIiiiiiiiiiOiiiiOiiiiiODDDDDDDddddddddOIIIIIIIiiiiiOiOdddddddOiiiiOiiiiiOdddddddddOIiiiODDDDDDDDddOIIIIIiiOIiiiiiiiOIiiiiiiiiiOddddODDDDDDDDddddOIIIIIIIIIOdddddOdddODDDDDDDDddOIIIiiiiiiiOIIIiiiiiiOiiiiiOiiiiiOiODdOiiiiOOiiiiiiiiOdddddddOdddddddODDDDDdddddddODddddOIIIIiiiiiOIIOIiODDDDDDDddddddOIIIIIIIIiiiODddddddOiiiiiOdddddddOIIODddddddOiiiiiiiiiODDDDDDDddddddddOIIIIIIIiiiiiiiiiODdddODDDDDDddddddOIIIIIIiiiiiiiiiOIiiiiODDDDDDDDdddOIIIIIIIiiiiiOiODdOIiiiiiOOiiiiODDddOO

    Dauert bei mir nur 5,3 Sekunden.
    (mit dem anderen Interpreter 2,7 ms)

    Hier ist mal der Encoder. Er beinhaltet aber zurzeit noch keine Optimierungen.
    Er geht immer linear auf sein Ziel zu mit den jeweils größt möglichen Schritten.
    r und R werden noch nicht verwendet.

    &quot;Encoder&quot;
    [autoit]

    Func _Asc2Ido($s)

    [/autoit] [autoit][/autoit] [autoit]

    Local $Kl = 97
    Local $Gr = 65
    Local $iLen = StringLen($s)
    Local $iMid, $sOut = '', $iNr = 65, $iDif

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iLen Step 1
    $iMid = Asc(StringMid($s, $i, 1)) ; Asc Code des Zeichens.
    $iDif = $iMid - $iNr

    [/autoit] [autoit][/autoit] [autoit]

    ;~ ConsoleWrite($iMid)

    [/autoit] [autoit][/autoit] [autoit]

    If Not $iDif Then
    $sOut &= 'O'
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $iDif > 0 Then ; Zeichen liegt oberhalb

    [/autoit] [autoit][/autoit] [autoit]

    While Not (Int($iDif/10) = 0)
    $iNr += 10
    $sOut &= 'I'
    $iDif = $iMid - $iNr
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    While Not ($iDif = 0)
    $iNr += 1
    $sOut &= 'i'
    $iDif = $iMid - $iNr
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Else ; Zeichen liegt unterhalb

    [/autoit] [autoit][/autoit] [autoit]

    While Not (Int($iDif/10) = 0)
    $iNr -= 10
    $sOut &= 'D'
    $iDif = $iMid - $iNr
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    While Not ($iDif = 0)
    $iNr -= 1
    $sOut &= 'd'
    $iDif = $iMid - $iNr
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $sOut &= 'O'

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $sOut

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit]

    Das Umwandeln dauert ca. 1ms und ist damit (noch) wesentlich schneller als das Interpretieren.

    Edit:
    Hab den Interpreter nochmal verbessert. Er packt das Interpretieren jetzt auch in 1ms.
    Das Problem lag darin, dass man in der langen Berechnung keinen Abbruch hat, sobald ein Ereignis zutrifft.
    Daher ist Switch um einiges schneller. Ein Zeichen kann nämlich nur eine Bedingung erfüllen.
    Aber wozu einfach, wenn es auch kompliziert geht^^

    &quot;Interpreter&quot;
    [autoit]

    Func _Ido2Asc($s)
    Local $n = 65, $o = ''
    For $i = 1 To StringLen($s) Step 1
    Switch Asc(StringMid($s, $i, 1))
    Case 105
    $n += 1
    Case 73
    $n += 10
    Case 100
    $n -= 1
    case 68
    $n -= 10
    Case 82
    $n = 65
    Case 114
    $n = 114
    Case 111
    $o &= Chr($n)
    Case 79
    $o &= Chr($n)
    EndSwitch
    Next
    Return $o
    EndFunc ;==>_Ido2Asc

    [/autoit]
  • Ja, damit geht's. Ich habe extra nochmal alles nachgeguckt, habe aber keinen Fehler gefunden.... Seltsam.

    Cool, ein Encoder.:thumbup:

    Habe ich auch schon dran überlegt, hab's aber gelassen. Hab mir gedacht, dass mir das den Spaß verdirbt. ;)

    Btw, hast du was dagegen, wenn ich deine Engine in den Interpreter mit einbaue?

    lg chess

  • chesstiger Gute Idee, gefällt mir!

    @Marsi So ähnlich hatte ich den Interpreter auch von Anfang an (hatte mich gleich 'ne eigene Version gebaut):

    [autoit]

    ConsoleWrite(IDO("IdddOriiiiOiiiiiiiOOiiiORDDDdddOrDOIIiiiiOiiiOddddddOddddddddODDDDDDDiiiO") & @LF)
    Func IDO($script)
    Local $command, $i, $data = "", $n = 65
    $command = StringSplit($script, "")
    For $i = 1 To $command[0] Step 1
    Switch Asc($command[$i])
    Case Asc("i")
    $n += 1
    Case Asc("d")
    $n -= 1
    Case Asc("I")
    $n += 10
    Case Asc("D")
    $n -= 10
    Case Asc("r")
    $n = Asc("a")
    Case Asc("R")
    $n = Asc("A")
    Case Asc("O"), Asc("o")
    $data &= Chr($n)
    Case Else
    Return SetError(1, $i, "")
    EndSwitch
    Next
    Return $data
    EndFunc

    [/autoit]

    Und weil wir schon gerade bei so sinnlosen Sprachen sind, hier mal meine Idee:
    Mit < und > verschiebt man den Pointer in einer 16bit-Integer und mit , flippt man das aktuelle Bit. Mit . gibt man den Wert der Int als Unicode-Zeichen aus:

    [autoit]

    ConsoleWrite(XorBitFlip(",<<<<<<,.") & @LF)
    Func XorBitFlip($script)
    Local $command, $i, $data = "", $n = 0, $p = 0
    $command = StringSplit($script, "")
    For $i = 1 To $command[0] Step 1
    Switch $command[$i]
    Case "<"
    $p += 1
    If ($p = 16) Then $p = 0
    Case ">"
    $p -= 1
    If ($p = -1) Then $p = 15
    Case ","
    $n = BitXOR($n, 2^$p)
    Case "."
    $data &= ChrW($n)
    Case Else
    Return SetError(1, $i, "")
    EndSwitch
    Next
    Return $data
    EndFunc

    [/autoit]
  • Sooo habs nun fertig.

    Der Interpreter aus meinem Post hatte noch einen Bug.
    Hab mich verschrieben, wodurch alles was mit r war fehlschlagen musste. (Zeile 16)

    Zum Interpreter hab ich den Encoder der (soweit ich das nachvollziehen kann) den optimalen Weg geht nun auch fertig.
    Leider war die Rechnung extrem kompliziert wonach ausgerechnet werden konnte welcher Weg der Beste ist, bevor man ihn beschreitet. Daher habe ich es mir leicht gemacht und auf Kosten der Geschwindigkeit alle 3 Wege getestet. Der kürzeste wird dann einfach genommen.

    Der Oben gepostete Text lässt sich nun in 338 Zeichen verpacken.

    Code
    IdddOrIddOddddOIiiiORDDDdddOrIddOIOiORDDDdddOriiiiOiiiiOiiiiiORDDDdddOrIOiODiiiOiiiiOiiiiiODiOIiiiOR
    DDDdddORIIdOIIdddOIIdOddddORDDDdddOrIIiiiiiOrIIOdddORDDDdddORiiiiOrIddOiiiiiOiiiiiOiODdOiiiiOOIddODi
    iiODiiiORDDiODddddOrDDOrOIiORDDDdddOrIIddOriiOiiiiiOrOIIOriiiiOIdORDDDdddOrIiiiiOriORDDDdddOriiiiOIi
    iiiORDDDdddOrIOiOrOIiiiiiOOiiiiODDddOO


    Hallo Welt (Hello World) passt in 56 Zeichen.

    Code
    Startpost: 
    IdddOriiiiOiiiiiiiOOiiiORDDDdddOrDOIIiiiiOiiiOddddddOddddddddODDDDDDDiiiO
    Neu:
    IdddOIIIdOrIiOOiiiORDDDdddOrDOIIiiiiOiiiOrIiODiiORDDDddO
    &quot;Skript&quot;
    [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $sInput = 'Hello World! - So könnte auch ihr Satz beginnen.'
    Local $Timer, $Interpretiert, $HalloWelt

    [/autoit] [autoit][/autoit] [autoit]

    $Timer = TimerInit()
    $HalloWelt = _Asc2Ido($sInput)
    $Timer = TimerDiff($Timer)
    ConsoleWrite('Encode: ' & Round($Timer, 2) & ' ms' & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    $Timer = TimerInit()
    $Interpretiert = _Ido2Asc($HalloWelt)
    $Timer = TimerDiff($Timer)
    ConsoleWrite('Decode: ' & Round($Timer, 2) & ' ms' & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite($Interpretiert & @CRLF & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('Anzahl Zeichen: ' & StringLen($HalloWelt) & @CRLF)
    ConsoleWrite(_Trennen($HalloWelt, 100) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; ohne alles 2114
    ; mit 10er Schritten 539
    ; Mit Rücksprüngen:470
    ; Mit R für positive Abstände: 436
    ; Vergessenes Abs() eingefügt: 419
    ; Mit r für positive Abstände: 393
    ; Mit R und r für neg Abstände: 338

    [/autoit] [autoit][/autoit] [autoit]

    Func _Asc2Ido($s)

    [/autoit] [autoit][/autoit] [autoit]

    Local $Kl = 97, $Gr = 65, $iLen = StringLen($s), $iMid, $sOut = '', $iNr = 65, $iDif, $iLen_Ohne, $iTMP_Nr, $iTMP_Dif, $sTMP_Out, $iMethode[3]

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iLen Step 1
    $iMid = Asc(StringMid($s, $i, 1)) ; Asc Code des Zeichens.
    $iDif = $iMid - $iNr

    [/autoit] [autoit][/autoit] [autoit]

    If Not $iDif Then
    $sOut &= 'O'
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    For $o = 0 To 2 ;Brute Force. Ich weiß nicht wie man ausrechnet welcher Weg der Beste ist...
    ; Eine reine Abstandsverringerung kann auch schlecht sein, wenn es z.B. genau auf einen Zehner aufgeht und mit kleinerem Abstand Einerschritte nötig werden...

    [/autoit] [autoit][/autoit] [autoit]

    $iTMP_Nr = $iNr
    $sTMP_Out = ''

    [/autoit] [autoit][/autoit] [autoit]

    Switch $o
    Case 0 ; Keine Veränderung
    Case 1 ; R -> Beginne bei 65
    $sTMP_Out &= 'R'
    $iTMP_Nr = $Gr
    Case 2 ; r -> Beginne bei 97
    $sTMP_Out &= 'r'
    $iTMP_Nr = $Kl
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    $iTMP_Dif = $iMid - $iTMP_Nr

    [/autoit] [autoit][/autoit] [autoit]

    If $iTMP_Dif >= 0 Then
    _Add($sTMP_Out, $iTMP_Dif, $iTMP_Nr, $iMid)
    Else
    _Sub($sTMP_Out, $iTMP_Dif, $iTMP_Nr, $iMid)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $iMethode[$o] = $sTMP_Out

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    $iNr = $iTMP_Nr
    $sOut &= $iMethode[_GetMin($iMethode)] & 'O'

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $sOut

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Asc2Ido

    [/autoit] [autoit][/autoit] [autoit]

    Func _Ido2Asc($s)
    Local $n = 65, $o = ''
    For $i = 1 To StringLen($s) Step 1
    Switch Asc(StringMid($s, $i, 1))
    Case 105
    $n += 1
    Case 73
    $n += 10
    Case 100
    $n -= 1
    Case 68
    $n -= 10
    Case 82
    $n = 65
    Case 114
    $n = 97
    Case 111
    $o &= Chr($n)
    Case 79
    $o &= Chr($n)
    EndSwitch
    Next
    Return $o
    EndFunc ;==>_Ido2Asc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Trennen($s, $l)

    [/autoit] [autoit][/autoit] [autoit]

    Local $iLen = StringLen($s)
    Local $iTeile = Ceiling($iLen / $l)
    Local $sOut = ''

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To $iTeile - 1 Step 1
    $sOut &= "'" & StringMid($s, $i * $l + 1, $l) & "'" & @CRLF
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return StringTrimRight($sOut, 2)

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Trennen

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetMin($a)
    Local $b = StringLen($a[0]), $c = 0
    For $i = 1 To 2 Step 1
    If $b > StringLen($a[$i]) Then
    $b = StringLen($a[$i])
    $c = $i
    EndIf
    Next
    Return $c
    EndFunc ;==>_GetMin

    [/autoit] [autoit][/autoit] [autoit]

    Func _Add(ByRef $sOut, ByRef $iDif, ByRef $iNr, $iMid)

    [/autoit] [autoit][/autoit] [autoit]

    While Not (Int($iDif / 10) = 0)
    $iNr += 10
    $sOut &= 'I'
    $iDif = Abs($iMid - $iNr)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    If $iDif >= 6 Then ; Abstand > 6
    $sOut &= 'I' & StringLeft('dddd', 10 - $iDif)
    $iNr += $iDif
    $iDif = 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    While Not ($iDif = 0)
    $iNr += 1
    $sOut &= 'i'
    $iDif = $iMid - $iNr
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Add

    [/autoit] [autoit][/autoit] [autoit]

    Func _Sub(ByRef $sOut, ByRef $iDif, ByRef $iNr, $iMid)

    [/autoit] [autoit][/autoit] [autoit]

    $iDif = Abs($iDif)

    [/autoit] [autoit][/autoit] [autoit]

    While Not (Int($iDif / 10) = 0)
    $iNr -= 10
    $sOut &= 'D'
    $iDif = Abs($iMid - $iNr)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    If $iDif >= 6 Then ; Abstand > 6
    $sOut &= 'D' & StringLeft('iiii', 10 - $iDif)
    $iNr -= $iDif
    $iDif = 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    While Not ($iDif = 0)
    $iNr -= 1
    $sOut &= 'd'
    $iDif = $iMid - $iNr
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Sub

    [/autoit]