| Bytes | Lang | Time | Link |
|---|---|---|---|
| 269 | Charcoal | 250919T110040Z | Neil |
| 123 | 05AB1E | 250917T135728Z | Kevin Cr |
| 038 | Vyxal | 250917T020752Z | lyxal |
Charcoal, 269 bytes
¿ΣθI⊗θ«¿‹⌈θaF⁴F⪪”{⊞¶σ?~⧴θπ⪪λpAz” F⪪”{⊞‴▶Lc⧴d~dφW¶″” F⪪”{⊞‴ΣAº⧴θπ⪪λpAz” ⊞υ⁺⁺⁺×Mικλμ«≔⁺⟦⟦⟧⟧⪪”↶⌈ü?↑»lη+:,x&⪫⁻↘ξⅈ↔⟲▶M↖S₂υüXα◨…≡⧴~→*MZv℅№ⅈSU{+ⅉ◨·c↨Xcⅉ×|№O_U⁼züN÷5\δHDKθZ↖×” ηF⪪”↶±!κ⊖⍘~vd⎇¿Σ¦#¬J§c✳“εWWs⊞G⧴lºμ¤TCX” F…ηχ⊞η⪫Φ⟦ικ⟧λ F…ηχF…ηχFη⊞υ⪫Φ⟦⁺ι thousand⁺κ hundredλ⟧μ »§υ⊗⌕υθ
Try it online! Link is to verbose version of code. Handles Roman numerals up to MCMXCIX and English up to four thousand nine hundred ninety nine. Explanation:
¿Σθ
Are there any non-zero digits in the input?
I⊗θ«
If so, then treat it as a decimal number and double it. Otherwise:
¿‹⌈θa
If the input contains no lower case letters, then...
F⁴F⪪... F⪪... F⪪... ⊞υ⁺⁺⁺×Mικλμ«
Generate all the Roman numerals from (0) to 3999 by concatenating entries from compressed strings. Otherwise:
≔⁺⟦⟦⟧⟧⪪... η
Start with the words from one to nineteen, plus the empty list for zero.
F⪪... F…ηχ⊞η⪫Φ⟦ικ⟧λ
Using the words from twenty to ninety, generate the numbers for twenty to ninety nine, and add those to the list.
F…ηχF…ηχFη⊞υ⪫Φ⟦⁺ι thousand⁺κ hundredλ⟧μ
Taking the first ten numbers twice and then the numbers from (0) to 99, generate the numbers from (0) to 9999. Note that since 0 is represented by an empty list, appending a string to it vectorises and therefore does nothing, resulting in a falsy value, which is excluded from the final join.
»§υ⊗⌕υθ
Look up the position of the input and output the string that represents double that value.
05AB1E, 123 bytes
н.li“€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“#D9£U.•L¬M%*æsËCA…Å¡Ω‡íÖγ±γk·Θ•#D¦'…§«s„ty«DXâðý9ô.ι)˜„°¡±°#vD¯šXð«y«s‘ðý«}DIk>·<èë.v·Iai.X
Try it online or verify all test cases.
Explanation:
н.li # If the first letter/digit of the (implicit) input is lowercase:
“€µ...ý«} # Push a list in the range ["one","nine thousand nine hundred ninty nine"]
# (explained separately below)
D # Duplicate this list
Ik # Pop one copy, and get the 0-based index of the input in it
>·< # Increase it to a 1-based index; double; decrease back
è # Index into the list again
# (after which it's output implicitly):
ë # Else:
.v # Convert the (implicit) input from a Roman number to an integer
# (no-op for numbers)
· # Double it
Iai # If the input only contains letters:
.X # Convert it back to a Roman number
# (after which this Roman number is output implicitly)
# (implicit else: output the doubled number implicitly)
Explanation of creating the list in the range ["one","nine thousand nine hundred ninty nine"]:
“€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“
# Push dictionary string "one two three four five six seven eight nine ten eleven twelve"
# # Split it on spaces to a list
D # Duplicate this list
9£ # Only keep the first 9 items, removing ["ten","eleven","twelve"]
U # Pop and store this list in variable `X`
.•L¬M%*æsËCA…Å¡Ω‡íÖγ±γk·Θ•
# Push compressed string "twen thir four fif six seven eigh nine"
# # Split it on spaces to a list
D # Duplicate
¦ # Remove the first item ("twen") from this copy
'…§« '# Append dictionary string "teen" to each
s # Swap to get the list again
„ty« # Append "ty" to each
D # Duplicate this list as well
Xâ # Cartesian product with list `X` of range ["one","nine"]
ðý # Join each inner pair with space-delimiter
9ô # Split it into sublists of size 9
.ι # Interleave it with the ["twenty","ninety"] list
) # Wrap everything on the stack into a list
˜ # Flatten this to a single list of strings
„°¡±° # Push dictionary string "hundred thousand"
# # Split on the space
v # Loop over this pair:
D # Duplicate the current list of strings
¯š # Prepend an empty list [] to this list of strings
X # Push list `X` of range ["one","nine"]
ð« # Append a space to each
y« # Append the current "hundred" or "thousand" to each
s # Swap to get the list of strings we've duplicated
â # Cartesian product
€˜ # Flatten each inner pair, to get rid of the [] again
ðý # Join each inner pair with space-delimiter
« # Merge the two lists together
} # Close the loop
See this 05AB1E tip of mine (sections How to use the dictionary? and How to compress strings not part of the dictionary?) to understand why “€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“ is "one two three four five six seven eight nine ten eleven twelve"; .•L¬M%*æsËCA…Å¡Ω‡íÖγ±γk·Θ• is "twen thir four fif six seven eigh nine"; '…§« is "teen"; and „°¡±° is "hundred thousand".
Vyxal, 304 bitsv2, 38 bytes
∆ċ` λ¬ `ðV\-ðV\,-)£E±[Ed|ȧæ[øṘdøṘ|륆?=;ṅd¥†
Bitstring:
0001010011000011011001111010101011000101111100011110000000110101000001100010100101101100101001111010001100000011011110000100011000101000111010001100110110101101111000010101100110101001001111100100101010100001010010110110011100101010110000011011101000010011001110000011101100010100011001110001110111111000
Honestly, the most annoying thing about this is the lack of punctuation in the english number format and that everything must be a string. I've range coded to compensate for how annoying it is :p.
Explained
∆ċ` λ¬ `ðV\-ðV\,-)£E±[Ed|ȧæ[øṘdøṘ|륆?=;ṅd¥†
∆ċ` λ¬ `ðV\-ðV\,-)£ # Helper function to convert numbers to words that match the challenge criteria:
∆ċ # Convert the number to words. Normally, this'd be where it ends, but we have to also:
` λ¬ `ðV # Replace " and " with a space
\-ðV # Replace "-" with a space
\,- # And remove any commas. The price I have to pay for having grammatically correct numbers.
£ # Store the helper in the register for later.
# Alright, now for the juicy stuff :p
E±[Ed # If the input is already a number, simply double it and call it a day. No special handling needed.
| # Otherwise:
ȧæ # Get the case of the input without spaces. Returns 1 if all uppercase, or 0 if all lowercase. I have to remove spaces otherwise all lowercase is considered mixed-case and returns -1. I want a simple 0/1.
[ # If it's all uppercase (i.e. Roman Numeral):
øṘdøṘ # Convert from roman numerals, double, and convert back to roman numerals.
| # Otherwise (i.e. english number):
륆?=;ṅ # Find the first number where:
¥† # Converting it to words with the helper function
?= # equals the input
d¥† # Double the result and convert it back to words with the helper function.
💎
Created with the help of Luminespire.