# Question
Title: .-...--..---.-...--..... the red-nosed reindeer
Can you recover a sequence of letters from a sequence of dots and dashes? In Morse code, `x` is represented by `-..-`, but without the help of spaces, `-..---.-...` could represent `xmas`, or `dole`, or `teettteteee`, etc.

I took the lyrics from "Rudolph, the Red-Nosed Reindeer" to make the following sequence of letters:

```
youknowdasheranddancerandprancerandvixencometandcupidanddonnerandblitzenbutdoyourecallthemostfamousreindeerofallrudolphtherednosedreindeerhadaveryshinynoseandifyoueversawityouwouldevensayitglowsalloftheotherreindeerusedtolaughandcallhimnamestheyneverletpoorrudolphjoininanyreindeergamesthenonefoggychristmasevesantacametosayrudolphwithyournosesobrightwontyouguidemysleightonightthenhowthereindeerlovedhimastheyshoutedoutwithgleerudolphtherednosedreindeeryoullgodowninhistory

```

and then I converted each letter to its Morse code representation to get

```
-.-----..--.--.---.---...-.........-..--.-..-...--.-.-...-..--.-...--..-..--.-.-...-..--.-.....-..-..-.-.-.-.-----.-.--.-..-.-...-.--...-...--.-..-..----.-...-..--.-..-....-....---...-.-.....---..----.-----..-.-..-.-..-.-...-..-.....-----...-..-..------..-....-....-.-.....-.---..-..-.-...-...-...--..---.-...--.....-......-..-..-.---....-...-....-.-.....-......--...-...-..-.-.--.........-.-.---.---.....--.-......-.-.-----..-....-..-.....-.--..--.-----..-.-----..-.-..-......-.-.....--.--..---..-..---.--....-.-...-..---..-.-.....----......-..-....-.-.....-...-....-..----.-...-..---......--.-..-.-..-.-...-........---..---....-.....-.---.....-..-..-...-.--.------.-..-...--..---.-...--......------..-...-..--.-.--.-....-.-.....-.--..---....-.....-.----....-.-----.--.-.---.-......-......---.-.......-.....--.-.--.-..---.----....--.--.-...--..---.-...--......--..-....-.-----..-.-.-.---.......----....-...--.....-.------.--.-----..---...-..-...---.--....-.....--.....-----...--.....--.....-.....---.---......-....-.-.....-..-..---...-.-........--.-...-.....-.--.......---..--.-..---..--.--..-....--..-.....-...--..---.-...--.....-......-..-..-.---....-...-....-.-.....-.-.-----..-.-...-..--.----..---.---...-..........----.-.-.--

```

For reference, here are a few Morse code libraries:

```
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 --..

```

```
.- 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

```

```
.- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --..

```

Write the shortest code that takes as input the sequence of dots and dashes above and one of the Morse code libraries above, and then outputs the sequence of letters above.

**Edit 1:** Since we are ignoring the letter spaces and word spaces that are typically used in Morse code, this challenge is nontrivial and significantly different from previous challenges involving Morse code. We are implicitly hunting for the *relative Kolmogorov complexity* of a fixed sequence of letters given the corresponding sequence of dots and dashes. This means your code only needs to run for the fixed inputs provided above, and produce the desired output provided above.

**Edit 2:** By popular request, I am relaxing the constraint on the Morse code library by providing two alternative libraries. If necessary, I am willing to add reasonable libraries in the future.

# Answer
> 15 votes
# Python 3, ~~356, 302,~~ 299 bytes

```
import sys
S,L,N="",input().split(),int("3EED3TD7OWRVC3DD9L9NKQY0NEADDU7704EYGXWLFF2PGCR6H6ET3DRODQ4O22XAAFV5KOSWET2D2CQZOMXRQWEO7I2US8FRU5Z2CU8D73B10GEG08YUJQPZND1978359JZOEUGKHT2HXO70Z6PK59T8RMY0BBRJ1D78AZEEYBWU4N7IW1TLUN57",36)
while N:S,N=S+chr(97+L.index(sys.stdin.read((N&3)+1))),N>>2
print(S)

```

Try it online!

Takes the library followed by a newline followed by the morsecode from the standard input.

The library used is `.- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --..`

## Explanation:

The majority of the code is a precalculated number of morse widths. A morse caracter in the library is between 1 and 4 dihs and dahs long. In the number i store this as two bits of information. To recall this number i & it with 3 and shift the result over by two bits.

I then read the number of dihs and dahs from the standard input and lookup in the library what the offset of that caracter is from "a". Then repeat and print.

I think the best way to shave of bytes will be to store the number more compactly.

---

Edit: removed 54 bytes by changing the library format, and storing the number as base36 following the suggestions of A Rex and Chas Brown

---

Edit: -3 bytes for removing redundant parameter from str.split() - Chas Brown

# Answer
> 10 votes
# APL (Dyalog Extended), ~~189~~ 188 bytesSBCS

Full program. Prompts for the Morse code. Doesn't need the library. Requires `⎕IO←0`

`⌊⌂morse⍞⊂⍨∊1↑⍨¨1+4⊤'⍳÷+≠í⍀÷<í∧○Ñ>å/∧∨êî∘ß∧äñ⍀○≠è[*⌷∨[î≠∇è⊂Øî⊃⍀[⌷Éäï\∘∧↑æ=íå⌿∧∨ëäÖ⌿ê/≤⌊∘[Å↓Öï○+Ü÷≥↓≤≥>⌷∘á⊃↑Ü⍳⊣[⌿-Ø↑ä/∧∧≠≠Ñíí+ßÜ+-○é↓↓≥≥×∧↑**⍨↑}∧⍨≥ç⍀∧}×⍀Àëç⍀Ø⍨∧∘[×/∘Å∧~≥○ëâ⊂å∨≥Àäè?'⍳⍨125↓⎕AV`

Try it online!

`⎕AV` the **A**tomic **V**ector (the character set)

`125↓` drop the first 125

`'``'⍳⍨` the indices in that of these characters

`4⊤` To-base four

`1+` increment

This gives us the length of each Morse letter.

`¨` for each of those lengths:

`1↑⍨` take that many elements from 1, padding with zeros when needed

**ϵ**nlist (flatten)

`⊂⍨` use that as a mask indicating partition-beginnings to **c**ut the following:

prompt for Morse code

`⌂morse` convert from Morse code to uppercase text

lowercase

# Answer
> 9 votes
# APL (Dyalog) + dfns \+ Jelly's dictionary, ~~181~~ 175 (172) bytesSBCS

Full program. Requires `⎕IO←0` and `⎕AV` redefinition. Doesn't use the challenge's Morse code library.

```
M←∊∘morse¨D⋄C←∊(7⍴51)⊤246⊥5 17⍴¯7+⎕AV⍳'k%aÏ⍵FþfÅ⍵ìÆ⌶á≥å3¶cÒ⍺\ujü─⍳%S⊣ì⍙ÒÛÙ3Ùp`Ø,hÇñ⊂┴Ö⍪l∪⍒i1⍵Í:-îà⌽ì≥3€ã(⍝S]ÁGXræ∇O7Uæî'
C↓⍨←≢i↓⍨←≢M⊃⍨w←(⊃C)⌷∊(⍸M⍷⍨⊂)¨⌽,\24↑i
⍞←819⌶w⊃D
→2

```

Try it online! \- 175 byte version, running at decent speed

```
M←∊∘morse¨D⋄C←∊(7⍴51)⊤246⊥5 17⍴¯7+⎕AV⍳'k%aÏ⍵FþfÅ⍵ìÆ⌶á≥å3¶cÒ⍺\ujü─⍳%S⊣ì⍙ÒÛ─3Ùp`Ø,hÇñ⊂┴Ö⍪l∪çi1⍵Û:-îà⌽ì≥3€ã(⍟S]ÁôXræ∇O7Uæî'
C↓⍨←≢i↓⍨←≢M⊃⍨w←(⊃C)⌷∊(⍸M⍷⍨⊂)¨⌽,\i
⍞←819⌶w⊃D
→2

```

Try it online! \- 172 byte version, taking about 20 times as long to finish (especially slow at beginning)

*-3 bytes by packing base 51 into base 246 instead of base 64 into base 256 and losing the apostrophe* *-3 bytes by ending with an error message instead of cleanly*
*-3 bytes by running about 20 times more slowly*

When I saw this question, I thought that the ultimate solution, the one the question was *made* for, would involve combining both the Morse code and a dictionary. I was surprised when the only submitted solutions turned out to use a table of letter boundaries. My interest was sparked; I'd take a crack at it myself.

The first step was to look for a suitable dictionary (I tried a few). Then I implemented the first version of the algorithm in C++. This enumerated all the possible words that could be at a given point, numbering them sequentially, until finding the one matching its corresponding value in an array made from running the same algorithm with the words of the song as a reference. This initial version enumerated the words in alphabetical order.

I was rather astonished to see just how ambiguous Morse code is without the inter-letter gaps. I expected it to be somewhat ambiguous, but not to the extent that it actually turns out to be! Some of the alternatives are pretty funny, too. Every time `reindeer` comes up, for example, it could also be `leech`. And the entire song can be mapped to completely different words, all the way from start to finish (gibberish, but present in the dictionary).

The dictionaries I tried turned out to be not so well-suited to the task. Either they were missing too many words, requiring them to be added to the dictionary for the algorithm to work, or they were *too* comprehensive, and the resulting array of "word choices" had elements exceeding 63, meaning it couldn't be packed into 6 bits per word.

Then it occurred to me to try Jelly's dictionary. It turned out to be *perfect* for this. Not every word is in the dictionary, including simple words like `a`, `names`, `games`, and `glows`, and the contractions `won't` (`wont` isn't in it either) and `you'll`, but I took advantage of the fact that there are no spaces in the output for this challenge, and cheated:

* `Blitzen``blitz` `en`
* `had` `a``Ha` `DA`
* `glows` `all``glow` `sall`
* `names` `they``Nam` `EST` `hey`
* `games` `then``gamest` `hen`
* `won't` `you``won` `Ty` `ou`
* `him` `as` `they``Hima` `ST` `hey`
* `you'll``you` `LL`

It was a spookily perfect fit for this challenge, even containing all of the proper nouns other than `Blitzen`. Another cheat was to use compound words to shrink the size of the array of word choices: `outwith` and `godown`. As result of all this, the word choice array had 116 elements in it, and with none exceeding 63, the whole thing could be packed into **87 bytes**. (This, despite the compromise of encoding `then` as `th` `en` so as not to exceed the value of 63.) Contrast this with the array of Morse codeword boundaries, which takes 119 bytes (118.5 rounded up).

But that leads to the next problem: Although the data size is considerably smaller, the code complexity is ballooned in comparison. I didn't know any golfing languages, and most of them have very limited documentation that's quite hard to use to learn from scratch.

So I worked on refining the algorithm. The next optimization was to iterate through letters from longest Morse codeword length to shortest, still in C++. This actually decreased the maximum index value to 59, meaning that with arithmetic rather than bitwise packing it could use base 60 to fit in 86 bytes. (For illustrative purposes I also ported this one to Java, which was interesting... I learned a little more Java, and was surprised to see it run even faster than the C++ version, using \>125% of a CPU core, even though the algorithm is inherently single-threaded. My best guess is that the hash function is multithreaded even for individual look-ups.) This data set would respond better to Huffman encoding than the previous one, though not enough to even break even.

I tried optimizing the C++ code for smaller compiled object code, evaluating if it was worthwhile to attempt hand-coding it in x86-32 assembly. It stubbornly remained way too large; the best I could do was to squeeze it in at just under 256 bytes, *not* including the data. So it wasn't worth hand-coding in asm (the letter-boundary version beats it by a huge margin).

So it seemed that the only way this algorithm would have justice done to it would be for me to learn a golfing language. Quite daunting, given that I've never used anything like these languages.

And then Adám offered to teach me APL. I jumped at the chance; while APL doesn't usually win challenges where there's also a Jelly or 05AB1E contender, it tends to come pretty close, has a deep and rich past, and formed the basis of or influenced many newer languages. Heck, I knew of it as a child, and was a bit curious about it even then, but never took a crack at learning it until now.

Many thanks to Adám for extensive help in teaching me various aspects of Dyalog APL and golfing down this program – my first APL program.

I initially tried porting the algorithm as it stood to Dyalog APL. It worked, but was very slow, even when compiled; in 60 seconds it only gets up to `donner` or so. Adám conferred with Marshall at Dyalog, and there wasn't really a way to speed it up any further. But it was suggested that encoding the entire dictionary in Morse code could result in a speedup. And I realized that this strategy could make for much better golf, too.

