UbuntuFlo
Anmeldungsdatum: 8. Februar 2006
Beiträge: 12317
Wohnort: /home/flo
|
Linux Magazin schreibt: Das Linux-Magazin zeigt unter dem Titel "Sprachwahl", wie Programmier-Profis Aufgaben in PHP, Perl, Python und Java lösen. Die Redaktion lässt Größen wie Zeev Suravski, James Gosling und Randal L. Schwartz vorprogrammieren, um von ihnen zu lernen. Daneben zeigen die Oldtimer-Sprachen Smalltalk und Lisp, dass sie noch lange nicht zum alten Eisen gehören. Die Sonderseite stellt die gesammelten Code-Listings sowie die Spezifikation der Aufgaben online zur Verfügung.
Wer kennt noch weitere Python-Kniffe? Wer kann die Java-Lösung kürzen oder die Perl-Variante effizienter gestalten? Welche anderen Programmiersprachen lösen das Problem vielleicht noch eleganter? Daneben sind die Leser aufgerufen, unter redaktion@linux-magazin.de eigene Lösungsvorschläge einzureichen. Einsendeschluss ist der 30. September. Die Redaktion prämiert die kreativsten drei Lösungen mit je einem Fachbuch. FLO
|
audax
Anmeldungsdatum: 15. September 2006
Beiträge: 1253
|
Die Python-Lösung ist ja mal scheiße... Und nebenbei ist sämtliche Einrückung weg.
|
PrairieDog
Anmeldungsdatum: 16. Februar 2006
Beiträge: 870
|
Wie, keine Benchmarks? Der Lesbarkeits-King steht mit Perl doch ohnehin fest. 🐸
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17625
Wohnort: Berlin
|
listing2.java, EndNotes.java, vermißt eine Datei sample-data.txt, die auf der Downloadseite nicht auftaucht. listing5.java, BibReorder.java, endet mitten in einem Bezeichner: | HashMap<String, BibliographyTag> tags = new HashMap<String, Bib
|
Beide sehen aus, als kämen sie aus der Mitte einer Email, da die Umbrüche keine Rücksicht auf den Kontext nehmen.
|
Greebo
Anmeldungsdatum: 21. November 2006
Beiträge: 3443
Wohnort: 97070 Würzburg
|
Ich hab heute einen Kneipentag gehabt und bin insofern wirklich weit davon entfernt ernsthaft Code kritisieren zu können, aber Java Code der Sachen wie
import java.util.*;
import java.util.ArrayList;
enthält ist wohl entweder eine Verschwörung oder einfach nur unheimlich schwachsinniger schlampiger Mist. Für ein Wettbewerbsbild jedenfalls ungeeignet und irgendwie auch (in meiner Weinlaune) extrem polemisch absichtlich missgestaltet. Sorry ich hatte vom Linux Magazin bis gerade keine Meinung, jetzt entwickelt sich eine.
|
Wh1sper
Anmeldungsdatum: 22. Mai 2007
Beiträge: Zähle...
|
Greebo schrieb:
aber Java Code der Sachen wie import java.util.*;
import java.util.ArrayList;
enthält ist wohl entweder eine Verschwörung oder einfach nur unheimlich schwachsinniger schlampiger Mist. Für ein Wettbewerbsbild jedenfalls ungeeignet und irgendwie auch (in meiner Weinlaune) extrem polemisch absichtlich missgestaltet. Sorry ich hatte vom Linux Magazin bis gerade keine Meinung, jetzt entwickelt sich eine.
Der Code ist nicht vom Linux-Magazin, sondern von ausgewiesenen Experten eingesandt worden.
Experten sind allerdings auch nur Menschen.
Aber du hast natürlich recht, das hätte auffallen müssen, aber es schadet ja nicht.
|
audax
Anmeldungsdatum: 15. September 2006
Beiträge: 1253
|
Ich hab das Gefühl, dass ausser Randal Schwartz keiner was ordentliche eingeschickt hat 😀
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4695
Wohnort: Berlin
|
Die Vorgabe scheint gewesen zu sein: Hackt mal eben schnell was zusammen. So sieht jedenfalls die Python-Lösung mit der quadratischen Laufzeit von nodups() und ohne jegliche Fehlerbehandlung aus. Der Aufruf nach Einsendungen hat auch einen komischen Beigeschmack. Die wollen die "kreativste" Lösung belohnen ─ dann fällt es ja schon einmal weg das ganze sauber und ohne komische Tricks und Kniffe zu implementieren. Lesbar und robust fänd ich irgendwie wichtiger. Die Spezifikation ist auch nicht ganz fehlerfrei: Werden die Fussnoten nun mit @footnote: oder @footnotes: eingeleitet?
|
PrairieDog
Anmeldungsdatum: 16. Februar 2006
Beiträge: 870
|
Ich hab grad geantwortet und mein Posting wieder gelöscht. Daraufhin verabschiedete sich der Thread auf die letzte Seite. Dieses Posting solls wieder gutmachen. *amen*
|
audax
Anmeldungsdatum: 15. September 2006
Beiträge: 1253
|
Hier mal ne ordentliche Python-Lösung:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 | #!/usr/bin/env python
#-*- coding: utf-8 -*-
# Copyright (c) 2007 Jens Kadenbach <j.kadenbach@gmx.de>
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
from __future__ import with_statement
import re
from cStringIO import StringIO
from optparse import OptionParser
from itertools import imap, takewhile, count
from functools import partial
__version__ = '0.1'
SAMPLE = StringIO('''A great brown fox [13] jumped of a pile of lorem ipsum [4],
[7]. He met with a silver penguin, browsing the Linux Kernel
Mailinglist [3]. They debated whether to start a C-program with
"main (int argc, char **argv)" or with "main (int argc, char *argv[])".
Square brackets annoyed them [9999]. Multiple references exist [4].
@footnote:
[13] Al Fabetus: "On characters and animals", 1888, self published.
[4] Lorem Ipsum, <a href="http://link.org/Lorem_Ipsum">Web Link</a>
[9999] Annoying Link.
[7] B. Fox: "More on Blind Text".
[3] Linux Kernel Maintainers: LKML
''')
FOOTSPLIT = '@footnote:\n'
NUMBER = re.compile(r'\[(\d+)\]')
def _parse_args():
parser = OptionParser(usage='%prog [options] FILE', version=__version__,
description=''
"Does nothing")
parser.add_option('-t', '--test',
help='use test file', action="store_true", dest='test')
parser.add_option('-a', help='order footnotes',
action="store_true", dest='foot')
parser.set_defaults(test=False, foot=False)
return parser.parse_args()
def as_num(line):
""" [3] Linux Kernel Maintainers: LKML
- > 3
"""
try:
start, _ = line[1:].split(']', 1)
return int(start)
except ValueError:
# bad line, ignore it
return None
# iterator that ends when it encounters FOOTSPLIT
def _end(l) : return not l == FOOTSPLIT
extract_body = partial(takewhile, _end)
def sort_footnotes(fh, sort_footer):
body, foot = extract_body(fh), fh
notes = {}
c = count(1)
def replace_num(match):
""" return new index and assign
it to current index in notes
"""
n = int(match.group(1))
if not n in notes:
i = c.next()
notes[n] = i
else:
i = notes[n]
return "[%d]" % i
for line in body:
yield NUMBER.sub(replace_num, line)
# orig footsplit was not saved
yield FOOTSPLIT
mapping = dict((n, "[%d]" % (i+1)) for i, n in enumerate(notes))
def num_in_mapping(match):
n = int(match.group(1))
return mapping[n]
footer = imap(partial(NUMBER.sub, num_in_mapping), foot)
if sort_footer:
footer = sorted(footer, key=as_num)
for line in footer:
yield line
def main():
""" The main function
"""
options, args = _parse_args()
try:
if options.test:
fh = SAMPLE
else:
fh = open(args[0], 'r')
for line in sort_footnotes(fh, options.foot):
print line,
finally:
fh.close()
if __name__ == '__main__':
main()
|
€dit:
Ist fehlerhalt.
|
audax
Anmeldungsdatum: 15. September 2006
Beiträge: 1253
|
diesmal sortiert er richtig herum: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 | #!/usr/bin/env python
#-*- coding: utf-8 -*-
# Copyright (c) 2007 Jens Kadenbach <j.kadenbach@gmx.de>
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
from __future__ import with_statement
import sys
import re
from cStringIO import StringIO
from optparse import OptionParser
from itertools import imap, takewhile, count
from functools import partial
__version__ = '0.2'
SAMPLE = StringIO('''A great brown fox [13] jumped of a pile of lorem ipsum [4],
[7]. He met with a silver penguin, browsing the Linux Kernel
Mailinglist [3]. They debated whether to start a C-program with
"main (int argc, char **argv)" or with "main (int argc, char *argv[])".
Square brackets annoyed them [9999]. Multiple references exist [4].
@footnote:
[13] Al Fabetus: "On characters and animals", 1888, self published.
[4] Lorem Ipsum, <a href="http://link.org/Lorem_Ipsum">Web
Link</a>
[9999] Annoying Link.
[7] B. Fox: "More on Blind Text".
[3] Linux Kernel Maintainers: LKML
''')
FOOTSPLIT = '@footnote:\n'
NUMBER = re.compile(r'\[(\d+)\]')
def _parse_args():
parser = OptionParser(usage='%prog [options] FILE', version=__version__,
description=''
"Does nothing")
parser.add_option('-t', '--test',
help='use test file', action="store_true", dest='test')
parser.add_option('-a', action="store_true", dest='foot',
help='order footnotes in order of appearance in text')
parser.set_defaults(test=False, foot=False)
return parser.parse_args()
def as_num(line):
""" [3] Linux Kernel Maintainers: LKML
- > 3
"""
try:
start, _ = line[1:].split(']', 1)
return int(start)
except ValueError:
# bad line, ignore it
return None
# iterator that ends when it encounters FOOTSPLIT
def _end(l) : return not l == FOOTSPLIT
extract_body = partial(takewhile, _end)
def create_footer_index(fh):
notes = {}
c = count(1)
footer = []
for line in fh:
try:
start, content = line[1:].split(']', 1)
num = int(start)
except ValueError:
# concat lines of one footer
try:
footer[-1] += line
except IndexError:
# happens maybe on first line
footer.append(line)
else:
idx = c.next()
notes[num] = idx
footer.append("[%d]%s" % (idx, content))
# back to start
fh.seek(0)
return notes, footer
def make_replacer(notes, sort_footer):
if not sort_footer:
def replace_num(match):
n = int(match.group(1))
# 0 when not found
return "[%d]" % notes.get(n, 0)
return replace_num, None
else:
foot_order = {}
c = count()
def replace_num(match):
n = int(match.group(1))
new = notes.get(n, 0)
if new not in foot_order:
foot_order[new] = c.next()
# 0 when not found
return "[%d]" % new
return replace_num, foot_order
def make_foot_sorter(foot_order):
def order(line):
num = as_num(line)
try:
return foot_order[num]
except KeyError:
return None
return order
def sort_footnotes(fh, sort_footer):
for line in extract_body(fh):
pass
# fh is placed in footer
notes, footer = create_footer_index(fh)
replace_num, foot_order = make_replacer(notes, sort_footer)
for line in extract_body(fh):
yield NUMBER.sub(replace_num, line)
yield FOOTSPLIT
if sort_footer:
footer = sorted(footer, key=make_foot_sorter(foot_order))
for line in footer:
yield line
def main():
""" The main function
"""
options, args = _parse_args()
try:
fh = SAMPLE if options.test else open(args[0], 'r')
w = sys.stdout.write
for line in sort_footnotes(fh, options.foot):
w(line)
finally:
fh.close()
if __name__ == '__main__':
main()
|
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
Boost kann zaubern. Ich habe es schon immer geahnt, aber nachdem ich boost.xpressive gesehen habe, weiß ich es. Der Einfachheit halber werden die Fußnoten in der Reihenfolge angeordnet, wie sie im Text vorkommen, es entspricht also eigentlich nicht der Aufgabenstellung. Diese hätte es erfordert, erst einmal von hinten durch die Zeilen zu iterieren, und dafür stellt die C++-Standardbibliothek m. W. keine Funktionalität bereit.
Das Programm benötigt boost.xpressive 1.36, niedrigere Versionen gehen nicht.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 | #include <iostream>
#include <fstream>
#include <map>
#include <algorithm>
#include <string>
#include <boost/xpressive/xpressive.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
using namespace xpressive;
typedef map<int,string> strmap;
class replacer {
replacer();
strmap& footnotes;
int& counter;
public:
replacer(strmap& s, int& i) :
counter(i), footnotes(s) {}
const string& operator()(const smatch& what) const {
int footnote_num = lexical_cast<int>(what[1]);
string& footnote = footnotes[footnote_num];
if (footnote.empty())
footnote = '[' + lexical_cast<string>(counter++) + ']';
return footnote;
}
};
int main(int argc, char** argv) {
if (argc != 2) {
cerr << "Usage: " << argv[0] << " <filename>\n";
return 1;
}
fstream in_file(argv[1], ifstream::in);
if (!in_file) {
cerr << "Error opening " << argv[1] << ".\n";
return 1;
}
strmap footnotes;
int footnote_counter = 1;
replacer repl(footnotes, footnote_counter);
string line;
sregex footnote_regex = '[' >> (s1= +_d) >> ']';
vector<string> last_lines;
last_lines.reserve(footnote_counter-1);
bool in_footnotes = false;
while (getline(in_file, line)) {
line = regex_replace(line, footnote_regex, repl);
if (in_footnotes)
last_lines.push_back(line);
else
cout << line << '\n';
if (line == "@footnote:")
in_footnotes = true;
}
sort(last_lines.begin(), last_lines.end());
copy(last_lines.begin(), last_lines.end(), ostream_iterator<string>(cout,"\n"));
}
|
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4695
Wohnort: Berlin
|
Mein Versuch in Python: http://paste.pocoo.org/show/84357/ @Hello World: Das was Du implementiert hast, ist ja auch in der Aufgabenstellung enthalten, die Hälfte hast Du also umgesetzt. ☺
|
UbuntuFlo
(Themenstarter)
Anmeldungsdatum: 8. Februar 2006
Beiträge: 12317
Wohnort: /home/flo
|
Kaum hielten die ersten Abonnenten das Linux-Magazin 10/2008 in Händen, füllten sich die Postfächer der Redaktion: Das Titelthema "Sprachwahl - Programmier-Päpste lösen und kommentieren vorgegebene Aufgaben" provozierte Fragen, Kritik und Anregungen - und außerdem einiges an selbstgeschriebenem Code, von Python über Ruby bis hin zu C++. Auch auf ein Problem in Python wird eingegangen. Außerdem gibt es ein Video über die Djangolösung. Linux-Magazin FLO
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
Autsch. So etwas hier tut ja einfach nur weh:
| def nodups(lst):
new = []
for x in lst:
if x not in new:
new.append(x)
return new
|
Wie wär's mit
| def nodups(lst):
return list(set(lst))
|
*Kopfschüttel*
|