2013 m. sausio 16 d., trečiadienis

Anarchy golfas - 1 (Perlu)

Šį semestrą (2012 rudens), suradau dar vieną prokrastinacijos būdą. Toks fun "žaidimas" - programinimas sunaudojant kuo mažiau keystrokų - kuo mažiau vargo pirštams (dėmesio šis žaidimas - tinginiams! kitiems nerekomenduoju ;) ).
Būtų viskas gerai, jeigu duotų naudos, ir jei pavyktų "suspausti" kodą iki mažai simbolių, tačiau dažniausiai - keblu būna suspausti, ir naudos iš tokio "programavimo" - nedaug.
Kodėl pasirinkau būtent "pakibti" ant tokių programavimo žaidimų - tema išeina iš už blogo paskirties.
Taigi - Perl golf!

Pagooglinau svetainių. Suradau šią - http://golf.shinh.org/all.rb , ir joje apsistojau. Čia pateikta daug paprastučių ir sudėtingesnių uždavinukų, kuriuos galima submitinti visokiomis programavimo kalbomis (sąrašas nemažas, plius pridėtos specialiai golfui skirtos kalbos).
Pats submitinau tik Perlu.

Statistikoje galima išskirti kalbas, kuriomis Golfą pavyksta sužaisti dažniausiai geriau.
Tai specialios golfingo kalbos.
Tai kai kurios mikrokalbos (sed, awk).
Ir Perl vs Ruby.

***

Perlo kodas sutrumpėja, naudojant specialiuosius kintamuosius, ir reguliariasias išraiškas. Kai kurių specialiųjų kintamųjų nenaudoju, bet matu naudotus kitų programose. Jų dar nepasimokiau. Tai $., $&, $/ , kt.. Taip pat kai kurių konstrukcijų dar nesu supratęs, ar žinantis. Bet šiek tiek išmokau naujo žiūrėdamas kitų parašytus kodus.

***

Pateiksiu keletą užduočių ir jų sprendimų.

1. http://golf.shinh.org/p.rb?two+kinds+of+digit - čia reik, kad programa išspausdintų visus skaičius nuo 1 iki 10k, kurie sudaryti iš dviejų skirtingų skaitmenų. 

Kodas:
for(1..10000){$b=$c=-2;/$b/&&$c++while($b++<9);$c||print"$_\n"} 

2. Identity Matrix - perskaityti matricos kraštinę, ir išspausdinti vienetinę matricą. Pvz. 2. Ats.:
1 0
0 1
Kodas:
$a=<>;$_="1"." 0"x--$a."\n";{print;s/(.+) 0$/0 $1/;redo if$a--}


Toliau pateiksiu kelis uždavinius, su jų pradiniais sprendimais, o dar toliau - tų užduočių patobulintus (sutrumpintus) sprendimus:

3a) "Reduce fractions" - http://golf.shinh.org/p.rb?Reduce+fractions - reikia "suprastinti" trupmenas.
Kodas: 
while(<>){chomp;@_=split/\//;$a=2;while($a<$_[1]){if(!($_[0]%$a)&& !($_[1]%$a)){for$i(0,1){$_[$i]=$_[$i]/$a};redo}$a++}print"$_[0]/$_[1]\n"}

4a) "Back and forth" - http://golf.shinh.org/p.rb?Back+and+forth , žiūrėti pvz.
Kodas: 
$_=join"",@_=<>;s/(\S+)/$i++%2?print" "x($j-=length$1).reverse"\n$1":print" "x$j,"$1\n";$j+=length$1if$i%2/meg;

5a) "Paragraph counter" - skaičiuoja kiek eilučių. Išveda atsakymą.
Kodas:

6aI) "Cross product of 2 strings" - http://golf.shinh.org/p.rb?Cross+Product+of+two+Strings .
Kodas:
6aII) Kodas:
---

3b) 
while(<>){chomp;$_=@_=split/\//;while($_<$_[1]){if(!($_[0]%$_||$_[1]%$_)){for$i(0,1){$_[$i]/=$_}redo}$_++}print"$_[0]/$_[1]\n"}


 4b-final)

5b)
 6b-final)
 ---

3c-final)
for(<>){$_=($a,$b)=/(\d+).(\d+)/;while($_<$b){until($a%$_||$b%$_){$a/=$_;$b/=$_}$_++}print"$a/$b\n"}
5c-final)
/.$/&&$i++for<>;print$i

*-*-*-*-*

Toliau pateiksiu kelis kodus, be paaiškinimų, ką jie atlieka.
Taip golf-kodas kartais būna ir obfuscation-kodas (t.y. nesuprantamas), nors nevisada...

7. 

8. (šis kodas užima 66 simbolius, ir tai yra prasčiausias rezultatas iš visų submitintų Perlu. Geriausias rezultatas - 56 simboliai. Tačiau mane tai labai pradžiugino, nes dažniausiai mano kodai nuo "varžovų" atsilieka per 1,5 ar 2, ar net 3 kartus)

9. 
<>;while(<>){$_=<>;while(/ /){s/(\d+) (\d+)//;for$i(1..$1){$2%$i||$1%$i or$j=$i}s/^/$j/}print}

*-*-*-*-*

Taip pat parodysiu kelių užduočių kodo kitimo istoriją. 

10. "Liouville number" - išspausdinti Liovilio skaičių (http://en.wikipedia.org/wiki/Liouville_number) iki 1000-ojo skaitmens po kablelio.

$_="0.".$i++x1e3;$i*=++$j,substr$_,$i+1,1,1while$j<6;print

11. "Simple preprocessor" - http://golf.shinh.org/p.rb?Simple+Preprocessor 
$_=join"",<>;s/^\s*(#.*\n)?|\s+$//mg,print