# Eh, codegolf shmodegolf

This challenge is about implementing Shm-reduplication, originating in Yiddish, where one takes a word, duplicates it, and replaces the first syllable in the second word with "Shm" in order to indicate that one does not care. Some examples include:

• "Isn't the baby cute?", "Eh, baby shmaby"
• "Come buy from my store, we have a sale!", "Pff, sale shmale"
• "I got this smartphone yesterday, isn't it cool?", "Meh, smartphone shmartphone"

# Rules

In the real world there are a bunch of special cases, but for this challenge we will use rules that describe a simplified version of the full linguistic phenomenon that is more suitable for programming:

1. Consonants up to first vowel are replaced by "shm".
2. Prepend shm to words beginning with vowels.
3. If a word contains no vowels it is returned unchanged. No vowel, no shm.
4. The vowels are: a, e, i, o, u.
5. The input will be restricted to lowercase letters.
6. The output should be a lowercase string containing the reduplicated version of the input. If the input is "string" the output should be "shming".

This is code golf, shortest code wins!

# Example solution (ungolfed python)

This is an example of code that would solve the challenge:

def function_shmunction(string):
vowels = "aeiou"
for letter in string:
if letter in vowels:
index = string.index(letter)
shming = "shm" + string[index:]
return shming
return string


# Test cases

• function -> shmunction
• stellar -> shmellar
• atypical -> shmatypical
• wwwhhhat -> shmat
• aaaaaaaaaa -> shmaaaaaaaaaa
• lrr -> lrr
• airplane -> shmairplane
• stout -> shmout
• why -> why

An answer has been accepted since there haven't been any new responses in a while, but feel free to add more!

• I've made a minor edit to your post, since the Zsh answer seems to think you should output the input + a space. If I misunderstood something and my edit is incorrect, feel free to revert it. May 24 at 8:41
• @KevinCruijssen No, you're correct. I might have been a bit unclear about that in the text. May 24 at 8:43
• @KevinCruijssen Added! I also included one that has a vowel directly after the first vowel. May 24 at 9:08
• @jezza_99 the sandbox actually had the same output format as this post, I believe my formatting of the explanation of the real world phenomenon was done carelessly and so was easy to interpret as the intended output format. May 24 at 9:18
• must. resist. changing. sh. to. sch. to. match. local. accent. May 24 at 17:18

# Jelly, 16 12 bytes

œlØḄṭ⁸¹?“shm


Try it online!

-4 thanks to ovs remembering there's a strip builtin

œlØḄ            Strip all leading consonants.
ṭ   “shm    Prepend "shm"
¹?        if there's anything left, otherwise
⁸          give the original word.

• Porting Jitse's Python answer gives 14 bytes: œlØḄ“shm”;$⁸Ẹ? – ovs May 24 at 10:21 • I was about to suggest you post that yourself until I realized what builtin it leans on... :facepalm: May 24 at 10:33 # sed, 29 bytes s/[^aeiou]*$$[aeiou]$$/shm\1/  Try it online! # Haskell, 52 bytes snd.span(notElem"aeiou")>>=(?) ""?s=s r?_="shm"++r  Try it online! # Stax, 11 bytes ÄFï¥░$º{═┘ç


Run and debug it

1. Left-trim consonants.
2. If non-empty, prepend "shm".
3. Else restore original input.

# sed, 25 bytes

/[aeiou]/s/[^aeiou]*/shm/


Try it online!

/[aeiou]/ is a conditional that only runs the substitution s/[^aeiou]*/shm/ if there is a vowel in the line. This prevents needing to capture the first vowel and then using a backreference as in the more obvious s/[^aeiou]*$$[aeiou]$$/shm\1/.

# Python 3.8 (pre-release), 62 bytes

lambda s:(q:=s.lstrip('bcdfghjklmnpqrstvwxyz'))and'shm'+q or s


Try it online!

# 05AB1E, 28 13 bytes

žNSÛ©ai®…shmì


Explanation:

