Geobitsian language is a new perversion of English where a word is broken into segments that each must start with a different letter. Then every time one of those starting letters appears in another string, it is replaced with its entire corresponding segment, maintaining capitalization.

This process is called Geobitsizing.

For example the word "Geobits" could be broken into geo bits, and the nonsense poem

Algy met a Bear
A Bear met Algy
The Bear was bulgy
The bulge was Algy

would be Geobitsized with it as

Algeoy met a Bitsear
A Bitsear met Algeoy
The Bitsear was bitsulgeoy
The bitsulgeoe was Algeoy

because every g becomes geo, every G (though there are none) becomes Geo, every b becomes bits, and every B becomes Bits.

Note that each substitution is performed with respect to the original string, not any intermediate step. e.g. if geo had been gbo instead, the b's created would not replaced with bits.


Write a program or function that can generate Geobitsian language.

Take in a single-line string made of lowercase letters (a-z) and spaces. This will be the word used as the Geobitsizing argument, with the spaces separating the segments. You can assume:

  • Segments will not be empty. So spaces will not neighbor each other nor be at the start or end of the string.
  • Each segment starts with a different letter. Thus there cannot be more than 26.

For example, some valid segmented strings you must support are geo bits, butt ner, alex, and do o r k nob (single letter segments have no effect but are valid). But geo , butt ner, Alex, and do o r k n ob are invalid.

Your program or function also needs to take in another arbitrary string to apply the Geobitsizing to, and print or return the resulting Geobitsian language.

  • You can assume this string only contains newlines and printable ASCII.

  • Remember that letter cases must be preserved from the input to the output.

Here are some more examples using no pro gr am m ing as the Geobitsizing argument:

[empty string][empty string]



Mmmm, mmm... MmmmMMM: m&m!Mmmm, mmm... MmmmMMM: m&m! (no change)

People think bananas are great, don't you?Proeoprole thingnok bamnoamnoams amre grreamt, dono't you?

Pet a Puppy
Google Wikipedia

Proet am Prouproproy
Groogrle Wingkingproedingam

Note that the results should be identical no matter how the argument is arranged, e.g. ing pro m no am gr should yield the same results as above.

The shortest code in bytes wins.

  • \$\begingroup\$ Can we take the "Geobitsizing argument" as an array? e.g. ["no", "pro", "gr", "am", "m", "ing"] \$\endgroup\$ – Downgoat Jun 7 '16 at 4:21
  • \$\begingroup\$ @Upgoat Sorry but no. \$\endgroup\$ – Calvin's Hobbies Jun 7 '16 at 4:22
  • \$\begingroup\$ @Upgoat Try \\b${l}(\\S+) although that does cost you 5 bytes. \$\endgroup\$ – Neil Jun 7 '16 at 9:12
  • 3
    \$\begingroup\$ -1 for arbitrary input requirement of a space-separated string. \$\endgroup\$ – AdmBorkBork Jun 7 '16 at 12:44
  • 2
    \$\begingroup\$ Suggested test case: abra cadabra, !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ That should cover all edge cases, and there are a lot of them if one tries to use regexes... \$\endgroup\$ – Dennis Jun 7 '16 at 18:13

12 Answers 12


Jelly, 18 bytes


Try it online!

Alternative version, 15 bytes (non-competing)

Jelly's title case function had a bug; it didn't capitalize the first word. That has been fixed, so the following works now.


This code does the same as in the competing version, except that Œt (title case) replaces the conditional uppercasing achieved by Œu1¦€.

How it works

ṣ⁶;Œu1¦€$;©ZḢiЀị®  Main link. Left argument: w (words). Right argument: s (string)

ṣ⁶                  Split w at spaces.
        $           Combine the two links to the left into a monadic chain.
       €              Map over the words.
   Œu1¦                 Uppercase the item at index 1.
  ;                   Append the result to the unmodified words.
         ;          Append all characters in s to the list of words.
          ©         Copy the result to the register.
           Z        Zip/transpose, grouping the first chars into the first list.
            Ḣ       Head; extract the list of first characters.
             iЀ    Find the first index of each character in s.
                ị®  Select the characters/strings from the list in the register
                    that are at those indices.

Python 3, 71 bytes

lambda w,s:s.translate({ord(t[0]):t for t in(w+' '+w.title()).split()})

Test it on Ideone.

How it works

In Python 3, the built-in str.translate takes a string and a dictionary, and replaces each character in the string whose code point is a key of that dictionary with the corresponding value, which may be a string, an integer or None (equivalent to the empty string).

Converting the string of words w to title case (i.e., capitalizing the first letter of each word) and appending it to the result of w+' ' creates a string of space separated words with lower- and uppercase version (first letter). Without a second argument, str.split splits at whitespace, so (w+' '+w.title()).split() creates the list of all words.

