2014 m. gruodžio 2 d., antradienis

2014 spalis-lapkritis

Dviejų mėnesių bėgyje, tiek kiek leido priežastys, pasiskaitydavau kažko naujo arba seno, ir paspręsdavau uždavinukų.

Skaitymas.
* Wikipedijoje skaitau atskirus straipsnelius programavimo tema, pažindindamasis (dažnai paviršutiniškai) su sąvokomis ir su programų veikimo mechanika. Labiausiai patiko "Optimizing compiler" ir iš jo atsišakojantys įvairių kompiliatoriaus daromų optimizacijų aprašymai. Iš jų labiau suprantami: dead-code elmination, constant folding, loop-invariant motion, strength reduction. Dar skaičiau: Index mapping (trivial hash f-tion), Look-up table (LUT), Minimalism (computing), Segmantation fault, Scripting language, Objective-C, Computer worms... kas papuola and minties.
* Mastering Regular Expressions - pdf'as, pagaliau perskaičiau, iš tiesų perskaičiau 7 iš 9 skyrių, nes >6 skyriai eina atskirai konkrečiãi kalbai, tai 7-ame skyriuje apie Perl'o regex'us. Knyga patiko. Skaityti užtruko ir buvo sunku. Tik galbūt reikėjo paieškot ir skaityt 3rd edition vietoj 2nd.
* Learning Perl - pdf'as, 6th (vėliausias) edition, perskaičiau daugumą skyrių, kelis permečiau akimis. Vienkartinio perskaitymo užteko visiems tiems puslapiams, kur aprašoma jau pažįstama medžiaga. O lėčiau tekdavo paskaityti nežinomus dalykus. Skyriai, į kuriuos mažiau gilinausi, ir/ar kurie man sunkesni, tai viskas apie Encoding'ą, Process management, darbas su failais ir direktorijomis, Perl modules (.pm). O 7, 8, 9 skyriai - greituoju skaitymu, nes apie reguliariasias išraiškas. Uždavinių knygoj neišsprendžiau.

[UPDATE] * Žiūrėjau Youtubėj video (57'), kurį vedė Larry Wall (Perl ir Perl 6 kalbų kūrėjas)). Vidijuje pasakoja jis apie naująją kalbą - Perl 6 (kuri iki šiol oficialiai neišleista), apie jos ideologinius ir konkrečius skirtumus nuo Perl kalbos (kitaip tariant nuo Perl 1..5 kalbos versijų, kurių kiekviena yra suderinama (compatible) su aukštesniąja iš bet kurių tos kalbos versija). Istoriškai gavosi, kad tiek įprastas Perl, tiek Perl 6 vystosi lygiagrečiai, ir nėra taip, kad Perl 6 yra skatintina::naudoti versija => geresnė už paskutiniąsias Perl versijas, t.y. Perl 5.20 su kapeikom. Perl 6 yra net ne atsišakojimas, o perrašyta naujai kalba(?), o jos autorius Larry Wall sako, tai yra ne kalba, o kalbos vienoje.
Man Perl 6 neteko naudotis, tačiau paklausyti šios paskaitos labai labai patiko. Be to buvo smagu paklausyti kalbos, kuria rašinėju, autoriaus kalbą!! Ir džiaugiuosi, kad nemažą dalį supratau apie ką kalbėjo, nes daug to, ką vartojo savo kalboje, perskaičiau Mastering Regular Expressions knygoje. [/U]


Programų rašymas.
* Turnyrėliai, uždavinukai.
Šiek tiek anarchy golf'o.
Kelis kart dalyvavau OpenCup'e. Sekėsi prastokai.
Kelis kart dalyvavau Codeforces. Sekėsi vidutiniškai arba kiek prasčiau.
* Pats sau.
Buvau kadaise nepriklausomai sugalvojęs paprastą klausimą: kaip implementuoti (parašyti) dvimačio fragmento paiešką dvimačiame masyve. Pvz. dvimačiame masyve yra 0- ir 1- ukai. Ar galima jame surasti (ir kiek) "pliusų" sudarytų iš 5 vienetukų. Kitaip tariant, pritempus prie reguliariųjų išraiškų, tai būtų dvimatės reguliarios išraiškos paieška(?).
Vieną dieną prisidėdau ir parašiau primityvią versiją, kurios paieškos greitis nedidelis. O veikimo principas toks: 1) paieškos paveikslėlis yra aprašytas keliomis eilutėmis reguliariųjų išraiškų formatu, tada šios eilutės yra sudedamos į masyvą. 2) duomenyse, kuriuos naršysime, paleidžiame ciklą per eilutes iš viršaus į apačią: 2.1) kiekvienoje toje eilutėje atliekame paprastą paiešką su pirmąja vienmačią reguliaria išraiška iš tų reguliarių išraiškų masyvėlio; 2.1.1) jeigu paieška sėkminga, tada einama laikinai prie sekančios eilutės (stojant į konkrečią jos vietą) ir būtent šioje vietoje atliekama paieška su antrąja masyve esančia reguliaria išraiška. Tam manipuliuoju su eilutės pos() (paieškos starto vieta) ir pririšu paiešką \G inkaru, kad neitų ieškot tolyn į priekį.
Suradus vieną sutapimą, programa veikia toliau ir ieško kitų sutapimų, kuriems leidžiama persidengti (tą suprogramuoti pasirodė kur kas lengviau).

