[Wettbewerb] Zweielementige boolesche Algebra

  • Carsten8 hat mich neulich daran erinnert, was man mit NOT- und OR-Gates alles bauen kann.
    Deshalb habe ich diesen Wettbewerb gestartet, um zu sehen, was ihr aus diesen sehr begrenzten Möglichkeiten alles machen könnt.

    !!! Achtung! Ich habe alles hier nochmal überarbeitet, was aber zur Folge hat, dass die Funktionen leichter verständlich sind und der Code der anderen Gates (AND, XOR, ...) kürzer wird. !!!
    Die Hauptänderung besteht darin, das die Funktionen nicht mehr die Inputs ändern, sondern eigene Outputs benutzen.

    Das Ziel
    Ein funktionierendes, möglichst sinnvolles Skript (z.B. einen Rechner) zu schreiben.

    Die Regeln
    Wie schon oben erwähnt, dreht sich bei diesem Wettbewerb alles um NOT- und OR-Gates.
    Ihr habt jetzt zwei Möglichkeiten:
    1) Ihr definiert eure Variablen und arbeitet dann nurnoch mit NOT und OR; z.B.:

    [autoit]

    $A = True
    $B = False
    $C = (Not ((Not $A) Or (Not $B)))

    [/autoit]


    2) Ihr könnt natürlich auch folgende sinnlose UDF benutzen, die aber im Grunde genau das Gleiche macht:

    Wire.au3
    [autoit]

    #include-once

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

    Func _Wire_Create()
    Return False
    EndFunc

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

    Func _Wire_Power(ByRef $Wire, $Power='On')
    Switch $Power
    Case 'On', 1
    $Wire = True
    Case 'Off', 0
    $Wire = False
    Case Else
    SetError(1)
    $Wire = False
    EndSwitch
    EndFunc
    Func _Wire_Value(ByRef $Wire)
    Return Int($Wire)
    EndFunc

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

    Func _Wire_NOT(ByRef $Input, ByRef $Output)
    $Output = (Not $Input)
    EndFunc

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

    Func _Wire_Connect(ByRef $Input1, ByRef $Input2, ByRef $Output)
    $Output = ($Input1 Or $Input2)
    EndFunc

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

    Func _Wire_FromInteger($Integer, ByRef $Wires, $Length = 32)
    $Integer = Int(Abs($Integer))
    Local $Binary, $i
    Do
    $Binary = Mod($Integer, 2) & $Binary
    $Integer = Int($Integer / 2)
    Until $Integer = 0
    For $i = StringLen($Binary)+1 To $Length Step 1
    $Binary = '0' & $Binary
    Next
    $Binary = StringRight($Binary, $Length)
    $Binary = StringSplit($Binary, '', 2)
    Dim $Wires[$Length]
    For $i = 1 To $Length Step 1
    $Wires[$i-1] = ($Binary[$Length-$i]==1)
    Next
    EndFunc
    Func _Wire_ToInteger($Wires)
    If (Not IsArray($Wires)) Then
    $Wires = StringSplit($Wires, '|', 2)
    EndIf
    Local $Binary = '', $Integer = 0, $i
    For $i = 0 To UBound($Wires)-1 Step 1
    $Binary = Int($Wires[$i]) & $Binary
    Next
    $Binary = StringSplit($Binary, '')
    For $i = 1 To $Binary[0] Step 1
    $Integer += $Binary[$i] * 2^($Binary[0]-$i)
    Next
    Return $Integer
    EndFunc

    [/autoit]


    Des weiteren könnt ihr auch InputBox, MsgBox, ConsoleWrite und GUIs für Ein- und Ausgaben benutzen. Außerdem dürft ihr Funktionen definieren, um eueren Code kürzer und übersichtlicher zu machen.

    Das Hauptproblem bestand gestern darin, dass ich die Funktionen _Wire_FromInteger und _Wire_ToInteger hinzugefügt habe, damit das Ganze um einiges einfacher wird. Aber wie Carsten schon sagte, hat das nichts mehr mit dem eigentlichen Thema zu tun.
    Deshalb würde ich sagen: Wer diese Funktionen verwenden will, kann dies gerne tun, und wer die Daten selbst unter Berücksichtigung der Regeln umwandeln will, um so besser.


    Der Wettbewerb endet vorerst am 31. Dezember 2012.
    Dann postet einfach jeder seinen Code und sagt, welches Skript er am besten findet. Der mit den meisten Stimmen gewinnt dann.
    (Denkt bei eurer Bewertung bitte daran, dass es schwieriger ist, die Daten umzuwandeln ohne die zwei oben beschriebenen Funktionen zu benutzen.


    MfG, James C.

    PS: Im Anhang mal ein Bild meiner momentanen Ausgabe der einzelnen Bits, nur falls jemand (wie ich gestern) denkt, das sei nicht möglich...

  • Phuu...das sagt mir jetzt auf den ersten Blick nicht viel aber mal sehen ;)
    Also du schlägst einen Taschenrechner vor aber es darf auch was anderes sein richtig?
    Aber ich fänds jetzt unfair, wenn du bereits ein Programm geschrieben hättest hoffe fas hast du nicht
    (nur um die Schummelmöglichkeit auszuschliessen)?

    c u

    Bild1: Ich beim debuggen

    • Offizieller Beitrag

    Nette Idee.
    Erinnert mich an meine Kindheit. Ich hatte im zarten Alter von 12 Jahren einen "Elektronik"-Bausatz bekommen. Das Teil bestand aus 8 "Registern" (das waren Plastikstäbe, die man vor oder zurück schieben konnte und die dabei jeweils Kontakte nach oben oder unten verbanden) die in einer Plastikplatte mit lauter Steckkontakten waren, die man mit Drahtbrücken verbinden konnte. Der generierte Zustand (On/Off) wurde in einer Lampe über dem Register angezeigt. Damit habe ich damals sogar eine Steuerung für meine Modelleisenbahn 'gestöpselt'. Und das ist genau das, was mit diesen Gattern geschieht: Zustände miteinander verknüpfen.
    Wer damit nicht vertraut ist, das Thema aber interessant findet, sollte sich zwingend vorher mal einige solcher Schaltungen anschauen und auch versuchen nachzuvollziehen, was dort passiert. Ohne dieses Verständnis kommt man sonst nicht weit. ;)
    Sucht mal nach Datenblättern für primitive Schaltkreise, da sollten passende Dokumentationen zu finden sein.
    Ob ich mitmache, weiß ich noch nicht. Das erste Quartal ist bei mir immer zeitmäßig etwas eng. Schaun' mer mal.

  • Interessante Idee...

    Kennst du Minecraft?
    Dort bauen auch Freaks mit Redstone Taschenrechner, CPU's, Ram, ...
    Ist im prinzip das gleiche.
    Hast ein Kabel (Redstone), und "NOT"-Gates. Mehr nicht.

  • Also du schlägst einen Taschenrechner vor aber es darf auch was anderes sein richtig?

    Natürlich, ich hab' das nur erwähnt, falls jemandem spontan nichts sinnvolles einfällt.

    Aber ich fänds jetzt unfair, wenn du bereits ein Programm geschrieben hättest hoffe fas hast du nicht (nur um die Schummelmöglichkeit auszuschliessen)?

    Ich habe heute mal angefangen, bin aber noch sehr weit von einem funktionierenden Taschenrechner entfernt.
    (Nur weil ich dieses Thema gewählt habe, heißt das ja nicht, dass ich Ahnung davon habe.)

    Ich persönlich bin bis jetzt mal so vorgegangen:
    Als erstes braucht man natürlich außer dem NOT-Gate noch Andere (z.B. AND, XOR), die kann man sich aber relativ leicht durch logisches Denken basteln (ich habs ohne Internet geschafft, aber mit Google findet man sowas garantiert leichter heraus).
    So, und weiter bin ich bis jetzt auch noch nicht gekommen...

    MfG, James

  • Interessante Idee...

    Kennst du Minecraft?
    Dort bauen auch Freaks mit Redstone Taschenrechner, CPU's, Ram, ...
    Ist im prinzip das gleiche.
    Hast ein Kabel (Redstone), und "NOT"-Gates. Mehr nicht.


    Dann kannst du dir garantiert auch denken, wodurch Carsten8 mich auf diese Idee gebracht hat. :D
    Aber ich selbst spiele kein Minecraft.

    • Offizieller Beitrag

    James:
    Ich habe mal ein wenig mit den Fuktionen gespielt.
    Den Sinn von ..Attach() verstehe ich nicht ganz. Laut Beschreibung sollte bei 2 mit Attach verbundenen Kabeln, Kabel1 immer On sein, wenn Kabel1 oder Kabel2 On ist. (Also ein OR-Gatter) Das ist aber nicht der Fall. Kabel1 und Kabel2 halten ihre Werte unabhängig voneinander, sie lassen sich auch unabhängig ändern.

  • BugFix : Ich verstehe jetzt nicht so ganz was du meinst.
    Also ja, der Sinn von Attach ist, zwei Kabel zu einem zusammenzuführen und ja, es ist ein OR-Gatter.
    Aber wieso ist das jetzt nicht der Fall?
    Die Werte lassen sich unabhängig ändern, aber auch nur, bis die zwei Kabel verbunden sind.

    Könntest du bitte nochmal erklären, was der Fehler in der Funktion ist?


    MfG, James

  • Denke mal das sollte man in den Talkbereich verschieben. Das ganze ist kein Wettbewerb mehr sonden eher eine Einführung in Elektorgrundkentnisse.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • BugFix Ich versteh' dich immer noch nicht so ganz, nach Attach ist auf Kabel2 immer kein Strom, da es ja sozusagen nicht mehr existiert. Wenn du es trotzdem weiterverwenden willst, musst du davor eben Detach benutzen.

    chip Ich habe auch nicht wirklich Ahnung von dem Ganzen, deshalb habe ich ja auch so viel Zeit gegeben.
    Und da ja jeder abstimmen soll, ist das auch völlig unnötig...


  • chip Ich habe auch nicht wirklich Ahnung von dem Ganzen, deshalb habe ich ja auch so viel Zeit gegeben.

    Jemand der einen Wettberwerb ansetzt sollte aber Ahnung davon haben weil er ja schließlich die Scripte auswerten muss.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • James ich kenne mich mit Redstone super aus =D , aber die Funktionen von autoit versteh ich noch niccht so ganz =D


    Um so besser:
    Also, bei Redstone hast du ja deine Kabel, die du wo auch immer verlegst.
    In meiner UDF erstellst du einfach ein Kabel mit

    [autoit]

    $Kabel = _Wire_Create()

    [/autoit]

    (Da wir hier nicht graphisch arbeiten, musst du dir um Sachen wie Platz, Repeater und ähnliches keine Sorgen machen.

    Wenn in Minecraft 2 (oder mehrere) Kabel nebeneinander liegen, sind sie automatisch verbunden. In diesem Fall brauchst du dafür _Wire_Attach. Z.B.:

    [autoit]

    $Kabel1 = _Wire_Create()
    $Kabel2 = _Wire_Create()
    _Wire_Power($Kabel2, 'On')
    _Wire_Attach($Kabel1, $Kabel2, $Kabel)

    [/autoit]

    $Kabel hat dadurch Strom, weil $Kabel1 oder $Kabel2 Strom hatte.
    Bei den meisten Gates wird nur das erste Kabel verändert, das zweite wird dann auf "Off" gesetzt. Falls du aber ein Kabel mehrmals verwenden willst/musst, spaltest du es vorher mit _Wire_Detach($Kabel1, $Kabel2) in $Kabel1 und $Kabel2 auf (welche dann beide den gleichen Wert haben).

    Bei Redstone ist eine Fackel ein NOT-Gate, in AutoIt machst du dafür einfach

    [autoit]

    _Wire_NOT($Kabel1, $Ausgabe)

    [/autoit]

    Jetzt brauchst du nur noch die anderen Gates, die machst du dann einfach so:

    [autoit]

    Func _Wire_AND(ByRef $Input1, ByRef $Input2, ByRef $Output)
    ; hier dann die Ganzen NOT-Gates und Verbindungen
    EndFunc

    [/autoit]

    MfG, James

  • Wenn, dann aber richtig. Das heißt FromInteger, ToInteger und so weiter muss raus. Alles was du hast ist NOT. Das reicht für alles andere. For, If und so weiter braucht man hier nicht, das lässt sich alles mittels Not-Gates realisieren. Für Inputs und Outputs lassen sich beispielsweise Checkboxen verwenden, die grundsätzlich auch nur zwei Zustände haben (aus -> 0 und an -> 1).

    Einmal editiert, zuletzt von Carsten8 (21. Februar 2012 um 13:41)

  • Schön dich auch mal wieder im Forum zu "sehen", Carsten.

    Bei binärem Input hast du recht, aber für einen Rechner ist dezimaler Input vielleicht doch eher angebracht.
    Des weiteren würde es mich interessieren, wie du If mit NOT-Gates realisieren würdest.

    MfG, James C.

  • Einen dezimalen Input zu verwenden wird in der Tat kompliziert, aber nicht unmöglich.
    Ich experimentiere gerade mit AutoIt. Alles was man braucht ist in der Tat "Not" und "BitOR". BitOR dient hierbei zur Verbindung zweier Kabel.
    Ein AND-Gate würde dabei wie folgt aussehen:

    [autoit]

    $a = False
    $b = False

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

    $c = Not BitOR(Not $a, Not $b)

    [/autoit]


    $a und $b stellen die beiden Inputs dar, $c ist das Ergebnis. Wenn $a und $b an sind, ist $c an. Auf diese Weise realisierst du dann dein If (je nachdem, was du machen willst).

  • Ok, dann hast du mich falsch verstanden.
    Ein AND-Gate habe ich schon, ich meinte ein If-Ersatz, bei dem du kein If mehr verwenden musst.
    Sonst könnte ich das ja einfach so machen:

    [autoit]

    If $Wire1 Then ...

    [/autoit]

    PS: Ich bin der Meinung, dass du mit den momentan vorhandenen Funktionen (mal abgesehen von To und FromInteger) unmöglich dezimalen Input verarbeiten kannst. Außerdem würde das die Verwirrung bei allen noch erheblich steigern.