So the next stage in adapting the algorithm was to translate the entire dictionary to Morse code, and at each point in the encoded song, iterate through possible words in reverse order of their length in Morse dots+dashes (with the longest being 24). Not only is this approach far, far faster in APL (and probably many other languages), and far more concise, but even the data is more lightweight – far more of the "word choice" array elements are `0` or `1`, the largest value is just `50`, and there are only 115 elements (the `then` no longer needed or benefited from breaking up), meaning that in languages with arbitrary-precision base conversion, it could be packed in base 51 and take up only **82 bytes**. In APL though, the overhead of implementing arbitrary-precision base conversion would override the benefit, and I stuck with packing groups of 7 elements, in base 51, into groups of 5 bytes in base 246 (as log246 517 ≈ 4.999295), taking up **85 bytes**. This data set responds even better to Huffman encoding than the previous, but still wouldn't break even: `4 1 2 21 1 13 0 23 0 3 26 1 23 0 26 0 27 15 8 6 0 34 10 0 1 1 7 0 43 23 0 4 37 50 1 0 3 23(24) 22 6 15 6 16 3 2 17 10 12 5 0 9 31 1 3 9 21 0 32 16 9 20 32 8 12 31 5 0 4 27 14 1 7 13 16 0 0(1) 27 4 4 22 10 0 16 5 7 15 3 12 18 4 2 13 1 0 50 4 49 2 1 4 38 20 0 0 19 0 43 23 0 1 6 12 0 38 0`

So as it turns out, in APL it still doesn't golf well enough to beat the existing letter-boundary solutions, even if the overhead for unpacking the "word choice" array (24 bytes) and for using Dyalog Unicode instead of Extended (7 bytes) are subtracted (yielding **144 (141) bytes** code+data). I still think that it might be possible to make it shorter than 129 bytes in one of the languages more specialized towards golfing, and will likely try that eventually.

Of course, with bigger source material than the song this challenge uses, this dictionary-based approach would win hands-down. Some interesting extensions to it would be: Look 2 or more words ahead, and perhaps use an N-gram frequency table; Look all the way ahead, using a model of most-likely N-grams (probably would be incredibly slow).

---

## Explanation of the code

Dyalog Unicode is used, even though Dyalog Extended could save 7 bytes (4+3, as described below), because the former allows compiling for speed, whereas the latter is very slow, to the point that it would be impractical for demonstration.

On my system, this version takes about 45 (or 901) seconds to finish (the first 7 seconds of this are taken converting the dictionary into Morse code). On TIO it doesn't quite finish within 60 seconds.

### Header

`⎕IO←0` \- set Index Origin to 0 (for 0-based array indexing)

`⎕AVU[62 63 60 93 11 94]←9016 9060 9056 8838 9018 9080` \- modify the default Atomic Vector to match the actual Single-Byte Character Set we're using (`£¢¥ýɫ·` overwritten with `⌸⍤⍠⊆⌺⍸`, at each character's respective index within the Atomic Vector)

`'morse'⎕CY'dfns'` \- import the Dyalog APL Morse code dfn – I decided to keep this in the header because Dyalog Extended has it by default

```
D←1(819⌶)'^\w+ = ''{3}|''{3}\.split\(\)$'⎕R''⊃⎕NGET'/usr/local/lib/python3.7/site-packages/jelly/dictionary.py'1

```

Load Jelly's dictionary, and convert it to lowercase:

`⊃⎕NGET'/usr/local/lib/python3.7/site-packages/jelly/dictionary.py'1` \- read the file as a set of newline-delimited lines into an array (with empty lines dropped, of which there is one)

`'^\w+ = ''{3}|''{3}\.split\(\)$'⎕R''` \- using a regex (PCRE) Replace, remove the Python code that surrounds the dictionary's two word lists (`short` and `long`), resulting in a merged list that keeps everything from `short` before everything from `long` (but is otherwise in case-insensitive alphabetical order)

`1(819⌶)` \- convert to uppercase, so that the `morse` dfn will work on it (since it only takes/gives uppercase input/output)

`D←` \- assign to the variable `D`

```
∇D R i;C;M;w

```

Define the tradfn `R`, taking left argument `D` (dictionary word list) and right argument `i` (the input, i.e. the song in undelimited Morse code), and having local variables `C` (word choice array), `M` (dictionary translated to Morse code), and `w` (array listing the indices into the dictionary of what the current word could be). The arguments are passed and the local variables are declared to allow the `R` to be compiled properly (see footer).

### Code

```
M←∊∘morse¨D⋄C←∊(7⍴51)⊤246⊥5 17⍴¯7+⎕AV⍳'k%aÏ⍵FþfÅ⍵ìÆ⌶á≥å3¶cÒ⍺\ujü─⍳%S⊣ì⍙ÒÛÙ3Ùp`Ø,hÇñ⊂┴Ö⍪l∪⍒i1⍵Í:-îà⌽ì≥3€ã(⍝S]ÁGXræ∇O7Uæî'

```

`∊∘morse¨D` \- compose the two functions  (Enlist - flatten / join) and `morse`, and apply the composed function to the dictionary `D`. Without the  composed in, `morse` returns an array of Morse codewords when given an alphabetical string as input, but we need the Morse-encoded dictionary to leave out inter-letter gaps, thus the  flattening.

`M←` \- assign the result to `M`, the Morse-encoded dictionary.

\- statement separator

`'k%aÏ⍵FþfÅ⍵ìÆ⌶á≥å3¶cÒ⍺\ujü─⍳%S⊣ì⍙ÒÛÙ3Ùp`Ø,hÇñ⊂┴Ö⍪l∪⍒i1⍵Í:-îà⌽ì≥3€ã(⍝S]ÁGXræ∇O7Uæî'` \- word choice array, packed into a string using Dyalog APL's updated SBCS. For this to work, the encoding must not contain newlines, i.e. `⎕UCS` `10`, `12`, or `13` (`⎕AV[2 3 5]`), and any apostrophes must be doubled (but there are none).

`⎕AV⍳` \- map characters to SBCS indices (in the range 0-255) using the modified Atomic Vector.

`¯7+` \- add −7 to all SBCS indices. The corresponding addition of 7 was done during the encoding, to avoid occurrences of any of the three types of newlines. Due to use of base 246, this addend is quite flexible, and could range from 6 to 10 and be guaranteed to stay within range regardless of the data; thus it can be adjusted to minimize the number of apostrophes (which would each cost 1 byte, as they need to be doubled in a quoted string). As it happened, it was possible to have zero apostrophes.

`5 17⍴` \- arrange into a matrix for base conversion; each of the 17 columns will be converted as a unit. (In Dyalog Extended, this could be done as `5 ¯1⍴`.)

`246⊥` \- base-convert the 5 values in each column that range 0-245 (base 246) into a single number ranging 0-900897818975, the top row being most significant, yielding a flat array. (But due to the nature of the underlying data, it will actually range 0-897410677850.)

`(7⍴51)⊤` \- base-convert each array element back into a column, with 7 rows, each number in the range 0-50 (base 51). (In Dyalog Extended, this could be done as `51⊤`. The number of rows would be autodetected, so if by a coincidence all values were less than 516, this shorthand syntax wouldn't work properly. In this case though, in would work, and would save **4 bytes**.)

\- flatten the matrix into an array, row by row.

`C←` \- assign to the variable `C`, the word choice array.

```
C↓⍨←≢i↓⍨←≢M⊃⍨w←(⊃C)⌷∊(⍸M⍷⍨⊂)¨⌽,\24↑i

```

This is Line 2 (as referred to by the `:GoTo` at the end of the loop):

`i` \- take the current value of the input (with the parts of it that have already been processed deleted)

`\24↑` \- truncate to 24 characters (dots+dashes). That is the length of the longest Morse encodings (`rudolph` and `christmas`). This step is omitted in the version, which results in almost identical operation, but far slower; the word choice array only needs to be modified in two places (increasing the choice value by 1 at the `and` in `andifyoueversawit` and at `christmas`), meaning that at all other words, no matches for \>24 dots+dashes are found in the dictionary.

`,\` \- make a list of Morse subsequences starting at the beginning of this, ranging from 1 dot/dash long to 24 dots/dashes long (or maximum length, in the version), from shortest to longest (e.g., at the very beginning, would be `'-' '-.' '-.-' '-.--' '-.---' '-.----' '-.-----' '-.-----.'`...`'-.-----..--.--.---.---..'`)

\- reverse that list, so that it goes from longest to shortest (this way of encoding results in smaller element values for the word choice array on average)

`(⍸M⍷⍨⊂)¨` \- to each item in this list, apply the function `⍸M⍷⍨⊂`: =enclose one level of nesting deeper, to match the nesting of the Morse-encoded dictionary; `M⍷⍨`=return an array the same size as the dictionary, where values of 0 mean "not found" and 1 means "found", =convert the list of `0`s and `1`s into a list of the indices of the `1`s. The result is a matrix with 24 rows (ranging from longest to shortest Morse, top to bottom), each of which contains a variable number of columns (minimum zero), listing the indices of all the words in the dictionary that match the Morse sequence from the input of the corresponding length (in alphabetical order, but with Jelly's `short` dictionary entries preceding its `long` ones).

\- flatten this. The end result is a list of the indices of all the words in the dictionary that match any item in the list of Morse sequences from the input that range from 24 to 1 dots+dashes long, retaining the sorting of longest to shortest (and within each length, entries from Jelly's `short` come before those from its `long`, and within that, they're alphabetically ordered).

`(⊃C)⌷` \- from the resulting list, take the element at the index of the current word choice (=first element of) from the word choice array `C`. Equivalent to wrapping everything to the right in `(` `)` and putting `[⊃C]` to the right of it, but saves 2 bytes.

`w←` \- assign this (the index into the dictionary of the correct current word in the song) to the variable `w`, returning it as a result

`M⊃⍨` \- return the `w`th element of `M` (the Morse code of the current word), unwrapped. Equivalent `⊃M` followed by wrapping everything to the right in `[` `]`, but saves 1 byte.

\- return the length of the Morse code of this word (in characters, i.e. dots+dashes). If it had not been unwrapped by , the result would always be `1`.

`i↓⍨←` \- delete that many characters (the length of the word in Morse code) from the beginning of the input `i`, so that on the next iteration of the loop, the next word will be handled, and return the number of characters deleted as the result

\- return the length of the number of characters; since that is a scalar, it will always be `1`

`C↓⍨←` \- delete that many (1) characters from the beginning of `C`, the word choice array, so that on the next iteration of the loop, the next word choice will be ready. This saves 1 byte relative to what a separate statement (`C↓⍨←1`) would take.

```
⍞←819⌶w⊃D

```

`w⊃D` \- Take the `w`th element of `D` (the current alphabetical word) and unwrap it, so that when printed, there are no spaces to its left or right. Equivalent to `⊃D[w]`.

`819⌶` \- Convert to lowercase. Equivalent to `0(819⌶)`. (In Dyalog Extended, this could be done as , saving **3 bytes**.)

`⍞←` \- Print the result without a newline. In TIO, this prints to stderr.

```
→2

```

`:GoTo` Line `2` (the beginning of the loop), unconditionally. A line number is used to save the 2 bytes that defining a label (e.g. `L:`) would cost. The lack of a looping condition results in the program ending with `* Command Execution Failed: INDEX ERROR` when it tries to access the first element of an empty array (after it has successfully printed the entire song).

If running this program locally, note that the error prevents `]runtime` from working. To work around this, the program may be called with `:Trap 3`...`:Else ⋄ :EndTrap` wrapping it.

The clean version, avoiding this error, would be `→2⊣¨i`, meaning `:GoTo` Line 2 while `i` is not empty. This would work because `2⊣¨i` returns an array of `2`s matching the length of `i`, and the `:GoTo` goes to the line number of the first value in the array, if one exists.

### Footer

\- end the tradfn `R`

`2(400⌶)'R' 'morse'` \- compile the user tradfn `R` and the built-in dfn `morse`. Without this, the program would run far slower.

`⍎'D R⍞⋄⍬'` \- Call tradfn `R` with dictionary `D` as its left argument and the input () as its right argument. This passing of arguments is done only for speed, so that the compile can work properly (it doesn't like global variables, or directly using input). The  and  constitute a workaround Adám wrote for me for the way the APLs work currently on TIO. They expect code in the input, but I wanted a clean separation between code and input.

# Answer
> 7 votes
# Jelly, ~~138~~ 135 bytes

```
ḲiⱮ“Q®ḃƁ⁼ṇÑ1¿Ọɠ\ƥȥ⁼ṙ⁴EŀƥŒEæʋØ>þ>⁴þʋ[⁾Ƒ]eÞḍ8ß®ⱮȮø⁹ç÷R?g®=,¥ėµ@ØU~"/Xçq®ÆƬ°ɠsṭṭ?dC#Ċ?gÑ¶PÇH5p@ʂEœ⁹½G6ḌƘṪµɦ8€(S¦Ḥ⁸ṫ"ḟḢlṾ¦ƤḃƭẊ@’ḃ4$ÄṬk⁹¤ịØa

