ssTTsSTtRrriinInnnnNNNIiinngg

18

2

Challenge

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

Notes

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

MilkyWay90

Posted 2019-04-02T23:23:51.287

Reputation: 2 264

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). – Chas Brown – 2019-04-03T01:21:25.347

@ChasBrown Yeah, I'll edit the question – MilkyWay90 – 2019-04-03T01:39:45.283

What options do we have as source of randomness, can we use the input string? – Expired Data – 2019-04-03T07:38:35.263

2I find the specification confusing. Can you be more explicit? For example, work out how String produces SSSTSStrTrIiinIIngn – Luis Mendo – 2019-04-03T09:02:55.467

7@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). – Kevin Cruijssen – 2019-04-03T11:09:44.950

3@KevinCruijssen Thanks, Your explanation fits the example, and is clear. The OP should confirm and edit that into the text – Luis Mendo – 2019-04-03T11:19:15.937

It took me several minutes to figure out what you meant by "switchcase version". Google didn't turn up anything. Might help to show an example on the line. – Daniel – 2019-04-03T15:05:21.953

@KevinCruijssen I will change "1 and 5" to "1 - 5" – MilkyWay90 – 2019-04-03T22:52:22.880

@LuisMendo What are you confused about? Do you have any suggestion on how to be more explicit? – MilkyWay90 – 2019-04-03T22:53:53.540

I think it's clear now. I removed my vote to close – Luis Mendo – 2019-04-04T06:23:49.923

Answers

6

Gaia, 25 bytes

ṇ\+†ṅ\⟨)₌¤:~+4ṛ⟨ṛ₌¤⟩ₓ\⟩¦$

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.

Giuseppe

Posted 2019-04-02T23:23:51.287

Reputation: 21 077

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). – Kevin Cruijssen – 2019-04-03T08:56:05.093

@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 – Giuseppe – 2019-04-03T10:50:12.103

15ṛ 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? – Kevin Cruijssen – 2019-04-03T11:32:43.430

1@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. – Giuseppe – 2019-04-03T11:41:55.430

4

APL (dzaima/APL), 23 bytes

Anonymous tacit prefix function.

∊2(⊣,{?4⍴⍨?5}⊇,,-⍤,)/

Try it online!

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

- the switchcase
 of
, 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)

Adám

Posted 2019-04-02T23:23:51.287

Reputation: 37 779

3

Bash, 121 bytes

-20 bytes thanks to Nahuel

-9 bytes thanks to roblogic

for((i=0;i<${#1};i++)){
s=${1:i:1}
m=${1:i:2}
m=${m,,}${m^^}
for((t=0;t++<RANDOM%6;)){
s+=${m:RANDOM%4:1}
}
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.

for((i=0;i<${#1}-1;i++));do
c=${1:$i:1}
n=${1:$((i+1)):1}
a=($n ${c,} ${c^} ${n,} ${n^})
shuf -e ${a[@]} -n "$(shuf -i 1-5 -n 1)"|xargs printf %s
done

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.

Jonah

Posted 2019-04-02T23:23:51.287

Reputation: 8 729

seems it's missing printf %s "$c" – Nahuel Fouilleul – 2019-04-03T08:06:58.537

1do and done can be replaced with undocumented { and } – Nahuel Fouilleul – 2019-04-03T08:08:44.397

with some changes – Nahuel Fouilleul – 2019-04-03T08:25:15.503

@NahuelFouilleul tyvm. nice improvements and nice catch -- i'd somehow missed the requirement always to output the current char. – Jonah – 2019-04-03T13:07:48.247

optimising the for loops to save 9 bytes :) – roblogic – 2019-04-03T21:27:20.043

1@roblogic that's clever. tyvm. – Jonah – 2019-04-03T21:36:58.417

1

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

– roblogic – 2019-08-12T03:42:17.717

Thanks @roblogic. – Jonah – 2019-08-12T03:46:13.810

3

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.

Jo King

Posted 2019-04-02T23:23:51.287

Reputation: 38 234

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. – Kevin Cruijssen – 2019-04-03T13:43:44.260

1Alas, (.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). – Ven – 2019-04-03T16:02:15.927

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. https://tio.run/##RYvBCoJAFEX3fcVNJBySkRa1UIygRS2FllEgOkrwdORNEmr661NB0eLC4XBuo5g2tuqwKBDDDqewHKTYelKMsRtM5@kC1kS4riE/sFz5g6TMf8o2G72dG4jRmrRD4Tnmzre6dEQ0@wofEr8dFZHGQzPl839iqOVGRDZhXXJaVe8/krbvSRmkdY69zhUOmooX

– Phil H – 2019-04-04T16:12:10.170

@PhilH No that doesn't work. Those solutions only capitalise one of the letters each

– Jo King – 2019-04-04T21:18:41.857

3

Jelly, 12 bytes

;Œsṗ5X¤XṭṖµƝ

Try it online!

Erik the Outgolfer

Posted 2019-04-02T23:23:51.287

Reputation: 38 134

2

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!

Chas Brown

Posted 2019-04-02T23:23:51.287

Reputation: 8 959

2

05AB1E, 18 17 bytes

ü)vyн5LΩFyD.š«Ω]J

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

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

Explanation:

ü)             # 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)

Kevin Cruijssen

Posted 2019-04-02T23:23:51.287

Reputation: 67 575

I don't know 05AB1E but, instead of INè, could you save anything by pushing the first character of y? – Shaggy – 2019-04-03T09:06:19.747

@Shaggy Yes, I indeed can.. Thanks! Maybe I should stop golfing for today, I'm a mess, lol.. – Kevin Cruijssen – 2019-04-03T09:08:46.063

*You're* a mess? ¨vNUy5LΩFy¹X>è«D.š«Ω? – Magic Octopus Urn – 2019-04-03T12:52:05.747

1@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. – Kevin Cruijssen – 2019-04-03T13:03:54.077

1

Charcoal, 27 bytes

FLθ«F∧ι⊕‽⁵‽⭆✂θ⊖ι⊕ι¹⁺↥λ↧λ§θι

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

FLθ«

Loop over all of the indices of the input string.

F∧ι⊕‽⁵

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.

Neil

Posted 2019-04-02T23:23:51.287

Reputation: 95 035

1

Jelly, 14 bytes

;;;Œs$Xɗ¥5X¤¡Ɲ

Try it online!

Explanation

             Ɲ | 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

Nick Kennedy

Posted 2019-04-02T23:23:51.287

Reputation: 11 829

1

perl 5 (-p), 77 bytes

s/(.)(?=(.))/$x=$1;'$x.=substr"\U$1$2\L$1$2",4*rand,1;'x(1+5*rand)/gee;s/.$//

TIO

Nahuel Fouilleul

Posted 2019-04-02T23:23:51.287

Reputation: 5 582

You can save 4 bytes by using $& instead of $1, and chop + -l instead of s/.$// – Dada – 2019-04-04T14:24:33.873

1

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

Shaggy

Posted 2019-04-02T23:23:51.287

Reputation: 24 623

1

Python 3, 167 bytes

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

Try it online!

Sara J

Posted 2019-04-02T23:23:51.287

Reputation: 2 576

1

C(GCC) 175 162 150 bytes

-12 bytes from LambdaBeta

-12 bytes from ceilingcat

f(s,S,i,r,a)char*s,*S,*i;{srand(time(0));for(i=S;s[1];++s)for(r=rand(*i++=*s)%5+1;r--;*i++=rand()&1&&a>96&a<123|a>64&a<91?a^32:a)a=s[~rand()&1];*i=0;}

Try it online!

rtpax

Posted 2019-04-02T23:23:51.287

Reputation: 411

I don't think you need the 0 in the first line. – LambdaBeta – 2019-04-03T21:28:07.597

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!

– LambdaBeta – 2019-04-03T21:31:33.087

@LambdaBeta turns out you are right about the 0, which made it not worth it to have the #define anymore – rtpax – 2019-04-04T14:57:58.960

140 bytes – ceilingcat – 2020-02-25T22:04:22.073

1

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

Veskah

Posted 2019-04-02T23:23:51.287

Reputation: 3 580

Oh, wow, thats a lot of bytes. – MilkyWay90 – 2019-08-14T16:49:49.223

1@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. – Veskah – 2019-08-14T18:36:02.690

1

I'm sorry 87 bytes

– mazzy – 2019-08-15T10:02:40.093

0

Japt -P, 43 16 bytes

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

Shortened by a lot now!

Try it

Embodiment of Ignorance

Posted 2019-04-02T23:23:51.287

Reputation: 7 014

This seems to return the same result every time. – Shaggy – 2019-04-03T10:01:52.950

@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?

– Embodiment of Ignorance – 2019-04-04T05:21:38.080

0

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!

Expired Data

Posted 2019-04-02T23:23:51.287

Reputation: 3 129

Does not work with non-alphanumeric characters. char b=a[0] -> var b=a[0], extra space in declaration of d in for-loop – Embodiment of Ignorance – 2019-04-04T05:11:59.870

0

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
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)

Ungolfed:

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
        cc
      })
  }.mkString
}

println(gobble(StdIn.readLine()))

Soren

Posted 2019-04-02T23:23:51.287

Reputation: 285

1No way to turn a :: b :: Nil into a::b::Nil? Same for a :+, a:+() or a.:+() might work – Ven – 2019-04-04T14:07:46.413

@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? – Soren – 2019-04-04T22:58:56.747

You only have only one elem here so it’s not autotupling anyway – Ven – 2019-04-04T23:41:23.237

0

Perl 5 -n, 61 bytes

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

Try it online!

Dada

Posted 2019-04-02T23:23:51.287

Reputation: 8 279

0

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
FROM(values(1),(2),(3),(4),(5))F(h),spt_values)D
WHERE'P'=type and n<len(@)-1and h>v%3+2ORDER
BY-n)E
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

t-clausen.dk

Posted 2019-04-02T23:23:51.287

Reputation: 2 874

0

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!

Embodiment of Ignorance

Posted 2019-04-02T23:23:51.287

Reputation: 7 014

0

C (gcc), 110 109 bytes

i,p;g(char*_){for(i=rand(putchar(*_))%1024;p=_[i%2],putchar(i&2&&p>64&~-p%32<26?p^32:p),i/=4;);_[2]&&g(_+1);}

Try it online!

-1 thanks to ceilingcat

i,p;g(char*_){
    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
            ?p^32:p),
        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)

attinat

Posted 2019-04-02T23:23:51.287

Reputation: 3 495

0

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=;}

roblogic

Posted 2019-04-02T23:23:51.287

Reputation: 554