# Accentuated abjad English (ōcćnt̮ōt̖d ōbj̄d óngḷsh)

An Abjad is a writing system where each symbol stands for a consonant, and where vowels are omitted. An impure Abjad is an abjad in which there are additionals symbols for vowels, usually diacritics.

Write a program or function that, given a string of lowercase text (i.e. nothing but ASCII letters from a to z, commas and spaces), outputs a corresponding impure abjad English transcript with the following rules:

### Representation of vowels

Each vowel (i.e. a e i o u) is represented as an accent on the immediately preceding consonant. For instance, assuming the accent representing the vowel e is ́, the word wet will be transcribed as ẃt.

If a vowel is not preceded by a consonant (two or more vowels in a row, or a word starting with a vowel), the symbol o is used as a "blank consonant". For example, the word peep will be transcribed as ṕóp

### Accent placement

Consonants that have ascenders are unpleasant to read when accentuated. Therefore, for those consonants, the symmetric accent will be displayed below the symbol instead of above. For instance, the letter combination te will be written t̖ rather than ́t

Those consonants are b d f h k l t.

### Accents for vowels

We are using Unicode combining characters to display accents on every consonant possible. The combining characters used can be found here. Combining accents are placed directly after the symbol they are to be put on.

The accents are presented on arbitrary consonants in this list.

• a

Above accent: U+0x0304, example: c̄

Below accent: U+0x0320, example: d̠

• e

Above accent: U+0x0301, example: ć

Below accent: U+0x0316, example: d̖

• i

Above accent: U+0x0307, example: ċ

Below accent: U+0x0323, example: ḍ

• o

Above accent: U+0x030c, example: č

Below accent: U+0x032d, example: ḓ

• u

Above accent: U+0x0311, example: c̑

Below accent: U+0x032e, example: d̮

Here is the list of all possible characters:

b̠ b̖ ḅ b̭ b̮
c̄ ć ċ č c̑
d̠ d̖ ḍ ḓ d̮
f̠ f̖ f̣ f̭ f̮
ḡ ǵ ġ ǧ g̑
h̠ h̖ ḥ h̭ ḫ
j̄ j́ j̇ ǰ j̑
k̠ k̖ ḳ k̭ k̮
l̠ l̖ ḷ ḽ l̮
m̄ ḿ ṁ m̌ m̑
n̄ ń ṅ ň n̑
p̄ ṕ ṗ p̌ p̑
q̄ q́ q̇ q̌ q̑
r̄ ŕ ṙ ř ȓ
s̄ ś ṡ š s̑
t̠ t̖ ṭ ṱ t̮
v̄ v́ v̇ v̌ v̑
w̄ ẃ ẇ w̌ w̑
x̄ x́ ẋ x̌ x̑
ȳ ý ẏ y̌ y̑
z̄ ź ż ž z̑
ō ó ȯ ǒ ȏ


### Test cases

• Input: programming puzzles and code golf

Output: přgr̄mṁng p̑zzl̖s ōnd čd̖ ǧlf

• Input: the quick brown fox jumps over the lazy dog

Output: th̖ q̑ȯck břwn f̭x j̑mps ǒv́r th̖ l̠zy ḓg

• Input: beautiful

Outpu: b̖ōȏṭf̮l

• Input: one ring to rule them all, one ring to find them, one ring to bring them all and in the darkness bind them

Output: ǒń ṙng ṱ ȓl̖ th̖m ōll, ǒń ṙng ṱ f̣nd th̖m, ǒń ṙng ṱ bṙng th̖m ōll ōnd ȯn th̖ d̠rkńss ḅnd th̖m

### Scoring

This is , so the shortest program or function in bytes wins.

• And suddenly reminded of why I chose not to try to learn Arabic. – Alex A. Jul 16 '15 at 15:27
• I think the hard part is using the Unicode.. – DeadChex Jul 16 '15 at 20:57
• Just to make it clear, you simply want a letter-to-accent-sign conversion, ignoring the actual pronunciation of the English words? – Paŭlo Ebermann Sep 13 '15 at 12:56
• @PaŭloEbermann Yes. There are no real consistent rules to english pronunciation anyway. – Fatalize Sep 13 '15 at 12:59
• @Fatalize: It can be understood through tough thorough thought, though. – Per Alexandersson Jan 13 '17 at 0:32

# CJam, 63 62 bytes

