Seite 1 von 7

Kurzer Prozess: Size Contest bei SPOJ

Verfasst: Freitag 20. Februar 2009, 13:26
von numerix
Seit ein paar Tagen gibt es einen neuen Size Contest bei SPOJ: https://www.spoj.pl/problems/NOP/

Grundidee dabei: Ein bestimmtes Problem ist zu lösen und der dafür benötigte Code (Quelltext) soll so kurz wie möglich sein. In diesem Fall sind maximal 360 Bytes erlaubt, aber das in Python keine wirkliche Einschränkung bei dieser Aufgabenstellung (allerdings gibt es z.Zt. immerhin eine Lösung mit 356 Bytes - würde ich gerne mal sehen ... :) )

Da das zu lösenden Problem hier sehr überschaubar ist (und weit weniger anspruchsvoll als ein Großteil der SPOJ-Aufgaben), hat der ein oder andere ja vielleicht Lust, beim Wettrennen um den kürzesten Python-Code sein Glück zu versuchen.

Zwar werden wir mit Python gegen Perl (zumindest was die Kürze des Codes angeht) nicht ankommen und anscheinend lässt sich das gestellte Problem auch in Ruby äußerst kompakt umsetzen, aber vielleicht können wir Python ja auf Platz 3 der Rangliste halten - das ist jedenfalls der aktuelle Stand: https://www.spoj.pl/ranks/NOP/.

Falls jemand gerne mitmachen will, aber mit der Aufgabenstellung wg. des Englischen (oder aus anderen Gründen) nicht klarkommt, wird er sicher hier auch Hilfe finden können.

Konkret zur Aufgabenstellung: Der übergebene String wird über stdin aufgenommen und über stdout zurückgeliefert, d.h. - wenn ich nichts übersehe - ein raw_input() und ein print sind auf jeden Fall fällig (zumindest kenne ich bis jetzt keine kürzeren Möglichkeiten für die Ein-/Ausgabe bei SPOJ).
Und: Der Eingabestring scheint in diesem Fall ein Zeilenende-Zeichen zu haben, das von raw_input() nicht automatisch entfernt wird. Muss man sich also selbst drum kümmern.

Verfasst: Freitag 20. Februar 2009, 14:39
von b.esser-wisser
Hab keine Lust mich bei SPOJ zu registrieren, aber ich mich mich mal daran versucht:
(74 Zeichen, aber nur mit den drei SPOJ-Beispielen getestet :roll: )

Code: Alles auswählen

import re
print sum(3-len(p)for p in re.split("[A-Z]",raw_input())[1:-1])
Mit python2.5 und RegEx krieg' ich's nicht kleiner, da muss wohl 'ne andere Lösung her.

gruß Jörg

Verfasst: Freitag 20. Februar 2009, 14:40
von snafu
Kannst du vielleicht mal deine derzeitige Version posten, damit man einen Anhaltspunkt hat? Ich blicke bei dem Problem ehrlich gesagt nicht durch, aber ich bin sowieso nicht gut in solchen Dingen.

Verfasst: Freitag 20. Februar 2009, 15:01
von numerix
b.esser-wisser hat geschrieben:Hab keine Lust mich bei SPOJ zu registrieren, aber ich mich mich mal daran versucht:
(74 Zeichen, aber nur mit den drei SPOJ-Beispielen getestet :roll: )

Code: Alles auswählen

import re
print sum(3-len(p)for p in re.split("[A-Z]",raw_input())[1:-1])
Mit python2.5 und RegEx krieg' ich's nicht kleiner, da muss wohl 'ne andere Lösung her.
Funktioniert nicht für alle Fälle korrekt. Ein paar Beispiele mit der richtigen Lösung:

Code: Alles auswählen

AdacBdadDasdEfaFweGsd
2
EaEbFabG
5
AbcdefttgBCDE
12
ABDdasdfasdfsdfas
6
Dein Code liefert:

Code: Alles auswählen

AdacBdadDasdEfaFweGsd
2
EaEbFabG
5
AbcdefttgBCDE
4
ABDdasdfasdfsdfas
6
@snafu: So lange ich mit meinem Code in der SPOJ-Rangliste für Python auf Platz 1 stehe, werde ich ihn noch nicht rausrücken ... :)

Verfasst: Freitag 20. Februar 2009, 15:07
von BlackVivi

