Gisteravond heb ik een klein artikeltje geschreven over quines.
Quines zijn programma's die zichzelf printen. Ik had al eerder quines geschreven, maar het schrijven van deze dingetjes is gewoon lollig.
Dat heeft mij toen 's nachts geinspireerd in een nieuwe quine in Java welke de data opslaat in een soort morse. Ik ben gewoon begonnen met het schrijven en hield een array bij met alle tokens die ik gebruikte in mijn programma.
Token zijn variabele namen, en characters in het programma, zie het als een soort huffman encoding. Er is dus een mapping tussen een int en de tokens.
Als eerste heb ik de mapping van int naar token geschreven. Die is makkelijk, dat is gewoon de array indexeren met de int. Enige probleem was de manier van decoden van de morse naar een int, maar dat is makkelijk (dat is ook al duizend keer voorbij gekomen als iemand vroeg hoe hij een int moest printen enzo, alleen dan nu deed ik het binair).
Ik ging natuurlijk niet met de hand mijn quine vertalen naar "morse". Dus een kleine functie geschreven die de quine uiteentrekt in tokens. Hij pakt een character uit de code, kijkt in de array met tokens of die erin staat, zo niet pakt hij weer een character enzovoort. Als hij teveel characters had gepakt, dan gaf hij een foutmelding, want dan is de token array waarschijnlijk incompleet.
Toen hij eenmaal werkte had ik een leuke data string dat er zo uitzag:
"...--..--.---..---.-..-----..-.....---.-.--..-.-..--.-------.....--.-...- etc".
Toen de quine af was, had ik 46 tokens gebruikt. Het is altijd een sport om je quine zo klein mogelijk te maken. Dat ging ik vooral doen door tokens te verwijderen die niet nodig waren. Dus spelen met de namen van variabelen enzo. Op een gegeven moment ging ik richting de 32 tokens. Dat is mooi, want dan kan ik een token in 5 bits encoden in plaats van de gebruikte 6. Het bleek niet makkelijk om maar 32 tokens te gebruiken, maar uiteindelijk is het me gelukt.
Nu kwam het volgende. Ik checkte alleen maar of er een bepaald teken stond, dan was het een 1, als dat er niet stond een 0. Dus ik kon alle andere tekens daarvoor in de plaats gebruiken, zolang het maar niet het 1 teken was. Ik heb er eerst een verhaaltje neergezet, maar dat was niet zo leuk. Dus heb ik er de code van de quine voor in de plaats gezet.
Dit is het geworden, let wel, als je hem wilt compilen moet je hem op 1 regel zetten:
Misschien ga ik er nog wel 1 proberen, met echte huffman code inplaats van dit bijvoorbeeld.
Ik weet dat niet echt een vraag is. Maar het lijkt me leuk om hier andere quine brouwsels van andere coders te zien. Of dat andere mensen ideeen hebben voor nieuwe quines. Succes met het schrijven van je eigen quines!
Quines zijn programma's die zichzelf printen. Ik had al eerder quines geschreven, maar het schrijven van deze dingetjes is gewoon lollig.
Dat heeft mij toen 's nachts geinspireerd in een nieuwe quine in Java welke de data opslaat in een soort morse. Ik ben gewoon begonnen met het schrijven en hield een array bij met alle tokens die ik gebruikte in mijn programma.
Token zijn variabele namen, en characters in het programma, zie het als een soort huffman encoding. Er is dus een mapping tussen een int en de tokens.
Als eerste heb ik de mapping van int naar token geschreven. Die is makkelijk, dat is gewoon de array indexeren met de int. Enige probleem was de manier van decoden van de morse naar een int, maar dat is makkelijk (dat is ook al duizend keer voorbij gekomen als iemand vroeg hoe hij een int moest printen enzo, alleen dan nu deed ik het binair).
Ik ging natuurlijk niet met de hand mijn quine vertalen naar "morse". Dus een kleine functie geschreven die de quine uiteentrekt in tokens. Hij pakt een character uit de code, kijkt in de array met tokens of die erin staat, zo niet pakt hij weer een character enzovoort. Als hij teveel characters had gepakt, dan gaf hij een foutmelding, want dan is de token array waarschijnlijk incompleet.
Toen hij eenmaal werkte had ik een leuke data string dat er zo uitzag:
"...--..--.---..---.-..-----..-.....---.-.--..-.-..--.-------.....--.-...- etc".
Toen de quine af was, had ik 46 tokens gebruikt. Het is altijd een sport om je quine zo klein mogelijk te maken. Dat ging ik vooral doen door tokens te verwijderen die niet nodig waren. Dus spelen met de namen van variabelen enzo. Op een gegeven moment ging ik richting de 32 tokens. Dat is mooi, want dan kan ik een token in 5 bits encoden in plaats van de gebruikte 6. Het bleek niet makkelijk om maar 32 tokens te gebruiken, maar uiteindelijk is het me gelukt.
Nu kwam het volgende. Ik checkte alleen maar of er een bepaald teken stond, dan was het een 1, als dat er niet stond een 0. Dus ik kon alle andere tekens daarvoor in de plaats gebruiken, zolang het maar niet het 1 teken was. Ik heb er eerst een verhaaltje neergezet, maar dat was niet zo leuk. Dus heb ik er de code van de quine voor in de plaats gezet.
Dit is het geworden, let wel, als je hem wilt compilen moet je hem op 1 regel zetten:
Java:
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
| class String0 {static String String=".la..,,,,,,,,,, ,,,,,,,,,String0,{static,String,String=,,;static,String[],charAt0={,,, ,,,,,,,',,,(,,,)..,.,.,,,,,,,,....,..,..,,,<,,..,.,Strin..,.S..tem,ou. ,pri.t.,.[..,..,,,],,..h.r.....cla.s,,,f.r,.,i.,,,i..,,....gth,,.main, ,,pu.li..,,ret..n,,,stat.c,,,.ub..ring,.,vo.d,,,{.,,..};pub.ic,..atic. vo..,main.St.ing[],.ai..{Syst.m,.u.,pri.t(..arAt(.tr..g),su.st..ng(0,. 5)...yste.,o..,prin.(.tring);.ys..m,out.p.in.(cha.At..tring.,.u.strin. (5..);}st.t.c..trin.,c..rAt(S.r..g,main.{S..ing,c.a..t.,,;f.r(..t,len. t...;leng.h<..in,le.g....;len.th..5){in..subs.ring=0;f.r(..t,Str..g=l. ngth.St..ng<le..th.5;Str.ng..){sub..ri..+=su.st..ng;if..a.n,char.t(..r ing)..'.'.subs.ri..++;}c..r..+=cha.At..subst..n...}ret.rn..harAt...cla ss,,.,,..,,,,,...,,.,Str.ng..{stat...S.ring,.tr..g=,,;...t..,Str.ng.., char....{,,,,,.,,..',,,(....,.,+,,.,,..,,,,0.....,,;,,.<,..=,,,S...... ,,Sy......u.,.r..t,.,[,,,..,..],,,c...A.,,,cl..s,,,fo..,..f.,.....,,l. ngth,..main,.,p....c,...etur...,s.atic..,..b.tr.ng,,......,,{,,..,.;pu bl..,s.at.c.vo.d,.ain(.tri.g.],...n){S..t..,.ut.pri.t.ch...t(St...g).s ubs..i..(.,5.));S......out,p..n.(S.r.ng.;S.stem.out.p.i.......A..Strin g..s.bstri.g(.5));..t..i.,Stri..,char.t(....ng..a.n){St.in.,c..rAt=,,. for(.n.,.e.g.h=0;l...t..main,l.n...(..len.th+=.).i.t...b.t....=0;fo... .t...rin..le.gth.S.r.n...en.t.+..Str.ng.+).su....i.g..substr...;if..ai n.char.t.S.r.ng)==...)..bstring..;.c..rA.+...a.A.0[..b.t.i...;...tu.n. c.ar.t.}.cl..s.,,.,.,,.,.,,.,,....t...g0,{.t.t..,S...ng,.t.i.g.,.;st.. ..,Stri....,c.arAt..{..,.,,.,,,..,,(..,),,,.,,,...,,,.,0,.,5...;,,,.,. ,=.,.S.r.n......st.m,o.t.p..nt.,,.,,.,,,,.......ar.t,,.c.a.s.......,.i f,,,i.t,.,l.n.t..........";static String[] charAt0={" ","\"","'","("," )","+",",",".","0","5",";","<","=","String","System.out.print","[","\\ ","]","charAt","class","for","if","int","length","main","public","retu rn","static","substring","void","{","}"};public static void main(Strin g[] main){System.out.print(charAt(String).substring(0,55));System.out. print(String);System.out.print(charAt(String).substring(55));}static S tring charAt(String main){String charAt="";for(int length=0;length<mai n.length();length+=5){int substring=0;for(int String=length;String<len gth+5;String++){substring+=substring;if(main.charAt(String)=='.')subst ring++;}charAt+=charAt0[substring];}return charAt;}} |
Misschien ga ik er nog wel 1 proberen, met echte huffman code inplaats van dit bijvoorbeeld.
Ik weet dat niet echt een vraag is. Maar het lijkt me leuk om hier andere quine brouwsels van andere coders te zien. Of dat andere mensen ideeen hebben voor nieuwe quines. Succes met het schrijven van je eigen quines!
[ Voor 6% gewijzigd door Macros op 31-10-2004 02:12 ]
"Beauty is the ultimate defence against complexity." David Gelernter