14
\$\begingroup\$

(or: Output the plural demonym.)

When in Rome, do as the Romans do. This is a well-known English phrase meaning that it’s best to follow what others are doing around you — to go with the flow. Today, you're going to rewrite the phrase to fit most (Western) place names.

To get the name of a group that lives within a region, there are a couple of cases:

  • If the name ends with an ‘i’, ‘o’, or ‘u’, append ‘ans’. If the name ends with an ‘e’ or ’a’, drop it and append ’ans’.
  • If the name ends with a ‘y’, replace it with an ’i’ if the preceding character is a consonant, and finally append ‘ans‘.
  • If the name ends in a consonant (excluding ‘y’), append ‘ians’.

Some examples:

  • “Italy” ends with a consonant followed by a ‘y’, so we replace the ‘y’ with an ‘i’ and append ‘ans’ to get “Italians”.
  • “Rome” ends with an ‘e’, so we drop it and append ‘ans’ to get “Romans”.
  • “Hungary” → “Hungarians”
  • ”Paraguay” → “Paraguayans”.

So, your task is: Given a name starting with an uppercase letter and ending with a lowercase letter, output the name of that group of people.

This is , so the shortest code per language wins! Defaults for code-golf apply.

Test cases:

When in Rome, do as the Romans do.

When in Transylvania, do as the Transylvanians do.

When in Code Golf, do as the Code Golfians do.

When in Hawaii, do as the Hawaiians do.

When in Sparta, do as the Spartans do.

When in America, do as the Americans do.

When in South Dakota, do as the South Dakotans do.

When in Korea, do as the Koreans do.

When in India, do as the Indians do.

(And yes, I know there are plenty of outliers, e.g. group names ending in ‘stani’, ‘ese’, ‘er’, etc. However, this formula seems to work for many English place names.)

\$\endgroup\$
12
  • 5
    \$\begingroup\$ Germanians ?? hmmm. \$\endgroup\$ Aug 21, 2023 at 7:07
  • 3
    \$\begingroup\$ "fit most (Western) place names.". Most European countries don't even fit including Spain, Portugal, Germany, France, Netherlands, Norway, Sweden, Denmark, Poland, England, Ireland \$\endgroup\$
    – Ivo
    Aug 21, 2023 at 10:57
  • 4
    \$\begingroup\$ @Ivo Europe doesn't exist in my imagination \$\endgroup\$
    – noodle man
    Aug 21, 2023 at 12:56
  • 2
    \$\begingroup\$ Heck, the US's nearest neighbors, the Canadans... \$\endgroup\$
    – wnoise
    Aug 21, 2023 at 21:22
  • 1
    \$\begingroup\$ An interesting followup to this might be to reproduce all conversions from en.wikipedia.org/wiki/Demonym, perhaps scoring by some formula like (codeLength/correctDemonymQuantity) \$\endgroup\$ Aug 22, 2023 at 17:21

10 Answers 10

9
\$\begingroup\$

Lexurgy, 72 65 bytes

y:
{y,*}=>i/!{a,e,i,o,u,y} _ $
a:
{e,a}=>ans/_ $
Else: *=>ans/_ $

Expects input as just the country name, and outputs the plural demonym.

Requires that spaces in the input be replaced with some non-space character due to how Lexurgy processes spaces.

  • -7 bytes by @SuperStomer by using else

Used test cases:

Italy
Rome
Hungary
Paraguay
Transylvania
Code_Golf
Hawaii
Sparta
America
South_Dakota
Korea
India
Noodle
Noodly
Noodley
Ay
By
Aby
Bay
Ohio
\$\endgroup\$
2
  • \$\begingroup\$ Right tool for the job? \$\endgroup\$
    – emanresu A
    Aug 20, 2023 at 19:24
  • 1
    \$\begingroup\$ 65 bytes \$\endgroup\$ Aug 21, 2023 at 1:44
8
\$\begingroup\$

K (ngn/k), 40 bytes