Code: Alles auswählen

print reduce(lambda x,y:x+(-(x+y)%4),[x for x,y in enumerate(raw_input()) if y.isupper()])
Ich denke meine Version ist schon relativ kurz :)

85 Zeichen...

Ich überleg die ganze Zeit, was ich noch kürzer kriegen könnte òo

Edit: 84 Zeichen, nach dem ich das eine Leerzeichen noch entfernt habe Oo

Mhm, hab noch das print vergessen... Ich depp. 90 Zeichen.

Verfasst: Freitag 20. Februar 2009, 15:10
von kbr
Hier mein Ansatz (84 Zeichen):

Code: Alles auswählen

import sys
N=p=0
for c in sys.argv[1]:
	if c<'a' and p:N+=4-p;p=0
	p=(p+1)%4
print N
Und bitte nicht auf PEP 8 hinweisen ... :)

Klaus

Verfasst: Freitag 20. Februar 2009, 15:22
von b.esser-wisser
Stimmt, mein Code funktionierte nicht , sobald mehr als 3 Kleinbuchstaben hintereinander vorkommen :(
Korrektur:

Code: Alles auswählen

import re;print sum(3-len(p)&3for p in re.split("[A-Z]",raw_input())[1:-1])
("%4" wäre ja langweilig :twisted: )

Sehe ich das richtig, dass der letzte "Befehl" nicht aufgefüllt werden muss?

Verfasst: Freitag 20. Februar 2009, 15:29
von hendrikS
kbr hat geschrieben:Hier mein Ansatz (84 Zeichen):

Code: Alles auswählen

import sys
N=p=0
for c in sys.argv[1]:
	if c<'a' and p:N+=4-p;p=0
	p=(p+1)%4
print N
Und bitte nicht auf PEP 8 hinweisen ... :)

Klaus
Den Algo selbst habe ich nicht gecheckt, aber der input soll ueber stdin kommen und nicht ueber einen Programmparameter. Also nimmst Du einfach raw_input und sparst Dir den import.

Verfasst: Freitag 20. Februar 2009, 15:41
von kbr
hendrikS hat geschrieben:der input soll ueber stdin kommen und nicht ueber einen Programmparameter. Also nimmst Du einfach raw_input und sparst Dir den import.
Hast Recht. Das spart dann noch mal 11 Zeichen (=73).

Klaus

Verfasst: Freitag 20. Februar 2009, 15:42
von name
Weit ham wirs gebracht, Code Golfing im Python Forum...

Verfasst: Freitag 20. Februar 2009, 15:42
von numerix
b.esser-wisser hat geschrieben:Stimmt, mein Code funktionierte nicht , sobald mehr als 3 Kleinbuchstaben hintereinander vorkommen :(
Korrektur:

Code: Alles auswählen

import re;print sum(3-len(p)&3for p in re.split("[A-Z]",raw_input())[1:-1])
("%4" wäre ja langweilig :twisted: )

Sehe ich das richtig, dass der letzte "Befehl" nicht aufgefüllt werden muss?
Ja, so ist es. Da dann nur noch "Parameter" folgen, ist da nichts mehr aufzufüllen.

Dein Code scheint jetzt richtig zu funktionieren, jedenfalls für die geposteten "testcases"; nach meiner Zählung 76 Bytes.
Edit: Sorry, 75 Bytes.

@kbr: Eingabe erfolgt über raw_input() nicht als Parameter. Und: Dein Algorithmus ist fehlerhaft. Ergebnis für obige testcases:
3
8
15
7

Verfasst: Freitag 20. Februar 2009, 15:46
von numerix
name hat geschrieben:Weit ham wirs gebracht, Code Golfing im Python Forum...
Für zwischendurch ist das doch mal eine nette Abwechslung. Andere lösen Kreuzworträtsel. Oder Sudokus ...

Verfasst: Freitag 20. Februar 2009, 15:48
von name
numerix hat geschrieben:
name hat geschrieben:Weit ham wirs gebracht, Code Golfing im Python Forum...
Für zwischendurch ist das doch mal eine nette Abwechslung. Andere lösen Kreuzworträtsel. Oder Sudokus ...
Da missbrauchen sie aber nicht eine Programmiersprache ;-)

