Elso korben az olvashatatlanra tordelt kodot szepen megformaztam. Eztan szepen kicsereltem a "$e" hivasokat "echo"-ra, meg persze a "$b"-ket "bc"-re - egyszeruen csak azert, hogy en atlassam (ha mar egyszer ez is egy alkalmazott obfuscator technika volt). Szepeszet utan elkezdtem az eredmenyt tanulmanyozni. Feltuntek a bash-specifikus dolgok (for i in {1..24}, vagy az echo '\Eakarmi'). Aztan baromi sokat elszoszmotoltem az "eval" resszel a vege fele, mire nagy nehezen leesett, hogy ott egy folosleges(nek tuno) valtozohivatkozas szerepel (egy nem letezo valtozora az erdekesseg kedveert). (Mashol inicializalatlan valtozohivatkozas is van az eredeti kodban - a legelso helyen, ahol a C-re hivatkozik). De lassan kepben lettem.
Szepen sorban kezdtem atirni bc-re. Celom volt, hogy ha valami GNU-bc specifikus, azt ne hasznaljam. Mondjuk a POSIX-bc csak egykarakteres, kisbetus valtozoneveket ismer - ez meg nem volna gond, hisz nem kellett a kodba 26-nal tobb valtozo. (Mondjuk a kenyelem kedveert ezzel nem foglalkoztam, mondvan ha mar keszen vagyunk, egy vi-beli :%s///g megoldana az ilyen valtozonevekkel kapcsolatos gondokat.) Vagy. A POSIX-bc-ben nincs az "if"-nek "else" aga, ez mondjuk kicsit olvashatatlanna tenne a kodot, de az egy darab if/else meg siman szetszedheto ket if-re, ha nagyon kell. Szoval ez a POSIX-kompatibilis dolog nem latszott nagyon remenytelennek. Ez sajnos a vegere bukott.
Az atiras nagyresze konnyu, persze nem volt minden trivialis. Utolag baromi egyszeru (meg a doksiban is benne van), de amikor az ember irja, akkor nem jut eszebe, hogy bizony a bc-ben baromi nagy a kulonbseg, hogy a++, vagy a += 1 szerepel a "for" ciklus lepteto utasitasaban. Az ilyesmikkel jol elment az ido. Baromi sokaig tartott, mire rajottem arra, hogy azert nem szines, hanem iszonyatosan kriksz-krakszos a vegeredmeny, mert a bc sztring-kiirasra hasznalt parancsa ( "sztring" ) nem tesz ugyan Enter-t a szoveg moge (ami nagyon jo), ellenben a szamok kiirasanal tesz Entert (ami kb logikus is). Sajnos ez itt jol bekavar, mert a szinezeshez a szekvenciat harom reszbol rajta ossze az eredeti kod, aminek a kozepe egy szep kis shell-valtozo helyettesites. Erre nem is jottem ra, hogy mi modon lehetne megoldani, igy maradt a print. (Ez volt az a pont, amikor kenytelen-kelletlen feladtam a remenyt, hogy hordozhatora - POSIX-bc - megirom.)
Es amikor vegre minden mukodik, akkor se megy minden tokeletesen. Vannak szovegek, meg latszik a szinezes, de egy osszevisszasag az egesz. Jo darabig eltartott, mire rajottem az okara. A bc ugyanis, amikor kiirja a szamitasok (esetleg) baromi hosszu eredmenyet, a 70 karakternel hosszabb sorokat szepen tordeli. Eddig semmi gond, hiszen en (marmint az eredeti szerzo) gyakorlatilag karakterenkent irja ki a szoveget. Igen am, de a bc (legalabbis a GNU-fele) minden nyomorult kiirasnal ellenoriz, es szamontartja hogy hol vagyok. Es mivel a karakterek szinezese betunkent kb 6-7 plusz karakter (a ESC-vezerloszekvencia) kiirasat eredmenyezi, itt bizony 8-10 karakterenkent "hosszu a sor, tordelni kell" lett az eredmeny. Ezen egy darabig gorcsoltem, aztan itt feladtam, es elovettem inkabb az eredeti elkepzelest, hogy maradjon az sh-script, csak kevesebb bc-vel.
Eloszor is kidobtam a bash-specifikus dolgokat es atirtam "rendes" sh-ra. Kidobtam a felesleges valtozohivatkozast, inicializaltam az inicializalatlan valtozot, kicsereltem a bash-fele \E sztringet valodi ESC-re (ez nem tul szep, de micsinaljak), majd megneztem, mit lehetne tenni a gyorsitasert. Hat az eredeti kodban ugye minden valtozo ertekenek kiszamitasahoz a=`echo a+b|bc` format hasznal. A belso ciklus elejen van is harom + ketto bc hivas (meg kozben egy shellbeli szamolas). No ezt egy kis tunodes utan le lehet egyszerusiteni 2 db-ra, ez akarhogy is nezem, 60%-kal kevesebb. (Mindez egy 24*80*33-szor lefuto ciklusban.) Aztan meg egy-ket finomitas, es eloallt a mukodo eredmeny. Jott a teszt, es szepen latszott is, hogy gyorsult a dolog - no a regi laptopon amin teszteltem, nem lett latvanyosan gyorsabb, viszont meg az eredetinel is sokkal olvashatatlanabb (lenne, ha az eredeti tordelest en is alkalmaznam).
Miutan ezzel megvoltam, csak nem hagyott nyugodni a bc-s verzio. (Az egesz azert volt fontos, mert szerettem volna latni, hogy mennyivel lenne ugy gyorsabb.) Es egy kis fejvakaras utan be is ugrott a megoldas: mivel a bc itt mar nem okosithato, nincs mas dolgom, mint a bc altal kiirt szoveget meg egy kis atalakitasnak alavetni - erre jo pl. egy kis sed. No nekiindultam annak is, es eleg hamar meglettem vele. Immar mukodik a dolog. Sajnos miutan megcsinaltam, akkor jottem ra, hogy egy szepsege elveszik. Mivel gyakorlatilag mindegyik sor vegen realisan varhato a Backslash-Enter kombo, ezert a sednek be kell olvasni az egesz adatot, es feldolgozas utan egyszerre fog megjelenni az abra - nem ugy mint az eredetiben, ahol szepen nyomonkovetheto a rajzolas folyamata. No mindegy.
Vegul az eredmenyek:
Az eredeti bash-specifikus kod az en oreg laptopomon a time parancs szerint fut 1046,25 sec ideig.
Az altalam modositott verzio, amiben kidobtam a bash-specifikus dolgokat, es lecsokkentettem a bc-hivasok szamat (ellenben meg olvashatatlanabba tettem az egeszet), az pedig 473,04 sec ideig fut. Azert latszik, hogy szinte teljesen meg van a 60% nyereseg, amit a 60%-kal kevesebb bc-bol azert lehetett sejteni. (Ez utobbi igy ahogy van mar fut a FreeBSD nativ sh-javal is, azzal meg egy kicsit gyorsabb lett.)
Vegul pedig a bc-ben megirt verzio, ahol sajnos kell a kimenet finomitasa seddel, az 0,53 sec idot birt produkalni :-)
Szoval fel masodperc a ~500 illetve a ~1000 elleneben :-)
Ja, a kodok: az altalam modositott shell+bc verzio (rendesen tordelve)
#!/bin/sh
S0=S;S1=H;S2=E;S3=L;S4=L;e=echo;b=bc;I=-1
C=0
x=1 ; while [ "$x" -le 24 ] ; do
R=-2
y=1 ; while [ "$y" -le 80 ] ;do
B=0;r=0;i=0
while [ $B -le 32 ];do
eval `$e '"r2=";'"$r*$r;"'"i2=";'"$i*$i;"'"i=";'"2*$i*$r+$I;"|$b`
eval `$e '"r=";'"$r2-$i2+$R;"'"B=";'"$B+1;"'"V=";'"($r2+$i2)>4;"|$b`
if [ "$V" -eq 1 ];then break;fi
done;
if [ $B -ge 32 ];then
$e -n " "
else
U=$(( ( $B * 4 ) / 15 + 30 ))
$e -n "^[[01;$U""m"
C=$(( $C % 5 ));
eval "$e -n \$S$C"
C=$(( $C + 1 ))
fi
R=`$e "$R+0.03125"|$b`
y=$(( $y + 1 ))
done
$e "^[[m"
I=`$e "$I+0.08333"|$b`
x=$(( $x + 1 ))
done
(Sajnos a szinezes ki es bekapcsolasahoz ESC-szekvencia kell, amit hordozhatoan csak ugy lehet begepelni, hogy a sztringbe valoban ESC-karakter kerul. Ellenben szerintem igen olvasmanyosra sikeredett az eredetiben szereplo sok-sok ertekadasnak az eval-ositasa ;-) )
Es a masik, a bc-s kod:
#!/usr/bin/bc
ii = -1
for ( x = 1; x <= 24; x += 1 ) {
rr = -2
for ( y = 1; y <= 80; y += 1 ) {
bb = 0 ; r = 0 ; i = 0
while ( bb <= 32 ) {
r2 = r * r ; i2 = i * i ; i = 2 * i * r + ii
r = r2 - i2 + rr ; bb += 1 ; vv = ( ( r2 + i2 ) > 4 )
if ( vv == 1 ) break
}
if ( bb >= 32 ) {
" "
} else {
uu = ( bb * 4 ) / 15 + 30
"^[[01;" ; print uu ; "m"
cc %= 5
if ( cc == 0 ) "S"
if ( cc == 1 ) "H"
if ( cc == 2 ) "E"
if ( cc == 3 ) "L"
if ( cc == 4 ) "L"
cc += 1
}
rr += 0.03125
}
print "^[[m^[(\r\n"
ii += 0.08333
}
quit
Itt szinten vannak ESC-ek, de ennek meg a hivasa is gyonyoru:
$ bc Mandelbrot.bc | sed -n -e 1h -e '2,$H' -e '${
g
s/\\\n//gp
}'
Vegul: es akkor mi van? Semmi, csak jatszottam egyet.
- Zahy blogja
- A hozzászóláshoz be kell jelentkezni
- 918 megtekintés
Hozzászólások
végre egy érdekes topic, már ki voltam "száradva" :)
- A hozzászóláshoz be kell jelentkezni
Ez fun topic, grat!
- A hozzászóláshoz be kell jelentkezni
Nem teljesen parancssoros, viszont tömör és szép:
gnuplot -persist -e 'se sa 200;se isos 200;se vi map;c(a,b)=a*{1,0}+b*{0,1};m(z,a,n)=n<=0||abs(z)>100?1:m(z*z+a,a,n-1)+1;sp [-2:1][-1.5:1.5] m({0,0},c(x,y),30) w pm3d'
- A hozzászóláshoz be kell jelentkezni
$ gnuplot -persist ....
Abort trap
$
???
- A hozzászóláshoz be kell jelentkezni
??? indeed. Az -e és a -persist opció is elég régóta van, a 4.2.6 óta biztosan.
Nálad lehet a probléma.
- A hozzászóláshoz be kell jelentkezni
jo, hogy meg vannak ilyen jatekos hangulatu blogok :)
- A hozzászóláshoz be kell jelentkezni
Nekem nem Mandelbrot-fraktált rajzol ki, csak efféléket irkál ki:
vz@Csiszilla /Depot/Letolt]sh ./mandelbrot
^[[01;30mS^[[01;30mH^[[01;30mE^[[01;30mL^[[01;30mL^[[01;30mS^[[01;30mH^[[01;30mE^[[01;30mL^[[01;30mL^[[01;30mS^[[01;30mH^[[01;30mE^[[01;30mL^[[01;30mL^[[01;30mS^[[01;30mH^[[01;31mE^[[01;31mL^[[01;31mL^[[01;31mS^[[01;31mH^[[01;31mE^[[01;31mL^[[01;31mL^[[01;31mS^[[01;31mH^[[01;31mE^[[01;31mL^[[01;31mL^[[01;31mS^[[01;31mH^[[01;31mE^[[01;31mL^[[01;31mL^[[01;31mS^[[01;31mH^[[01;31mE^[[01;31mL^[[01;31mL^C
és így tovább.
Mi lehet a hiba nálam?
-------------
Használj GoboLinuxot!
http://mek.oszk.hu/05800/05895/
:::A #86-os sorszámú hivatalosan bejegyzett GoboLinux felhasználó
- A hozzászóláshoz be kell jelentkezni
íEz a sok ocsmánysáh képernyő színezésére hazsnálható ESC-szekvencia. Az, hogy nálad nem a színváltás a következménye, ez annyit jelent, hogy a használt terminálemulátor nem ismeri ezeket a szekvenciákat. Próbáld bekapcsolni a DEC VT100 (vagy valami ennél komolyabb) terminál emulációját a használt eszközben.
- A hozzászóláshoz be kell jelentkezni
Én az Mrxvt terminálemulátort használom, és fogalmam sincs, hogyan lehetne bekapcsolni rajta valami más terminál emulációját. De azt tudom, hogy az Mrxvt-ben is vannak színek, mert számos parancsnak szines output az eredménye benne, plusz természetesen a promptom is színes.
-------------
Használj GoboLinuxot!
http://mek.oszk.hu/05800/05895/
:::A #86-os sorszámú hivatalosan bejegyzett GoboLinux felhasználó
- A hozzászóláshoz be kell jelentkezni
Rajottem. En a fenti kodban ^[ formaban irtam ki az ESC karaktereket, te meg ha copy'n'paste-tel raktad be, termeszetesen nemlesz belole ESC. Szoval a forrasban minden helyen ahol ^[ all, ezt csereld ki egy ESC karakterre. Ez vi-ban trivialis. (Es figyelj, az ESC csak ^[, a mogotte levo [ - vagy barmi egyeb - mar kell!)
- A hozzászóláshoz be kell jelentkezni
Igazán kezdőhöz "méltó" kérdést teszek akkor most fel neked kedves Zahy:
Hogyan kell ESC karaktert bevinni (mondjuk az MC editorában)? Ugyanis még sosem fordult elő velem, hogy ezt kellett volna beütnöm, márpedig ha csak úgy simán Esc-t nyomok, akkor semmit nem ír be, ha meg az Esc után megnyomok egy másik billentyűt, akkor ki akar lépni a dokumentumból!
-------------
Használj GoboLinuxot!
http://mek.oszk.hu/05800/05895/
:::A #86-os sorszámú hivatalosan bejegyzett GoboLinux felhasználó
- A hozzászóláshoz be kell jelentkezni
Sajnos erre nem tudok válaszolni, mert soha (értsd az elmúlt 10 évben biztosan nem) használtam MC-t, épp ezért feltelepítve sincs, így nem tudom. (vi-ban speciel szövegbevitel közben kell Ctrl-V -t beütni, majd utána az ESC-et - így került be a szövegbe valóban ESC, mégha ^[ formában jelzi is ki.)
- A hozzászóláshoz be kell jelentkezni
Köszi a tippet, megcsináltam vim-mel, s így már működik és tök jó! Nagy vagy, hogy így kitaláltad ezt a felgyorsítást!
-------------
Használj GoboLinuxot!
http://mek.oszk.hu/05800/05895/
:::A #86-os sorszámú hivatalosan bejegyzett GoboLinux felhasználó
- A hozzászóláshoz be kell jelentkezni
csak tipp: ctrl+q esc esc
- A hozzászóláshoz be kell jelentkezni
Az MC editorában ez nem válik be.
-------------
Használj GoboLinuxot!
http://mek.oszk.hu/05800/05895/
:::A #86-os sorszámú hivatalosan bejegyzett GoboLinux felhasználó
- A hozzászóláshoz be kell jelentkezni
azóta kipróbáltam, érdekes, nálam működik, szimplán a "ctrl+q esc esc" (így egymás után) egyetlen esc (dec27) karaktert szúr be, F4 után a replace is működik hiába a replace all előtt még csak pontnak látszik, utána már jó
mcedit --version
GNU Midnight Commander 4.7.0.6
- A hozzászóláshoz be kell jelentkezni