Posts mit dem Label Art of Code werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Art of Code werden angezeigt. Alle Posts anzeigen

Freitag, 29. Juni 2007

Informatikerprobleme

So, also alle, die sich nich für schönen code interessieren, brauchen gar nich erst weiterlesen. (warscheinlich wird gar keiner weiterlesen ;D) aber irgendwie muss ich ja mein medinf-studium rechtfertigen.
da mein SWT-Praktikum nun fast (und relativ erfolgreich) abgeschlossen ist (präsentation war schon, nur noch n paar nachbesserungen (dabei: danke ans team, nice work!)) hab ich ja nun wieder zeit, mich mit sinnloseren sachen zu beschäftigen.
also hier mal wieder was ganz dolles (natürlich nur mit C++ möglich (haskell und sowas sind für mich keine sprachen)):
vieleicht hatten manche von euch in mathe in der uni das schieberegister. wenn man in körpern mit polynomen als elementen rechnen soll, zb GF(2)[X]/x^4+x+1, is so n schieberegister ganz hilfreich, weil man dann in nullkommanix p1*p2 mod x^4+x+1 ausrechnen kann. nun ist so n schieberegister auch auf GF(3)[X] etc erweiterbar, was dann rauskommt, sind solche zahlenkolonnen:
100
010
001
120
012...

jedenfalls hab ich s heut geschafft, ein programm dafür zu programmieren, welches mir genau diese zahlen ausgibt, ansich nichts großes, WENN ich es mir einfach gemacht hätte, aber ich würde das nich hier posten, wenn s n normales programm wär ;)
also das dolle an dem programm ist: es wird rein gar nix zur laufzeit berechnet
das wird durch die templates von C++ möglich, soll heißen, wenn man das programm kompiliert, ist alle arbeit schon getan und es wird beim starten des programmes nur noch das ergebnis angezeigt.
das war alles ein kleines experiement, um übung in C++-templates zu bekommen.
hier könnt ihr euch mal (wen es denn interessiert) den code dazu anguggn: source

falls es zu unübersichtlich ist ;P hier das herzstück des schieberegisters:
typedef typename tmp::shift::type::add<typename poly::mult<tmp::shift::rest>::type >::type next;

das is eigentlich alles, was man braucht, der rest sind helfer, damit das da funzt

Mittwoch, 17. Januar 2007

was war da los, herr aßmann?

ha, gestern mal wieder swt (software-Technik: uml+javaprogrammierung) gehabt, thema: generics. Da man mit generics schön komplizierte sachen anstellen kann, zeigte uns der prof auch gleichmal, WAS so möglich ist:

// A functional object that adds, once invoked
interface BinOp<P>
{
P execute(P p1, P p2);
}
// an interface for a collection of binary operation on
// collections
interface Functional<Collection<P>,B extends BinOp<P>>
{
P compute(Collection<P> p);
}

class Accumulate<C,P> implements Functional<C,P>
{
P curSum;
P element;
B binaryOperation;
public P compute(Collection<P> c)
{
for (int i = 0; i < c.size(); i++)
{
element = c.getIndex(i);
curSum = binaryOperation.execute(curSum,p);
}
return curSum;
}
}

Da kam er dann doch glatt ins schwitzen ;). Er versuchte die situation noch zu retten, schrieb im code noch etwas rum, aber s wurde nur noch schlimmer (am anfang war der code glaube ich richtig ;D).
Allerdings bin ich mir auch nich ganz sicher...werden C und P nur für das implement verwendet und im body von accumulate dann die parameternamen von functional?
laut diesem code wärs so (dann wären C die collection<P> und P das B) in accumulate<C,P>
und im body wär B dann die binäre operation und P der elementtyp in der Collection...doll, warum einfach (functionpointer), wenns auch kompliziert geht ;)
aber ok, eins muss ich diesem konstrukt zugestehen...funktionpointer auf unspezialisierte templates in C++ sind am ende warscheinlich auch bloß so ähnlich machbar. bei gelegenheit gugg ich mir das mal in C++ an...

Sonntag, 7. Januar 2007

mehr, als man denkt

hiermit eröffne ich ne Kategorie, wo ich hoffe, dass da schön viele einträge reinkommen...
"Art of Code" - hier kommen kleine snippets rein, welche sozusagen den trick 17 in C++ benutzten. Advanced techniques--

hier also das erste Snippet:

#define EXPORT(className, stat) static bool _init_##className = objFactory::getInstance().registrate<classname>(#className, objCreator<classname>(stat));

Schick, oder? wer mir auf den ersten blick sagen kann, was das macht, bekommt n Keks!
Aber ich schreib hier ja keine rätsel, also:
Ziel war es, eine einfache möglichkeit zu finden, dem prorgammierer zu erlauben, klassen zu schreiben und die in ner Factory (aka DLL-Interface) zu registriern, das aber ohne, dass der benutzter ne extra funktion schreiben muss oder überhaupt viel mehr schreiben muss als unbedingt nötig.
ich suchte also ne möglichkeit, ohne ne funktion zu erstellen, ne funktion von der factory aufzurufen...static is die lösung!
mit static kann man statische variablen anlegen zb globale.
static int bla = 4;
statische variablen in DLLs werden genau dann initialisiert, wenn die DLL geladen wird.
Was, wenn man nun funktionen statt feste werte als initialisierung angibt? geht natürlich auch:
static int bla = func();
ok, soweit, so gut.
das makro da oben macht nix andres als ne static bool variable anzulegen mit _init_klassenname und initialisiert die mit der registriermethode der factory...
aber wie den typ übergeben? template-magic is da natürlich die einzige lösung
also bau ich mir n objCreator, das ist eine klasse, welche den übergebenen typ instanziiert und ne methode create hat, die mir ne instanz des Typs zurückgibt.
nun wird per #classname der klassenname in n string umgewandelt, und schon hab ich ne string-=-Typ beziehung.
Ich hab dann noch die möglichkeit eingebaut, dass der Objcreator entweder immer n neues Objekt (halt per new) zurückgibt, was aber automatisch bei entladen der DLL gelöscht wird, oder n statisches Objekt (also immer dieselbe instanz).

naja, haltet mich für verrückt, aber genau wegen solchen sachen liebe ich C++