Country name mashup generator

10

1

Part 1 of the task is here

Flags Mashup Bot is a small Twitter bot that generates a new country name based on two random country names and tweets the result every couple of minutes.

Task

Your task is to replicate what the bot does by writing a script or a function based on the following criteria:

  • The input is two country names in English as shown in this page. Country names contain upper or lowercase letters of the English alphabet, spaces or dashes, and there's a special case of Côte d'Ivoire. They are usually capitalised with the exception of prepositions and similar words. Examples: United States of America, Portugal, Côte d'Ivoire, Guinea-Bissau.
  • The output is a single country name that is a mixture of the two inputs based on the following rules:

    • If both names are single words you have to split each country name after a vowel randomly, then use the first half from the first country and the second half of the second country.
      • Vowels are a, e, i, o, u, or their uppercase variants
      • After the split both parts should contain at least one letter. The first half will always contain the vowel it was split by. The second half doesn't need to contain vowels however.
      • Example: Poland can be split by either Po/land or Pola/nd
      • Example: Algeria can be split by A/lgeria, Alge/ria, or Algeri/a. However Algeria/ is not valid, as the second half doesn't contain any letters.
      • Example output: Mixing Poland and Algeria can be either of the following: Polgeria, Poria, Poa, Polalgeria, Polaria or Polaa
    • If one of the country names are multiple words while the other is a single one, then you have to replace either the first word of the multi-word one, or the last word with the other dependent on whether the multi-word country name is the first or second.
      • Example: United States of America and France is United States of France.
      • Example: France and United States of America is France States of America
    • If both names are multi-word ones then you have to split both of them at one of the word boundaries and then join them together afterwards.
      • Example: United States of America and Trinidad and Tobago can be United and Tobago, United States and Tobago, United States of and Tobago, United Tobago, United States Tobago, or United States of Tobago
    • Special case 1: countries containing dashes counts multi-word ones. If you split the name at the dash you have to use a dash in the output instead of a space
      • Example: United States of America and Guinea-Bissau can be United States of-Bissau among others
      • Example: Spain and Timor-Leste is Spain-Leste
    • Special case 2: If you enter the same country twice, you have to return <country name> 2.
      • Example: United States of America and United States of America will return United States of America 2
      • Example: Hungary and Hungary will return Hungary 2

Notes:

  • Your submission should work for at least the countries as shown in this list
  • It is okay if the result is the same as one of the input countries, e.g. United States of America and United Kingdom can result in United Kingdom
  • Côte d'Ivoire counts as two words: Côte and d'Ivoire.
  • There are no countries in the list that contain both spaces and dashes
  • Vowels are a, e, i, o, u, A, E, I, O, U
  • Standard loopholes, as usual, are prohibited

Examples with all valid answers for a specific pair:

Poland, Algeria
Polgeria, Poria, Poa, Polalgeria, Polaria, Polaa

Algeria, Poland
Aland, And, Algeland, Algend, Algeriland, Algerind

United States of America, France
United States of France

France, United States of America
France States of America

United States of America, Trinidad and Tobago
United and Tobago, United States and Tobago, United States of and Tobago, United Tobago, United States Tobago, United States of Tobago

Trinidad and Tobago, United States of America
Trinidad States of America, Trinidad of America, Trinidad America, Trinidad and States of America, Trinidad and of America, Trinidad and America

Hungary, Hungary
Hungary 2

United States of America, United States of America
United States of America 2

United States of America, Guinea-Bissau
United-Bissau, United States-Bissau, United States of-Bissau

Guinea-Bissau, United States of America
Guinea-States of America, Guinea-of America, Guinea-America

Timor-Leste, Spain
Timor-Spain

Spain, Timor-Leste
Spain-Leste

Côte d'Ivoire, Portugal
Côte Portugal

Portugal, Côte d'Ivoire
Portugal d'Ivoire

Côte d'Ivoire, Timor-Leste
Côte-Leste