Finally, the dictionary comprehension {ord(t[0]):t for t in...} turns each word t into a dictionary entry with key ord(t[0]) (code point of the first letter) and value t, so str.translate will perform the intended substitutions.


Python, 126 99 95 81 bytes

Alot thanks to Dennis:

lambda G,S,j=''.join:j(s+j(g[1:]for g in G.split()if g[0]==s.lower())for s in S)

Edit1: don't need to append to a temporary

Edit2: S may contain uppercase...

Edit3: don't duplicate G

Edit4: compressed a little bit more and shoved it into one line

Edit5: using unnamed lambda and j=join' '


Pyth, 19 bytes


Try it online!

  • 1
    \$\begingroup\$ We can't take the geobitsizing argument as an array, unfortunetly \$\endgroup\$ – Downgoat Jun 7 '16 at 4:26
  • \$\begingroup\$ Sorry, didn't notice. \$\endgroup\$ – Leaky Nun Jun 7 '16 at 4:31

Vim, 46 keystrokes

Ugly, and Hacky.

A <esc>:s/\<\w/:%s\/\0\\c\/\\0/g<cr>:s/ /eg<C-v><Cr>/g<cr>dgg@"
  • \$\begingroup\$ Why not in V? D: \$\endgroup\$ – Downgoat Jun 7 '16 at 14:52
  • \$\begingroup\$ @Upgoat Cause it's a buggy mess. \$\endgroup\$ – James Jun 7 '16 at 15:14

Retina, 36 bytes

Byte count assumes ISO 8859-1 encoding.


Try it online!


Pyth, 18 16


Try it here

Defines a function g that performs the geobitsising. As a program this would be a bit shorter if the second string is single line, but multiline input isn't worth it:


The general idea here was to title case the geobitsian string and append that to the original string. Then split that on spaces and for each string, take the first letter and map it to the string it represents. That way X will turn the first letter of each word into the full word.

  • \$\begingroup\$ Did you just... outgolf Dennis? \$\endgroup\$ – Bojidar Marinov Jun 8 '16 at 13:44
  • \$\begingroup\$ @BojidarMarinov If you count Dennis using some other language that had a bug in it as outgolfing, then yes ;) \$\endgroup\$ – FryAmTheEggman Jun 8 '16 at 13:57

Python 2, 83 78 bytes

lambda w,s:''.join(c+w[(' '+w).find(' '+c.lower()):].split()[0][1:]for c in s)

Test it on Ideone.

How it works

We iterate over all characters c in the string s.

We prepend a space to the string of words w, then search for a occurrence of lowercased c, preceded by a space.

  • If such an occurrence exists, find will return the index of the space in the string ' '+w, which matches the index of c in w.

    w[...:] thus returns the tail of w, starting from the word with first letter c. split() splits the tail at spaces, [0] selects the first chunk (the word) and [1:] removes its first letter.

    After prepending c to the previous result, we obtain the correctly cased word that starts with c.

  • If no word begins with c, find will return -1.

    Thus, w[...:] yields the last character of w, split() wraps it in an array, [0] undoes the wrapping, and [1:] removes the only character from the string.

    After prepending c, we obtain the singleton string whose character is c, so the whole operation is a no-op.

Finally, ''.join concatenates all resulting strings, returning the Geobitsized version of s.


Julia, 72 68 bytes

w%s=prod(c->"$c"join((W=w|>split)[find(t->t[1]==c|' ',W)])[2:end],s)

Try it online!


CJam, 19 bytes


Test it here.


l       e# Read first line of input (list of words).
q\      e# Read remaining input and swap with first line.
S/      e# Split around spaces.
_       e# Duplicate.
32af.^  e# Convert the first letter of each word to upper case by taking
        e# the element-wise XOR with the list [32].
+       e# Append the upper-cased words to the original ones.
_:c     e# Duplicate and convert each word to its first character.
\       e# Swap characters with words.
er      e# Transliteration, replacing each character with the corresponding word.

JavaScript ES6, 67 63 70 bytes


Test this on Firefox. bugs are making this longer than I'd like


function(gbarg, str) {
   return str.replace(/\S/g, function(chr) { // Replace non-whitespace w/...
        return chr + (
         gbarg.match(`\\b\\${l}(\\S+)`,'i')  // That word in the gbstr
        ||[,""])[1]                          // if not in gbstr, use blank str
  • \$\begingroup\$ f("abracadabra")("1Dbw") returns "1abracadabraDbracadabrababracadabrawbracadabra". \$\endgroup\$ – Dennis Jun 7 '16 at 17:59

Ruby, 65 60 58 bytes


Try it online!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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