žNSÛ           # Trim all leading consonants of the (implicit) input-string
©          # Store this new string in variable ® (without popping)
ai        # Pop, and if any letters are left (thus the input-string contains
# a vowel):
®       #  Push string ® again
…shmì  #  Prepend "shm"
#  (implicitly print it as result)
# (implicit else)
#  (implicitly output the implicit input-string)


# Powershell, 36 bytes

$args-replace('^.*?([aeiou])','shm$1')


### Explanation

Simple replace with a named group reference.

+4

Thanks caird coinheringaahing

-5

Thanks mazy

• Welcome to Code Golf, and nice answer! May 24 at 22:58
• Welcome to Code Golf! Currently, this answer does not meet our standard rules: 1) this doesn't appear to work unless the input begins with a vowel, and 2) this assumes the input is saved in the $x variable, which is not an acceptable form of input. Both of these can be corrected for +9 bytes May 24 at 23:56 • @anothervictimofthemouse You're welcome to use the program I linked to. You can find an answer template on that site if you click the link button, and scroll down to the "Code Golf Answer" option. You can also find formatting tips in the "Answering" post in the Welcome page I linked May 25 at 0:14 • Sorry, my bad, I got the regex wrong: it should be ^.*?([aeiou]) in the replacement stage May 25 at 1:40 • you can save 5 bytes Try it online! May 25 at 18:59 # Japt, 15 bytes r"^.*?%v"ÈÌi¢m  Try it (Includes all test cases) # Retina, 19 bytes Just a regex replacement, there might be some language feature which allows for a shorter solution. ^.*?(?=[aeiou]) shm  Try it online! # Zsh, 36 bytes <<<${(S)1/#(#b)*([aeiou])/shm$match} Attempt This Online! • <<<: print • ${1}: the input...
• //: replace the first match
• #: matching only at the beginning of the string
• (#b): activate backreferences, so the () group gets stored in the $match variable • (S): use the shortest possible match, rather than the longest • *: anything • (): store this match in the variable: • [aeiou]: followed by a vowel • with shm$match: the string shm, plus the matched vowel

$match is actually an array which contains all the backreference groups, but since there's only one group, we don't need to access any specific element with [1] # Python, 53 bytes lambda s:re.sub("^.*?([aeiou])","shm\\1",s) import re Attempt This Online! Another regex answer. Alternative: # Python, 53 bytes lambda s:re.sub(".*?(?=[aeiou])","shm",s,1) import re Attempt This Online! # C (gcc), 81 bytes i;f(char*s){for(i=0;*s-"aeiou"[++i%6];i%6||s++);printf("shm%s"+3*!*s,s-i*!*s/6);}  Try it online! # JavaScript, 37 bytes s=>s.replace(/^.*?([aeiou])/,"shm$1")


Try it online!

# Perl 5 + -p, 20 bytes

Uses the ; separator (as ; is implicitly added via -p).

s;.*?(?=[aeiou]);shm

Try it online!

# Perl 5 + -lF/^[^aeiou]+/ -M5.10.0, 17 bytes

Slightly more cheaty with the regex in the flags, but saves a few bytes

• Find the index of the first $ • Replace chars before this index with shm • If no vowels, return input. • 78 bytes =IFERROR("shm"&MID(A1,MIN(IFERROR(FIND({"a","e","i","o","u"},A1),"")),9^9),A1). 9^9 is well over the 2^15-1 character limit for a cell so it works fine in the MID() function for all valid inputs. May 25 at 13:44 # Charcoal, 25 bytes ≔⌕Ｅθ№aeiouι¹η¿⊕η«shm✂θη»θ  Try it online! Link is to verbose version of code. Explanation: ≔⌕Ｅθ№aeiouι¹η  Count the number of vowels in each character and find the first 1 i.e. the index of the first vowel in the input. ¿⊕η  If there was in fact a vowel, then... «shm✂θη»  ... output the literal string shm followed by the input sliced starting at that index. θ  Otherwise just output the input string. # Java 8, 40 bytes s->s.replaceAll("^.*?([aeiou])","shm$1")


Port of the JavaScript and Retina answers.

Try it online.

Or a minor alternative:

s->s.replaceAll("^.*?(?=[aeiou])","shm")


Try it online.

Explanation:

s->             // Method with String as both parameter and return-type:
s.replaceAll( //  Modify and return the String: Regex-replace all
"...",      //  these matches
"...")      //  with these replacements


Regex-explanation 1:

^.*?([aeiou])    # Match:
^                #  At the start of the string
.*              #  Match zero or more characters
?             #  Which are optional, to give other matches precedence
[aeiou]     #  Followed by a vowel
(       )    #  captured in capture group 1

shm$1 # Replacement: shm # Literal "shm"$1            #  And the vowel of capture group 1


Regex-explanation 2:

^.*?([aeiou])    # Match:
^                #  At the start of the string
.*              #  Match zero or more characters
?             #  Which are optional, to give other matches precedence
(?=       )  #  Followed by a positive (non-matching) look-ahead to:
[aeiou]   #   A vowel

shm              # Replacement:
shm              #  Literal "shm"


Minor note: the replaceAll with ^ is basically the same as a replaceFirst without the ^, but 1 byte shorter: try it online.

• Java is shorter than Python. What is going on... May 24 at 23:12
• It's really a regex solution :-) May 27 at 12:30

# Vyxal, 14 bytes

k⁰øl:[shmp|_


Try it Online!

Port of Jelly.

## How?

k⁰øl:[shmp|_
:[         # If there's anything left:
shmp   # Prepend "shm"
|_ # Else, pop, returning the implicit input


# Pip, 15 bytes

a~XVaH$(:"shm"a  Attempt This Online! ### Explanation a~XVaH$(:"shm"a
a                Command-line argument
~               Find first match of
XV             regex [aeiou]
$( Index of that match aH Prefix of cmdline arg containing that many characters : Set to "shm" that string If a vowel was not found,$( is nil, which means no assignment is done
and a's value remains unchanged
a  Autoprint the (possibly changed) value of a


# APL (Dyalog Extended), 31 bytes

{⍵≢⍛≡n←⌊/⍵⍳'aeoiu':⍵⋄'shm',n↓⍵}


Try it online!

Jun 2 at 11:01

f s|g s>""="shm"++g s|1>0=s
g=dropWhile(notElem"aeiou")

Attempt This Online!

-1 byte thanks to Wheat Wizard ♦

# V (vim), 23 bytes

:%s/.\{-}\ze[aeiou]/shm


Try it online!

Same in “magic very very” mode:

# 23 bytes

:%s/\v.{-}[aeiou]@=/shm


Try it online!

Further 3 bytes can be saved by replacing :%s/ with V’s specific í

# Factor, 7061 45 bytes

[ R/ ^[^aeiou]*(?=[aeiou])/ "shm"re-replace ]


Try it online!

# Lua, 39 bytes

print((...):gsub("^.-%f[aeiou]","shm"))


Uses the frontier pattern to shave off two bytes. String must be provided as argument, printed output is (1) the shmodegolfed string and (2) 0 if unmodified, 1 if modified.

Try it online!

# Batch, 157 145 bytes

@set i=%1
:l
@(echo %i:~,1%|findstr/r [aeiou]&&set a=1||set a=0)>nul
@if %a%==0 (if %i%. neq . (set i=%i:~1%&goto:l)else echo %1)else echo shm%i%


Input is taken from the command line.

-12 bytes thanks to Neil.

• Can you not just echo %1 and echo shm%i% rather than setting i?
– Neil
May 25 at 13:00

# C (gcc) with -m32, 908583 79 bytes

• -2 thanks to ceilingcat
• -4 by removing an unused variable
v;f(char*s){for(v=s;v**s;)index("aeiou",*s++)&&printf("shm",v=0);puts(v?:--s);}
`

Try it online!