Timor-Leste, Côte d'Ivoire
Timor-d`Ivoire

, so shortest code by byte count wins and will be accepted. Please include example a set of input & output with your submission

SztupY

Posted 2019-11-24T13:42:52.650

Reputation: 3 639

@EmbodimentofIgnorance "after the split both parts should contain one letter." The second part does not necessarily need any vowels. (The first part will though, because the vowel you split on goes to the first part.) – Value Ink – 2019-11-26T01:04:50.900

Will there be any countries that have both spaces and dashes in the name? – Value Ink – 2019-11-26T01:06:01.040

@ValueInk no, there's none in the supplied list that contains both so you don't need to cater for this possibility – SztupY – 2019-11-26T18:18:07.867

Answers

5

Jelly, 74 73 bytes

JṖXṬk⁸ḢḢFṪ;ƲƭF)jṪḢƭ€Ṁ$$
ḢṖ;
ṪḢṪ;Ɗṭ
Fe€ØcṖTXṬkḢḢṪƭ)
e€⁾ -k)ẈỊḄ‘ƲĿ
Ḣ,2KƊÇE?

Try it online!

A full program that takes a list of two strings as its argument and implicitly outputs the mashed up country name.

The handling of hyphens is relatively costly, particularly since they are included whichever side of the split they fall.

Explanation

Helper link 1

Handles case where both countries have multiple words

              )         | For each country:
J                       | - Sequence along words
 Ṗ                      | - Remove last
  X                     | - Pick one at random
   Ṭ                    | - Convert to a boolean list with a 1 at that index
    k⁸                  | - Split list of words after that point
            ƭ           | - Alternate between:
      Ḣ                 |   - Head (first set of words for the first country)
           Ʋ            |   - Following as a monad (for the second country)
       Ḣ                |     - Head (first set of words, also removed from the country)
        F               |     - Flatten
         Ṫ              |     - Tail (i.e. last character which will be space or hyphen)
          ;             |     - Concatenate to remaining words for second country
             F          | - Flatten
                      $ | Following as a monad
               j     $  | - Join countries with following as a monad
                ṪḢƭ€    |   - Alternate between tail for first country and head for second
                    Ṁ   |   - Max (will be hyphen if one present, otherwise space)

Helper link 2

Handles case where only first country has multiple words

Ḣ   | Head (first country)
 Ṗ  | Remove last word
  ; | Concatenate to second country

Helper link 3

Handles case where only second country has multiple words

Ṫ      | Tail (second country)
    Ɗ  | Following as a monad:
 Ḣ     | - Head (first word; note this will also be removed from the first country)
  Ṫ    | - Tail (last character)
   ;   | - Concatenated to remaining words
     ṭ | Tag onto the end of the first country

Helper link 4

Handles case where both countries have single words

              ) | For each country
F               | - Flatten (remove the layer of lists generated in helper link 5)
 eۯc           | - Check whether each character is a vowel
     Ṗ          | - Remove last
      T         | - Comvert to list of indices
       X        | - Pick one at random
        Ṭ       | - Convert to a boolean list with a 1 at that index
         kḢ     | - Split the original country name after that vowel
           ḢṪƭ  | - Alternate between taking the head (for first country) and tail (for second)

Helper link 5

Splits each country into words and dispatched to helper links 1-4 depending on which countries have multiple words

      )       | For each country:
e€⁾ -         | - Check whether each character is a space or hyphen
     k        | - Split country after those characters
           ƲĿ | Call the link indicated by the number calculated by the following monad:
       Ẉ      | Lengths of lists (i.e. number of words in each country)
        Ị     | Insignificant (abs(x)<=1)
         Ḅ    | Convert from binary
          ‘   | Increment by one

Main link

Determines if countries are equal, and otherwise calls helper link 5

      E? | If both countries equal:
    Ɗ    | Then, as a monad:
Ḣ        | - Head (first country)
 ,2      | - Pair with 2
   K     | - Join with spaces
     Ç   | Else: Call helper link 5

Nick Kennedy

Posted 2019-11-24T13:42:52.650

Reputation: 11 829

3

Python 2, 395 332 336 318 313 bytes

def f(c,d):
 j,k=[' -'['-'in s]for s in c,d];u=c.split(j);v=d.split(k);n,m=len(u),len(v);D=max(j,k);b=D in c+d
 if(n>1)^(m<2):i,j=[choice([i+1for i in range(len(s)-1)if s[i]in['aeiouAEIOU',' -'][b]])for s in c,d];R=c[:i-b]+b*D+d[j:]
 else:R=D.join((u[:-1]or u)+v[m>1:])
 return[R,c+' 2'][c==d]
from random import*

Try it online!

17 bytes thx to Value Ink; and a hat tip to SztupY for pointing out a bug.

Chas Brown

Posted 2019-11-24T13:42:52.650

Reputation: 8 959

315 bytes by merging the last 2 conditionals. – Value Ink – 2019-11-26T01:57:56.000

3

C# (Visual C# Interactive Compiler), 242 bytes

a=>b=>a==b?a+" 2":((d=a.LastIndexOfAny(z=((j=new[]{a,b}.Count(x=>"- ".Any(x.Contains)))>0?"- ":"aeiouAEIOU").ToArray()))<0?a:a.Remove(d+1))+b.Remove(0,j+new Random().Next()>0?(d=b.IndexOfAny(z)-j%2+1)<0?0:d:b.LastIndexOfAny(z));dynamic z,d,j;

Try it online!

Embodiment of Ignorance

Posted 2019-11-24T13:42:52.650

Reputation: 7 014

Output doesn’t seem to be random – Nick Kennedy – 2019-11-25T23:49:04.227

@NickKennedy Fixed, now there is a 1/2147483647 chance of the output being different – Embodiment of Ignorance – 2019-11-26T05:12:25.957

2while technically true, that seems to against the usual definition of randomness for questions here (though I accept this specific question didn’t say they had to be with equal probability). – Nick Kennedy – 2019-11-26T21:48:14.523

3

Lua, 614 604 600 585 bytes

g,s,y,e={},{},{}r=math.random for _,v in ipairs({A,B})do c=0 for w in v:gmatch(".?.'?%a+.")do c=c+1(_<2 and g or s)[c]=w end end h=s[1]:find('-')and'-'or' 'u,k=#g,#s if u==1 and k>1then s[1]=g[1]..h e=s elseif u>1 and k==1then g[u]=s[1]e=g elseif u>1 and k>1then c=0 for i=1,r(u-1)do c=c+1y[c]=g[i]end for j=r(2,k),k do y[c]=y[c]:gsub(' ',h)c=c+1y[c]=s[j]end e=y else g,s={},{}for i=1,10 do t=("aeiouAEIOU"):sub(i,i)p=A:sub(1,A:find(t)or 0)g[#g+1]=#p>0 and#p<#A and p or q;p=B:sub(1+(B:find(t)or#B),#B)s[#s+1]=#p>0 and p or q end e={g[r(1,#g)],s[r(#s)]}end return A==B and{A," 2"}or e 

Try it online!

All possible combinations (75532) --> Click!

LuaNoob

Posted 2019-11-24T13:42:52.650

Reputation: 69

Love the full list – SztupY – 2019-11-26T20:49:00.480

Thanks, whats your favorite name? – LuaNoob – 2019-11-27T12:19:42.367

1

Ruby, 230 228 bytes

->c,d{g=->s,r{(0..s.size-2).select{|i|s[i]=~r}.sample}
i=g[c,e=/[ -]/];j=g[d,e];c==d ?c+" 2":(c+d)[e]?c[e]&&!d[e]?c[/.*[ -]/]+d:!c[e]&&d[e]?c+d[/[ -].+/]:c[0,i]+[c[i],d[j]].max+d[j+1..-1]:c[0..g[c,r=/[aeiou]/i]]+d[g[d,r]+1..-1]}

Try it online!

Value Ink

Posted 2019-11-24T13:42:52.650

Reputation: 10 608