Greeklish, a portmanteau of the words Greek and English, is a way of writing modern Greek using only ASCII characters. This informal way of writing was extensively used in older applications / web forums that did not support Unicode, and were not programmed to show Greek characters. Nowadays, its use is minimized due to the Unicode support of modern platforms, but there are still some users who opt to write in it.

Input / Output:

Your task in this challenge, should you choose to accept it, is to take as input a lowercase, non-punctuated sentence written in Greeklish and output it in the same format in non-accented modern Greek. To do this conversion you should use the table below. Note that the digraph characters take precedence over single characters during conversion. You are free to opt any acceptable string format that works best for you (e.g., a sentence, a list of words, etc.).

Conversion table

ASCII Character(s) Greek Character
a α
b β
g γ
d δ
e ε
z ζ
h η
8 θ
i ι
k κ
l λ
m μ
n ν
ks, 3 ξ
o ο
p π
r ρ
s σ
t τ
y υ
f φ
x χ
ps, 4 ψ
w ω

Test cases

geia soy kosme                         ->  γεια σου κοσμε
epsaxna gia mia aggelia sth thleorash  ->  εψαχνα για μια αγγελια στη τηλεοραση
kati 3erei sxetika me ayto             ->  κατι ξερει σχετικα με αυτο
pswnisa ksylina spa8ia                 ->  ψωνισα ξυλινα σπαθια
ekeinh agorase 4aria kai 8ymari        ->  εκεινη αγορασε ψαρια και θυμαρι


  • \$\begingroup\$ Sandbox and Related \$\endgroup\$
    – solid.py
    Commented Jul 8, 2022 at 8:46
  • \$\begingroup\$ What happened to "th"? \$\endgroup\$
    – Adám
    Commented Jul 8, 2022 at 8:49
  • 6
    \$\begingroup\$ I will reiterate what I said in the sandbox: We already have a bunch of challenges to implement a substitution substitution cypher, and the only thing novel is the Greek theme. \$\endgroup\$
    – Wheat Wizard
    Commented Jul 8, 2022 at 8:49
  • \$\begingroup\$ @Adám The comment section was erased after a while, a user suggested its removal, and to add a precedence rule for diglyphs. Frankly, you need lexical context to catch it. (E.g. authimeron -> αυθημερον vs auth -> αυτή \$\endgroup\$
    – solid.py
    Commented Jul 8, 2022 at 8:50
  • 1
    \$\begingroup\$ @WheatWizard There is one more novelty aspect. The simultaneous replacement of a digraph and a single character. The digraph has precedence. \$\endgroup\$
    – solid.py
    Commented Jul 8, 2022 at 8:51

7 Answers 7


Python, 121 bytes

lambda s:re.sub("[kp]s|\S",lambda c:chr(1023&"abgdezh8iklmn3opr_styfx4w".find(c[0])%(824+2*ord(c[0][0]))-79),s)
import re

Attempt This Online!

This is a lot like Arnauld's approach. I did some weird math and I'm not sure if it helped.


JavaScript (ES6),  106  105 bytes


Try it online!


s =>                           // s = input string
s.replace(                     // replace in s:
  /[kp]s|\S/g,                 //   the digraph 'ks', the digraph 'ps'
                               //   or any other non-space character
  s =>                         //   with
  String.fromCharCode(         //   the character whose Unicode code point
    946 +                      //     is 946 (for 'β')
    'bgdezh8iklmn3opr_styfx4w' //     + the position of the reference
    /* ς is missing  ^ */      //     character in this lookup string
                               //     (giving -1 for 'a' which is omitted)
    .search(                   //     where said reference character is:
      s[1] ?                   //       if this is a digraph:
        s < 'p' ? 3 : 4        //         '3' for 'ks' or '4' for 'ps'
      :                        //       else:
        s                      //         s itself
    )                          //     end of search()
  )                            //   end of String.fromCharCode()
)                              // end of replace()

Retina 0.8.2, 45 bytes


Try it online! Link includes test cases. Explanation:


Translate the digraphs.


Translate the letters. The order is chosen to minimise the number of Greek letters used, going so far as to add in the dummy _ (which never matches unless quoted) so that the missing ς doesn't need to be special-cased. (Note that d, h, o and p have special meanings if they are not quoted or part of a range.)


Charcoal, 50 bytes

≔”+%⊟⊟Kκ↓⁼≧T_X4⍘«⊞⊞ ↘”θ⭆⪫⪪⪫⪪SksI³psI⁴⎇№θι℅⁺⁹⁴⁵⌕θιι

Try it online! Link is to verbose version of code. Explanation: Port of @Arnauld's JavaScript answer.

≔”+%⊟⊟Kκ↓⁼≧T_X4⍘«⊞⊞ ↘”θ

Create the lookup table abgdezh8iklmn3opr¶styfx4w from a compressed string.


Replace ks with 3 and ps with 4 in the input, then translate any characters in the lookup table to the appropriate Greek letter.

Note that although the Greek letters are in Charcoal's character set, they need to be quoted and can't be compressed which makes them too expensive to use.


Lexurgy, 127 bytes

Simple 1-1 substitution. The Symbol forces ks and ps to be treated as a single character/string.

Symbol ks,ps

05AB1E, 48 46 45 bytes


Try it online.


Although 05AB1E's codepage includes a lot of the Greek characters (αβδεaγηιλμοζ), it doesn't include all of them (missing φκνπρστωχυ), so just converting codepoint-integers to the characters for all of them is shorter than using part literal string and part conversion.

3„ks4„ps8  # Push 3, "ks", 4, "ps", 8
         ) # Wrap the stack into a list: [3,"ks",4,"ps",8]
.•ŒMb•     # Push compressed string "qcujv"
A          # Push the lowercase alphabet: "abcdefghijklmnopqrstuvwxyz"
 S         # Convert it to a list of characters
r          # Reverse these three values on the stack
 ‡         # Transliterate "q"→"3"; "c"→"ks"; "u"→"4"; "j"→"ps"; "v"→"8"
           # (note that "c"→"ks" comes before "k" and "j"→"ps" before "p" in the alphabet)
           # Push compressed integer 259947718887064480860780139517113420
  ₂в       # Convert it to base-26 as list: [1,2,14,4,5,22,3,7,9,24,10,11,12,13,15,16,14,17,19,20,24,8,25,23,21,6]
    944+   # Add 944 to each: [945,946,958,948,949,966,947,951,953,968,954,955,956,957,959,960,958,961,963,964,968,952,969,967,965,950]
        ç  # Convert these codepoint-integers to characters: ["α","β","ξ","δ","ε","φ","γ","η","ι","ψ","κ","λ","μ","ν","ο","π","ξ","ρ","σ","τ","ψ","θ","ω","χ","υ","ζ"]
:          # Replace all "a"→"α"; "b"→"β"; "ks"→"ξ"; etc. in the (implicit) input
           # (after which the result is output implicitly)

See this 05AB1E tip of mine (sections How to compress strings not part of the dictionary?; How to compress large integers?; and How to compress integer lists?) to understand why .•ŒMb• is "qcujv"; •qâ&¬k±ûï+%ΘÔβ>&• is 259947718887064480860780139517113420; and •qâ&¬k±ûï+%ΘÔβ>&•₂в is [1,2,14,4,5,22,3,7,9,24,10,11,12,13,15,16,14,17,19,20,24,8,25,23,21,6].


Vyxal, 53 bytes


Try it Online!

Transliterate doesn't work when replacing two-character strings unfortunately, so ks and ps had to be done separately. Otherwise this would be 45 bytes.

‛ks    V               # Replace all occurrences of "ks" with...
   958C                #  Character code 958, "ξ"
        ‛ps    V       # Replace all occurrences of "ps" with...
           968C        #  Character code 968, "ψ"
ka                     # Push the lowercase alphabet
  «Þİ»«                # Push compressed string "cjquv"
       »1m»            # Push compressed number 12348
           Ŀ           # Transliterate in the alphabet, c -> 1, j -> 2, q -> 3, u -> 4, v -> 8
                       # Produces "ab1defghi2klmnop3rst48wxyz" (as a list of single-character strings). Call this V
»4⁽.ṘŻ⟨«⋎D-§ƛE←₍»      # Compressed integer 255394376001292872295693368395691084
₄τ                     # Convert to base-26 as a list
  944+                 # Add 944 to each
      C                # Get the character codes of each: "αβαδεφγηιακλμνοπξρστψθωχυζ" (as a list of single-character strings). Call this X
       Ŀ               # Replace each of V with the corresponding character in X in the input

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.