# Organize a Kiowa library

We are probably all used to the English alphabetical order:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


When we compare words in English for the sake of alphabetization we first compare the first letter, whichever word has the later first letter comes later. If they are the same we check the second letter and so on until we reach two letters that are different or one of the words runs out of letters to check in which case the word that ran out of letters comes first.

However in the Kiowa language, things work a little differently. The letters are ordered based on phonetic principles so the order is completely different:

A AU E I O U B F P V D J T TH G C K Q CH X S Z L Y W H M N


You will notice also that certain digraphs such as TH are considered single letters.

We can use the same process for alphabetization with the Kiowa alphabetical order to get very different results.

We start by comparing the first letter, noticing that the digraphs AU, TH and CH each count as a single letter. So if we are comparing AN and AUN, AN comes first because A comes before AU, even though N comes after U.

If the first letters are the same we move onto the second letter repeating the process and so on until we reach two letters that are different or one of the words runs out of letters to check in which case the word that ran out of letters comes first.

You will take two non-empty strings as input and output the string which comes first in terms of the alphabetization described above.

You may alternatively choose to always output the string which comes last or both strings in either ascending or descending order as long as you do so consistently.

The input strings will only consist of a sequence of letters from the Kiowa alphabet as described above in upper case.

This is so the goal is to minimize the size of your source code as measured in bytes.

## Test cases

Here we output the string which comes earlier.

A N -> A
N A -> A
EEED EEEE -> EEEE
EVEV EVEV -> EVEV
AN AUN -> AN
CH CN -> CN
CH CA -> CA
CH KH -> KH
CH XA -> CH


Some simplifications are made here to serve the purpose of this challenge. Natural languages are wonderfully complex things and you should not take anything here as fact. However if you are interested I encourage you to learn more as the details can be quite interesting.

# R, 9996 95 bytes

\(a)a[order(chartr("AEIOUBFPVDJTtGCKQcXSZLYWHMN","1A-Z",gsub("(A)U|(T|C)H","\\L\\1\\2",a,,T)))]

Attempt This Online!

Outputs the sorted strings.

Explanation outline:

• substitutes digraphs with their first letter converted to lowercase (with some PERL regex magic)
• translates Kiowa's order to A-Z with 1 prepended (we omit the a as it's in the right place and notice that there's no R in Kiowa language so we need only two additional characters: 1 and a)
• orders with the built-in string method (digits first).

# 05AB1E, 42 bytes

Σžn29£S•3ž¶ÆNιÐßóθ£÷•.Is.•1ƶ<ð•u2ôžRlS:Sk


I/O as a pair of string, where the output is correctly ordered.

Explanation:

Σ                   # Sort the (implicit) input-pair by:
žn                 #  Push "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
29£              #  Only leave the first 29: "ABC...XYZabc"
S             #  Convert it to a list of characters
•3ž¶ÆNιÐßóθ£÷•
#  Push compressed integer 273531916594452580416824730457
.I          #  Get the 273...457'th permutation of the earlier string:
#   (as list) "AaEIOUBFPVDJTbGCKQcXSZLYWHMNR"
s                  #  Swap so the current string is at the top
.•1ƶ<ð•           #  Push compressed string "authch"
u          #  Converted to uppercase: "AUTHCH"
2ô        #  Split into parts of size 2: ["AU","TH","CH"]
žR      #  Push builtin "ABC"
lS    #  Converted to lowercase list: ["a","b","c"]
:   #  Replace the ["AU","TH","CH"] to ["a","b","c"]
S  #  Then split the string to characters
k #  And get the index of each in the earlier alphabet
# (after which the sorted pair is output implicitly)


See this 05AB1E tip of mine (sections How to compress strings not part of the dictionary? and How to compress large integers?) to understand why •3ž¶ÆNιÐßóθ£÷• is 273531916594452580416824730456 and .•1ƶ<ð• is "authch".

The 273531916594452580416824730456 is generated (as 1-based index instead of 0-based) with the Jelly builtin Œ¿.

# Perl 5, 81 bytes

