# Boo! A Halloween Code Golf Challenge

Write a program that takes an input string of length 2 or more characters and adds the string  ~BOO!~  (that string has a leading and ending space) in a uniformly random spot in the string that is not on either end.

Disallowed sample inputs: 2 or   (an empty input)

Disallowed sample outputs: Hello ~BOO!~  or  ~BOO!~ Hello for the input Hello

Sample input: Hello, World!

Sample outputs: Hel ~BOO!~ lo, World! or Hello, Worl ~BOO!~ d!

This is code golf, fellas. Standard rules apply. Shortest code in bytes wins.

Congratulations to Dennis for having the shortest, spookiest program! Happy Halloween!

• Would a command-line argument be okay, or does it have to be stdin? Oct 31 '15 at 2:51
• Anything that takes an input and prints that output with the modification is acceptable. I use STDIN by default because it's the only term I'm familiar with. Oct 31 '15 at 2:57

# Pyth, 19 18 bytes

j" ~BOO!~ "cz]OtUz


Thanks to @Jakube for golfing off 1 byte!

Try it online.

### How it works

                    (implicit) Store the input in z.
Uz  Compute [0, ... len(z)-1].
t    Remove the first element.
O     Select an integer, pseudo-randomly.
]      Wrap it in an array.
cz       Split the input string at that point.
j" ~BOO!~ "         Join the split string, using " ~BOO!~ " as separator.


# GML, 91 bytes

s=get_string("","")
show_message(string_insert(" ~BOO!~ ",s,irandom(string_length(s)-2)+1);


Simple enough - get a string, insert the substring into it, output the string. Done.

• Never thought I'd see GML on codegolf. Oct 31 '15 at 19:50

# Python 3, 60 bytes

s=input();n=1+hash(s)%(len(s)-1);print(s[:n],'~BOO!~',s[n:])


Note:

The modulo of hash() will be uniformly distributed over the length of the string. If you think that's bending the rules, note that because of python's hash randomization, this is actually random: repeated executions with the same input will give different results.

# CJam, 20 bytes

l_,(mr)/(" ~BOO!~ "@


Try it online

Explanation:

l       Get input.
_,      Calculate length.
(       Decrement, since the number of possible positions is 1 less than length.
mr      Generate random number between 0 and length-2
)       Increment, giving random number between 1 and length-1.
/       Split. Note that this splits repeatedly, but this will not do any harm.
We will only really use the first split.
(       Peel off the first fragment after the split.
" ~BOO!~ "
Push the magic string.
@       Rotate the list with the remaining fragments to the top.


## Pip, 19 bytes

Takes input from the command-line. If the input has spaces or other special characters, it will need to be placed in quotes.

a^@1RR#aJ" ~BOO!~ "


Explanation:

a                    Command-line arg
^@                  Split at index...
1RR#a             ...random integer >= 1 and < length(a) (Python randrange)
J" ~BOO!~ "  Join on that string and autoprint

• Do you mean that the input has to be passed as a single command-line argument, or do you actually have to pass quotes to Pip? Oct 31 '15 at 4:51
• @Dennis The former. The quotes are to prevent shell expansion, and to prevent stuff with spaces from being treated as multiple command-line args. Oct 31 '15 at 5:00

# Julia, 70 bytes

print((s=readline())[1:(r=rand(2:length(s)-2))]," ~BOO!~ ",s[r+1:end])


Ungolfed:

# Read a line from STDIN

# Define a random integer within the bounds of s
r = rand(2:length(s)-2)

# Print to STDOUT with boo in there somewhere
print(s[1:r], " ~BOO!~ ", s[r+1:end])


## APL, 27 bytes

{(-⌽' ~BOO!~ ',⍵⌽⍨⊢)?¯1+⍴⍵}


APL doesn't have an insert function, so we rotate the string instead.

{                          }    ⍝ Monadic function:
?¯1+⍴⍵     ⍝ Place to insert string, let's say it's X
⍵⌽⍨⊢            ⍝ Rotate input by X (⊢) to the left
' ~BOO!~ ',                 ⍝ Concatenate ' ~BOO!~ '
-                             ⍝ -X
⌽                            ⍝ Rotate that by X to the right


Example input on TryAPL

# Lua, 75 bytes

s=io.read()m=math.random(2,#s/2);return s:sub(1,m).." ~BOO!~ "..s:sub(m,#s)


## Python 3, 79 bytes

from random import*;s=input();n=randint(1,len(s)-1);print(s[:n],'~BOO!~',s[n:])


Try it online

Pretty self-explanatory - read a string, pick a random integer between 1 and the length of the string, and print the string with ' ~BOO!~ ' inserted.

• My solution exactly. To the letter. Oct 31 '15 at 2:32
• @Mego Seeing a random <code> ~BOO!~ </code> show up in your program is pretty spooky. Oct 31 '15 at 2:35
• Since multiple arguments to print are printed space-separated, you can cut the spaces with print(s[:n],'~BOO!~',s[n:]).
– xnor
Oct 31 '15 at 7:44

# Perl, 35 bytes

34 bytes code + 1 byte command line

$-=rand y///c-2;s/..{$-}\K/~BOO!~/


Usage:

perl -p entry.pl


# C#, 125 bytes

using System;class X{static void Main(string[]a){Console.Write(a[0].Insert(new Random().Next(a[0].Length-2)+1," ~BOO!~ "));}}


Expanded:

using System;
class X
{
static void Main(string[] a)
{
Console.Write(a[0].Insert(new Random().Next(a[0].Length - 2) + 1, " ~BOO!~ "));
}
}


This solution assumes that the string is passed in as the first command-line parameter. This is not usual for C# (stdin is more normal), so I’ve also included a solution that uses normal stdin:

# C#, 139 bytes

using System;class X{static void Main(){var x=Console.In.ReadToEnd();Console.Write(x.Insert(new Random().Next(x.Length-2)+1," ~BOO!~ "));}}


Expanded:

using System;
class X
{
static void Main()
{
Console.Write(x.Insert(new Random().Next(x.Length - 2) + 1, " ~BOO!~ "));
}
}

• (see comments, arguments are ok) static void Main(string[] x) {Console.Write(x[0].Insert (...) x[0].Length (...) will shorten your code Oct 31 '15 at 12:53

# MATLAB, 69 bytes

i=input('');a=randi(nnz(i)-1,1);disp([i(1:a) ' ~Boo!~ ' i(a+1:end)]);


Inserting a string mid string at a given index in MATLAB is costly in terms of bytes. If there was a simple way to do it, I could save a fair amount by moving to an anonymous function, but I can't find one. Ah well.

Basically it gets a random number between 1 and the length of the string minus 1. Then it displays everything up to and including that index, followed by the ~Boo!~, and then everything after the index to the end.

It also works with Octave, so you can try it out online here.

# Vitsy, 19 Bytes

Note that z and Z were edited today, but not for this challenge.

I1-R1+\i" ~OOB~ "zZ
I1-                   Get the length of the input, minus 1
R                  Push a random number from 0 to the top item of the stack.
1+                Add one to it - this is now a random number from 1 to input
length - 1.
\i              Get that many items of input.
" ~OOB~ "     Push ' ~BOO~ ' to the stack.
z    Get the rest of the input.
Z   Output it all.


echo $1|sed "s/.\{shuf -i1-$((${#1}-1)) -n1\}/\0 ~BOO!~ /"  Takes input string as argument # Ruby, 46 bytes $><<gets.insert(rand(1..$_.size-2),' ~BOO!~ ')  # JavaScript, 79 r=Math.random()*((x=prompt()).length-1)+1;x.substr(0,r)+" ~BOO!~ "+x.substr(r);  It's for the browser console; have fun just popping that in. # Java 8, 158 154 bytes interface M{static void main(String[]a){int i=a[0].length()-2;System.out.println(a[0].substring(0,i=1+(i*=Math.random()))+" ~BOO!~ "+a[0].substring(i));}}  Try it here. EDIT: Only now reading program instead of the default function/program in the challenge description.. So added the bordercode with interface and main method. If a function would be allowed it would be (99 95 bytes) s->{int i=s.length()-2;return s.substring(0,i=1+(i*=Math.random()))+" ~BOO!~ "+s.substring(i);}  Try it here. Explanation: s->{ // Method with String as both parameter and return-type int i=s.length()-2; // The length of the input - 2 return s.substring(0,i=1 // Return the first part of the input from index 0 to 1 +(i*=Math.random())) // + a random integer between 0 and length-2 +" ~BOO!~ " // appended with the literal " ~BOO!~ " +s.substring(i); // appended with the rest of the input-String } // End of method  # Chaîne, 23 bytes {il1-R1+} ~BOO!~ {<$/}


# TeaScript, 30 bytes

xh(j=N(xn-1)+1)+' ~BOO!~ '+xS(j)


Very straight forward.

## CJam, 19 bytes

q_,mr)/(" ~BOO!~ "@

• This will fail when mr returns 0 or 1, because neither -1 nor 0 are valid for splitting a string with /. Dec 13 '15 at 11:40
• Then it must be ) Dec 13 '15 at 11:59
• Now it can put BOO at the end of the string, You'd also need a ( before mr. But then it's identical to this answer: codegolf.stackexchange.com/a/62355/8478 Dec 13 '15 at 12:00
• I use q (reads all input, including newline), he uses l (reads only 1 line) Dec 13 '15 at 15:23
• Oh okay, then you should specify that your code expects the input to have a trailing linefeed (because it doesn't necessarily have one, in which case q and l` are synonymous). Dec 13 '15 at 15:30