R-ohjelmointi.org

Tilastotieteellistä ohjelmointia R-kielellä

Brainfuck-ohjelmointia R:llä

Ostin kesälomalukemiseksi Jussi Pekka Kasurisen Outoa ohjelmointia -kirjan. Kirja esittelee esoteerisiä ohjelmointikieliä. Esoteeristen kielten on usein tarkoitus hauskuuttaa tai olla mahdollisimman erilaisia kuin muut, tavallisemmin käytetyt ohjelmointikielet. Eräs tunnetuimmista esoteerisistä ohjelmointikielistä lienee Brainfuck. Kirjasta riitti hupia yhdeksi illaksi, mutta ajattelin harrastuksen vuoksi ohjelmoida R:llä brainfuck-tulkin, koska kieli on todella yksinkertainen. Richard Cotton tosin ehti ensin, joten en jaksakaan nähdä vaivaa. Cottonin R-kielellä toteutettu Brainfuck-tulkki löytyy Bitbucketista. Toteutuksen käyttö on dokumentoitu mm. Cottonin blogissa.

Alkuperäisessä toteutuksessa on 30000 muistipaikkaa, joista kuhunkin voi tallentaa luvun väliltä 0-255 (tai 0-127). Kukin luku vastaa yhtä ASCII-merkkiä. Kun tulkki käynnistetään, alustetaan kaikkiin muistipaikkoihin lukuarvo 0 ja oletusmuistipaikaksi valitaan 0. muistipaikka. Cottonin toteutus noudattelee tätä toteutusta.

Brainfuckin komennot ovat lyhyesti kuvattuna seuraavat:

< ja > siirry muistipaikasta toiseen
+ ja - lisää tai vähennä muistipaikan arvoa yhdellä
[ ja ] silmukkarakenne
. ja , tulosta stdout:iin tai lue stdin

Esimerkiksi muistipaikkaan yksi voitaisiin siis sijoittaa numero kolme seuraavasti:

>        # siirrytään yksi muistipaikka oikealle 
+++      # ja lisätään sen arvoa kolmella

Näillä kahdeksalla komennolla on mahdollista toteuttaa hyvinkin monimutkaisia laskutoimituksia, kunhan vain ensin keksii miten. Useita Brainfuck-algoritmeja on koottu esimerkiksi esolangs-blogiin.

R:ssä Brainfuck-tulkin käyttö onnistuu seuraavasti. Asennetaan ensin paketti Bitbucketista ja ladataan se muistiin. Tämän jälkeen alustetaan tulkki komennolla fuckbrain(). Tulkille annetaan merkkijonona Brainfuck-kielinen koodi, jolla tässä tapauksessa sijoitetaan merkkijonoa ”Jarno” (”Hello world!” oli turhan pitkä) vastaavat ASCII-merkkien numerot viiteen eri muistipaikkaa, joista ne lopuksi tulostetaan ruudulle. Lopuksi Brainfuck-koodi välitetään tulkille.

devtools::install_bitbucket("richierocks/brainfuck")
library(brainfuck)
 
bfi <- fuckbrain()
 
tmp<-"
++[>+++++++++++++++++++++++++++++++++++++<-]><       # J
++++[>>++++++++++++++++++++++++<<-]>>+<<             # a
++++++[>>>+++++++++++++++++++<<<-]>>><<<             # r
+++++[>>>>++++++++++++++++++++++<<<<-]>>>><<<<       # n
+++++[>>>>>++++++++++++++++++++++<<<<<-]>>>>>+<<<<<  # o
>.>.>.>.>.
"
 
bfi$interpret(tmp)

Minusta Brainfuckiin kannattaa tutustua! Se tuntuu nimittäin rassaavan vähän eri hermoratoja kuin tavanomaisten ohjelmointikielten käyttö. Esimerkiksi laskutoimitusten tapauksessa pitää muistipaikkojen numeroihin (0-9) lisätä 48, jotta ne näkyvät numeroina myös näytöllä. Näin toteutettuna esimerkiksi kahden yksinumeroisen luvun tulo on melko helppo toteuttaa, mutta toisaalta saman voisi tehdä myös binäärilukuja käyttäen. Tiedä sitten kumpi on helpompi käytännössä, mutta täytyypä kokeilla.

Tags: