For each character of the string except for the last one, do the following:

  • Output the current character.

  • Followed by randomly outputting from the following list a random number of times between 1 - 5 (inclusive):

    • The current character
    • The next character of the string
    • The switchcase version of the character that you are currently on
    • The switchcase version of the next character of the string.

Test Cases

String --> SSSTSStrTrIiinIIngn

, . , . , . Hello world! --> ,,, .. , ,, .... , , .. .. . HHH HHEeelLlLllooO wwOworOOrrrRllDd!!D

Programming Puzzles and Code Golf --> PrPPrRrOooooogggRgGraAraaaMMMmmmimMIiininGGgG PPPPuZzZZzZzzZzllLLEEeEsEsssS a aANnNddD C COCoooOOdeDe E GGGoOllFFf


  • You only need to apply the switchcase version of a character if the character is part of the alphabet (A-Z and a-z).
  • Your random function does not need to be uniform but it still needs to have a chance of returning any element in the list given.
  • You are allowed to use any standard I/O format.
  • You may assume that the length of the input is greater than or equal to two.
  • You may assume that the input only consists of ASCII characters.
  • The title is not a test case (it is unintentional if it is a valid test case).
  • Switchcase means to turn the char to lowercase if it is uppercase and to turn it to uppercase if it is lowercase.
  • \$\begingroup\$ In addition to '... does not need to be uniform', I think you probably want to specify that given some input, all finite legal outputs should in principle be possible to generate (otherwise, my non-uniform random integer in [1,2,3,4,5] is always going to be 2, and I'll just output the original string). \$\endgroup\$
    – Chas Brown
    Commented Apr 3, 2019 at 1:21
  • \$\begingroup\$ @ChasBrown Yeah, I'll edit the question \$\endgroup\$
    – MilkyWay90
    Commented Apr 3, 2019 at 1:39
  • 2
    \$\begingroup\$ I find the specification confusing. Can you be more explicit? For example, work out how String produces SSSTSStrTrIiinIIngn \$\endgroup\$
    – Luis Mendo
    Commented Apr 3, 2019 at 9:02
  • 7
    \$\begingroup\$ @LuisMendo I'm not OP, but I think: [S]SSTSS [t]rT, [r]I, [i]inII, [n]gn, where the characters between the blocks are the first bullet points ("Output the current character"), and the other characters are 1-5 times randomly one of the four choices for that character. But I agree, some more explicit explanations would be appropriate. Apart from the test case it wasn't particularly clear we have to pick a random choice 1-5 times. Instead of picking a random choice repeated 1-5 times (as the Gaia answer currently does). \$\endgroup\$ Commented Apr 3, 2019 at 11:09
  • 3
    \$\begingroup\$ @KevinCruijssen Thanks, Your explanation fits the example, and is clear. The OP should confirm and edit that into the text \$\endgroup\$
    – Luis Mendo
    Commented Apr 3, 2019 at 11:19

24 Answers 24


Gaia, 25 bytes


Try it online!

Thanks to Kevin Cruijssen for pointing out 2 bugs!

ṇ\				| delete the last character from the input
  +†				| push the input again and concatenate together, so for instance
				| 'abc' 'bc' becomes ['ab' 'bc' 'c']
    ṅ\				| delete the last element
       ⟨       		⟩¦	| for each of the elements, do:
	)₌			| take the first character and push again
	  ¤			| swap
	   :			| dup
	    ~			| swap case
	     +			| concatenate strings
	      4ṛ		| select a random integer from [1..5]
	        ⟨    ⟩ₓ		| and repeat that many times
		 ṛ₌¤		| select a random character from the string
		      \ 	| clean up stack
			   $	| convert to string

Note that 4ṛ is because is implemented for an integer z as python's random.randint(1,z+1), which returns an integer N such that 1<=N<=z+1.

  • \$\begingroup\$ Are you sure the run-length encode is correct here? If I understand the challenge correctly: the four options should be chosen 1-5 times randomly, instead of choosing one of the four randomly, repeated 1-5 times. The first example output SSSTSStrTrIiinIIngn ([SSSTSS, trT, rI, iinII, ngn]) seems to reflect this, and currently isn't a possible output in your program (I think). \$\endgroup\$ Commented Apr 3, 2019 at 8:56
  • \$\begingroup\$ @KevinCruijssen I interpreted "output from the list a random number of times" to mean run-length decode, but you're right, the test cases do seem to indicate the other interpretation; I think it should be pretty easy to fix \$\endgroup\$
    – Giuseppe
    Commented Apr 3, 2019 at 10:50
  • 1
    \$\begingroup\$ 5ṛ can result in 6 for some reason Try it online? PS: Isn't there an integer to ranged list, or ranged for-loop in Gaia? \$\endgroup\$ Commented Apr 3, 2019 at 11:32
  • 1
    \$\begingroup\$ @KevinCruijssen dang, Business Cat really needs to fix off-by-one errors...I really thought there was a for type construct, but I'm pretty sure it's which isn't even documented on the wiki page. \$\endgroup\$
    – Giuseppe
    Commented Apr 3, 2019 at 11:41

APL (dzaima/APL), 23 bytes

Anonymous tacit prefix function.


Try it online!

2()/ apply the following infix tacit function between each character pair:

- the switchcase
, the concatenation of the pair

,, prepend the concatenation of the pair to that

{}⊇ pick the following elements from that:

  ?5 random number in range 1…5

  4⍴⍨ that many fours

  ? random indices for those

ϵnlist (flatten)


Perl 6, 60 bytes

{S:g{.)>(.)}=$/~[~] roll ^5 .roll+1,$/.lc,$/.uc,$0.lc,$0.uc}

Try it online!

The lowercase/uppercase part is kinda annoying.

  • \$\begingroup\$ I don't know Perl, so I'm probably saying something stupid here. But is it somehow possible to concat the $/ and $0 together and use .lc on that string, and then create a copy of that string and use .uc, and concat those two together? Not sure if that's even possible, or shorter than your current $/.lc,$/.uc,$0.lc,$0.uc, but it would mean you'd use $/, $0, .lc, and .uc once each. \$\endgroup\$ Commented Apr 3, 2019 at 13:43
  • 1
    \$\begingroup\$ Alas, (.lc~.uc for $0~$/).comb is longer. Perl 6 really wants to distinguish strings and lists, so "abc"[0] eq "abc" (it pretends to be a single-item list). \$\endgroup\$
    – Ven
    Commented Apr 3, 2019 at 16:02
  • \$\begingroup\$ You can do it by slipping and an anonymous function applied to a list: {.lc,|.uc}($/,|$0) for -5 bytes, and just use the list of matches {.lc,|.uc}(@$/) for -8 bytes. tio.run/… \$\endgroup\$
    – Phil H
    Commented Apr 4, 2019 at 16:12
  • \$\begingroup\$ @PhilH No that doesn't work. Those solutions only capitalise one of the letters each \$\endgroup\$
    – Jo King
    Commented Apr 4, 2019 at 21:18

Jelly, 12 bytes


Try it online!


Bash, 121 bytes

-20 bytes thanks to Nahuel

-9 bytes thanks to roblogic

printf "$s"

Try it online!

Original answer

Bash, 150 bytes

Have done very little golf bashing and trying to improve my bash, so any comments welcome.

a=($n ${c,} ${c^} ${n,} ${n^})
shuf -e ${a[@]} -n "$(shuf -i 1-5 -n 1)"|xargs printf %s

Try it online!

Code is straightforward loop through chars setting current c and next n character, then creating an array of the 4 possibilities, repeating one of them so there's exactly 5. Next we shuffle that array, and then choose n elements from it, where n itself is random between 1 and 5.

  • \$\begingroup\$ seems it's missing printf %s "$c" \$\endgroup\$ Commented Apr 3, 2019 at 8:06
  • 1
    \$\begingroup\$ do and done can be replaced with undocumented { and } \$\endgroup\$ Commented Apr 3, 2019 at 8:08
  • \$\begingroup\$ with some changes \$\endgroup\$ Commented Apr 3, 2019 at 8:25
  • 1
    \$\begingroup\$ @roblogic that's clever. tyvm. \$\endgroup\$
    – Jonah
    Commented Apr 3, 2019 at 21:36
  • 1
    \$\begingroup\$ The 121-byte solution is a bit fragile/buggy, here's a more robust (133-byte) version that should handle all printable ASCII, tio.run \$\endgroup\$
    – roblogic
    Commented Aug 12, 2019 at 3:42

Python 2, 107 bytes

f=lambda s:s and s[0]+''.join(sample((s[:2]+s[:2].swapcase())*5,randint(1,5)))+f(s[1:])
from random import*

Try it online!


05AB1E, 18 17 bytes


Inspired by @Giuseppe's Gaia answer.
-1 byte thanks to @Shaggy.

Try it online 10 times or verify all test cases 10 times.


ü)             # Create all pairs of the (implicit) input
               #  i.e. "Hello" → [["H","e"],["e","l"],["l","l"],["l","o"]]
  v            # Loop over each these pairs `y`:
   yн          #  Push the first character of pair `y`
   5LΩ         #  Get a random integer in the range [1,5]
      F        #  Inner loop that many times:
       y       #   Push pair `y`
        D.š«   #   Duplicate it, swap the cases of the letters, and merge it with `y`
            Ω  #   Then pop and push a random character from this list of four
  ]J           # After both loops: join the entire stack together to a single string
               # (which is output implicitly as result)
  • \$\begingroup\$ I don't know 05AB1E but, instead of INè, could you save anything by pushing the first character of y? \$\endgroup\$
    – Shaggy
    Commented Apr 3, 2019 at 9:06
  • \$\begingroup\$ @Shaggy Yes, I indeed can.. Thanks! Maybe I should stop golfing for today, I'm a mess, lol.. \$\endgroup\$ Commented Apr 3, 2019 at 9:08
  • \$\begingroup\$ You're a mess? ¨vNUy5LΩFy¹X>è«D.š«Ω? \$\endgroup\$ Commented Apr 3, 2019 at 12:52
  • 1
    \$\begingroup\$ @MagicOctopusUrn Although a pretty original approach, I'm afraid it doesn't do the first bullet point of the challenge ("Output the current character."), since the result can start with t, T, or s for input "String" in your program, while it's supposed to always start with the S. \$\endgroup\$ Commented Apr 3, 2019 at 13:03

Charcoal, 27 bytes


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


Loop over all of the indices of the input string.


Except for the first index, loop over a random number from 1 to 5 inclusive...


... extract the previous and next characters from the string, take the upper and lower case versions, and pick a random character of the four.


Print the character at the current index.


perl 5 (-p), 77 bytes



  • \$\begingroup\$ You can save 4 bytes by using $& instead of $1, and chop + -l instead of s/.$// \$\endgroup\$
    – Dada
    Commented Apr 4, 2019 at 14:24

Japt -P, 14 bytes

äÈ+Zu pv ö5ö Ä

Try it

äÈ+Zu pv ö5ö Ä     :Implicit input of string
ä                  :Take each consectutive pair of characters
 È                 :Pass them through the following function as Z
  +                :  Append to the first character of the pair
   Zu              :    Uppercase Z
      p            :    Append
       v           :      Lowercase
         ö         :    Get X random characters, where X is
          5ö       :      Random number in the range [0,5)
             Ä     :      Plus 1
                   :Implicitly join and output

Python 3, 167 bytes

from random import*;c=choice
def f(s):
 for i in range(len(s)-1):
  for j in range(randrange(5)):r+=c([str.upper,str.lower])(c(s[i:i+2]))
 return r

Try it online!


Jelly, 14 bytes


Try it online!


             Ɲ | For each overlapping pair of letters
;              | Join the first letter to...
         5X¤¡  | Between 1 and 5 repetitions of...
      Xɗ¥      | A randomly selected character from...
 ;;Œs$         | A list of the two letters and the swapped case versions of both

PowerShell, 154 105 103 95 87 bytes

-67 bytes thanks to mazzy who can't be stopped

-join(($x=$args)|%{$_;$x[$i,++$i]*5|%{"$_"|% *wer;"$_"|% *per}|random -c(1..5|random)})

Try it online!

Not a fantastic method but it works. Now it's pretty good. Takes input via splatting

  • \$\begingroup\$ Oh, wow, thats a lot of bytes. \$\endgroup\$
    – MilkyWay90
    Commented Aug 14, 2019 at 16:49
  • 1
    \$\begingroup\$ @mazzy Dang dog. I need to get into the habit of splatting all the time but didn't know you could hotswap the wildcard members like that. \$\endgroup\$
    – Veskah
    Commented Aug 14, 2019 at 18:36
  • 1
    \$\begingroup\$ I'm sorry 87 bytes \$\endgroup\$
    – mazzy
    Commented Aug 15, 2019 at 10:02

C(GCC) 175 162 150 bytes

-12 bytes from LambdaBeta

-12 bytes from ceilingcat


Try it online!

  • \$\begingroup\$ I don't think you need the 0 in the first line. \$\endgroup\$
    – LambdaBeta
    Commented Apr 3, 2019 at 21:28
  • \$\begingroup\$ Also can save a lot of characters by taking the buffer S as a parameter and adding your variables to the argument list: Try it online! \$\endgroup\$
    – LambdaBeta
    Commented Apr 3, 2019 at 21:31
  • \$\begingroup\$ @LambdaBeta turns out you are right about the 0, which made it not worth it to have the #define anymore \$\endgroup\$
    – rtpax
    Commented Apr 4, 2019 at 14:57
  • \$\begingroup\$ 140 bytes \$\endgroup\$
    – ceilingcat
    Commented Feb 25, 2020 at 22:04

Scala 2.12.8, 214 bytes

Golfed version:

val r=scala.util.Random;println(readLine.toList.sliding(2).flatMap{case a :: b :: Nil=>(a +: (0 to r.nextInt(5)).map{_=>((c: Char)=>if(r.nextBoolean)c.toUpper else c.toLower)(if(r.nextBoolean)a else b)})}.mkString)

Golfed with newlines and indents:

val r=scala.util.Random
  case a :: b :: Nil=>
    (a +: (0 to r.nextInt(5)).map{_=>
      ((c: Char)=>if(r.nextBoolean)c.toUpper else c.toLower)(if(r.nextBoolean)a else b)


import scala.io.StdIn
import scala.util.Random

def gobble(input: String): String = {
  input.toList.sliding(2).flatMap {
    case thisChar :: nextChar :: Nil =>
      val numberOfAdditions = Random.nextInt(5)
      (thisChar +: (0 to numberOfAdditions).map { _ =>
        val char = if(Random.nextBoolean) thisChar else nextChar
        val cc = if(Random.nextBoolean) char.toUpper else char.ToLower

  • 1
    \$\begingroup\$ No way to turn a :: b :: Nil into a::b::Nil? Same for a :+, a:+() or a.:+() might work \$\endgroup\$
    – Ven
    Commented Apr 4, 2019 at 14:07
  • \$\begingroup\$ @Ven a::b::Nil causes a compile error. +: is a method defined on the list, so it might save space by getting rid of the outer parens? \$\endgroup\$
    – Aly
    Commented Apr 4, 2019 at 22:58
  • \$\begingroup\$ You only have only one elem here so it’s not autotupling anyway \$\endgroup\$
    – Ven
    Commented Apr 4, 2019 at 23:41

Perl 5 -n, 61 bytes

s/.(?=(.))/print$&,map{(map{lc,uc}$&,$1)[rand 4]}0..rand 5/ge

Try it online!


C# (Visual C# Interactive Compiler), 236 213 209 bytes

a=>{int i=0,j;var m=new Random();var s="";var c = a.Select(x=>Char.IsLetter(x)?(char)(x^32):x).ToArray();for(;i<a.Length-1;i++)for(j=m.Next(1,5);j-->0;)s+=new[]{a[i],c[i],a[i+1],c[i+1]}[m.Next(0,3)];return s;}

Try it online!

  • \$\begingroup\$ Does not work with non-alphanumeric characters. char b=a[0] -> var b=a[0], extra space in declaration of d in for-loop \$\endgroup\$
    – Gymhgy
    Commented Apr 4, 2019 at 5:11

T-SQL query, 286 bytes

DECLARE @ char(999)='String'

SELECT @=stuff(@,n+2,0,s)FROM(SELECT
top 999*,substring(lower(c)+upper(c),abs(v%4)+1,1)s
FROM(SELECT*,number n,substring(@,number+1,2)c,cast(newid()as varbinary)v
WHERE'P'=type and n<len(@)-1and h>v%3+2ORDER
PRINT LEFT(@,len(@)-1)

Try it online unfortunately the online version always show the same result for the same varchar, unlike MS SQL Server Management Studio


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

n=>{var k=new Random();int i=0;foreach(var j in n.Skip(1).Zip(n,(a,b)=>a+b))for(Write(j[1]),i=0;i++<k.Next(5);)Write(k.Next()%2<1?j.ToUpper():j.ToLower());}

Try it online!


Japt -P, 43 16 bytes

äÈ+(Zv +Zu)ö5ö Ä

Shortened by a lot now!

Try it

  • \$\begingroup\$ This seems to return the same result every time. \$\endgroup\$
    – Shaggy
    Commented Apr 3, 2019 at 10:01
  • \$\begingroup\$ @Shaggy will fix. Also, ä's description says it gives three arguments, with the last being x+y. But as you can see here, it just returns 1. Is this a bug? \$\endgroup\$
    – Gymhgy
    Commented Apr 4, 2019 at 5:21

C (gcc), 110 109 bytes


Try it online!

-1 thanks to ceilingcat

    for(i=rand(putchar(*_)) //print current char
         %1024;             // and get 10 random bits
        p=_[i%2],           //1st bit => current/next char
        putchar(i&2&&       //2nd bit => toggle case
            p>64&~-p%32<26  // if char-to-print is alphabetic
        i/=4;);             //discard two bits
    _[2]&&g(_+1);           //if next isn't last char, repeat with next char

The number of characters printed (per input character) is not uniformly random:

1  if      i<   4 (  4/1024 = 1/256)
2  if   4<=i<  16 ( 12/1024 = 3/256)
3  if  16<=i<  64 ( 48/1024 = 3/ 64)
4  if  64<=i< 256 (192/1024 = 3/ 16)
5  if 256<=i<1024 (768/1024 = 3/  4)

Zsh, 113 107 bytes

With a lot of help from man zshexpn and man zshparam. Try it Online!

  • -6 by me, tweaking
for ((;i<#1;i++)){m=${1:$i:2};m=$m:l$m:u
for ((;t<RANDOM%5;t++))x+=${m[RANDOM%4]}
echo ${1[i]}$x\\c;t=;x=;}

Ruby, 74 bytes

gsub(/.(?=(.))/){([$&,$1,$&.swapcase,$1.swapcase]*5).sample(rand 1..5)*""}

Attempt This Online!


Stax, 17 bytes


Run and debug it at staxlang.xyz!

Unpacked (20 bytes) and explanation:

2B                      all size-2 subarrays
  F                     for each:
   ch]p                   print its first element
       c                  copy it on the stack
        :~                case-swap the copy
          +               concatenate
           5R|'           random integer 1-5, inclusive
               :$         Cartesian power
                 |'       random choice
                   p      print

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.