Qq{_"aeiou"#:I){;___eu='o*\"bdfhklt"&"F<IST""*'-27"?I=730+}&}/


Try it online in the CJam interpreter.

### How it works

Qq             e# Push an empty string and read from STDIN.
{              e# For each character in the input:
e#   Push a copy of the character.
:I)          e#   Save in I and add 1.
{            e#   If I + 1 != 0:
___        e#     Copy the previous character (or the empty array) three times.
eu=        e#     Convert the last copy to uppercase and check for equality.
e#     This pushes 1 for non-letters and 0 for letters.
'o*        e#     Push a string of that many o's.
\          e#     Swap the last copy with the string of o's.
"bdfhklt"& e#     Intersect with that string.
"F<IST"    e#     Push that string.
"*'-27"    e#     Push that string.
?          e#     Select the first iff the intersection is non-empty.
I=         e#     Retrieve the character at index I.
730+       e#     Add 730 to its code point.
}&           e#
}/             e#

• A full 206 bytes shorter than my solution. Nice. :) – Alex A. Jul 17 '15 at 20:09

# GNU sed, 16815813410598 85 byt̖s

ǒr 75 ch̠rs (b̭th ȯncl̮ḍng +1 f̭r th̖ -r fl̠g).

s/([bdfhklt])([aeiou])/\1\u\2/g;y/aeiouAEIOU/̠̖̣̭̮̄́̇̌̑/;s/\B[^ ,a-z]/o&/g


### óxpl̠n̄ṭǒn

Wó s̄v́ ō ḅt ȏṡng th̖ čnstr̄ȯnt th̠t ȯnp̑t ȯs ōll ḽẃr-c̄ś. Wó ȏpc̄ś ōny v̌ẃl f̭lḽẇng ō čnšn̄nt, b̖f̭ŕ čnv́rṭng ōll v̌ẃls ṱ ōcćnts.

#!/bin/sed -rf

s/([bdfhklt])([aeiou])/\1\u\2/g  # upcase vowel following ascender
y/aeiouAEIOU/̠̖̣̭̮̄́̇̌̑/
s/\B[^ ,a-z]/o&/g                # precede with 'o' if needed


Th̖ ǒdd-ḽǒḳng ch̠r̄ct̖rs ōŕ // čnt̠ȯṅng ōll t̖n ōcćnts (/̠̖̣̭̮̄́̇̌̑/). óxp̄nd̖d ǒȏt ẇth sp̄ćs, th̖y w̌ȏld ḽǒk ḷk̖ / ̄ ́ ̇ ̌ ̑ ̠ ̖ ̣ ̭ ̮ /.

### ǒȏtp̑t

přgr̄mṁng p̑zzl̖s ōnd čd̖ ǧlf
th̖ q̑ȯck břwn f̭x j̑mps ǒv́r th̖ l̠zy ḓg
b̖ōȏṭf̮l
ǒń ṙng ṱ ȓl̖ th̖m ōll, ǒń ṙng ṱ f̣nd th̖m, ǒń ṙng ṱ bṙng th̖m ōll ōnd ȯn th̖ d̠rkńss ḅnd th̖m

• 1. The output of the first test case is wrong. Looping is not the same as appending g to each s since the last five commands may replace digits after underscores. If you loop only over the first five and use y for the rest, you shorten and correct the code at the same time. 2. You can save more bytes by doing s/([ ,aeiou])([aeiou])/\1~\2/g at the beginning and replacing ~ with o in the transliteration. – Dennis Jul 18 '15 at 3:15
• Thanks for your observation (1) - fix pending. I didn't think that y would work with multi-byte characters, but I've now tried it and it does - I should have tested to begin with. Your suggestion (2) fails with the last example which would need (^|[ ,aeiou]) instead of ([ ,aeiou]) - I tried something like that and lost (actually it was (^|[ ,1-5]) after the first y). – Toby Speight Jul 21 '15 at 7:54
• I've now updated - and now I know that y works by character rather than by byte, I replace with accents immediately. Thanks @Dennis for prompting my improvements. I now remember why inserting o with a single step didn't work (e.g. suggestion to use s/([ ,aeiou])([aeiou])/\1~\2/g) - this only makes one replacement when there's two consecutive vowels, leading to b̖ō̑ṭf̮l for testcase 3. So I've stuck with inserting too many o and removing the unnecessary ones afterward. – Toby Speight Jul 21 '15 at 8:14
• 1. I cannot copy and paste your golfed code. A lot of characters are missing. Copying the ungolfed code works just fine, but I count only 104 bytes. Not sure if I'm still missing one. 2. [^ ,a-z] is shorter and should work fine in the last substitution. – Dennis Jul 21 '15 at 14:42
• @Dennis - 1. I printed the reduced code to xterm and then pasted that; perhaps xterm converted to precomposed or something? I'll try doing it directly within emacs. And did you count 1 for -r? 2. I still don't see how [^ ,a-z] will create the initial o in the last testcase. Edit: I see what you mean - shorter than the ten accents in the second group. Even better, [^ -~] will work, to save a further 2. – Toby Speight Jul 21 '15 at 15:34

