| Bytes | Lang | Time | Link |
|---|---|---|---|
| 038 | Charcoal | 250228T010020Z | Neil |
| 026 | x8664 machine code | 250227T185140Z | m90 |
| 047 | JavaScript Node.js | 250227T025340Z | l4m2 |
| 031 | Uiua 0.15.0dev.2 | 250227T032902Z | Tbw |
Charcoal, 38 bytes
℅⁺℅θײ⁸I§⪪”{⊞¶∨A⧴⧴C~p№↙✳⊖@“;”²÷⁺⁶⁸℅θ²⁸
Try it online! Link is to verbose version of code. I/O is in characters. Explanation:
θ Input character
℅ Take the ordinal
⁺ Plus
”...” Compressed look-up table of offsets
⪪ Split into substrings of length
² Literal integer `2`
§ Indexed by
θ Input character
℅ Take the ordinal
⁺ Plus
⁶⁸ Literal integer `68`
÷ Integer divided by
²⁸ Literal integer `28`
I Cast to integer
× Multiplied by
²⁸ Literal integer `28`
℅ Convert to character
Implicitly print
(You can change the I/O format to ordinals by replacing all of the ℅s with Is.)
x86-64 machine code, 26 bytes
8D 97 54 54 FF FF 6A AC 58 01 C2 78 0A 04 E4 7B F5 01 C2 79 F4 F7 D8 01 F8 C3
Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes a 32-bit integer in EDI and returns a 32-bit integer in EAX.
The offsets needed to the vowel indices are [4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, 5, -5, -5, -5, -5, -5, ?, ?, ?]. The ?s are don't-care values, which will be set to -3 to fit the pattern of n repeats of n and -n. When working on the combined character code, the pattern is scaled up by a factor of 28.
In assembly:
f: lea edx, [rdi - 43948] # Set EDX to the character code minus 43948.
# With this offset, the Hangul characters start at 28*3.
r3: push -84; pop rax # Set EAX to -84 = -28 * 3.
r: add edx, eax # Add EAX to EDX.
js e # Jump if the result is negative (offset in EAX).
add al, -28 # Decrease EAX by 28, using its low byte for shortness.
jpo r3 # Jump back if the sum of the low 8 bits is odd
# (which occurs at -28 * 6) to reset EAX.
add edx, eax # Add EAX to EDX.
jns r # Jump if the result is not negative.
neg eax # Negate EAX (to reverse the offset).
e: add eax, edi # Add EDI (the original character code) to EAX.
ret # Return.
JavaScript (Node.js), 47 bytes
x=>x+28*((x=(x+68)/28%21)<4?4:x<8?-4:x<13?5:-5)
JavaScript (Node.js), 49 bytes by Arnauld
x=>x+((x%=588)<44|x>519?4:x<156?-4:x<296?5:-5)*28
JavaScript (Node.js), 50 bytes
x=>x+((x+68)%588<224?-4:5)*((x-44)%588<252||-1)*28
Uiua 0.15.0-dev.2, 32 31 bytes SBCS
⍜(◿21÷28+68)(⨬(+8◿10+1)◿₈⊸<4-4)
Takes a Unicode code point as input and output (the link uses under F @\0 to convert to and from code points).
-1 byte inspired by l4m2's comment
Explanation
⍜(◿21÷28+68)(⨬(+8◿10+1)◿₈⊸<4-4)
⍜( ) # do this first, then undo at the end:
◿21÷28+68 # add 68, divide by 28, mod 21
-4 # minus 4
⨬ ⊸<4 # test if less than 4
◿₈ # if so, mod 8
(+8◿10+1) # if not, add 1, mod 10, add 8