Boo! A Halloween Code Golf Challenge

15

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!

Arcturus

Posted 2015-10-31T02:15:22.837

Reputation: 6 537

Would a command-line argument be okay, or does it have to be stdin? – DLosc – 2015-10-31T02:51:14.343

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. – Arcturus – 2015-10-31T02:57:17.383

Answers

6

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.

Dennis

Posted 2015-10-31T02:15:22.837

Reputation: 196 637

4

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.

Niet the Dark Absol

Posted 2015-10-31T02:15:22.837

Reputation: 647

Never thought I'd see GML on codegolf. – Steffan Donal – 2015-10-31T19:50:27.633

3

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.

alexis

Posted 2015-10-31T02:15:22.837

Reputation: 432

2

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.

Reto Koradi

Posted 2015-10-31T02:15:22.837

Reputation: 4 870

2

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

DLosc

Posted 2015-10-31T02:15:22.837

Reputation: 21 213

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? – Dennis – 2015-10-31T04:51:22.070

1@Dennis The former. The quotes are to prevent shell expansion, and to prevent stuff with spaces from being treated as multiple command-line args. – DLosc – 2015-10-31T05:00:59.517

1

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.

Mego

Posted 2015-10-31T02:15:22.837

Reputation: 32 998

My solution exactly. To the letter. – Arcturus – 2015-10-31T02:32:03.883

@Mego Seeing a random <code> ~BOO!~ </code> show up in your program is pretty spooky. – Arcturus – 2015-10-31T02:35:04.053

Since multiple arguments to print are printed space-separated, you can cut the spaces with print(s[:n],'~BOO!~',s[n:]). – xnor – 2015-10-31T07:44:07.347

1

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()
    {
        var x = Console.In.ReadToEnd();
        Console.Write(x.Insert(new Random().Next(x.Length - 2) + 1, " ~BOO!~ "));
    }
}

Timwi

Posted 2015-10-31T02:15:22.837

Reputation: 12 158

(see comments, arguments are ok) static void Main(string[] x) {Console.Write(x[0].Insert (...) x[0].Length (...) will shorten your code – Jan 'splite' K. – 2015-10-31T12:53:04.527

1

Julia, 70 bytes

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

Ungolfed:

# Read a line from STDIN
s = readline()

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

Alex A.

Posted 2015-10-31T02:15:22.837

Reputation: 23 761

1

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
 (                  )           ⍝ Monadic train:
               ⍵⌽⍨⊢            ⍝ Rotate input by X (⊢) to the left
    ' ~BOO!~ ',                 ⍝ Concatenate ' ~BOO!~ '
  -                             ⍝ -X
   ⌽                            ⍝ Rotate that by X to the right

Example input on TryAPL

lirtosiast

Posted 2015-10-31T02:15:22.837

Reputation: 20 331

1

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.

Addison Crump

Posted 2015-10-31T02:15:22.837

Reputation: 10 763

1

Lua, 75 bytes

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

Digital Veer

Posted 2015-10-31T02:15:22.837

Reputation: 241

1

Perl, 35 bytes

34 bytes code + 1 byte command line

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

Usage:

perl -p entry.pl

Jarmex

Posted 2015-10-31T02:15:22.837

Reputation: 2 045

0

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

Kevin Cruijssen

Posted 2015-10-31T02:15:22.837

Reputation: 67 575

0

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.

Tom Carpenter

Posted 2015-10-31T02:15:22.837

Reputation: 3 990

0

Ruby, 46 bytes

$><<gets.insert(rand(1..$_.size-2),' ~BOO!~ ')

Peter Lenkefi

Posted 2015-10-31T02:15:22.837

Reputation: 1 577

0

Bash/GNU, 61 bytes

echo $1|sed "s/.\{`shuf -i1-$((${#1}-1)) -n1`\}/\0 ~BOO!~ /"

Takes input string as argument

Fabian Schmengler

Posted 2015-10-31T02:15:22.837

Reputation: 1 972

0

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.

ŽaMan

Posted 2015-10-31T02:15:22.837

Reputation: 151

0

Chaîne, 23 bytes

{il1-R1+`} ~BOO!~ {<$/}

Conor O'Brien

Posted 2015-10-31T02:15:22.837

Reputation: 36 228

-1

TeaScript, 30 bytes

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

Very straight forward.

Downgoat

Posted 2015-10-31T02:15:22.837

Reputation: 27 116

-1

CJam, 19 bytes

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

username.ak

Posted 2015-10-31T02:15:22.837

Reputation: 411

This will fail when mr returns 0 or 1, because neither -1 nor 0 are valid for splitting a string with /. – Martin Ender – 2015-12-13T11:40:16.510

Then it must be ) – username.ak – 2015-12-13T11:59:47.337

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: http://codegolf.stackexchange.com/a/62355/8478

– Martin Ender – 2015-12-13T12:00:37.443

I use q (reads all input, including newline), he uses l (reads only 1 line) – username.ak – 2015-12-13T15:23:27.220

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). – Martin Ender – 2015-12-13T15:30:04.483

Wait, actually that doesn't solve the problem. I means that BOO could be placed after the linefeed which is yet another character too far away. – Martin Ender – 2015-12-13T15:31:07.060

In some implementations, linefeeds can be put as part of one input – username.ak – 2015-12-13T15:34:39.283

Let us continue this discussion in chat.

– Martin Ender – 2015-12-13T15:37:34.180