Žemiau:
1) tai, ko ieško programa (4 simboliai, ignoruokim tarpus - jie nėra paieškoje),
2) programos veikimo rezultatas (su parodytomis eilutėmis vėliau naudosimomis reguliariose išraiškose),
3) pavyzdinis programos kodas
3.1) kodo apačioje po užrašo __DATA__ yra duomenų dvimatis laukas, kuriame paieška vykdoma.

1.
 #
#
  #.

2.
(0: .{1}#)
(1: #)
(2: .{2}#\.)
Number of matches: 3;
Upper-left corners match at:
[row: 1|column: 1]
[row: 1|column: 6]
[row: 2|column: 0]

3.
use warnings;
use strict;

sub two_d_search{
    my $amount_of_data = shift;
    my @data = splice @_, 0, $amount_of_data;
    my @pattern = ();
    my ($arg, $indentation, $string);
    my $i = 0;
    
    while (@_){
        $arg = shift;
        if ($arg eq "\n"){
            $i++;
            $arg = shift;
            }
        $indentation = $arg;
        $string = shift;
        $pattern[ $i ] .= ".{$indentation}" if $indentation;
        $pattern[ $i ] .= $string;
        print "($i: $pattern[ $i ])", "\n";
        }
    
    my $pos;
    my $match = 0;
    my @matches = ();
    
    for my $i (0 .. @data - 1){
        undef pos $data[ $i ];
        
        OUT_2:
        while ($data[ $i ] =~ m/$pattern[0]/g){
            ($pos) = @-;
            # matches can overlap, so 'pos' increases only by +1:
            (pos $data[ $i ]) = $pos + 1;
            
            for my $j (1 .. @pattern - 1){
                pos ($data[ $i + $j ]) = $pos;
                if ($data[ $i + $j ] =~ m/\G$pattern[$j]/){
                    # do nothing
                    }
                else {
                    next OUT_2
                    }
                }
            $match ++;
            push @matches, "[row: $i|column: $pos]";
            }
        
        }
    $" = "\n"; # set list output separator to "\n"
    return     "Number of matches: $match;", 
            "Upper-left corners match at:\n@matches"
    }

my @data = <DATA>;
chomp @data;

my @info = &two_d_search(
    scalar @data,
    @data,

#    indentation; string; argument of line separation
    1, '#', "\n",    # two_d_regex first line
    0, '#', "\n",    # two_d_regex second line
    2, '#\.'    # two_d_regex third line
    );

print "@info",$/;

__DATA__
#..#.....#.
..#...##...
.#....#..##
#..#....#..
..#...#..#.
.......#.#.
...........