# Julia, 269 bytes

This is really long and can probably be golfed further, but I'm just psyched that I was able to come up with a working solution at all!

s->(u=700+[72,69,75,80,85];l=800+[0,-10,3,13,14];R=replace;r(m)=(i=findin("aeiou",m[2])[1];j=m[1]∈"bdfhklt"?l[i]:u[i];string(m[1],char(j)));t(m)=string("o",char(u[findin("aeiou",m)[1]]));R(R(R(s,r"(?![eiou])[b-z][aeiou]",r),r"(?<=^| )[aeiou]",t),r"(?<=\S)[aeiou]",r))


This creates an unnamed function that accepts a string and returns a string.

Ungolfed + explanation:

function f(s)
# Construct arrays of integers representing the unicode accents
# u is for the upper accents and l is for the lower
u = 700 + [72,69,75,80,85]
l = 800 + [0,-10,3,13,14]

# Define a function to accent consonants followed by vowels
r(m) = begin
# m is the consonant-vowel pair from the regex match
i = findin("aeiou", m[2])[1]
j = m[1] ∈ "bdfhklt" ? l[i] : u[i]
string(m[1], char(j))
end

# Define a function to accent vowels
t(m) = string("o", char(u[findin("aeiou", m)[1]]))

# Accent consonants
rep1 = replace(s, r"(?![eiou])[b-z][aeiou]", r)

# Accent vowels at the start of a string or before a space
rep2 = replace(rep1, r"(?<=^| )[aeiou]", t)

# Accent remaining unaccented vowels
rep3 = replace(rep2, r"(?<=\S)[aeiou]", t)

# Return
rep3
end


Examples:

julia> println(f("beautiful"))
b̖ōȏṭf̮l

julia> println(f("programming puzzles and code golf"))
přgr̄mṁng p̑zzl̖s ōnd čd̖ ǧlf


Note that if you look at the raw text in the post, the "t" in the first example is accented correctly but for some reason it doesn't display that way in the rendered markdown, at least for me.

• As long as it displays correctly in your examples for me (and it does), it's good – Fatalize Jul 17 '15 at 18:44
• @Fatalize Oh I'm glad it displays correctly for you. I wonder why it doesn't for me. Regardless, nice challenge, glad I could participate! – Alex A. Jul 17 '15 at 18:45

# Ŕṭn̄ 0.8.2, 71 byt̖s

Taei\oū́̇̌̑
T̠̖̣̭̮̄́̇̌̑[bdfhklt]*.
+([^a-z])([̠̖̣̭̮̄́̇̌̑])
$1o$2


Try ȯt ǒnḷń!

### Óxpl̠n̄ṭǒn

Taei\oū́̇̌̑          ŕpl̠ćs th̖ ch̠r̄ct̖rs aeiou ẇth th̖ črŕsp̌nṡng ḍōcṙṭcs ōb̭v́.
T̠̖̣̭̮̄́̇̌̑[bdfhklt]+.    ŕpl̠ćs th̖ ḍōcṙṭcs ōb̭v́ ẇth ḍōcṙṭcs b̖ḽw ȯf pŕćd̖d by ǒń ǒr śv́r̄l ch̠r̄ct̖rs ẇth ōsćnd̖rs.
+([^a-z])([̠̖̣̭̮̄́̇̌̑])     ȏnṭl th̖ ȯnp̑t sṱps ch̠nġng, ŕpl̠ć óv́ry ḍōcṙṭc ňt pŕćd̖d by ō l̖tt̖r...
$1o$2              ...ẇth th̖ s̄ḿ ch̠r̄ct̖rs b̮t ẇth ōn o b̖tẃón th̖m.