37
\$\begingroup\$

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!

\$\endgroup\$
9
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ May 24, 2022 at 8:41
  • 1
    \$\begingroup\$ @KevinCruijssen No, you're correct. I might have been a bit unclear about that in the text. \$\endgroup\$
    – JSorngard
    May 24, 2022 at 8:43
  • 1
    \$\begingroup\$ @KevinCruijssen Added! I also included one that has a vowel directly after the first vowel. \$\endgroup\$
    – JSorngard
    May 24, 2022 at 9:08
  • 2
    \$\begingroup\$ @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. \$\endgroup\$
    – JSorngard
    May 24, 2022 at 9:18
  • 16
    \$\begingroup\$ must. resist. changing. sh. to. sch. to. match. local. accent. \$\endgroup\$
    – Joshua
    May 24, 2022 at 17:18

37 Answers 37

11
\$\begingroup\$

sed, 29 bytes

s/[^aeiou]*\([aeiou]\)/shm\1/

Try it online!

\$\endgroup\$
10
\$\begingroup\$

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.
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Porting Jitse's Python answer gives 14 bytes: œlØḄ“shm”;$⁸Ẹ? \$\endgroup\$
    – ovs
    May 24, 2022 at 10:21
  • \$\begingroup\$ I was about to suggest you post that yourself until I realized what builtin it leans on... :facepalm: \$\endgroup\$ May 24, 2022 at 10:33
10
\$\begingroup\$

Haskell, 50 bytes

snd.break(`elem`"aeiou")>>=(?)
""?s=s
r?_="shm"++r

Try it online!

Thanks to Roman Czyborra for -2 bytes

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 50: span.notElem==break.elem \$\endgroup\$ Jan 14 at 1:51
9
\$\begingroup\$

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/.

\$\endgroup\$
8
\$\begingroup\$

Stax, 11 bytes

ÄFï¥░$º{═┘ç

Run and debug it

  1. Left-trim consonants.
  2. If non-empty, prepend "shm".
  3. Else restore original input.
\$\endgroup\$
6
\$\begingroup\$

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]

\$\endgroup\$
0
6
\$\begingroup\$

Python 3.8 (pre-release), 62 bytes

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

Try it online!

\$\endgroup\$
6
\$\begingroup\$

05AB1E, 28 13 bytes

žNSÛ©ai®…shmì

Try it online or verify all test cases.

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)
\$\endgroup\$
6
\$\begingroup\$

Powershell, 36 bytes

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

Explanation

Simple replace with a named group reference.

+4

Thanks caird coinheringaahing

-5

Thanks mazy

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ May 24, 2022 at 22:58
  • 2
    \$\begingroup\$ 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 \$\endgroup\$ May 24, 2022 at 23:56
  • 2
    \$\begingroup\$ @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 \$\endgroup\$ May 25, 2022 at 0:14
  • 2
    \$\begingroup\$ Sorry, my bad, I got the regex wrong: it should be ^.*?([aeiou]) in the replacement stage \$\endgroup\$ May 25, 2022 at 1:40
  • 1
    \$\begingroup\$ you can save 5 bytes Try it online! \$\endgroup\$
    – mazzy
    May 25, 2022 at 18:59
5
\$\begingroup\$

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!

\$\endgroup\$
5
+150
\$\begingroup\$

Haskell, 48 bytes

g.break(`elem`"aeiou")
g(s,"")=s
g(_,r)="shm"++r

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ I forgot about your comment but I would have encouraged you to post an answer so I'm glad you did! Nice find, it's funny how span being shorter than takeWhile or dropWhile encourages you to use both parts even if you can make do with one. \$\endgroup\$
    – xnor
    Jun 2, 2022 at 8:31
5
\$\begingroup\$

Japt, 15 bytes

r"^.*?%v"ÈÌi`¢m

Try it (Includes all test cases)

r"^.*?%v"ÈÌi`¢m     :Implicit input of string
r                   :Replace
 "^.*?%v"           :  RegEx /^.*?[aeiou]/gi
         È          :  Pass each match through a function
          Ì         :    Last character
           i        :    Prepend
            `¢m     :      Compressed string "shm"
\$\endgroup\$
4
\$\begingroup\$

Retina, 19 bytes

Just a regex replacement, there might be some language feature which allows for a shorter solution.

^.*?(?=[aeiou])
shm

Try it online!

\$\endgroup\$
4
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 49 bytes

	I =INPUT
	I BREAK('aeiou') ='shm'
	OUTPUT =I
END

Try it online!

BREAK "matches zero or more characters provided they are not in the set of characters in the argument string. That is, it matches up to, but not including, a character from the argument string."

\$\endgroup\$
4
\$\begingroup\$

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!

\$\endgroup\$
4
\$\begingroup\$

Vyxal, 13 bytes

k⁰øl:[«88«p|_

Try it Online!

Port of Jelly.

How?

k⁰øl:[«88«p|_
k⁰øl           # Strip leading consonants
    :[         # If there's anything left:
      «88«p    # Prepend "shm"
           |_  # Else, pop, returning the implicit input
\$\endgroup\$
4
\$\begingroup\$

JavaScript, 36 bytes

s=>s.replace(/.*?([aeiou])/,"shm$1")

Try it online! (includes all test cases)

\$\endgroup\$
2
  • \$\begingroup\$ Why u need the ^? \$\endgroup\$
    – l4m2
    Jan 12 at 17:59
  • \$\begingroup\$ Possibly a holdover from my Japt solution, @l4m2, where it's cheaper to use ^ than it is to disable the global flag, which is enabled by default. Ping me on Monday to remind me to investigate properly. \$\endgroup\$
    – Shaggy
    Jan 13 at 20:06
3
\$\begingroup\$

Excel, 149 bytes

=IFERROR(REPLACE(A1,1,FIND("$",SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"a","$"),"e","$"),"i","$"),"o","$"),"u","$"))-1,"shm"),A1)

102 bytes just to find the vowels. If anybody knows a better way to do this. please share.

From inside out:

  • SUBSTITUTE vowels with $
  • Find the index of the first $
  • Replace chars before this index with shm
  • If no vowels, return input.
\$\endgroup\$
1
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ May 25, 2022 at 13:44
3
\$\begingroup\$

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

say@F?(shm,@F):$_

Try it online!

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

C (gcc), 125 113 bytes

-8 bytes thanks to @ceilingcat

#define T&&*s-
main(s,v)char**v,*s;{for(s=*++v;*s T'a'T'e'T'i'T'o'T'u'||!(*v=memcpy(s-3,"smh",3));++s);puts(*v);}

Try it online!

\$\endgroup\$
1
2
\$\begingroup\$

Charcoal, 25 bytes

≔⌕Eθ№aeiouι¹η¿⊕η«shm✂θη»θ

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

≔⌕Eθ№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.

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Java is shorter than Python. What is going on... \$\endgroup\$
    – Romanp
    May 24, 2022 at 23:12
  • \$\begingroup\$ It's really a regex solution :-) \$\endgroup\$
    – toolforger
    May 27, 2022 at 12:30
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Extended), 31 bytes

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

Try it online!

\$\endgroup\$
1
2
\$\begingroup\$

Haskell, 58 57 bytes

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

Attempt This Online!

-1 byte thanks to Wheat Wizard ♦

\$\endgroup\$
0
2
\$\begingroup\$

V (Eh, vim shmim), 23 bytes

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

vim non-greedy regex with look-ahead.

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 í

\$\endgroup\$
2
\$\begingroup\$

Go, 103 bytes

import."regexp"
func f(s string)string{return MustCompile(`^.*?([aeiou])`).ReplaceAllString(s,"shm$1")}

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

tinylisp 2, 64 61 bytes

(\(S)(: T(drop-while(. !(p contains?"aeiou"))S)(? T(,"shm"T)S

Try it at Replit. Example session:

tl2> (\(S)(: T(drop-while(. !(p contains?"aeiou"))S)(? T(,"shm"T)S
(() (S) (: T (drop-while (. ! (p contains? "aeiou")) S) (? T (, "shm" T) S)))
tl2> (def shm _)
shm
tl2> (map shm (list "codegolf" "stellar" "airplane" "lrr"))
("shmodegolf" "shmellar" "shmairplane" "lrr")

Explanation

Port of Unrelated String's Jelly answer, among others.

First, we need a function that tests whether a character is not a vowel:

(. !(p contains?"aeiou"))
(.                      ) ; Compose
   !                      ; Logical negation
    (p                 )  ; with the partial application of
       contains?          ; the contains? function
                "aeiou"   ; to "aeiou"

Then our main function is as follows (where (...) represents the above function):

(\(S)(: T(drop-while(...)S)(? T(,"shm"T)S)))
(\                                         ) ; Lambda function
  (S)                                        ; that takes a string S:
     (: T                                 )  ;  In what follows, let T be
         (drop-while     S)                  ;   Drop characters from S while
                    (...)                    ;   they are not vowels
                           (? T          )   ;  Is T truthy (nonempty)?
                               (,"shm"T)     ;  If so, concatenate "shm" with T
                                        S    ;  If not, return the original string S
\$\endgroup\$
2
\$\begingroup\$

Nibbles, 15.5 bytes

?,;>~$-~?"aeiou"$:"shm"@@

Attempt This Online!

Nibbles has no built-in for vowels, which makes it slightly worse than other golfing languages for this.

Explanation

?         If
,          non-empty
;           x :=
>~           drop-while
$             from input
-~            not
? "aeiou"      contained in "aeiou"
$              it
          then
: "shm"    prepend "shm"
@          to x
          else
@          input
\$\endgroup\$
1
\$\begingroup\$

Factor, 70 61 45 bytes

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

Try it online!

\$\endgroup\$

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.