| 

.NET C# Java Javascript Exception

0
Angeregt von "Eleganteste Lösung für kleine Aufgabe"
hat mir ein Kumpel etwas sehr Seltsames vorgelegt,
was aber tatsächlich funktioniert.

print "@{[1 .. 10]}" =~              # string expansion of a list
/ (\d+) \b # number followed by termination
(?{ $^N % 2 }) # code assertion, capt number $^N, result $^R
(??{ $^R ? "" : "!" }) # code expr, in-place regex mod
/gx;

Mit den Erklärungen kann ich nicht viel anfangen
da diese auf Englisch (glaube ich) sind. Wie
geht das?

Ergebnis: 1 3 5 7 9

Danke & Gruß
08.09.2009
Damengummistiefel 377 1 6
1
Ich kann mir zwar vorstellen, wie das funktioniert, aber nichtin Gänze nachvollziehen.
Aber ob das elegant ist, ist die andere Frage :D
anonym 08.09.2009
1
"Englisch (glaube ich)"?! oO
Tomalak 08.09.2009
3 Antworten
4
Erstmal haut der 1. reguläre Ausdruck ([1::10])die Zahlen 1 bis 10 raus,
jagt diese der Reihe nach in die Funktion mod 2 ($^N % 2) $^N == Ergebnis aus 1. Ausdruck
danach ab in den Ausdruck $^R ? "" : "!" der bewirkt, daß bei $^R == 0 ein "" ansonsten $^R als integer (!) zurückgegeben wird.

Ich würde es als elegeant bezeichenen, da es nur eine Zeile Code ist und damit zumindest in Sachen "komprimierter Komplexität" ganz weit vorne ist.
08.09.2009
MiW 1,0k 1 8
1
Ach Quatsch, dein Beitrag ist doch codetechnisch wesentlich informativer. Habe mich auf eine laienhafte Darstellung beschränkt ;)
Dustin Klein 08.09.2009
3
Dein Kollege benutzt in diesem Fall reguläre Ausdrücke. In der ersten Zeile heißt es im Wortlaut:

- Nimm jede Zahl von 1 bis 10 die folgenden Regeln entspricht:

Danach folgt der reguläre Ausdruck, bzw. eine Kombination. Dort geht er jede weitere Zahl durch und prüft ob diese durch 2 teilbar ist (% 2 = MODULO). Wenn dies der Fall ist, wird die Zahl NICHT ausgegeben, anderenfalls schon (also wenn % 2 einen Rest hinterlässt der ungleich 0 ist)

Reguläre Ausdrücke können sehr hilfreich sein, vor allem wenn man Variablen auf bestimmte Reihenfolgen oder ähnliches untersuchen will. Nachteil ist nur, dass sie oft sehr kryptisch aussehen ;)
08.09.2009
Dustin Klein 2,9k 2 9
hab zu lange gebraucht zu tippen :( als ich angefangen habe, war dein post noch nicht da. Jetzt denken bestimmt alle ich hab von dir abgeschrieben *lol*
MiW 08.09.2009
1
Da keine der bisherigen Antworten vollständig oder wirklich korrekt waren:

"@{[1 .. 10]}" ist nur eine andere Schreibweise für "1 2 3 4 5 6 7 8 9 10".

Der Operator =~ wendet einen regulären Ausdruck auf eine Zeichenkette an und gibt ein Array von Treffern zurück.

Der reguläre Ausdruck sucht zunächst nach zusammenhängenden Zifferngruppen (\d+), hinter denen sich eine Wortgrenze \b befindet. Wenn auf diese Weise eine Zahl gefunden wurde, wird der nachfolgende Codeblock (?{ $^N % 2 }) ausgeführt. In $^N ist die gefundene Zahl gespeichert. Die Modulo-Operation ergibt 0 bei geraden und 1 bei ungeraden Zahlen. Das Ergebnis wird implizit in der Variable $^R gespeichert. Der nächste Codeblock (??{ $^R ? "" : "!" }) modifiziert den regulären Ausdruck während des Matchings. Dazu wird der Wert von $^R abgefragt. Ist er 0 (d.h. wenn die Zahl gerade war), so tritt an die Stelle des Codeblocks ein Ausrufezeichen. Damit ein Treffer gefunden wird, müsste auf die Zahl jetzt ein Ausrufezeichen folgen. Das ist nicht der Fall, also schlägt das Matching fehl. Ist andererseits $^R gleich 1 (d.h. wenn die Zahl ungerade war), so wird der Codeblock durch den leeren String ersetzt. Es gibt nichts mehr zu matchen, somit wurde ein Treffer gefunden.

Man erhält somit ein Array aller ungeraden Zahlen aus dem ursprünglichen String, das abschließend mit print ausgegeben wird.
08.09.2009
reima 334 2 2
reima 334 2 2
Und das ist jetzt grundlegend anders als unsere "falschen und unvollständigen" Antworten ?
MiW 08.09.2009
1
Deine Antwort enthält eine falsche Interpretation des ternären Operators. Bei $^R == 0 wird "!" zurückgegeben, andernfalls "". Auch hat das "!" nichts mit der Rückgabe „als integer“ zu tun.

Keine der bisherigen Antworten ist auf die Bedeutung von (??{…}) zur Modifikation des regulären Ausdrucks während des Matchings eingegangen, was aber gerade der „Witz“ dieser Lösung ist. Deshalb habe ich eine vollständige Erklärung nachgetragen.
reima 08.09.2009
1
"@{[1 .. 10]}" ist nur eine andere Schreibweise für "1 2 3 4 5 6 7 8 9 10". Das ist definitiv korrekt, im gegensatz zu den anderen Interpretationen. Bei dem Rest lass ich euch lieber fachsimpeln... ;)
Moritz 08.09.2009
Sehr schöne Facherklärung, ich glaube genauer kann man es nicht beschreiben! (Wie ich schon sagte, wollte ich bewusst bei einer laienhaften Erklärung bleiben, um den Fragesteller nicht direkt mit Fachbegriffen zu überfluten) ;)
Dustin Klein 08.09.2009
Schöne Erklärung finde ich! Ich kenne mich mit RegEx nicht 100% aus, aber für mich war diese Erklärung sogar nachvollziehbar und verständlicher. Deshalb ein Plus von mir ;-)
Scout 08.09.2009

Stelle deine Regex-Frage jetzt!