Tävlingsprogrammering/Uppgifter/Leet speak

Från Wikibooks


Leet speak

Pappa Thomas har tröttnat. Sonen Pim gör inget annat än att sitta framför datorn och spela skjutspel. Han spelar så mycket skjutspel att han inte bryr sig om att prata med sin pappa längre. Pappa Thomas har bestämt sig för att försöka ta kontakt med Pim genom att logga in på det där internet och ta reda på vad sonen egentligen sysslar med. För att det inte ska verka misstänkt så vill han prata samma språk som Pims cyberkompisar gör. Han har förstått att språket kallas leet speak, men han behärskar det inte själv. Thomas tog först kontakt med ett konsultbolag och bad dem skriva ett program som översatte meningar från vanligt språk till leet speak. Konsultbolaget ansåg dock att problemet var för svårt.

Därför tar nu Thomas det här till nästa nivå, och vänder sig till de tävlade i Programmeringsolympiaden. Kan du hjälpa honom att skriva ett program som översätter meningar från vanligt språk till leet speak? Leet speak är ett substitutionschiffer där varje bokstav i det vanliga alfabetet byts ut mot ett tecken i leet speak-alfabetet. Till din hjälp har du alfabetet för respektive språk:

vanligt: abcdefghijklmnopqrstuvwxyz
leet speak: 48()3}6#!]X|MN09Q2Z7MVWXJZ


Programmet ska läsa in en mening: en rad med tecken som kan vara a-z (stora eller små bokstäver), blanksteg eller punkt. Raden avslutas alltid med en punkt, och det finns inga andra punkter i raden. Blanksteg förekommer aldrig i början av meningen och aldrig mer än ett i följd. Programmet ska skriva ut meningen översatt till leet speak.

Körningsexempel 1

Vanligt ? lEet speAK.
Översatt: |337 Z934X.

Körningsexempel 2

Vanligt ? The quick brown fox jumps over a lazy dog.
Översatt: 7#3 QM!(X 820WN }0X ]MM9Z 0V32 4 |4ZJ )06.

Lösning[redigera]

Detta är ett typexempel på en implementationsuppgift, det krävs inga insikter för att lösa problemet, utan det är bara att göra som det står i problemspecifikationen. Det viktigaste är att fundera ut på vilket sätt man ska lägga upp programmet på så att koden inte blir allt för lång. Att ha 26 stycken if-satser är förstås ett möjligt tillvägagångssätt, men det är onödig. Här följer ett exempel på en ganska kort lösning i C++:

Lösning i C++:

#include <string>
#include <iostream>
using namespace std;

string leet = "48()3}6#!]X|MN09Q2Z7MVWXJZ";

char translate(char in) {
    if (in >= 'A' && in <= 'Z') in -= 'A' - 'a'; // se till att alla bokstaver ar sma
    if (in == '.' || in == ' ') return in;
    return leet[in - 'a'];
}

int main() {
    string input;
    getline(cin, input); // las in hela raden
    for (int i = 0; i < input.length(); ++i) {
        cout << translate(input[i]); // ga igenom tecken for tecken och omvandla
    }
    cout << endl;
}

Lösning i Python 2.7:

#coding: utf-8
from string import maketrans
print "Översatt: " + raw_input("Vanligt ? ").lower().translate(maketrans("abcdefghijklmnopqrstuvwxyz", "48()3}6#!]X|MN09Q2Z7MVWXJZ"))

Enkel lösning i C (av Anton Fors Hurdén):

#include <stdio.h>
int main(){char c=0;while(c!=10)putchar((c=getchar())>64?"48()3}6#!]X|MN09Q2Z7MVWXJZ"[c-(c>96?97:65)]:c);}

Och om man inte bryr sig om att kanske få en varning eller två från kompilatorn (varför skulle man?):

c;main(){while(c!=10)putchar((c=getchar())>64?"48()3}6#!]X|MN09Q2Z7MVWXJZ"[c-(c>96?97:65)]:c);}

Sedan så kan man alltid dra ner på lösningens storlek lite mer om man slår på den med en golfklubba:

main(c){while(c-10)putchar((c=getchar())>64?"48()3}6#!]X|MN09Q2Z7MVWXJZ"[(c|32)-97]:c);}

Sådär. Där har vi alltså en lösning i C som kräver minimalt med arbete från programmerarens sida.