{_[-~0 3'a;x],(0<a:"yeaiou"?*|x)_"ians"}

Try it online!

\$\endgroup\$
1
  • 3
    \$\begingroup\$ An explanation would be nice for those of us who don’t speak K, but don’t feel obliged to add one \$\endgroup\$
    – noodle man
    Aug 21, 2023 at 8:51
7
\$\begingroup\$

sed, 35 bytes

Using sed with extended regexes:

s/([^aeiouy])y?$/\1i/;s/[ea]?$/ans/

\$\endgroup\$
1
  • \$\begingroup\$ Note that this is exactly the same as Neil’s Retina answer. Maybe edit that into the post? Just a thought \$\endgroup\$
    – noodle man
    Aug 21, 2023 at 8:54
6
\$\begingroup\$

Retina 0.8.2, 31 bytes

([^aeiouy])y?$
$1i
r`[ea]?$
ans

Try it online! Link includes test cases. Explanation:

([^aeiouy])y?$
$1i

Add is after trailing consonants and replace consonant + y with consonant + i.

r`[ea]?$
ans

Remove any trailing e or a and append ans. The r` is needed to prevent a second empty match after removing the trailing e or a.

\$\endgroup\$
3
\$\begingroup\$

Charcoal, 38 bytes

P←⮌SM⁼KKy←¿№aeiouKKMⅈ←«→Pi»M¬№aeKK→ans

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

P←⮌S

Write the input to the canvas, but with the last letter under the cursor and the first letter to the left.

M⁼KKy←

Move left if the last letter is a y.

¿№aeiouKK

If the (previous) letter is a vowel, then...

Mⅈ←

... move back to the last letter, otherwise...

«→Pi»

... move right and place an i, which either overwrites a trailing y or appends if there was no trailing y.

M¬№aeKK→

Move right unless the last letter is an a or an e.

ans

Overwrite the a or e with ans or append ans otherwise.

\$\endgroup\$
1
  • \$\begingroup\$ Clever use of the canvas! Didn’t expect a solution like this. \$\endgroup\$
    – noodle man
    Aug 21, 2023 at 8:50
3
\$\begingroup\$

05AB1E, 33 bytes

žPSD'y«s„aeS)vDyÅ¿àiNi'i«ë¨]…ans«

Try it online or verify all test cases.

Explanation:

žP              # Push all consonants (minus "y")
  S             # as a list of characters
D'y«           '# Duplicate it, and append an "y" to each consonant
    s           # Then swap so the consonant-list is at the top again
„aeS            # Push pair ["a","e"]
)               # Wrap all three items on the stack into a list
 v              # Pop and loop over this triplet of lists:
  D             #  Duplicate the current string
                #  (which will be the implicit input in the first iteration)
       i        #  If
    Å¿          #  the current string ends with
      à         #  any of the items of
   y            #  the current list of the loop:
        Ni      #   If this is the second iteration (the 0-based index is 1):
          'i«  '#    Append an "i" to the string
         ë      #   Else (index is 0 or 2):
          ¨     #    Remove the last character instead
 ]              # Close both the if-else statement and loop
  …ans«         # Append string "ans"
                # (after which the result is output implicitly)
\$\endgroup\$
2
\$\begingroup\$

Python, 119 bytes

-5 bytes thanks to noodle man.

lambda c,v='iouea',s='ans':(((c+'i'+s,(k:=c[:-1])+'iy'[c[-2]in v]+s)['y'==(l:=c[-1])],k+s)[l in v[3:]],c+s)[l in v[:3]]

Attempt This Online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can save five bytes by indexing into 'iy' instead of ('i','y') \$\endgroup\$
    – noodle man
    Aug 21, 2023 at 9:03
2
\$\begingroup\$

JavaScript (SpiderMonkey), 96 bytes

x=>((p=[...x])[l=x.length-1]=`${"iou"[c="contains"](r=p[l])?r:!"ae"[c](r)?"i":""}ans`)&&p.join``

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Using the regex from the Retina/sed answers would be 60 bytes: s=>s.replace(/([^aeiouy])y?$/,"$1i").replace(/[ea]?$/,"ans") \$\endgroup\$
    – corvus_192
    Aug 21, 2023 at 15:45
  • \$\begingroup\$ @corvus_192 yeah, regex make it shorter but I didnt wanted to use it tbh \$\endgroup\$ Aug 21, 2023 at 15:46
2
\$\begingroup\$

Python >= 3.8, 173 bytes

import re
lambda k:any((l:=re.subn(a,b,k))[1]for a,b in map(lambda m:f'({m}ans'.split('|'),(r'\w[iou])$|\1',r'\w)[ea]$|\1',r'[aeiou]y)$|\1',r'[^aeiou])y$|\1i','$)|i')))*l[0]

any stops iterating after the first truthy result (in this case, when subn replaces at least 1 time)

ATO! (f = added to run test cases)

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf, and nice answer! By the way, you can put the import after the lambda and put `f=` in the header: ATO \$\endgroup\$
    – The Thonnu
    Aug 27, 2023 at 16:21
1
\$\begingroup\$

Vyxal , 186 bitsv2, 23.25 bytes

÷‛aeF:\y=¨iȮ:\o+Ah¬\i*`□⟑

Try it Online!

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.