```

Try it online!

A dyadic link taking the library as the left argument and the Morse code input as the right argument. Returns a Jelly string of the lyrics. The long integer that takes the majority of the code has the lengths of each Morse code character encoded within it.

## Explanation

```
Ḳ                      | Split at spaces
 iⱮ              ¤     | Find index of these in each of the following:
   “Q...@’             | - Base-250-encoded integer 742925387377430937422864458121941352705403867269973650879937105837755604647313120541399315429452997316260711263757137193164236124383957174543961671910365268304120327243209050996915401898167278257845227193061059012165352924148307417330452740236835399667569278751322913192633409885614815
          ḃ4$          | - Bijevtive base 4
             Ä         | - Cumulative sum
              Ṭ        | - Convert to logical list with 1s at the appropriate indices
               k⁹      | - Split right argument at those positions
                  ịØa  | Finally, index into lowercase letters

```

# Answer
> 5 votes
## Python, 487 bytes

`lambda a,b:'youknowdasheranddancerandprancerandvixencometandcupidanddonnerandblitzenbutdoyourecallthemostfamousreindeerofallrudolphtherednosedreindeerhadaveryshinynoseandifyoueversawityouwouldevensayitglowsalloftheotherreindeerusedtolaughandcallhimnamestheyneverletpoorrudolphjoininanyreindeergamesthenonefoggychristmasevesantacametosayrudolphwithyournosesobrightwontyouguidemysleightonightthenhowthereindeerlovedhimastheyshoutedoutwithgleerudolphtherednosedreindeeryoullgodowninhistory'`

Takes morse code and any of the three libraries as input, returns the text.

# Answer
> 5 votes
# 05AB1E, ~~149~~ ~~131~~ 129 bytes

```
•Nα0Ω¤èGë™jƒć›
Ù¾₂¶É¨=Yàf§ì[ðEÎλ`÷¡2Ä|~āΔí¹–4₂≠āó3Tv₁‰[Öò‚S»‰CþEηFA‡γ÷¯¿Þ₃âÖ.³εûV^ÕÜ₄Ú¹þ‘ΘVÅÍÅΘΛ9m|\Ó8g8ì&ÓiUΩÎQ:ÇºZÎgöæ•4в>£I#A‡

```

-18 bytes thanks to *@Deadcode*.
-2 bytes thanks to *@Grimmy*.

Uses the complete morse-string as first input, and the lookup format as second input.

Try it online. (Outputs as a list of characters, so the `J` in the footer is to join it together to a single string to pretty-print.)

**Explanation:**

```
•Nα0...göæ• # Push compressed integer 2178625864988239449532491166807818445418276694861550892023336765049187401437036816274840827319861935617150192366925629812414499033245212320687403711053517272798896860734190937884895522347710320033920004354990136205425279052925026955638024859428057287730519725429748232597858786841294379
   4в       # Converted to base-4 as list: [3,2,2,2,1,2,2,2,1,2,3,0,2,1,1,2,2,1,1,3,0,2,1,1,2,3,2,1,1,3,0,2,1,1,2,3,1,3,0,1,3,2,1,0,0,1,1,2,3,2,3,1,2,1,1,2,2,2,1,1,0,2,1,1,2,3,3,1,0,3,0,1,3,2,0,2,2,3,2,2,2,0,3,1,3,3,0,3,0,1,2,2,0,3,1,1,2,2,2,2,0,1,1,2,0,0,2,2,3,1,3,3,2,2,2,2,3,3,3,0,3,0,2,0,2,1,2,2,0,2,2,0,1,1,2,0,0,2,3,1,2,1,3,0,2,3,2,3,1,1,3,1,2,2,0,1,1,2,1,3,3,2,2,0,3,0,2,2,1,2,1,0,3,2,2,2,2,2,3,2,0,3,0,1,2,1,3,1,0,2,3,2,2,2,1,3,3,2,3,0,3,0,2,0,3,0,2,2,0,1,1,2,0,0,2,2,2,0,2,0,2,3,1,2,2,3,1,1,2,3,1,3,3,3,1,1,1,1,1,0,2,0,3,0,3,1,0,3,0,2,3,0,0,3,2,2,2,2,2,2,2,3,3,3,3,2,1,1,1,1,1,1,3,2,0,1,1,2,0,0,2,2,1,1,0,2,0,3,0,1,2,1,0,3,2,2,2,3,3,3,2,1,2,0,1,1,2,0,3,0,2,1,1,0,1,3,1,1,0,0,2,2,1,3,2,2,2,2,3,3,3,2,1,0,3,3,2,2,2,1,2,2,0,2,2,3,2,1,2,3,0,2,2,1,0,3,2,2,2,2,1,2,0,1,3,2,3,0,1,2,3,0,2,1,1,2,3,0,0,3,0,1,3,2,2,0,3,0,2,0,1,1,2,0,0,2,3,2,3,0,2,3,1,1,1,2,0,3,0,3,2,3,2,2,0,0,2,2,2,0,2,1,0,3,2,3,0,0,2,2,2,2,3,3,3,0,3,0,2,0,2,1,2,2,0,2,2,0,1,1,2,0,0,2,3,2,2,3,3,2,2,2,2,2,1,1,1,3,1,2,0,2,2,3]
     >      # Increase each value by 1
      £     # Split the first (implicit) input-string into parts of that size
       I#   # Push the second input-string spit by spaces
         A  # Push the lowercase alphabet: "abcdefghijklmnopqrstuvwxyz"
          ‡ # Transliterate all morse-strings in the list by the characters in the alphabet
            # (after which the resulting character-list is output implicitly)

```

See this 05AB1E tip of mine (sections *How to compress large integers?* and *How to compress integer lists?*) to understand how the compression works.

---

Also, since I was curious what the program length would be if we wouldn't take any input and just use the 05AB1E dictionary to output the string, I created a program for that as well, which is **266 bytes**:

```
’4ƒ€Þßer0–›r0prancer0vixen†„t0ï›id0¥Úner0bÙîØˆ€³€·4¾Î3‚¢£–2€‚€Ÿ13†¾5d2‚†a‚Òshiny5€ƒ€¬4ˆë–æ€•4€ÞƒÎ…è€•é»s€Ÿ€‚3€¶2‚›€„ÇÇ0„Ò„šŒî€»†™†³—‹1…¯€†€Æ2ƒ‚‚½€µÚƒgyŒÎ»ˆš´‹é€„…è1€Ž€ž5€Ê®Á¢²t4„²€¯slŸ¯o†æ‚½€ß32®œ„š€œ€»sh€Äed€Ä€Žgï³13†¾5d24ll‚œ„‹€†„ª’5Ý’€ƒ rudolph reinÆÓ €€ €î ÄÃ’#:

```

Try it online.

**Explanation:**

```
’4ƒ€Þßer0–›r0prancer0vixen†„t0ï›id0¥Úner0bÙîØˆ€³€·4¾Î3‚¢£–2€‚€Ÿ13†¾5d2‚†a‚Òshiny5€ƒ€¬4ˆë–æ€•4€ÞƒÎ…è€•é»s€Ÿ€‚3€¶2‚›€„ÇÇ0„Ò„šŒî€»†™†³—‹1…¯€†€Æ2ƒ‚‚½€µÚƒgyŒÎ»ˆš´‹é€„…è1€Ž€ž5€Ê®Á¢²t4„²€¯slŸ¯o†æ‚½€ß32®œ„š€œ€»sh€Äed€Ä€Žgï³13†¾5d24ll‚œ„‹€†„ª’
      # Push dictionary string "4knowdasher0dancer0prancer0vixencomet0cupid0donner0blitzenbutdo4recall3mostfamous2ofall13red5d2hadaveryshiny5andif4eversawit4wouldevensayitglowsallof3other2usedtolaugh0callhimnamestheyneverletpoor1joininany2gamesthenonefoggychristmasevesantacametosay1withyour5sobrightwont4guidemysleightonightthenhow32lovedhimastheyshoutedoutwithglee13red5d24llgodowninhistory"
 5Ý   # Push a list in the range [0,5]: [0,1,2,3,4,5]
   ’€ƒ rudolph reinÆÓ €€ €î ÄÃ’
      # Push dictionary string "and rudolph reindeer the you nose"
  #   # Split it on spaces: ["and","rudolph","reindeer","the","you","nose"]
   :  # Replace all [0,1,2,3,4,5] with ["and","rudolph","reindeer","the","you","nose"] in the string
      # (after which the result is output implicitly)

```

See the same 05AB1E tip as linked above (but section *How to use the dictionary?* this time), to understand how the dictionary strings work.

# Answer
> 3 votes
# Charcoal, ~~145~~ 141 bytes

```
≔⪪⮌θ¹θＦ”)“1§μX↶)⟧¶»-↘3ω◧i⌊⊞⁸Ｑ9m;T›|ＬDμ…›Ｏ⦄hTYＩO5x÷↶×‹,⟲"yＭLUＣgq.ＢNＥ2⁴⎇c⬤χＮ±⸿↙＆7⟧χ⁰‹Ｙs´ΣC⁼{9ω�Pi＆◧êKσＰDfY9wi⟲f[Φτ³Ｊ‹‴V[^ＷＲEαF[-T^ς”§β⌕⪪η ⭆⊕ι⊟θ

```

Try it online! Link is to verbose version of code. Edit: Saved ~~3~~ 4 bytes by using a less inconvenient library format. (Thanks to @Deadcode for pointing out that I'd pasted in the wrong version.) Explanation:

```
≔⪪⮌θ¹θ

```

Reverse the sequence and split it into individual characters.

```
Ｆ...

```

Loop over the characters of a compressed string which are the digits `0..3` (which compress better than `1..4` for some reason).

```
§β⌕⪪η ⭆⊕ι⊟θ

```

For each digit, pop one more than that many characters from the sequence, concatenate them, look them up in the library split in spaces and output the desired character (using the predefined lowercase alphabet).

137 bytes with an even more convenient library format:

```
≔⪪⮌θ¹θＦ”)“1§μX↶)⟧¶»-↘3ω◧i⌊⊞⁸Ｑ9m;T›|ＬDμ…›Ｏ⦄hTYＩO5x÷↶×‹,⟲"yＭLUＣgq.ＢNＥ2⁴⎇c⬤χＮ±⸿↙＆7⟧χ⁰‹Ｙs´ΣC⁼{9ω�Pi＆◧êKσＰDfY9wi⟲f[Φτ³Ｊ‹‴V[^ＷＲEαF[-T^ς”§η⭆⊕ι⊟θ

```

Try it online! Link is to verbose version of code. Explanation:

```
≔⪪⮌θ¹θ

```

Reverse the sequence and split it into individual characters.

```
Ｆ...

```

Loop over the characters of a compressed string which are the digits `0..3` (which compress better than `1..4` for some reason).

```
§η⭆⊕ι⊟θ

```

For each digit, pop one more than that many characters from the sequence, concatenate them, look them up in the library and output the desired character.

# Answer
> 3 votes
# Perl 5, ~~283~~ 244 bytes

```
$s=<>;$s=~s/..{$_}//+print$s=~/(.) \Q$& / for map{vec unpack('u',q{MJZDYEM98;HWE31N4>Y9:6'Y,BZYRSZ1<JI2@]ZH_(Z8H)7@V[G5*V2NC&:NZM3':XVCLCHY2@(IY>WE\5,L<XK*K^6U5+"5K(9*S^)B5CT07:JK_Q:HINCL:J=23LYEL.T,E*".U[)[`HJQ@ZJ/R.F*"6XOJK5B0X`}),$_,2}0..473

```

Try it online!

This corresponds to:

```
$L = <<'';                            # length bits in base64
MJZDYEM98;HWE31N4>Y9:6'Y,BZYRSZ1<JI2@]ZH_(Z8H)7@V[G5*V2NC&:NZM3':XVCLCHY2@(IY>WE\5,L<XK*K^6U5+"5K(9*S^)B5CT07:JK_Q:HINCL:J=23LYEL.T,E*".U[)[`HJQ@ZJ/R.F*"6XOJK5B0X`

$s = <>;                              # read inputs
$s =~ s/..{$_}//                      # take current length morse code from start
  + print $s=~/(.) \Q$& /             # ...and print corresponding letter
  for map vec(unpack('u',$L), $_, 2), # find morse code lengths of the letters
      0..473                          # 474 letters

```

This could perhaps be further shortened by encoding in base128 or directly in "base256". Huffman encoding the lengths could shorten the length data, but most probably enlarge the rest of the code by too much.

# Answer
> 3 votes
# MATLAB R2016a, ~~290~~ ~~285~~ ~~277~~ ~~266~~ ~~245~~ ~~223~~ 219 bytes (99+119+1)

```
function r(m,d);[a,b]=ismember(mat2cell(m,1,fread(fopen('j'),474,'bit2')+3),strsplit(d));char(b+96)

```

The inputs are the Morse code sequence `m` and the dictionary `d` in the third format. The function uses a 119-byte file `j` available here that contains the lengths of the 474 Morse codewords. According to the rules of scoring multiple files, this adds an additional byte to the score.

# Answer
> 3 votes
# Pyth \+ Jelly's dictionary, ~~135~~ ~~134~~ ~~131~~ ~~130~~ 129 (126) bytesSBCS

The algorithm and data in this answer were originally implemented in this APL answer, and their explanation is there. But as implemented there, it failed in its entire purpose, which was to beat the previously lowest-scoring submission to this challenge, Kevin Cruijssen's **129 byte** 05AB1E answer. Here, it finally succeeds in its very purpose for existing, and just barely manages to beat that answer's length. I learned Pyth to do this; it was a promising choice with very good documentation. It's unclear if any of the other golfing languages would be able to implement an imperative algorithm like this in fewer bytes.

With a longer Morse code message this algorithm would win by a significantly larger margin.

```
Kcwd=bmsm@KxGkdTVjC"êêVÞøA?cUqg´§¼F¦e~zEºÊú[!Áw¶uQå´çý½Ê*¤jrkIæwÐó*S.(4áëÌöÅ×¹ñp.ÑQÐgBê "51=>zl@bJ@sxRb_._<z24Np@TJ

```

(contains C1 control characters, forbidden by HTML5, thus the above can't be copied to clipboard and is for illustration purposes only)
Try it online! \- 129 byte version, running at decent speed

```
Kcwd=bmsm@KxGkdTVjC"êêVÞøA?cUqg´§¼F¦e~zEºÊúvMÇìý÷¼]¾I/||ÊÁê,Ømø×i]Z8©b¤0åé'½bIý>ä
lGùUK½"51=>zl@bJ@sxRb_._zNp@TJ

```

(contains C1 control characters, forbidden by HTML5, thus the above can't be copied to clipboard and is for illustration purposes only)
Try it online! \- 126 byte version, taking about 20 times as long to finish (especially slow at beginning)

## Explanation of the code

### Header

```
 $exec('

```

Anything in `$`...`$` is `eval`ed as Python code. Open an `exec` block here (since statements can't be executed in `eval`). The leading space suppresses `imp_print`.

```
def Pprint(a): print(a, end="", flush=True); return a

```

On my system, this program takes 46.4 (or 921) seconds to finish, but on TIO, it is on the very edge between not finishing in 60 seconds or just barely finishing. If it didn't manage to finish, no output would be shown. If it was manually interrupted before finishing, the incomplete output would be shown – so it appears TIO sends a SIGINT (Ctrl+C) to the process for this, but something more powerful (perhaps even SIGKILL) when reaching the 60 second limit.

By default, Python only flushes its standard output on newlines. The `-u` command line argument forces stdout (and stderr) to be unbuffered, but TIO does not provide a way to send arguments to the host Python process that spawns Pyth.

This header line redefines Pyth's `Pprint()` macro to flush its output, so that if the program does not finish within 60 seconds, the incomplete output will still be shown. It's the next best thing to `-u`.

Funnily enough, forcing each individual print to flush seems to actually make it run faster on TIO; it was able to finish in under 58 seconds with this, whereas in my tests on TIO the 134 byte version never finished without this.

```
_imp_print = imp_print;
def imp_print(a): globals()["imp_print"] = globals()["_imp_print "]; return a

```

Work around the newline inserted by TIO between the Header and Code sections, which would trigger an `imp_print()` on the first expression otherwise. Suppress only the very first `imp_print` that happens next, and then allow all subsequent ones.

```
')$

```

End the `exec` block.

```
=TrL0$exec('from jelly import dictionary') or dictionary.short + dictionary.long$

```

Import Jelly's dictionary and assign the concatenation of its short and long dictionaries, changed to all-lowercase, to the Pyth variable `T`. Equivalent to:

`from jelly import dictionary`
`T = list(map(lambda arg:arg.lower(), dictionary.short + dictionary.long))`

### Code

```
Kcwd

```

The Morse code version of the song has already been read from input implicitly, as `z = input()`.

Read the Morse code look-up table from input. Equivalent to `K = input().split(' ')`.

```
=bmsm@KxGkdT

```

Translate Jelly's dictionary into Morse code, with the inter-letter gaps deleted. Equivalent to:
`b = list(map(lambda d:''.join(map(lambda k:K[string.ascii_lowercase.index(k)], d)), T))`

(The outer lambda uses `d` as its argument, whereas the inner lambda automatically advances to using `k` as its argument.)

`jC"êêVÞøA?cUqg´§¼F¦e~zEºÊú[!Áw¶uQå´çý½Ê*¤jrkIæwÐó*S.(4áëÌöÅ×¹ñp.ÑQÐgBê "51`
`jC"êêVÞøA?cUqg´§¼F¦e~zEºÊúvMÇìý÷¼]¾I/||ÊÁê,Ømø×i]Z8©b¤0åé'½bIý>ä␊lGùUK½"51`
(contains C1 control characters, forbidden by HTML5, thus the above can't be copied to clipboard and is for illustration purposes only)
Unpack the word choice array (115 elements), packed in base 51 in an **82 byte** base 256 encoded string. Luckily there happened to be no characters that needed escaping.

`C"`...`"` \- convert the base 256 encoded string into an arbitrary-precision integer
`j`...`51` \- convert the base 51 integer into a list of integers

---

`V`...`=>zl@bJ@sxRb_._<z24Np@TJ`
`V`...`=>zl@bJ@sxRb_._zNp@TJ`

Main loop.

`V`... - `for N in` ...`:` \- for each element `N` of the list decoded above, execute all of the following statements:

`_._<z24` \- `reverse(list(map(lambda arg1:z[:arg1], range(1, 24+1))))` \- make a list of Morse subsequences starting at the beginning of input (`z`), ranging from 24 to 0 dots/dashes long (from longest to shortest)
`_._z` \- `reverse(list(map(lambda arg1:z[:arg1], range(1, len(z)))))` \- make a list of Morse subsequences starting at the beginning of input (`z`), ranging from maximum length to 0 dots/dashes long (from longest to shortest)

`J@sxRb`...`N` \- `J = sum(map(lambda arg2:index(arg2,b),` ...`), [])[N]`, where `index(arg2,b)` finds all occurrences of `arg2` in `b` \- enumerate all words that match the Morse code at the current position in the input, up to 24 dots+dashes, and store this list of dictionary indices (which apply to both `b` and `T`) in `J`

`=>zl@bJ` \- `z = z[len(b[J]):]` \- remove the processed Morse code from the beginning of the input

`p@TJ` \- `print(T[J])` \- look up this word in the dictionary and print it

# Answer
> 2 votes
# JavaScript (Node.js),  ~~270~~  269 bytes

Takes input as `(string)(lookup)`, where *lookup* is in the 3rd format.

```
s=>t=>(B=Buffer)("SNB6>B5>V]@a5U)McAQ>@a/;3bRD7;2?R:1P_Sb7K@22MHO5V?O:AWZPATRV4A/VBW[0K:1PJ`Q?Fg=-ZD46TRRgC=]:1P-ZLYRgN<Z@9?H^RfCdRQPC6BTR1U;6>64UZ0MHc`=ZTSH2.cHRg4JQP<*VfRB]1b").map(n=>[0,2,4].map(i=>o+=B([97+t.split` `.indexOf(s.slice(p++,p+=n-40>>i&3))])),o=p='')&&o

```

Try it online!

### How?

For each character in the data string, we take the ASCII code minus \\$40\\$ to get a 6-bit value holding the lengths of the next 3 morse codes.

*Example:*

```
"S" --> ASCII code 83 --> 43 --> 101011 --> 10 10 11
                                             |  |  |
                                             |  |  +--> 3+1 = 4 -> -.-- (y)
                                             |  +-----> 2+1 = 3 -> ---  (o)
                                             +--------> 2+1 = 3 -> ..-  (u)

```

# Answer
> 2 votes
# Python 3, 452 bytes

```
lambda a,b:''.join([chr(96+int(''.join([f'{ord(c):07b}'for c in'''ezVswP,A8BpeH	A82dDY
po4ZqVHDw,A8AMa+!ezd(a1J+/NCkuN"Rq'LJRdQd)>2I)8BK3!2ssIY>Rl,StiKu]zX!6iCJ4Go,1s(A/Qe)8BK3J`5\0\ a1DkA4YhA98[R_Uv BO%d\YHT\!%HpZ,t Wq&<sr&:eXYBuK#s*#lAS">Y|eMq$IhRw]&/TzR!-f6
IhQw:Q\CwQd*.RdcvDh3QsVBH}4];*H{"D$9yJ$E%b
,Y>V;d>wr	N'''])[i:i+5],2))for i in range(0,2346,5)])+'tory'

```

Try it online!

Same morse-ignoring, hardcoding approach as ScoopGracie's answer, but with each character's 5 LSB concatenated and re-encoded in printable ASCII (i.e. 7 free bits out of each byte).

This shortens the string from 474 to 339 bytes, not counting delimiters (which need to be multiline for the encoded string) and an escape sequence in place of a NUL byte. I also cut the string off at the last clean byte boundary (to not deal with partial bytes) so I had to hardcode the final four characters.

Then there's not-insignificant overhead for the decoding process, so it's not much shorter this way. Improvement suggestions welcome!

Using the standard library instead to compress the lyrics with `base64.b64encode(gzip.compress(...))` actually saves 2 bytes:

# Python 3, 450 bytes

```
lambda a,b:decompress(b64decode('H4sIAAaPGF4C/3WQ0XbsIAhFv5UJRG2VkyU41n79xdzJY19cBE62WxbGt2IyWZZOykx63MXVn+pdfkQPNPH4OMZVeOegek9ftfiv6Gs4Y2F0OahWz9JgflLDsC5FWaTjjEkfjHrlCHRhhQk/40xMb+nLctG1JwEvZyAlukazeNQTo3I01GgVTxXTAoozeNjMBzYC7Kg0Ut7SkcmlKTWxSC3dyCp+Af0j9IWiRUnXQ0ifsELlRErryL2YN7L42Uidjkg4QuSDCMO8N7DdDa9eUvYJ3dppFJa2rMpuQve52Rnz3sT/KyvewuFJt6RlDBeOY4NT3a/6a3dxRa0JjBmPyKGJvv4BRj4fyNoBAAA=')).decode('ascii')
from gzip import*
from base64 import*

```

Try it online!

# Answer
> 2 votes
# Python 3, ~~265~~ ~~261~~ ~~259~~ 255 bytes

Uses the same base-256-in-a-string data-encoding method as my other Python answer, but actually uses the Morse code input. Like many of the other answers, encodes the lengths of the 474 Morse codewords into **119 bytes** using base 4. The Morse stage of the decoding is based on steviestickman's answer, with some further golfing.

Takes the Morse library and representation as two lines from stdin and outputs to stdout:

```
#coding=L1
i=int.from_bytes('Õª¾¸%(¦#?ªÆ*\nìÉ^;R2´Ã9;IªÆnjñ¿ªÚÑc%&þ¬dÈZ    KU[þª¬8Ç2_Þ^" £#;Ú¸vLº«£+ÙJuî6x%(¦#?ª÷ ª\¤Ïr®L~XZ{MånXÖ9©«'.encode('L1'),'big')
*m,I=input().split()
while i:j=i%4+1;print(end=chr(97+m.index(I[:j])));I=I[j:];i//=4

```

(contains C1 control characters, forbidden by HTML5, thus the above can't be copied to clipboard and is for illustration purposes only)
Try it online! (can't use the actual Latin-1 coding header, since TIO only accepts UTF-8)
Try it on repl.it (demonstrates the actual 255 byte source code file)

*-4 bytes by using the alias* `437` *for* `cp437`
*-2 bytes by using* `L1` *instead of* `437`
*-4 bytes by separating the Morse code library and representation in the input with a space instead of a newline*

Here's a Python program (TIO) to generate the full program with choice of string encoding.

# Answer
> 2 votes
# Pyth, 142 bytesSBCS

Like many of the other answers, and my Python answer, encodes the lengths of the 474 Morse codewords into **119 bytes** using base 4. Shares many similarities with my Pyth + Jelly's dictionary answer.

My primary reason for posting this answer is to show that in Pyth, apparently the 474-codeword-lengths method does *not* beat the 115-Jelly-dictionary-word-indices method!

Takes the Morse representation and library as two lines from stdin and outputs to stdout:

```
Kcwdsm@GxK<~>zddhMjC"¦¦Éir[%·AnÙjR[Ó+¨ß1£Z¡`ú¯Ì¢ÙËµÚ~¦NªãÒê~Ì¡`¨k[UHÍ2Ãª«þU^
R1«ùu
z¯äú+):¦ÆÉl1èÈX.ËV3º
;
¯Ì¢ëê¥v+"4

```

(contains C1 control characters, forbidden by HTML5, thus the above can't be copied to clipboard and is for illustration purposes only)
Try it online!

## Explanation of the code

```
Kcwd

```

The Morse code version of the song has already been read from input implicitly, as `z = input()`.

Read the Morse code look-up table from input. Equivalent to `K = input().split(' ')`.

```
hMjC"¦¦Éir[%·AnÙjR[Ó+¨ß1£Z¡`ú¯Ì¢ÙËµÚ~¦NªãÒê~Ì¡`¨k[UHÍ2Ãª«þU^
R1«ùu
z¯äú+):¦ÆÉl1èÈX.ËV3º
;
¯Ì¢ëê¥v+"4

```

Unpack the array that stores the Morse code width (in dots+dashes) of each letter of the song (474 elements), packed in base 4 (with 1 subtracted from each element) in an **119 byte** base 256 encoded string. Luckily there happened to be no characters that needed escaping.

`C"`...`"` \- convert the base 256 encoded string into an arbitrary-precision integer
`j`...`4` \- convert the base 4 integer into a list of integers
`hM` \- add 1 to all elements

```
sm@GxK<~>zdd

```

`m` \- map each element `d` of the list decoded above through the following lambda:

`~>zd` \- `z = z[d:]` \- remove the first `d` dots+dashes from the input (`z`), and return the previous value of `z` (let's call it `ʐ`)

`@GxK<ʐd` \- `string.ascii_lowercase[K.index(ʐ[:d])]` \- alphabetical letter decoded from the first `d` dots+dashes from the input

`s` \- join the resulting list of characters into a string

# Answer
> 2 votes
# Vyxal `s`, 131 bytes

```
»ʀAλT‛⊍½⇧ṗ.‹ẇṡN↳ḢZµẊ₃r#≤*₂⇩vǐ†⁰₈{≬√¬Ṗ}↑żPǍĊṁ⟑ZUżǓ∧∞:Yβv₴ǒ›ƈĖβ•„†G€
→C≬⁋İꜝ[≠₴m∑E¼ y±⋎\↲Ċ„ġQ Ṙ₍ṘQ∵«1}w⌊×+×⇩e⌊-¨T⁰ɽoṪḊ$⁰+‡∪»4τ›⟑;ẇ⁰⌈yĿ

```

Try it Online!

Port of 05AB1E.

-1 byte thanks to Deadcode

# Answer
> 1 votes
# Python 3, ~~381~~ ~~375~~ 372 bytes

Just like Seb's answer and ScoopGracie's answer, gracefully takes the Morse code representation and any of the three libraries as input, blithely ignores them and gives you the output.

Takes Seb's strategy a step further, encoding the text in base 26 in an integer encoded in base 256 in a string (as opposed to Seb's which encodes in base 32 in base 128 in a string). Both of our solutions are confined by not being able to contain the bytes NUL (0x00) or CR (0x0D), which Python interprets as end-of-file and LF (0x0A), respectively, even when found in a triple-quoted raw string literal. CR+LF is also interpreted as LF. Backslash escape codes are interpreted (unless the raw prefix `r` is used). Backslash followed by any kind of newline is treated as nothing, stripping both the backslash and the newline. And the string can't end in a backslash. (So it's really sort of a slightly-less-than-base-254 masquerading with the help of luck as base 256.)

To work around this problem I had to complicate the encoding a bit. Neither ASCII-97 nor 122-ASCII, nor using base 27 instead of 26 (and optionally adding 1), avoided containing these bytes or sequences, so I settled upon adding 1 to the encoded integer before each multiplication by 26, which luckily costs only 3 bytes (compare `i//=26` to `i=i//26-1`). With significantly larger text, the luck would have to be incredible, or every NUL, CR, and `\` would have to be replaced with `\0`, `\r`, and `\\` respectively. On the other hand, with better luck, newlines might be absent altogether, meaning single-quoting could be used instead of double-quoting.

The `#coding=L1` costs 11 bytes (without this it'd be 361 bytes), but this beats the cost of using base 128 (which would take 319 bytes for the string, whereas base 256 takes **279 bytes**, and thus would cost 40 bytes instead of 11, not counting the different Python code that would be needed to decode it). An alternative coding is `437`, which would cost a further 2 bytes, since the encoding name is used twice. Note that the disadvantage of using `L1` instead of `437` is that ISO 8859-1 doesn't map as cleanly to UTF-8, and there may be difficulty faithfully copying and/or pasting it in some software.

This standalone program, written in the ISO 8859-1 codepage, ignores the Morse code representation and library taken as command-line parameters, and prints the output to stdout:

```
#coding=L1
i=int.from_bytes(' îã¸ÌÒ^ë9|iéëMþ³\H0Äï;ÿÒ¸FÈªÎ©«|°M®QcWtgUî[¡U*¤ßºN¨øA¡:¾ç¢Àãþú/æòêåá\IÕi#vv³Ü¡\'jîÐtÄí6.ñÎé¤¥Yî³d}fLLEXµ*îB§ ç^eleW?Ð|¶S¯±[Iûçä2ý¥ð°,üTÃ·0èÅEÛçå\LW&uMeÑ@ûÍÿ`Ñ3CÒæ%2¿¬ÌïÆçGÌîXë[MDØmI¥íâÃ½9t±¤]#ÏYî8M·Ckò¡"J'.encode('L1'),'big')
while i:print(end=chr(i%26+97));i=i//26-1

```

(contains C1 control characters, forbidden by HTML5, thus the above can't be copied to clipboard and is for illustration purposes only)
Try it online! (can't use the actual coding header, since TIO only accepts UTF-8)
Try it on repl.it (demonstrates the actual 372 byte source code file)

*-6 bytes by using* `L1` *instead of* `cp437`
*-3 bytes by using* `i=i//26-1` *instead of* `i=i//26^4`*, resulting in no newlines, allowing single-quoting*

Here's a Python program (TIO) to generate the full program with choice of string encoding.

---

If it absolutely has to be a function and not a program, then it's **382 bytes** (not counting the `#coding=L1`):

```
def R(a,b):
    s='';i=int.from_bytes('…'.encode('L1'),'big')
    while i:s+=chr(i%26+97);i=i//26-1
    return s

```

Try it online!

If it has to be a lambda, **391 bytes** (not counting the `#coding=L1`):

`lambda a,b,i=int.from_bytes('…'.encode('L1'),'big'):exec("global s;s=''\nwhile i:s+=chr(i%26+97);i=i//26-1")or s` \- Try it online!

If it has to be a lambda that doesn't modify any globals, **395 bytes** (not counting the `#coding=L1`):

`lambda a,b,l={'i':int.from_bytes('…'.encode('L1'),'big')}:exec("s=''\nwhile i:s+=chr(i%26+97);i=i//26-1",l)or l['s']` \- Try it online!

# Answer
> 1 votes
# Deadfish~, 2496 bytes

```
{{i}}{ii}ic{d}ciiiiiic{d}ciiicic{i}ddc{dd}icdddc{ii}ddc{d}dcdddc{i}iiic{dd}iiic{i}iiic{d}ccdddc{i}iiic{d}dciic{i}iiic{dd}iiic{i}iiic{d}c{i}iiciic{dd}iiic{i}iiic{d}dciic{i}iiic{dd}iiic{i}iiic{d}c{ii}ddc{d}dddc{i}iiiiic{dd}ic{i}dc{d}dc{i}iicddc{d}iic{i}iiiiic{dd}ic{i}iiic{d}cdc{ii}ddcdddddc{d}iiicdddddcdddc{i}iiic{d}cc{i}icdcc{d}ic{i}iiic{dd}iiic{i}iiic{d}cddc{i}cdddc{i}iciiiiiic{dd}dc{i}dc{d}ddc{ii}dcdc{d}ddddddc{i}ic{i}c{d}ciiiiiicdddc{d}dddcddcddc{i}icc{i}ddc{d}ddcdddc{i}ddciiciiiicic{d}ddddcdddddc{i}iiciiciiiiiicddcdc{d}dddciiiiciiiiic{d}cicc{i}iiicdddc{d}icdddddc{i}icciiiiiiciiic{dd}iiic{i}icdddciiiic{d}iic{i}iic{d}ddcdddc{i}iiic{d}dddcdc{i}ciciiiic{d}ddddcdc{i}iiiic{d}dddciiiiciiiiic{d}cicc{i}iiic{d}c{d}iiiciiicdddc{ii}ic{dd}iiic{i}iiic{i}dddcddddddc{d}dciciiiiic{i}ic{d}dciciiiic{d}ddddcddddc{i}iiic{d}ciiiiicdddc{ii}dc{d}ciiiiiic{d}ddddddc{ii}dddc{dd}iiic{i}iiicic{dd}iic{ii}iic{d}ddddc{i}iciiiiic{d}ciiiiiiciic{d}iiciiiiiic{d}ic{d}iicic{ii}dddc{dd}iiic{i}dciiiiic{dd}iic{ii}iiiic{d}ddddddc{i}ic{d}dddciiiiiciiic{i}ddcddddc{dd}iic{i}icciiic{d}ic{i}iiiic{d}ddcdddc{i}ciiiiic{d}ddcdddc{i}iiicc{d}dddciiiiciiiiic{d}cicc{i}iiiciiicddc{d}ddddcdc{i}iiiiiicdddddcdddc{d}dc{ii}c{d}ddddcic{d}iiic{i}iiic{d}cdcddc{i}iccddddciciiiicic{d}dddc{i}iic{d}iic{i}iiiicic{d}ddcdddc{ii}c{d}dc{d}ic{ii}dddc{dd}iiic{i}iiicddddddc{d}iiic{i}iiiiicddddcdcciiicciiic{dd}iiic{i}icdddciiiic{d}iiciiciiiiicddddddciiiiicdddddciiiiic{d}dddc{i}iiic{i}ic{d}iiic{d}dddciiiiciiiiic{d}cicc{i}iiic{d}dcddddddc{i}iic{d}iic{i}iiiicic{d}ddcdddc{i}dcicdc{d}icic{i}dc{d}iicc{ii}ddc{dd}ddciiiiic{i}c{d}ic{i}cic{d}iiic{d}ddc{ii}ddc{d}ddddc{ii}dddc{dd}iiic{i}iiiic{dd}iic{i}iiiciiiiiic{dd}iciicddc{i}iic{d}iic{i}iiiiicdddddciiiic{dd}iic{ii}iiiic{d}iiiciiic{dd}iiic{i}icdddciiiic{d}iic{i}iiiiic{d}ddddc{i}ic{d}ddc{ii}dddc{d}ciiiiiicdddcddddciciiiic{d}ddddc{i}iiiicddddc{d}dddc{i}iiiiiic{d}icddcic{i}iiciiic{d}iicdciiiiiiciiiiic{d}ciiiiiic{d}ddddc{i}iiiic{d}ddcdddddcic{i}ddc{i}iicddddddc{d}iiic{d}iiiciiiicddcic{i}iicdddddcdcdddddcddcic{i}iicc{d}ddcdddc{i}dcddddddc{i}dddc{i}ddcdddc{d}ddcdddc{i}iiic{d}dddciiiiciiiiic{d}cicc{i}iiicddddddciiic{i}dddc{dd}iiicdciiiiciciiiic{d}ddc{ii}ddcic{d}ddcdddc{ii}cddddddc{d}dc{i}dddciiiiiicdc{d}dddddcdc{i}iciiiiiicdciiic{d}ddddc{i}ic{d}ddcdciiiiic{d}iiicc{i}iiiciiic{dd}iiic{i}icdddciiiic{d}iic{i}iic{d}ddcdddc{i}iiic{d}dddcdc{i}ciciiiic{d}ddddcdc{i}iiiic{d}dddciiiiciiiiic{d}cicc{i}iiic{i}dddc{d}ciiiiiic{d}iccdddddc{i}ddc{d}dc{i}ic{i}ddc{d}icdddddciiiiicddddddcic{i}cicdddddciiic{i}dddc

```

Uses an alternative interpreter. But in the ordinary one, you can give it input. It's not going to do anything though.

Try it online!

---
Tags: code-golf, kolmogorov-complexity, compression, morse
---


title: Convert from Greeklish to modern Greek

text:
# Question
Title: Convert from Greeklish to modern Greek
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        ->  εκεινη αγορασε ψαρια και θυμαρι

```

## Rules

# Answer
# JavaScript (ES6),  ~~106~~  105 bytes

```
s=>s.replace(/[kp]s|\S/g,s=>String.fromCharCode(946+'bgdezh8iklmn3opr_styfx4w'.search(s[1]?s<'p'?3:4:s)))

```

Try it online!

### Commented

```
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()

```
> 3 votes

# Answer
# 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.
> 3 votes

# Answer
# 05AB1E, ~~48~~ ~~46~~ 45 bytes

```
3„ks4„ps8).•ŒMb•ASr‡•qâ&¬k±ûï+%ΘÔβ>&•₂в944+ç:

```

Try it online.

**Explanation:**

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)
•qâ&¬k±ûï+%ΘÔβ>&•
           # 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]`.
> 2 votes

# Answer
# Retina 0.8.2, 45 bytes

```
ks
3
ps
4
T`abg\dez\h8ik-n3o-pr_styfx4w`α-ω

```

Try it online! Link includes test cases. Explanation:

```
ks
3
ps
4

```

Translate the digraphs.

```
T`abg\dez\h8ik-n3o-pr_styfx4w`α-ω

```

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.)
> 2 votes

# Answer
# Vyxal, 53 bytes

```
‛ks958CV‛ps968CVka«Þİ»«»1m»Ŀ»4⁽.ṘŻ⟨«⋎D-§ƛE←₍»₄τ944+CĿ

```

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.

```
‛ks958CV‛ps968CVka«Þİ»«»1m»Ŀ»4⁽.ṘŻ⟨«⋎D-§ƛE←₍»₄τ944+CĿ
‛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

```
> 2 votes

# Answer
# Charcoal, 50 bytes

```
≔”+%⊟⊟Kκ↓⁼≧T_Ｘ4⍘«⊞⊞ ↘”θ⭆⪫⪪⪫⪪ＳksＩ³psＩ⁴⎇№θι℅⁺⁹⁴⁵⌕θιι

```

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

```
≔”+%⊟⊟Kκ↓⁼≧T_Ｘ4⍘«⊞⊞ ↘”θ

```

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

```
⭆⪫⪪⪫⪪ＳksＩ³psＩ⁴⎇№θι℅⁺⁹⁴⁵⌕θιι

```

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.
> 2 votes

# Answer
# Lexurgy, 127 bytes

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

```
Symbol ks,ps
k:
{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}=>{α,β,γ,δ,ε,ζ,η,θ,ι,κ,λ,μ,ν,ξ,ξ,ο,π,ρ,σ,τ,υ,φ,χ,ψ,ψ,ω}

```
> 2 votes

---
Tags: code-golf, string, natural-language, substitution
---


title: Typo resistant pin codes

text:
# Question
Title: Typo resistant pin codes
## Background

I was working on a system where for convenience (not security) people could use four digit codes to identify themselves. I figured this is something that may actually be useful in many real cases, yet is well enough defined that it could make a nice challenge!

## Explanation of pin codes and typo resistant sets

EDIT: Based on the comments, this is probably a more formal definition:

> I think a mathematical way of specifying what you are looking for is a maximal set of strings with length 4 over the alphabet {0,1,2,3,4,5,6,7,8,9} with minimum pairwise hamming distance 2, if it helps others.

There are 10000 possible pin codes (0000-9999).

Example pin code

```
1234

```

However, since a typo is easily made you are to generate a set of pincodes that is resistant to a single typo.

Example of set that is NOT resistant to single typo:

```
0000
0005 (if you mistype the last digit as 0 instead of 5, you get another code in the set)

```

Example of set that IS resistant to single typo

```
0000
0011
0101
0202

```

## Allowed outputs

The allowed output can be a bit flexible, specifically:

* A pincode may be a string or a number
* You may always have separators (e.g. comma, newline), however if your codes are always represented as 4 digits separators are optional
* The codes should be represented by 0-9, not other characters

Example sets:

```
0011,0022: OK
00220011: OK
11,22,33: OK
112233: NOT OK
abcd,abef: NOT OK
{'1111',/n'2222'}: OK

```

## Scoring system

The primary score is the number of unique pin codes generated (note that 0001,1000 would count as 2).

Edit: If your code does not always generate the same amount of unique pin codes you must estimate the amount it will at least generate in 95% of the cases and you may use that as your score. So for example if you uniformly randomly generate between 300 and 400 unique pincodes, your score would be 395.

In case there is a tie, the shortest code wins!

Please post your score as: Language, #Unique codes generated with bytes (e.g. Python, 30 codes generated with 123 bytes)

(I guess formally this could be rewritten to 'generate X typo resistant pin codes' but as I have no idea what X is I will keep it like this, this also allows simpler solutions to compete against each other on lenght for 'third place' and beyond.)

---

In principle no inputs are needed and for simplicity sake I will not make it part of the challenge and scoring, but it would be interesting to see how the code would need to be changed to allow for various length pin codes.

# Answer
# Vyxal `M`, 6 bytes, 1000 codes

```
k2'∑₀Ḋ

```

Try it Online!

Uses that the digit sum must be divisible by 10.

```
k2'∑₀Ḋ
k2'    # Filter for elements in [0, 10000]:
   ∑₀Ḋ #  Is the digit sum divisible by 10?

```
> 2 votes

# Answer
# Python 2, 1000 unique pin codes, 44 bytes

```
i=0;exec'print i+int(`i`,11)%10;i+=10;'*1000

```

Try it online!

I suspect 1000 pin codes is optimal. You can check the verification program.

## How was this discovered?

The process for discovering this rather simple formula was quite messy for me. The first insight I had was that you can transform this into a graph problem - let the PIN numbers be nodes and connect edges if and only if the hamming distance between the PIN numbers is greater than 1. Then the problem boils down to finding a maximum clique of the graph. From reading some papers apparently there was a simple C program available in the web archive that solves the maximal clique problem for small instances, so I downloaded it (and patched it a little bit since it doesn't compile on a modern compiler). I wrote a simple driver program to generate input in the format it expected and ran it. It was too slow for the full problem but I noticed something odd about its output for smaller instances:

```

...
level = 9997(10000) best = 100 time =     0.65
level = 9998(10000) best = 100 time =     0.65
level = 9999(10000) best = 100 time =     0.65
level = 10000(10000) best = 100 time =     0.65
Record: 9 10 21 32 43 54 65 76 87 98 100 111 122 133 144 155 166 177 188 199 201 212 220 234 245 253 267 278 289 296 302 313 324 330 341 356 368 379 385 397 403 414 425 431 447 458 469 470 486 492 504 515 526 537 548 559 560 571 582 593 605 616 623 638 649 657 661 672 680 694 706 717 728 739 740 751 762 773 784 795 807 818 829 835 846 852 863 874 881 890 908 919 927 936 942 950 964 975 983 991

```

For the first 1000 PINs, the optimal clique had 100 nodes, which suspiciously looks like just the number of PINs divided by 10. And also, every prefix from `000..099` appeared once. This led me to hypothesize that there was some closed form solution of the form:

```
10 * i + f(i) % 10

```

It looks like `f` is almost just `f(i) = i` but occasionally it jumps some extra.

After toying around a little bit, I came across the formula `(i + i / 10 + i / 100) % 10`, which passes. But `(i + i / 10 + i / 100) % 10` is just `int(str(i), 11) % 10`, that is, reinterpreting the digits of `i` in base 11! This gives the final answer.
> 10 votes

# Answer
# 05AB1E, 1000 codes generated with 7 bytes

```
9Ý4ãʒOθ

```

Try it online!

Works using the observation that you can append any function \\$ f(a, b, c) \\$ to all 3-digit PINs \\$ abc \\$ iff after fixing two of the variables you get a permutation - no value appears more than once. This code uses \\$ f(a, b, c) = (1 - a - b - c) \mod 10 \\$, which is equivalent to the statement that the last digit of the PIN's digit sum is 1.

```
9Ý     push [0, 1, 2, ..., 9]
4ã     push the fourth cartesian power, all choices of four values from the above list
ʒ      keep only elements for which the following returns 1
 O     sum all values
 θ     take the last digit of the sum

```
> 7 votes

# Answer
# K (ngn/k), 1000 codes, 16 bytes

```
(~10!+/')#+!4#10

```

Try it online!

-5 bytes thanks to @CommandMaster and @ovs!

Uses @xnor's clever observation that each pin can satisfy `(digit sum) mod 10 == 0`.

## Explanation

* `+!4#10` generate all 4-digit pins
* `(...)#` filter...
    + `~10!+/'` equivalent to `(digit sum) mod 10 == 0`
> 4 votes

# Answer
# Charcoal, 1000 codes, 17 bytes

```
ＵＢ0←ＥΦＸχ⁴¬﹪Σιχ⮌Ｉι

```

Try it online! Link is to verbose version of code. Explanation: Uses @xnor's observation.

```
ＵＢ0                 Zero-fill the output.
   ←Ｅ         ⮌Ｉι   Output right-aligned an in reverse order.
       χ            Predefined variable `10`
      Ｘ             Raised to power
        ⁴           Literal integer `4`
     Φ              Filter over implicit range
            ι       Current value
           Σ        Digital sum
          ﹪         Modulo
             χ      Predefined variable `10`
         ¬          Is zero

```

By replacing the  with an  the program will accept the number of digits in the PIN as an input.
> 3 votes

# Answer
# JavaScript (ES6), 1000 codes, 46 bytes

Returns a comma-separated string. Based on xnor's observation.

```
f=(n=1e3)=>--n&&n+[~(~(n/100)-n-n/10)%10,f(n)]

```

Try it online!
> 3 votes

# Answer
# Desmos, 61 bytes

```
l=[0...9999]
l[[mod(floor(i/10^{[0...3]}).total,10)fori=l]=0]

```

Outputs a list of numbers. Uses xnor's observation that the digit sum has to be a multiple of 10.

Try It On Desmos!

Try It On Desmos! - Prettified
> 2 votes

---
Tags: code-golf, code-challenge, generation
---


title: Are the lists divisible?

text:
# Question
Title: Are the lists divisible?
*Inspired (with the explanation stolen from) this*

## Background

Say you have two lists `A = [a_1, a_2, ..., a_n]` and `B = [b_1, b_2, ..., b_n]` of integers. We say `A` is **potentially-divisible** by `B` if there is a permutation of `B` that makes `a_i` divisible by `b_i` for all `i`. The problem is then: is it possible to reorder (i.e. permute) `B` so that `a_i` is divisible by `b_i` for all `i`? For example, if you have

```
A = [6, 12, 8]
B = [3, 4, 6]

```

Then the answer would be `True`, as `B` can be reordered to be `B = [3, 6, 4]` and then we would have that `a_1 / b_1 = 2`, `a_2 / b_2 = 2`, and `a_3 / b_3 = 2`, all of which are integers, so `A` is potentially-divisible by `B`.

As an example which should output `False`, we could have:

```
A = [10, 12, 6, 5, 21, 25]
B = [2, 7, 5, 3, 12, 3]

```

The reason this is `False` is that we can't reorder `B` as 25 and 5 are in `A`, but the only divisor in `B` would be 5, so one would be left out.

## Your task

Your task is, obviously, to determine whether two lists (given as input) are potentially divisible. You may take input in any accepted manner, as with output.

Duplicates in the lists are a possibility, and the only size restrictions on the integers are your language. All integers in both lists will be larger than 0, and both lists will be of equal size.

As with all s the output values must be 2 distinct values that represent true and false.

This is a so shortest code wins!

## Test cases

```
Input, input => output

[6, 12, 8], [3, 4, 6] => True
[10, 5, 7], [1, 5, 100] => False
[14, 10053, 6, 9] [1,1,1,1] => True
[12] [7] => False
[0, 6, 19, 1, 3] [2, 3, 4, 5, 6] => undefined

```

# Answer
# Husk, ~~7~~ ~~6~~ 5 bytes

Saved 2 bytes thanks to @Zgarb

```
▼▲‡¦P

```

Takes argents in reverse order and returns `1` for `True` and `0` for `False`.

Try it online!

### Explanation

```
    P     -- Permutations of the first argument
  ‡       -- Deep zip (vectorises function) with second argument
   ¦      --   Does x divide y
 ▲        -- Get the maximum of that list, returns [1,1...1] if present
▼         -- Get the minimum of that list, will return 0 unless the list is all 1s

```
> 10 votes

# Answer
# Jelly, 5 bytes

```
Œ!%ḄẠ

```

Returns **0** for *True*, **1** for *False*.

Try it online!

### How it works

```
Œ!%ḄẠ  Main link. Arguments: A, B (arrays)

Œ!     Generate all permutations of A.
  %    Take each permutation modulo B (element-wise).
   Ḅ   Convert all resulting arrays from binary to integer.
       This yields 0 iff the permutation is divisible by B.
    Ạ  All; yield 0 if the result contains a 0, 1 otherwise.

```
> 10 votes

# Answer
# MATL, ~~8~~ ~~7~~ 6 bytes

*1 byte off using an idea from Dennis' Jelly answer*

```
Y@\!aA

```

Inputs are `B`, then `A`. Output is `0` if divisible or `1` if not.

**Try it online!**

### Explanation

```
Y@     % Implicit input: row vector B. Matrix of all permutations, each on a row
\      % Implicit input: row vector A. Modulo, element-wise with broadcast. Gives
       % a matrix in which each row contains the moduli of each permutation of B
       % with respect to A
!a     % True for rows that contain at least a nonzero value
A      % True if all values are true. Implicit display

```
> 6 votes

# Answer
# 05AB1E, 7 bytes

Input: takes lists B and A (reversed order)
Output: 1 when true, 0 otherwise

```
œvIyÖPM

```

Try it online!

Explanations:

```
œvIyÖPM    Complete program
œ          Pushes all permutations of B as a list
 v         For each permutation
  I        Pushes last input on top of the stack
   yÖ      Computes a % b == 0 for each element of A and B
     P     Pushes the total product of the list
      M    Pushes the largest number on top of the stack

```
> 6 votes

# Answer
# Mathematica, 52 bytes

```
Cases[Permutations@#2,p_/;And@@IntegerQ/@(#/p)]!={}&

```

*thanks @ngenisis for -5 bytes*
> 4 votes

# Answer
# Haskell, ~~79~~ ~~74~~ ~~68~~ ~~62~~ 61 bytes

```
import Data.List
f a=any((<1).sum.zipWith rem a).permutations

```

Try it online!

*Saved 1 byte thanks to @nimi*
> 4 votes

# Answer
# JavaScript (ES6), ~~67~~ 63 bytes

Returns a boolean.

```
f=([x,...a],b)=>!x||b.some((y,i)=>x%y?0:f(a,c=[...b],c[i]=1/0))

```

### Test cases

```
f=([x,...a],b)=>!x||b.some((y,i)=>x%y?0:f(a,c=[...b],c[i]=1/0))

console.log(f([6, 12, 8],[3, 4, 6]))        // true
console.log(f([10, 5, 7],[1, 5, 100]))      // false
console.log(f([14, 10053, 6, 9],[1,1,1,1])) // true
console.log(f([12],[7]))                    // false
```
> 4 votes

# Answer
# \+ combinat, ~~69~~ ~~66~~ 58 bytes

*-3 bytes thanks to Jarko Dubbeldam*

*another -8 bytes thanks to Jarko*

```
function(a,b)any(combinat::permn(b,function(x)all(!a%%x)))

```

oddly, R doesn't have a builtin for generating all permutations. Returns a boolean.

Additionally, with Jarko's second improvement, `any` coerces the list to a vector of `logical` with a warning.

Try it online! (r-fiddle)
> 4 votes

# Answer
# Mathematica, 42 bytes

```
MemberQ[Permutations@#2,a_/;And@@(a∣#)]&

```
> 3 votes

# Answer
# C (gcc), 191 bytes

```
#define F(v)for(i=0;i<v;++i){
#define X if(f(s,n,a,b))return 1
j;f(s,n,a,b,i)int*a,*b;{if(--n){F(n)X;j=i*(n%2);b[j]^=b[n];b[n]^=b[j];b[j]^=b[n];}X;}else{F(s)if(a[i]%b[i])return 0;}return 1;}}

```

Try it online!

**Usage:** `f(int size, int size, int *a, int *b)`

returns `1` if divisable, `0` otherwise. See example usage on TIO.

(Gotta do permutations the hard way in C, so this is hardly competitive)
> 3 votes

# Answer
# Brachylog, 6 bytes

```
pᵐz%ᵛ0

```

Try it online!

The predicate succeeds if the two lists are potentially divisible and fails if they are not.

```
pᵐ        For some pair of permutations of the two input lists,
  z       for each pair of corresponding elements
   %ᵛ0    the first mod the second is always zero.

```
> 3 votes

# Answer
# Jelly, 7 bytes

```
Œ!ọẠ€1e

```

Try it online!

Factorial complexity in the length of the list.
> 2 votes

# Answer
# Pyth - 11 bytes

```
sm!s%Vdvz.p

```

Test Suite.
> 2 votes

# Answer
# CJam, ~~20~~ 17 bytes

```
:A;e!{A\.%:+!}#W>

```

Test Version

Function that takes array B as the first argument and array A as the second argument. Note that in the test version I switch the order to A then B.
> 2 votes

# Answer
# PHP, ~~112 180~~ 178 bytes

I was thinking too short.

```
function($a,$b){for($p=array_keys($b);++$i<count($b);){foreach($b as$k=>$x)$f|=$a[$k]%$x;if($f=!$f)return 1;$p[$i]?[$b[$j],$b[$i],$i]=[$b[$i],$b[$j=$i%2*--$p[$i]],0]:$p[$i]=$i;}}

```

anonymous function takes two arrays, returns `NULL` for falsy and `1` for truthy.
Throws an error if second array contains `0`.

Try it online.
> 2 votes

# Answer
# J, 27 bytes

```
0=[:*/(A.~i.@!@#)@]+/@:|"1[

```

Try it online!

Takes the first list as the left argument and the second list as the right.
> 2 votes

# Answer
## JavaScript (ES6), 100 bytes

```
f=(a,b)=>!a[0]||a.some((c,i)=>b.some((d,j)=>c%d<1&f(e=[...a],d=[...b],e.splice(i,1),d.splice(j,1))))

```

Somewhat inefficient; an extra `&` would speed it up.
> 2 votes

# Answer
# Python 2, 90 bytes

```
lambda a,b:any(sum(map(int.__mod__,a,p))<1for p in permutations(b))
from itertools import*

```

Try it online!
> 2 votes

# Answer
# Perl 6, 38 bytes

Actually @nwellnhof's answer seems to be too much readable, so I set out to follow the fine Perl tradition of write-only code :—).

1 byte saved thanks to @nwellnhof.

```
{min max (@^a,) XZ%% @^b.permutations}

```

Try it online!

What does it do: It's an anonymous function that takes two list arguments. When we say `@^a`, we mean the first one, when `@^b`, it's the second one.

`(@^a,)` is a list containing the list `@^a`. `@^b.permutations` is the list of all the permutations of `@^b`. The "XZ%%" operator makes all possible pairs of that one list on the left and all the permutations on the right, and uses the operator "Z%%" on them, which is the standard "zip" operation using the divisibility operator %%.

The `max` operator gives the largest element of the list (in this case, it's the list that has the most `True`'s in it). We then reduce it using the logical AND operator to see if all elements of that "most true" list are true, and that's the result. It's nearly exact copy of what @nwellnhof wrote, just using obscure operators to shave off bytes.
> 2 votes

# Answer
# Factor \+ `math.combinatorics math.unicode`, 49 bytes

```
[ <permutations> [ v/ [ ratio? ] ∄ ] with ∃ ]

```

Try it online!

* `<permutations> [ ... ] with ∃` Is there any permutation of the second input where...
* `v/` ...the quotient of the first input and the permutation...
* `[ ratio? ] ∄` ...contains no ratios? (In other words, are they all integers?)
> 2 votes

# Answer
# Vyxal, 7 bytes

```
Ṗ$vḊvAa

```

Try it Online!
> 2 votes

# Answer
# Python 2, 92 bytes

```
lambda a,b:any(all(x%y<1for x,y in zip(a,p))for p in permutations(b))
from itertools import*

```

Try it online!

Yer basic implementation.
> 1 votes

# Answer
# Japt, ~~12~~ 11 bytes

Outputs `true` or `false`.

```
Vá de@gY vX

```

Test it

---

## Explanation

Implicit input of arrays `U` & `V` (`A` & `B`, respectively)

Generate an array of all permutations of `V`.

```
d

```

Check if any of the elements (sub-arrays) return true.

```
e@

```

Check if every element in the current sub-array returns true when passed through the following function, with `X` being the current element and `Y` the current index.

```
gY

```

Get the element in `U` at index `Y`.

```
vX

```

Check if it's divisible by `X`.
> 1 votes

# Answer
# Ruby, 56 bytes

```
->x,y{x.permutation.any?{|p|p.zip(y).all?{|a,b|a%b==0}}}

```

Try it online!

Fairly straightforward, exploits the fact that `permutation` exists.
> 1 votes

# Answer
# Scala, 60 Bytes

**Golfed:**

```
a=>b=>b.permutations exists(a zip _ forall(p=>p._1%p._2==0))

```

**Ungolfed:**

```
a=>b=>         // Function literal taking 2 lists of integers, a and b.
b.permutations // All permutations of b.
exists(        // Whether the given function is true for any element.
a zip _        // Zips a and the current permutation of b into a list of pairs.
forall(        // Whether the given function is true for all elements.
p=>            // Function literal taking a pair of integers.
p._1%p._2==0)) // If the remainder of integer division between the members of the pair is 0.

```
> 1 votes

---
Tags: code-golf, math, array, decision-problem
---


title: Is it a strong word?

text:
# Question
Title: Is it a strong word?
They say that `hate` is a strong word. I wanted to find out why, so I had a good look at the word.

I noticed that every consonant had a vowel after it. That made it look quite strong to me, so I decided that that's what makes a word strong.

I want to find more strong words, so I'll need a program for it!

# Finding strong words

Strong words are words where every consonant (letters in the set `BCDFGHJKLMNPQRSTVWXZ`) is followed by a vowel (letters in the set `AEIOUY`). That's it. Nothing else matters.

If the word starts with a vowel, you don't have to worry about any of the letters before the first consonant. If the word has no consonants in it at all, it's automatically a strong word!

Some examples of strong words are `agate`, `hate` and `you`. `agate` is still a strong word because although it starts with a vowel, every consonant is still followed by a vowel. `you` is a strong word because it has no consonants.

There is no restriction on length for strong words.

# The challenge

Write a program or function that takes a non-empty string as input, and outputs a truthy value if it is a strong word or a falsy value if it is not.

# Clarifications

* You may decide to take the input in either lowercase or uppercase. Specify which in your answer.
* Words will not contain punctuation of any kind. They will only contain plain letters in the set `ABCDEFGHIJKLMNOPQRSTUVWXYZ`.
* Instead of truthy and falsy values, you may choose two distinct and consistent values to return for true and false. If you do this, specify the values you have picked in your answer.
    + You may alternatively output a falsy value for a strong word and a truthy one for a non-strong word.

# Test cases

```
Input      -> Output
hate       -> true
love       -> true
popularize -> true
academy    -> true
you        -> true
mouse      -> true
acorn      -> false
nut        -> false
ah         -> false
strong     -> false
false      -> false
parakeet   -> false

```

# Scoring

Since this is , the answer with the least bytes wins!

# Answer
# JavaScript (ES6), ~~36~~ ~~28~~ 27 bytes

<sup>*Saved 1 byte by inverting the result, as suggested by LarsW*</sup>

Takes input in lowercase. Returns `false` for a strong word and `true` for a non-strong word.

```
s=>/[^aeiouy]{2}/.test(s+0)

```

### How?

We append a `0` (non-vowel) at the end of the input string and look for two consecutive non-vowel characters. This allows us to cover both cases that make a word *not* strong:

* it contains two consecutive consonants
* *or* it ends with a consonant

### Test cases

```
let f =

s=>/[^aeiouy]{2}/.test(s+0)

;[
  "hate", "love", "popularize", "academy", "you", "mouse", "a", "euouae",
  "acorn", "nut", "ah", "strong", "false", "parakeet"
]
.forEach(s => console.log(s + ' --> ' + f(s)))
```
> 18 votes

# Answer
# Python 2, 48 bytes

```
lambda s:'se, F'in`[v in'aeiouy'for v in s+'b']`

```

An unnamed function taking a (lowercase) string, `s`, and returning `False` if strong or `True` if not.

**Try it online!** (inverts the results to match the OP)

### How?

Non-strong words have either a consonant followed by a consonant or end in a consonant.

The code adds a consonant to the end (`s+'b'`) to make the required test be just for two consonants in a row.

It finds out if each letter in the altered word is a vowel with the list comprehension `[v in'aeiouy'for v in s+'b']`.

It now needs to check for two `False` results in a row (signalling a non-strong word), it does so by getting a string representation (using ``...``) of this list and looking for the existence of `'se, F'`. This is the shortest string found in `'False, False'` but none of: `'True, True'`; `'False, True'`; or `'True, False'`.

As an example consider `'nut'`, the list comprehension evaluates each letter, `v`, of `'nutb'` for existence in `'aeiouy'` yielding the list `[False, True, False, False]`, the string representation of this list is `'[False, True, False, False]'` which contains `'e, F'` here: `'[False, True, Fals>>e, F<<alse]'` hence the function returns `True` meaning that nut is **not** a strong word.
> 12 votes

# Answer
# Jelly,  ~~10~~  9 bytes

```
e€ØY;Ạ11ẇ

```

A monadic link taking a list of characters and returning:

* `0` if strong
* `1` if not

**Try it online!** or see the test-suite.

### How?

```
e€ØY;Ạ11ẇ - Link: list of characters, s      e.g. "hate"  or  "you"  or  "not"
  ØY      - consonant yield                   "BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"
e€        - exists in? for €ach letter            [1,0,1,0]   [0,0,0]    [1,0,1]
     Ạ    - all truthy? (1 for any valid input)   1           1          1
    ;     - concatenate                           [1,0,1,0,1] [0,0,0,1]  [1,0,1,1]
      11  - literal eleven
        ẇ - sublist exists?                       0           0          1
          -  N.B.: left of ẇ implicitly makes digits so it looks for the sublist [1,1]

```

Note: The reason for using  is just to save a byte over using `1` (since we then want to use `11` straight away).
> 7 votes

# Answer
# , 43 bytes

```
function(s)grep("[^aeiouy]{2}",paste(s,""))

```

Try it online!

A port of Arnauld's JavaScript answer; returns 1 for weak words and `integer(0)` for strong ones; it appends a  (space) to the end of the string.

This is actually vectorized; with a vector of strings, it returns the indices (1-based) of the weak words.
> 5 votes

# Answer
# 05AB1E, 8 bytes

### Code

```
žPS¡¦õÊP

```

Uses the **05AB1E** encoding. Try it online!

### Explanation

```
žPS¡         # Split the string on consonants (bcdfghjklmnpqrstvwxz)
    ¦        # Remove the first element of the array to handle cases when the
               string starts with a consonant
     õÊP     # Check if the empty string is not in the array

```

### Example

```
             # "popularize"
žPS¡         # ['', 'o', 'u', 'a', 'i', 'e']
    ¦        # ['o', 'u', 'a', 'i', 'e']
     õÊ      # [1, 1, 1, 1, 1]
       P     # 1

```
> 5 votes

# Answer
# Dyalog APL, 20 bytes

```
⎕←∧/2∨/0,⍨⍞∊'aeiouy'

```

Try it online!
> 3 votes

# Answer
# Haskell, ~~61~~ 54 bytes

```
f=and.(zipWith(||)=<<tail).(map(`elem`"aeiouy")).(++"z")

```

Try it online!

I had to add a `z` at the end of the string to handle the case of a trailing consonant.
> 3 votes

# Answer
# Husk, 12 bytes

```
ΛΣX_2m€¨γaıu

```

Try it online!

Thanks to H.PWiz for help with -4. ~~Returns inconsistent but appropriately truthy or falsy values.~~
Thanks to Leo for -1, now returns consistent truthy/falsy value.
> 3 votes

# Answer
# Java (OpenJDK 8), ~~93~~ 81 bytes

```
s->{int w=0,p=w,l;for(char c:s)w|=p&(p=l="aeiouy".indexOf(c)>>31);return w+p>=0;}

```

Try it online!
> 2 votes

# Answer
# Pyth, 18 bytes

```
:+Q1."2}M>åYà

```

**Verify all the test cases.**

"Borrowed" the regex from the JS answer. This returns `False` for strong words, `True` otherwise
> 2 votes

# Answer
# Ruby, 25 bytes

```
->w{w+?t!~/[^aeiouy]{2}/}

```

Try it online!

Everybody else is doing it, so why can't Ruby?
> 2 votes

# Answer
# Brachylog, ~~18~~ ~~11~~ 10 bytes

```
,Ḷs₂{¬∈Ẉ}ᵐ

```

Try it online!

Neat and simple (except maybe for the 2 extra initial bytes to handle the final consonant case, like "parakeet").

Is falsey for strong words and truthy for non-strong words.

```
,Ḷ               % append a newline (non-vowel) at the end of input,
                 %   to catch final consonants
     s₂          % the result has some substring of length 2
       {¬∈Ẉ}ᵐ    % where neither of its elements belong to
                 %   the set of alternate vowels (with "y")

```
> 2 votes

# Answer
# Jelly, 11 bytes

```
e€ØY;1a2\¬Ȧ

```

Try it online!

```
e€ØY;1a2\¬Ȧ  Main link
 €           For each letter
e            Is it an element of
  ØY         The consonants (excluding Yy)?
    ;1       Append 1 (true) (consonant) to make sure last letter isn't consonant
       2\    For all (overlapping) slices of length 2 (the <link><nilad>\ functionality)
      a      Logical AND of the two values; is it a consonant pair?
         ¬   Logical NOT vectorizing; for each (overlapping) pair, is it not a consonant pair?
          Ȧ  Any and all; make sure all pairs are not consonant pairs

```

Yes I know I've been beaten a lot by Jonathan Allan but I wanted to share my approach anyway :P

-4 bytes by stealing a little bit of Jonathan Allan's answer (instead of appending a consonant to check for last-letter edge case, just append 1)
-1 byte thanks to miles
> 1 votes

# Answer
# Perl 5, 31 bytes (30 + 1)

```
$_=''if/[^aeiouy](?![aeiouy])/

```

+1 byte for `-p` command line flag. Prints the word if it's a strong word, or the empty string if it is not.
> 1 votes

# Answer
# Retina, ~~23~~ 18 bytes

```
$
$
1`[^aeiouy]{2}

```

Try it online! Outputs 0 for strong, 1 if not. Add 1 byte to support mixed case. Edit: Saved 5 bytes thanks to @ovs.
> 1 votes

# Answer
# Awk, 39 bytes

```
/([^aeiouy]{2}|[^aeiouy]$)/{print "n"}

```

prints `n` for non-strongword, nothing (or, just a newline) for strongword

following the pack and searching for two consecutive non-vowels on lowercase input

testing

```
$ awk -f strongwork.awk
hate
love
popularize
academy
you
mouse
acorn
n
nut
n
ah
n
strong
n
false
n
parakeet
n

```
> 1 votes

# Answer
# Kotlin, 49 bytes

```
{Regex(".*[^aeiouy]([^aeiouy].*|$)").matches(it)}

```

**True and false are swapped**

## Beautified

```
{
    Regex(".*[^aeiouy]([^aeiouy].*|$)").matches(it)
}

```

## Test

```
var s:(String)->Boolean =
{Regex(".*[^aeiouy]([^aeiouy].*|$)").matches(it)}
data class TestData(val input: String, val output: Boolean)

fun main(args: Array<String>) {
    val items = listOf(
            TestData("hate", true),
            TestData("love", true),
            TestData("popularize", true),
            TestData("academy", true),
            TestData("you", true),
            TestData("mouse", true),
            TestData("acorn", false),
            TestData("nut", false),
            TestData("ah", false),
            TestData("strong", false),
            TestData("false", false),
            TestData("parakeet", false)
    )

    items
            .filter { s(it.input) == it.output }
            .forEach { throw AssertionError(it.toString()) }

    println("Test Passed")
}

```

TryItOnline

Based on @Arnauld's Answer
> 1 votes

# Answer
# Java 8, ~~53~~ 42 bytes

```
s->s.matches(".*[^aeiouy]([^aeiouy].*|$)")

```

-11 bytes by using the same regex as in *@jrtapsell*'s Kotlin answer instead.

Try it here. (`false` if strong; `true` if not)

**Explanation:**

```
s->               // Method with String parameter and boolean return-type
  s.matches(      //  Checks if the String matches the following regex:
    ".*           //   One or more characters
     [^aeiouy]    //   Followed by a consonant
     ([^aeiouy].* //   Followed by another consonant (+ any more characters)
      |$)")       //   Or the end of the String
                  // End of method (implicit / single-line return statement)

```

So it basically checks if we can find two adjacent consonants, or if the String ends with a consonant.

---

Old answer (**53 bytes**):

```
s->s.matches("[aeiouy]*([a-z&&[^aeiouy]][aeiouy]+)*")

```

Try it here. (`true` if strong; `false` if not)

Uses regex to see if the input-String matches the 'strong'-regex. Note that `String#matches` in Java automatically adds `^...$` to check if the String entirely matches the given regex.

**Explanation":**

```
 s->                   // Method with String parameter and boolean return-type
  s.matches(           //  Checks if the String matches the following regex:
    "[aeiouy]*         //   0 or more vowels
    ([a-z&&[^aeiouy]]  //     { A consonant,
     [aeiouy]+)        //       plus one or more vowels }
    *")                //    Repeated 0 or more times
                       // End of method (implicit / single-line return statement)

```

---

A search instead of matches (like a lot of other answers use) is actually longer in Java:
**70 bytes**:

```
s->java.util.regex.Pattern.compile("[^aeiouy]{2}").matcher(s+0).find()

```

Try it here. (`false` if strong; `true` if not)
> 1 votes

# Answer
# Python 2, 58 bytes

*-30 bytes by realizing it can be as simple as Arnauld's JS answer.*

```
lambda s:re.search('[^aeiouy]([^aeiouy]|$)',s)<1
import re

```

Try it online!
> 0 votes

# Answer
# SOGL V0.12, ~~19~~ 18 bytes

```
æ"[^ŗy]”ŗ(ŗ|$)”øβ=

```

Try it Here!

Explanation:

```
æ                   push "aeiou"
 "[^ŗy]”            push "[^ŗy]" with ŗ replaced with pop
        ŗ(ŗ|$)”     push `ŗ(ŗ|$)` with ŗ replaced with pop
               øβ   replace in the input that regex with nothing
                 =  check for equality with the original input

```
> 0 votes

# Answer
# 05AB1E, 11 bytes

```
žP¹SåJ1«11å

```

Try it online!

Uses Jonathan's algorithm, returns `0` for true and `1` for false.
> 0 votes

# Answer
## C++, ~~195~~ 194 bytes

-1 bytes thanks to Zacharý

Uppercase, return true if input is a strong word, false otherwise ( C++ have simple int to bool implicit cast rules, 0 =\> false, true otherwise )

```
#include<string>
#define C(p)(v.find(e[p])==size_t(-1))
std::string v="AEIOUY";int s(std::string e){for(int i=0;i<e.size()-1;++i)if(e[i]>64&&e[i]<91&&C(i)&&C(i+1))return 0;return!C(e.size()-1);}

```

**Code to test :**

```
auto t = {
    "HATE",
    "LOVE",
    "POPULARIZE",
    "ACADEMY",
    "YOU",
    "MOUSE",
    "ACORN",
    "NUT",
    "AH",
    "STRONG",
    "FALSE",
    "PARAKEET"
};

for (auto&a : t) {
    std::cout << (s(a) ? "true" : "false") << '\n';
}

```
> 0 votes

# Answer
# Swift 3.1, 85 bytes

```
import Foundation
{($0+"0").range(of:"[^aeiouy]{2}",options:.regularExpression)==nil}

```

**Try it here!**

This borrows Arnauld's regex.
> 0 votes

# Answer
# Lua, 41 bytes

```
return#(io.read()..0):match"[^aeiouy]+"<2

```

Reads from standard input

# Lua (loadstring'ed), 37 bytes

```
return#((...)..0):match"[^aeiouy]+"<2

```

Reads from function parameter(s)

---

Input is lowercase

Sees if there is a string of length 2 or more, consisting only of not vowels (consonants) or if the string ends with a non-vowel

Returns true/false
> 0 votes

# Answer
# C, 107 Bytes

```
i,v,w,r,t;a(char*s){w=0;for(r=1;*s;s++){v=1;for(i=6;v&&i;)v=*s^" aeiouy"[i--];r=w&&v?0:r;w=v;}return r&~v;}

```

Returns 1 for *strong* word and 0 for *weak* word. Tested with the words given in the main post.
> 0 votes

# Answer
# C (gcc), 59 bytes

```
f(char*s){return*s?strcspn(s,"aeiouy")+!s[1]<2?f(s+1):0:1;}

```

Try it online!
> 0 votes

# Answer
# **PHP, 69 bytes**

```
preg_match("/([^AEIOUY][^AEIOUY]+|[^AEIOUY]$)/",$_SERVER['argv'][1]);

```

Returns **1** is the word is not strong.
> 0 votes

# Answer
# CJam, 57 bytes

```
q{"aeiouy"#W=}%_,:B{_A={_A_)\B(<{=!X&:X;}{0:X;;;}?}&}fA;X

```

Try it online!

---

Reads input, converts to 1s for consonants, 0s for vowels. For every consonant, AND predefined variable X (predefined to 1) with next character's value. Output X
> 0 votes

# Answer
# Zsh, 21 bytes

```
>$1x<*[^aeiouy](#c2)*
```

Attempt This Online!

Same method everyone else is using. Outputs via exit code: 1 for strong, 0 for not strong. Requires the `extendedglob` option.
> 0 votes

---
Tags: code-golf, string, decision-problem
---