Verfasst: Freitag 20. Februar 2009, 15:52
von numerix
name hat geschrieben:Da missbrauchen sie aber nicht eine Programmiersprache ;-)
Ich sehe das eher als eine von vielen Möglichkeiten, die Leistungsfähigkeit einer Sprache zum Ausdruck zu bringen. Und ich finde bei < 100 Bytes darf PEP 8 ausnahmsweise auch mal außen vor bleiben ... :wink:

Verfasst: Freitag 20. Februar 2009, 15:53
von name
numerix hat geschrieben:
name hat geschrieben:Da missbrauchen sie aber nicht eine Programmiersprache ;-)
Ich sehe das eher als eine von vielen Möglichkeiten, die Leistungsfähigkeit einer Sprache zum Ausdruck zu bringen.
Das finde ich aber ueberhaupt nicht. Das wuerde ja heissen das Perl leistungsfaehiger als Python ist, weil mit Perl laesst sich normalerweise besser golfen....

Verfasst: Freitag 20. Februar 2009, 15:53
von BlackVivi
name hat geschrieben:
numerix hat geschrieben:
name hat geschrieben:Weit ham wirs gebracht, Code Golfing im Python Forum...
Für zwischendurch ist das doch mal eine nette Abwechslung. Andere lösen Kreuzworträtsel. Oder Sudokus ...
Da missbrauchen sie aber nicht eine Programmiersprache ;-)
Man programmiert ja auch keine Applikation für den ernsten Einsatz. Man löst mit einer Programmiersprache ein Problem. Das Problem ist diesmal nicht der Algorithmus selbst, sondern die Größe des Algorithmus :) Und alles was unter dem Perfektionismus liegt, ist'n Flaschenhals ;P

Verfasst: Freitag 20. Februar 2009, 15:56
von name
BlackVivi hat geschrieben:Man löst mit einer Programmiersprache ein Problem. Das Problem ist diesmal nicht der Algorithmus selbst, sondern die Größe des Algorithmus :)
Man loest ein nicht-existentes Problem, aber gut, wenns Spass macht ;-)
BlackVivi hat geschrieben:Und alles was unter dem Perfektionismus liegt, ist'n Flaschenhals ;P
Hae? Nix verstehen...

Verfasst: Freitag 20. Februar 2009, 16:06
von BlackVivi
name hat geschrieben:
BlackVivi hat geschrieben:Man löst mit einer Programmiersprache ein Problem. Das Problem ist diesmal nicht der Algorithmus selbst, sondern die Größe des Algorithmus :)
Man loest ein nicht-existentes Problem, aber gut, wenns Spass macht ;-)
BlackVivi hat geschrieben:Und alles was unter dem Perfektionismus liegt, ist'n Flaschenhals ;P
Hae? Nix verstehen...
Das 2te beantwortet das erste. Stell dir vor - das Problem heißt: "Mach den Code so kurz wie möglich. Alles was länger ist als 0 Zeichen ist zu lang. Dann versucht man das Problem zu lösen :P Und zwar immer besser...

Verfasst: Freitag 20. Februar 2009, 16:08
von numerix
name hat geschrieben:
numerix hat geschrieben:
name hat geschrieben:Da missbrauchen sie aber nicht eine Programmiersprache ;-)
Ich sehe das eher als eine von vielen Möglichkeiten, die Leistungsfähigkeit einer Sprache zum Ausdruck zu bringen.
Das finde ich aber ueberhaupt nicht. Das wuerde ja heissen das Perl leistungsfaehiger als Python ist, weil mit Perl laesst sich normalerweise besser golfen....
Leistungsfähigkeit hat ja unterschiedliche Facetten. C als leistungsfähiger einzustufen als Python ist als allgemeine Aussage auch falsch, nur weil C Programme bei vergleichbaren Algorithmen schneller sind als Python-Programme.

Auch die Lesbarkeit eines Codes oder die Entwicklungsgeschwindigkeit sind Leistungsmerkmale und da spielt Python ja nachweislich auf den vorderen Plätzen mit.

Was die Kürze des Codes angeht, so ist Perl Python nun mal überlegen.

Verfasst: Freitag 20. Februar 2009, 16:13
von name
numerix hat geschrieben:Was die Kürze des Codes angeht, so ist Perl Python nun mal überlegen.
Seh ich zwar nicht so als Leistungsmerkmal, solang ich keine Romane schreiben muss ;-)