Kirjautuminen

Haku

Tehtävät

Joulukalenteri 2009: Piet

Kirjoittaja: tgunner (20.12.2009)

Piet on David Morgan-Marin luoma esoteerinen ohjelmointikieli, jonka lähdekooditiedostojen on tarkoitus näyttää abstrakteilta maalauksilta. Kieli on nimetty geometrista abstraktia taidetta maalanneen Piet Mondrianin mukaan.

Pietin pienin yksikkö on koodeli (eng. codel). Koodeli on pienin yksittäinen, neliön muotoinen värialue, jonka kääntäjä ymmärtää. Se voi olla yksi pikseli, 10x10-alue tai vaikka nxn-alue. Koodelit muodostavat väripalikoita (eng. colour block), jotka ovat yhdestä tai useammasta koodelista koostuvia alueita lähdekoodissa. Väripalikoiden muodolla ei ole väliä, ja niiden sisällä voi olla muita väripalikoita.

Kääntäjä lukee lähdekoodia kuljettamalla bittikartan yllä kuvitteellista lukupäätä, joka aloittaa matkansa kuvan ylävasemmasta koodelista ja jatkaa siitä suuntamuuttujien DP (Direction Pointer) ja CC (Codel Chooser) osoittamalla tavalla. DP voi saada arvoja right, down, left, up; ja sen oletusarvo on right. CC voi saada arvoja left tai right; oletusarvona left. Suunta päätetään seuraavan taulukon mukaan:

  DP       CC       suunta
---------------------------
          left       ylin
 right
          right      alin

          left       oikeanpuolimmaisin
 down
          right      vasemmanpuolimmaisin

          left       alin
 left
          right      ylin

          left       vasemmanpuolimmaisin
 up
          right      oikeanpuolimmaisin

Oletusarvona on right, left (DP, CC), joten ensimmäisestä väripalikasta poistutaan oikealle kaikkein ylimmästä koodelista. Jos DP olisi up ja CC left, lukupää jatkaisi matkaansa kaikkein vasemmanpuoleisimmasta koodelista ylöspäin.

Kääntäjä suorittaa komentoja aina, kun lukupää siirtyy väripalikasta toiseen, ellei kyseessä ole siirtymä valkoiseen väripalikkaan tai valkoisesta väripalikasta. Mustalle alueelle tai ulos kuvasta ei voi siirtyä. Värit on määritelty alla olevan taulukon mukaisesti. Komentojen kannalta ratkaisevia ovat sävy (eng. hue) ja kirkkaus (eng. brightness).

Sävy muuttuu: red -> yellow -> green -> cyan -> blue -> magenta -> red.
Kirkkaus muuttuu: light -> normal -> dark -> light.

Komentoja on yhteensä seitsemäntoista ja jokainen niistä käyttää hyväkseen Pietille oleellista pinoa. Pinoon varastoidaan kokonaislukuja ohjelman kulun aikana ja sitä käsitellään komennoilla push ja pop. Push nostaa pinosta päällimmäisen arvon ja pop asettaa arvon pinon päällimmäiseksi. Arvot määräytyvät sen väripalikan koodelien lukumäärän mukaan, josta poistutaan. Pinosta ei voi nostaa arvoja välistä eikä niitä voi asettaa aikaisempien arvojen väliin.

Komennot:

a = pinon päällimmäinen arvo, b = pinon toisiksi päällimmäinen arvo

push     : asettaa koodelien lukumäärän pinoon
pop      : poistaa pinon päällimmäisen arvon
add      : nostaa pinosta arvot a ja b, laskee ne yhteen ja pushaa summan pinoon
subtract : nostaa pinosta arvot a ja b, laskee b - a ja pushaa erotuksen pinoon
multiply : nostaa pinosta arvot a ja b, laskee a * b ja pushaa tulon pinoon
divide   : nostaa pinosta arvot a ja b, laskee b / a ja pushaa osamäärän pinoon
mod      : nostaa pinosta arvot a ja b, laskee b % a ja pushaa jakojäännöksen pinoon
not      : korvaa a:n nollalla, jos a = 0, tai ykkösellä, jos a != (erisuuri) 0
greater  : nostaa pinosta arvot a ja b, pushaa ykkösen, jos b > a, tai nollan, jos a > b
pointer  : nostaa a:n ja pyörittää DP:tä myötäpäivään arvon osoittaman luvun verran; vastapäivään, jos a < 0
switch   : nostaa a:n ja vaihtaa CC:tä arvon osoittaman luvun verran
duplicate: kopioi a:n ja pushaa sen pinoon
roll     : nostaa a:n ja b:n pinosta ja valitsee b:n osoittaman määrän pinon päällimmäisiä lukuja muodostaen niistä ryhmän. Ryhmän päällimmäinen luku siirretään viimeiseksi ja tämä toiminto suoritetaan a kertaa
in       : lukee arvon STDINistä, numeron tai merkin, ja pushaa sen pinoon
out      : nostaa a:n ja kirjoittaa sen STDOUTiin joko numerona tai merkkinä
                             kirkkauden muutos
sävyn muutos          0              1           2
     0                             push         pop
     1               add         subtract     multiply
     2              divide          mod         not
     3              greater       pointer     switch
     4             duplicate       roll      in(number)
     5             in(char)     out(number)  out(char)

Mustat väripalikat ja kuvan reunat rajoittavat ohjelman kulkua. Jos lukupää yrittää siirtyä ulos ohjelmasta tai mustalle alueelle, se pysähtyy ja säätää CC:tä (jos CC on left, niin CC saa arvon right ja toisinpäin). Jos lukupää kohtaa uuden esteen, se vaihtaa DP:n arvoa järjestyksessä seuraavaan (right -> down -> left -> up -> right), CC:n arvo pysyy samana. Jos lukupää ei pääse jatkamaan, CC:tä muutetaan taas. Näin tapahtuu, kunnes CC:tä on muutettu kahdeksan kertaa. Tämän jälkeen ohjelman suoritus loppuu.

Siirryttäessä valkoiselle palikalle tai valkoiselta palikalta pois, komentoja ei suoriteta. Kun lukupää saapuu valkoiselle värialueelle, se jatkaa suoraa viivaa DP:n osoittamaan suuntaan. Jos vastassa on musta alue tai reuna, CC:tä muutetaan, mutta koska CC:n muuttaminen ei vaikuta mihinkään, DP muuttuu välittömästi.

Esimerkki: tekstin tulostus

Alla oleva kuva tulostaa tekstin "Hello world!". Koodelin kokona yksi pikseli.

Trace route eli mistä kääntäjä kulkee.

Esimerkki: Fibonaccin luvut

Seuraava esimerkki tulostaa Fibonaccin luvut väliltä 1-100.

Trace route

Esimerkki: alkulukujen tutkija

Tässä esimerkissä tarkastellaan käyttäjän antamaa syötettä. Käyttäjä syöttää luvun ja ohjelma kertoo, onko se alkuluku vai ei.

Trace route

Hauska tietää

Pietin nimen piti alun perin olla "Mondrian", mutta nimi oli jo varattu Utrechtin yliopistossa kehitetylle Haskellia ja Javaa yhdistävälle skriptikielelle.

Linkit

Tietoa sivustosta