Lua-Aufgabe 44: abwechselnde Paare

!!! Please ensure, that your contribution or question is placed into the relevant section !!!
Questions about rolling stock, for example, do not belong in "Questions about the Forum". Following is perhaps the right area where your question will be better looked after:
General questions to EEP , Splines, rolling stock, Structures in EEP, landscape elements, Signalling system and controlling, designers, Europe-wide EEP meetings , Gossip
Your cooperation to keep the forum clear is appreciated.
  • Aufgabe:

    Entferne aus dem gegebenen String str jedes zweite Zeichenpaar. Die Zeichen 1, 2, 5, 6, 9, 10 etc. bleiben erhalten, der Rest fliegt raus.


    Beispiele:

    paarweise("Wedaicbuhelo") -> "Weiche"

    paarweise("Signal") -> "Sial"

    paarweise("Bahnhofsmission") -> "Bahomiio"



    LUA Source Code
    1. function paarweise(str)
    2. end

    Ergänze die obige Funktion so, dass sie aus dem String str jedes zweite Zeichenpaar entfernt und das Ergebnis zurück gibt.




    Setze deine Funktion statt der ersten drei Zeilen in folgendem Testskript ein und lasse es in einem Lua Interpreter oder einer leeren EEP Anlage laufen um deine Funktion zu überprüfen.

  • Die Funktion hat alle Tests bestanden:


    LUA Source Code
    1. function paarweise(str)
    2. local ausgabe = ""
    3. for i = 1, #str, 4 do
    4. ausgabe = ausgabe..string.sub(str,i,i+1)
    5. end
    6. return ausgabe
    7. end

    EEP 15
    MS Windows 10 Pro 64bit
    Prozessor: AMD FX-8370 Eight-Core Processor 4,0GHz // RAM: 32GB // SSD 128GB // Grafikkarte: GeForce GTX 950

  • Das ersten beiden Paare müssen die Schleife nicht durchlaufen, ansonsten gleich.

    LUA Source Code
    1. function paarweise(str)
    2. local newstr = string.sub(str,1,2) -- das 1. Paar immer
    3. -- das 2. Paar nie, daher ab 5. Buchstaben
    4. for n = 5, #str, 4 do -- in 2 ja + 2 nein = 4 Buchstabenschritten
    5. newstr = newstr..string.sub(str,n,n+1) -- jeweils das 1. Paar anhängen
    6. end
    7. return newstr
    8. end

    Fried-liche Grüße:aq_1:


    Laptop: i7-4710HQ 2,5GHz, 8GB RAM, Intel HDGraphics 4600, NVIDIA GeForce GTX860M, Windows 10 Pro 1803 64bit

    EEP: (7, 10, 12 alle Basic), 14.1 Expert Plugin1, 15 Expert Patch 3, ModellKatalog, TauschManager, Modell-Explorer


    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr!

  • In der Kürze liegt die Würze (mit regulärem Ausdruck):

    LUA Source Code
    1. function paarweise(str)
    2. return str:gsub("(..)..?", "%1")
    3. end

    Gruß

    Christopher

    PC: Intel i7-7700K; 64bit; 4,2 GHz; 16GB RAM; GeForce GTX 1080 (8 GB); Win 10; EEP 6, 13.2 Plugins 1+2, 14.1 (Dev), 15 (Dev); HomeNOS 14 (Dev)
    Laptop: Intel i5 3230M; 64bit; 2,6 GHz; 8GB RAM; GeForce GT740M (1 GB); Win 8.1; EEP 6, 13.2 Plugins 1+2; HomeNOS 13 (User)

  • cetz

    Sieht toll aus, doch zuerst verstand ich nur Bahnhof. Ein paar erklärende Worte wären schön gewesen.

    Ich habe versucht, sie mir selbst zu erklären. So weit bin ich gekommen:


    Die Funktion string.gsub(Zeichenkette, Muster, Ersatz, [Anzahl]) gibt eine Kopie von Zeichenkette wieder mit bis Anzahl Vorkommen [voreingestellt ist alle] von Muster, wobei Muster durch Ersatz ersetzt wird.

    Gleichwertig zur Schreibweise string.gsub(Zeichenkette, Muster, Ersatz, [Anzahl]) kann ich auch Zeichenkette.gsub(Muster, Ersatz, [Anzahl]) schreiben, so wie du es getan hast. Im Muster bedeutet jeder Punkt ein beliebiges Zeichen, 4 Punkte also 4 beliebige Zeichen. Das Fragezeichen ? kommt einem oder keinem Zeichen gleich RICHTIGE DEUTUNG SIEHE #10. Die Klammern () fangen aus dem Muster eine Auswahl ein, in dieser Aufgabe die ersten beiden der 4 Zeichen. %1 gibt die 1. Auswahl wieder und das als Ersatz.


    So weit die Theorie. Was ich nicht verstehe, ist, warum das ? notwendig ist. Es ist notwendig, denn wenn ich es weg lasse, wird im 3. Prüfkriterium str = "yak" "yak" zurückgegeben (also auch der 3. Buchstabe) und nicht "ya".


    Vielleicht hilfst du oder ein anderer Lua-Guru mir auf die Sprünge.

    Fried-liche Grüße:aq_1:


    Laptop: i7-4710HQ 2,5GHz, 8GB RAM, Intel HDGraphics 4600, NVIDIA GeForce GTX860M, Windows 10 Pro 1803 64bit

    EEP: (7, 10, 12 alle Basic), 14.1 Expert Plugin1, 15 Expert Patch 3, ModellKatalog, TauschManager, Modell-Explorer


    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr!

    The post was edited 1 time, last by Fried ().

  • Die berüchtigten "Regular Expressions" habe ich schon in meiner Uni-Zeit vor über 20 Jahren hassen gelernt, als ich zum ersten Mal mit Unix in Berührung kam. So mächtig und kompakt sie auch sein mögen, sind sie Gift für die Lesbarkeit von Programmcode. Die kommen in meiner Beliebtheitsskala gleich hinter dem Emacs.

  • Hallo Oliver ( klioli ),


    dass "Regular Expressions" nicht leicht zu lesen sind,ist mir bekannt. Ich nutze sie (ein kleinem Maße) bei Suchen & Ersetzen in html- bzw. epub-Dateien. Etwas andere Syntax aber ähnlich.

    Dennoch sind sie normalerweise logisch.

    Ich interpretiere das ? in deiner Lösung so, dass ein 5. Buchstabe folgen kann oder nicht. Oder stimmt das nicht?

    Was ich nicht verstehe, warum bei einem "3"-Zeichen-String ohne das ? das 3. Zeichen ausgegeben wird und mit ? nicht; wenn es das 5. Zeichen repräsentiert.

    Du hast es doch gesetzt und musst einen Grund dafür haben. Oder hast du es mit try & error ausprobiert.

    Fried-liche Grüße:aq_1:


    Laptop: i7-4710HQ 2,5GHz, 8GB RAM, Intel HDGraphics 4600, NVIDIA GeForce GTX860M, Windows 10 Pro 1803 64bit

    EEP: (7, 10, 12 alle Basic), 14.1 Expert Plugin1, 15 Expert Patch 3, ModellKatalog, TauschManager, Modell-Explorer


    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr!

  • Du hast es doch gesetzt und musst einen Grund dafür haben.

    äh ... nein. Das was Christopher.


    :aq_1:Gruss Jürg

    Samsung Series 9 Laptop / Lenovo Z50 - 70 Laptop
    Intel i5 1.7 Ghz / Intel i7 2.0 Ghz
    4 Gb Speicher / 8 Gb Speicher
    Intel HD Graphics 4000 / NVIDIA Geforce 840M
    Windows 10 64 /Windows 10 64
    EEP15 / EEP14, EEP15
    AnlagenBau / AnlagenLaufLass

    ________________________________________________________________________

    [Modelle scannen]

  • Jetzt machen mich die "Regular Expressions" schon ganz kirre. :bk_1:


    Entschuldugung Oliver ( klioli ) ! Danke Jürg ( juemei )!


    Muss ich warten :co_k: bis Christopher ( cetz ) #5 und #7 gelesen hat und hoffentlich antwortet.

    Fried-liche Grüße:aq_1:


    Laptop: i7-4710HQ 2,5GHz, 8GB RAM, Intel HDGraphics 4600, NVIDIA GeForce GTX860M, Windows 10 Pro 1803 64bit

    EEP: (7, 10, 12 alle Basic), 14.1 Expert Plugin1, 15 Expert Patch 3, ModellKatalog, TauschManager, Modell-Explorer


    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr!

  • Muss ich warten bis Christopher ( cetz (CE1) ) #5 und #7 gelesen hat und hoffentlich antwortet.

    Komme schon ... :av_1:

    cetz

    Sieht toll aus, doch zuerst verstand ich nur Bahnhof. Ein paar erklärende Worte wären schön gewesen.

    Meine Meinung zu regulären Ausdrücken (= regular expressions): Sie sind sehr mächtig, aber auch ganz schön kryptisch. (Aber das nur so nebenbei.)


    Gerne will ich meine Überlegungen zu dem Einzeiler veröffentlichen:

    Ich verwende hier nur wenige Konstrukte der regulären Ausdrücke, nämlich:

    .: ein beliebiges Zeichen

    (): ein Speicher, auf den ich später beim Ersetzen wieder zugreife

    ?: das letzte Konstrukt darf vorkommen, muss aber nicht. Wenn es vorkommt, wird es verwendet.

    Da fangen die Details schon an: Die meisten Konstrukte sind "greedy" (das könnte man mit "gefräßig" übersetzen), d.h. sie werden auf den längstmöglichen Teil-String angewendet. Ein .* heißt beispielsweise: Ein beliebiges Zeichen und das beliebig oft. Wenn jetzt der reguläre Ausdruck damit endet, "frisst" er alle Zeichen bis zum Ende der Zeichenkette.


    Tatsächlich dachte ich zuerst, dass der reguläre Ausdruck (..).. ausreichen würde. Er bedeutet: Nimm ein Zeichen (.) und nimm noch eines (.) und merke Dir die beiden Zeichen ((..)). Dann finde in gleicher Weise zwei weitere Zeichen, die Du Dir nicht merken musst (..). Das Ganze ersetze dann durch die beiden gespeicherten Zeichen (%1).

    Das klappt auch für alle Testfälle — außer "yak". Wenn der reguläre Ausdruck auf "yak" trifft, speichert er das "y" und das "a", braucht aber für eine echte Übereinstimmung noch zwei weitere Zeichen. Es kommt aber nur noch ein "k", also zu wenig. Damit passt der ganze reguläre Ausdruck nicht auf die Eingabe, und infolgedessen wird auch nichts ersetzt.

    Deshalb habe ich den regulären Ausdruck auf (..)..? geändert. Das bedeutet jetzt: Merke Dir zwei Zeichen, finde auf alle Fälle ein weiteres (, das dann durch nichts ersetzt wird,) und nach Möglichkeit (.?) noch ein weiteres Zeichen, das gemeinsam mit dem vorigen durch nichts ersetzt wird. Wenn das vierte Zeichen existiert, wird es wegen der "Greedyness" ersetzt. Wenn es nicht existiert, weil der String zu Ende ist, ist es auch okay.

    Und wegen der "Greedyness" funktioniert das ganze auch bei mehreren Ersetzungen.


    Alles klar?

    Christopher

    PC: Intel i7-7700K; 64bit; 4,2 GHz; 16GB RAM; GeForce GTX 1080 (8 GB); Win 10; EEP 6, 13.2 Plugins 1+2, 14.1 (Dev), 15 (Dev); HomeNOS 14 (Dev)
    Laptop: Intel i5 3230M; 64bit; 2,6 GHz; 8GB RAM; GeForce GT740M (1 GB); Win 8.1; EEP 6, 13.2 Plugins 1+2; HomeNOS 13 (User)

  • Alles klar?

    Jawoll :ap_1:

    Das Fragezeichen bezieht sich nur auf den letzten Punkt = Zeichen = Konstrukt.

    Damit passt der ganze reguläre Ausdruck nicht auf die Eingabe, und infolgedessen wird auch nichts ersetzt.

    Bei "ya" und "y" passt es auch nicht und es wird nichts ersetzt, sondern alles kopiert.:bo_1:

    Fried-liche Grüße:aq_1:


    Laptop: i7-4710HQ 2,5GHz, 8GB RAM, Intel HDGraphics 4600, NVIDIA GeForce GTX860M, Windows 10 Pro 1803 64bit

    EEP: (7, 10, 12 alle Basic), 14.1 Expert Plugin1, 15 Expert Patch 3, ModellKatalog, TauschManager, Modell-Explorer


    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr!