Tässä koodihaastekatsauksen jälkimmäisessä osassa (katso 1. osa tästä!) perehdymme pintapuolisesti erilaisiin ratkaisutyyppeihin, joilla haasteen vastaajat olivat purkaneet salakirjotusta. Lopuksi kerromme mietteitämme, mitä opimme tämän haasteen tekemisestä, ja mitä voisimme pitää mielessä seuraavaa haastetta suunnitellessa.

Yleisimmät ratkaisutavat
Sanakirja
Yleisin ratkaisutapa vastausten joukossa oli kääntää jokainen lause jokaisella mahdollisella avaimella, eli aakkoston pituudella, ja katsoa millä avaimella lauseesta löytyy eniten sanoja sanakirjasta. Sen lisäksi pitää olla vielä jokin pisteraja, millä yritetään päätellä, onko eniten pisteitä saanut ratkaisu siltikään suomea. Yleisin käytetty sanakirja oli Kotuksen 94 110 sanatietuetta sisältävä XML-tiedosto. Kyseinen sanakirja sisältää perusmuodossa olevia sanoja, mikä hankaloittaa vertailua. Monella olikin ratkaisussa mukana muitakin tapoja pisteyttää lauseet tai sitten yrityksiä muuttaa lauseiden sanat perusmuotoon. Tällainen tekstin muuttaminen tuo helposti huteja mukanaan. Kun sanoista karsitaan päätteitä, voi jäljelle jäädä suomenkielisiä sanoja, jotka eivät kuitenkaan sovi mitenkään lauseyhteyteen.

N-grammit
N-grammi viittaa koodihaasteen kontekstissa yksinkertaistettuna n-mittaisiin tekstissä esiintyviin merkkijonoihin, jotka ovat osittain päällekkäisiä. Esimerkiksi sanan ”ilma” digrammit (2-grammi) ovat “il”, “lm” ja “ma”. Mutta mitä hyötyä tästä on kielentunnistuksessa?
Yksinkertaisimmassa esimerkissä sanakirjasta voitaisiin kerätä kaikki 3-grammit, ja tieto siitä, montako kertaa ne esiintyvät aineistossa. Jos aineisto on tarpeeksi laaja, voidaan esiintymistiheydestä päätellä eri 3-grammien todennäköisyys suomenkielisessä tekstissä esiintymiselle. Kerätyllä datalla voidaan arvioida aineistoon kuulumattomien lauseiden järkevyyttä; esimerkiksi sana, jossa esiintyy merkkijono “kas” voi olla suomea, kun taas merkkijonon “xcj” sisältävä sana todennäköisesti ei ole.
N-grammiratkaisut toimivat luotettavimmin pidemmillä lauseilla, mutta toteutustavasta riippuen heikkoudeksi voi osoittautua teksti, joka sisältää suomenkielisiä tavuja tai jopa kokonaisia sanoja, mutta on silti ihmislukijalle siansaksaa, kuten esimerkiksi seuraava lause: ”Ovellei oilkuu mantistei ehroiten lilakka itomman pisto sittenpien lommamaikiin allan alitin kevioideka.”
Tavulista
Massiivisten sanalistojen tavoin netistä löytyy myös kattavia listoja yleisistä suomen kielen tavuista, joita voi hyödyntää kielentunnistuksessa. Tämä lähestymistapa on hyvin lähellä n-grammiratkaisua, ja toteutuksesta riippuen voidaankin lukea siihen kuuluvaksi, sillä n-grammi voi olla merkin lisäksi muukin kielen yksikkö, kuten sana tai tavu. Pelkästään tavujen määrän ja lauseen pituuden suhteen mukaan pisteytys karsii pois ilmiselvän roskan, mutta kaatuu helposti suomea muistuttavaan siansaksaan. Tulosta voi parantaa esimerkiksi keräämällä korpuksesta dataa eri tavujen peräkkäisyyden todennäköisyydestä, jolloin pelkkä epämääräinen ketju tavuja ei enää saa korkeaa pisteytystä algoritmissa.
Yleisin kirjain
Tätä tyyliä ei vastauksissa ollut käytetty, eikä se täysin toimisikaan tässä tapauksessa, kun jokainen lause on salattu satunnaisella avaimella. Jos jokainen lause olisi salattu käyttäen samaa avainta, voisimme tarkastaa kaikkien lauseiden joukosta yleisimmän kirjaimen ja päätellä sen olevan A-kirjain, joka on suomen kielen yleisin kirjain. Sen jälkeen saisimme avaimen selville laskemalla, montako askelta kyseisestä kirjaimesta on aakkostossa A-kirjaimeen. Tätä lähestymistapaa vaikeuttaa tässä tapauksessa tosin vielä se, että siansaksalauseita on kolminkertainen määrä kääntyviin lauseisiin nähden. Tämä voi sotkea sen, että joku muu kuin A-kirjain olisikin yleisin.
Mitä opimme
Aikaisemmin pyörittämämme koodihaasteet ovat olleet laajuudeltaan pienempiä ja rajatumpia niin teknologioiden kuin vastausten suhteen. Tämän vuoden haasteemme oli laajuudeltaan ihan uudella tasolla, jonka myötä opimme myös paljon.
Kuten aiemmassa blogissa jo mainitsimme, haasteeseen ei ollut yhtä ja/tai oikeaa vastausta. Tällä on sekä plussat että miinuksensa. Täysin vapaa tyyli vastauksen suhteen antaa haasteen tekijän luovuudelle rajoittamattomat mahdollisuudet. Tällainen ei välttämättä olisi mahdollista tarkkaan määritellyssä tehtävänannossa, jossa etsitään tietynlaista ratkaisua. Toisaalta taas tämä tekee vastausten arvioinnista huomattavasti hankalampaa. Tämän kaltaisia haasteita tehdessä on syytä pohtia etukäteen, kuinka paljon resursseja on käytettävissä sekä haasteen suunnitteluun että vastausten läpikäyntiin. Haasteen julkaisusta kuukausi eteenpäin voi muiden projektien aikataulut tiukentua, kun pitäisikin alkaa käymään vastauksia läpi. Entä jos vastauksia olisi tullut tuplasti tai triplasti enemmän kuin nyt tuli? Tällä kertaa menimme tietoisella riskillä, mikä kannatti, sillä haasteesta tuli kokonaisuudessaan onnistunut.
Vastausten tarkistamiseen liittyen opimme myös sen, että jatkossa on hyvä pyytää tekijää kirjoittamaan ohjeet sovelluksen pystyttämiseen ja käynnistämiseen. Jotkin vastaukset vaativat useampien ohjelmien asentamista, mitkä piti itse selvittää. Ongelmia tuli myös vastausten kanssa, jossa oli ohjeet käynnistämiseen, mutta tekijällä ja tarkastajalla oli eri versiot vaadittavista ohjelmista. Live demot osoittautuivat hyvin käytännöllisiksi. Joidenkin sovellusten paikallisesti käyntiin saaminen vaati turhan paljon aikaa kaikenlaiseen selvittelyyn ja säätämiseen, ja sitten sama juttu virtuaalikoneen Ubuntulla kun on ensin Windowsissa epäonnistuttu. Jos sovelluksesta on live demo, ei ratkaisun tarkastajan tarvitse välttämättä edes käynnistää sovellusta itse paikallisesti.
Vastauksen tarkastajaa voisi myös helpottaa, jos vastaaja itse lyhykäisesti kuvaisi, mitä sovellus tekee ja miten. Koodin kommentointi helpottaa myös hahmottamaan paremmin, mitä minkäkin funktion on tarkoitus tehdä. Näiden hyödyllisyys korostuu erityisesti, kun kyseessä on teknologia, joka ei ole tarkastajalle välttämättä kovinkaan tuttu.
Jälkifiilikset
Kaiken kaikkiaan vaikuttaisi siltä, että koodihaaste jätti positiivisen mielikuvan niin toteuttajille ja ratkaisijoille, kuin myös muillekin, niin firman sisä- kuin ulkopuolellakin. Haasteen suunnittelu oli varsin mielekäs haaste itsessään jo meille toteuttajille. Sen lisäksi nautimme myös suuresti Ubuntun työpöytää ja terminaalia muistuttavan koodihaasteen nettisivun toteuttamisesta, jonne oli piilotettu myös easter eggejä, kuten nsfw-kansiosta löytyvä virus.exe. Olemme saaneet hyvää palautetta sen puolesta, että meidän tulisi jatkossakin julkaista koodihaasteita. Ja niin myös aiommekin. Seuraa meitä sosiaalisissa medioissa, niin saat tietoa, kun seuraava haaste on eetterissä!
Löydät meidät someista @Solidabis:
Tässä vielä muutama esimerkki palautteista, joita saimme vastaajilta:
”Kiitoksia hienosta haasteesta. Sopivan kevyt mutta samalla parhaan ratkaisun hiomiseen saisi kulutettua vaikka kuinka paljon aikaa!”
”Kiitos hauskasta pähkinästä.”
”Perkeleen koodihaaste! Näin sen typerän sponsoroidun postauksen Facebookissa enkä voinut vastustaa kiusausta. Tehtävänanto oli kyllä hauska, myönnettäköön.”
Tutustu tästä lisää Solidabikseen ja katso avoimet työpaikkamme!
Saattaisit olla kiinnostunut myös näistä:
- Kevään reittiopas-teemainen koodihaaste on ratkaistu – tutustu voittajaratkaisuun! – kevään 2020 koodihaasteen läpikäyntiä
- Full-stack devaaja Vellu voitti koodihaasteen – tutustu Velluun, joka koodihaasteen voitettuaan aloitti työt Solidabiksella
- Koodihaastekatsaus, osa 1: Voittajat ja yleiskatsaus – syksyn 2019 koodihaastepostauksen ensimmäinen osa