s/(A)U|(T|C)H/$1$2_/g;s/C_/Q_/g;y/EIOUBFPVDJTGCKQXSZLYWHMN/B-Z/;/ /;$_=$F[$gt$']


Try it online!

s/(A)U|(T|C)H/$1$2_/g;           #turn all AU, TH, CH in input into A_, T_, C_
s/C_/Q_/g;                       #turn all C_ into Q_ since CH lies right after Q
y/EIOUBFPVDJTGCKQXSZLYWHMN/B-Z/; #remap all letters into letters of correct order
#...as recognized by gt below
/ /;                             #sets $ to converted string before space #...and$' to converted string after space
$_ =$F[                         #output first or second word in input array @F
$ gt$'                       #gt is true(1) if first converted word is
]                                #...greater than(gt) the second, otherwise
#...false(0), using 0 or 1 as index in array @F


# C (gcc), 282 277 bytes

• -5 thanks to ceilingcat

Returns the lowest-sorted input. The digraphs are converted into [0..2] and the source string advanced, then the characters are compared; comparisons continue until the end of one of the strings or a mismatch.

#define a(a,b,c,d,e)a-c|*b-d||(a=e,b++),
*n="A0EIOUBFPVDJT1GCKQ2XSZLYWHMN";f(s,t,e,u,v,c,d)char*s,*t,*u,*v,c,d;{for(u=s,v=t,e=0;!e&&(c=*u++)&&(d=*v++);)a(c,u,65,85,48)a(d,v,65,85,48)a(c,u,84,72,49)a(d,v,84,72,49)a(c,u,67,72,50)a(d,v,67,72,50)e=index(n,c)-index(n,d);s=e<0?s:t;}


Try it online!

# JavaScript (ES6),  112  111 bytes

Saved 1 byte thanks to @l4m2

Expects (a)(b). Returns the string which comes earlier.

a=>b=>(g=s=>s.replace(/AU|[TC]H|./g,([a,b])=>10+"AA0EIOUBFPVDJTT0GCKQC0XSZLYWHMN".search(b?a+0:a)))(a)<g(b)?a:b


Try it online!

### How?

Using the regular expression /AU|[TC]H|./g, the helper function g replaces each Kiowa letter in a given string with a 2-digit number between 10 and 40 according to their position in the following lookup string:

AA0EIOUBFPVDJTT0GCKQC0XSZLYWHMN
^         ^         ^         ^
10        20        30        40


where the letters AU, TH and CH are first turned into A0, T0 and C0 respectively.

The final result is found with a standard lexicographic comparison between g(a) and g(b).

• 109 bytes by reversing the lookup string, which allows 0AA and 0TT to be merged into 0A and 0T, and allows 100 to be changed to 99: Try it online! Apr 1 at 13:31
• @pxeger Unfortunately, this would fail on C which is found in 0C. Apr 1 at 14:44
• Why +100, not +10?
– l4m2
Apr 1 at 20:52

# Python 2, 120 bytes

lambda*a:min(a,key=lambda s:map("@EIOUBFPVDJT?GCKQ#XSZLYWHMN".find,R(R(R(s,"AU","@"),"TH","?"),"CH","#")))
R=str.replace

Attempt This Online!

Replaces each digraph with a special character, and then uses the indices of each character in the magic string @EIOUBFPVDJT?GCKQ#XSZLYWHMN to choose the lexicographically earliest of the two strings.

⊟⌊ＥＥ²Ｓ⁺Ｅ⪫⪪⪫⪪⪫⪪ιAUＩ⁰THＩ¹CHＩ²⌕”B↗3∧=◧$×⁸}U‹⌕VψωB↑?υ”λ⟦⁰ι  Try it online! Link is to verbose version of code. Explanation:  ² Literal integer 2 Ｅ Map over implicit range Ｓ Next input string Ｅ Map over input strings ι Current string ⪪ AU Split on AU ⪫ Ｉ⁰ Joined with 0 ⪪ TH Split on TH ⪫ Ｉ¹ Joined with 1 ⪪ CH Split on CH ⪫ Ｉ² Joined with 2 Ｅ Map over characters ⌕ Find index of λ Current character ”...” In compressed lookup table ⁺ Concatenated with ⟦ List of ⁰ Zero terminator ι Current string ⌊ Take the minimum ⊟ Pop the original input string Implicitly print  # Retina 0.8.2, 70 68 bytes %^$',
TL06ga27fu3birvx48j_nc59tmsq.+,
05
1
cu
e
gu
k
O^
!\w+$ Try it online! Takes input on separate lines but link is to test suite that splits on commas for convenience. Explanation: %^$',


Duplicate each word.

TL06ga27fu3birvx48j_nc59tmsq.+,


Convert the (uppercase) letters in the first copy to an extended alphabet of digits and lowercase letters that aren't magic in Retina's Transliterate command, sorted in Kiowa order.

05
1
cu
e
gu
k


Fix up the digraphs.

O^


Sort in reverse order, so that the required word is now at the very end.

!\w+\$


Output just that word.