7
\$\begingroup\$

The challenge

Insert one string into another at a given index.

Given a string input in the format:

#:Pattern:Word

Where:

  • # is a positive integer marking the index
  • Pattern is the string (whose length is undefined) to insert
  • : is a delimiter
  • Word is the string to insert into.

Assume that a : will not be used in either string.

For example, if your input was

3:A2C:Hello World!

The output would be

HelA2Clo World!

If an invalid index is provided, the program must respond with an error. For example

12:!*!:Hello

is a valid input and must be explicitly handled somehow. For example, printing "Invalid input!" (or nothing at all!) is a valid way to catch, however crashing is not valid.

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Does invalid index just refer to indexes that are too high, or do we have to worry about negative indexes, non-integers or just non-numeric garbage? \$\endgroup\$
    – Dennis
    Oct 20, 2015 at 2:19
  • 2
    \$\begingroup\$ How do you define "respond with an error"? In many languages, this is done by crashing, so how strict is the rule on "crashing is not considered handling"? For example, when Java errors it stops execution and prints the stacktrace. Is this for or against the rules? \$\endgroup\$
    – GamrCorps
    Oct 20, 2015 at 2:36
  • \$\begingroup\$ @Dennis Just indexes that are too high. Assume the # is a valid, positive integer. \$\endgroup\$
    – Jon
    Oct 20, 2015 at 3:28
  • \$\begingroup\$ @GamrCorps I tired to be more specific. Basically your code has to explicitly do something, you can't rely on the language to deal with it for you. \$\endgroup\$
    – Jon
    Oct 20, 2015 at 3:29
  • 1
    \$\begingroup\$ @Chipperyman Bah, no I have to rewrite the whole thing... (Also, that's appending, not inserting. :P) \$\endgroup\$
    – Dennis
    Oct 20, 2015 at 5:22

18 Answers 18

5
\$\begingroup\$

CJam, 20 bytes

q':/~La+@~/(@@_{];}|

Try it online in the CJam interpreter.

How it works

q':/                e# Read all input and split it at colons.
    ~                e# Dump index, pattern and word on the stack.
     La+             e# Append the array [""] to the word.
                     e#   This increases the word's length by 1 (to deal with the
                     e#   highest index possible index) without affecting output.
        @~           e# Rotate the index on top and evaluate it.
          /          e# Split the word into chunks of that length.
           (         e# Shift out the first chunk.
            @@       e# Rotate pattern and remaining chunks on top.
              _      e# Copy the array of remaining chunks.
                     e#   This array will be empty if the index was too high.
               {];}| e# If the array if falsy, clear the stack.
\$\endgroup\$
3
\$\begingroup\$

CJam, 34 bytes

Terribly ungolfed, but its my first CJam golf ever! Thanks to sp3000 for helping me with this on The Nineteenth Byte chat!

l':/~_,W$i>{W$i/(:+-2$+-3$+:+p}&];

EDIT: oops, I was in the process of posting this and I didn't see Dennis' CJam post. If the answers do end up using the same process, just count mine as a non-competitive answer. Sorry for the confusion.

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

JavaScript ES6, 49 bytes

s=>([a,b,c]=s.split`:`,c.slice(0,a)+b+c.slice(a))

Very straightforward. Slices the string and inserts the new substring in the middle

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

Python 3, 65 bytes

a,b,c=input().split(':')
a=int(a)
if c[a-1:]:print(c[:a]+b+c[a:])

Does nothing if the index is past the end of the string. Try it online.

\$\endgroup\$
2
  • \$\begingroup\$ Based on this clarification that the insertion can happen at the end, the a<len(c) should be a<=len(c). \$\endgroup\$
    – xnor
    Oct 20, 2015 at 5:15
  • \$\begingroup\$ It's a bit shorter to do if c[a-1:]. \$\endgroup\$
    – xnor
    Oct 20, 2015 at 5:21
2
\$\begingroup\$

Pyth, 33

=Ycw\:JvhYp?>leYJjk[<eYJ@Y1>eYJ)Z

Prints 0 if the index is past the end of the string

Try is online

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

Ruby, 43 bytes

37 bytes of code:

G,O,L=$F
$_=(L[G.to_i,0]=O;L)rescue p

and 6 bytes of flags:

$ ruby -apF: code.rb < input
       ^^^^^^
\$\endgroup\$
2
\$\begingroup\$

Pyth, 23

*sX0ceJcz\:KvhJhtJgleJK

Unfortunately (in this scenario anyway), Pyth doesn't error on chopping a string by too large a value. Otherwise the check would go from 6 bytes to 2.

I'm unsure if this is the most optimal approach, but this chops the word after the number of characters from the input. Then it does a += on the first element of the list and returns the sum. It multiplies the resulting string by a boolean representing if the value was out of range.

Also note that this does not work if the input is 0. The OP said we could assume the number is positive, so I believe this is ok.

Try it online

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

Pyth, 32 bytes

Beats the other Pyth answer! Still needs a lot of golfing though. Took the naïve approach.

?gleJcz":"KvhJ++:eJ0KhtJ:eJKleJ"

Try it online.

\$\endgroup\$
1
  • \$\begingroup\$ Based on a comment, you should be able to add the value at the end. This can be fixed at no cost by using g instead of >. With some additional golf changes I get 26 bytes. PM me if you are curious about any of the changes, most are just aliases. Happy Pyth golfing! :) \$\endgroup\$ Oct 20, 2015 at 17:36
2
\$\begingroup\$

Perl 5, 41 Bytes (40 + 1)

Outputs 0 when a replacement couldn't be made.

($n,$s,$_)=split/:/;$_=0if!s/.{$n}/$&$s/

Test

$ echo "6:Online :Hello World!" |perl -p -e '($n,$s,$_)=split/:/;$_=0if!s/.{$n}/$&$s/'
$ Hello Online World!
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Why that , in front of if? Works without too. And as the -e command line option is for free and you only need 1 more character if you write it as -pe, your code could be 40 + 1 = 41 bytes. \$\endgroup\$
    – manatwork
    Oct 21, 2015 at 7:38
  • \$\begingroup\$ Corrected. Yeah well, was counting 2 bytes for using -p, since in another solution the - was also counted. But it should indeed be only 1 penalty for -p. Thanks for noticing the comma. It's often needed with that post-notation, but I didn't check if it was needed this time. \$\endgroup\$
    – LukStorms
    Oct 21, 2015 at 8:38
2
\$\begingroup\$

Perl, 34 bytes

(includes 1 switch)

perl -pe '$x="."x$_;s/.*:(.*):($x)|.*/$2$1/'

Prints an empty line on error.

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

C++11, 186 bytes

Golfed

#include<iostream>
#include<regex>
int main(){std::string p,w;int i,j;std::getline(std::cin>>i,p);j=p.find(58,1);w=p.substr(j+1);if(i<=w.length())std::cout<<w.insert(i,p.substr(1,j-1));}

Ungolfed

#include <iostream>
#include <regex>

int main()
{
    std::string p, w;
    int i, j;
    std::getline(std::cin >> i, p);
    j = p.find(':', 1);
    w = p.substr(j + 1);
    if (i <= w.length())
        std::cout << w.insert(i, p.substr(1, j - 1));
}

Looking for: Improvements and someone who can do Shakespear, so that I am not last again :)

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

Retina, 38 bytes

(()1)*:(.+):((?<-2>.)*)(?!\2)|^.+
$4$3

Run the code from a single file with the -s flag. This takes input in unary, e.g.

111:A2C:Hello World!

yields

HelA2Clo World!

If the index is too large, an empty line will be printed.

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

Haskell, 97 bytes

a=fmap tail.span(/=':')
m!(n,e)|m>length e=""|0<1=take m e++n++drop m e
f l|(o,r)<-a l=read o!a r

Defines f, a function that takes a string like "2:x:ABC" and returns "ABxC".

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

Julia, 66 bytes

s->(x=split(s,":");i=parse(Int,x[1]);x[3][1:i]*x[2]*x[3][i+1:end])

This creates an unnamed function that accepts a string and returns a string. It errors if the index is out of bounds.

Ungolfed:

function f(s::AbstractString)
    # Split the input on the colon
    x = split(s, ":")

    # Convert the first element of x to an integer
    i = parse(Int, x[1])

    # Join the pieces
    return x[3][1:i] * x[2] * x[3][i+1:end]
end
\$\endgroup\$
0
\$\begingroup\$

Ruby, 55 bytes

a,b,c=gets.split ?:;(c[a,0]=b;p c)if c.size>=(a=a.to_i)

It's been a while since I've golfed in Ruby... this feels a bit suboptimal.

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

Gema: 47 characters

*\:*\:*=@subst{<U$1>\*=\$1@quote{$2}\*\;\*=;$3}

Sample run:

bash-4.3$ gema '*\:*\:*=@subst{<U$1>\*=\$1@quote{$2}\*\;\*=;$3}' <<< '3:!*!:Hello'
Hel!*!lo

bash-4.3$ gema '*\:*\:*=@subst{<U$1>\*=\$1@quote{$2}\*\;\*=;$3}' <<< '13:!*!:Hello'

(If you want an explicit error message, just insert it after the last = sign.)

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

MUMPS, 70 bytes

a(s) s w=$P(s,":",3) q:s>$L(w)  w $E(w,1,s)_$P(s,":",2)_$E(w,s+1,9**9)

There is no output if an invalid index is provided.

This code is basically ANSI-compliant; the only issue is that I've saved a byte by taking advantage of the fact that the maximum length of a string on the two major surviving MUMPS platforms is less than 99 bytes: InterSystems Caché caps strings at 32 KiB, and GT.M caps strings at 1 MiB. Nonetheless, in principle, some jerk could write an implementation that allows strings over ~369 MiB, in which case there would be valid inputs for which this code fails.

We can save 3 additional bytes, bringing us down to 67, if we use non-ANSI Caché ObjectScript-specific extensions to $EXTRACT:

a(s) s w=$P(s,":",3) q:s>$L(w)  w $E(w,1,s)_$P(s,":",2)_$E(w,s+1,*)
\$\endgroup\$
0
\$\begingroup\$

Perl 6, 58 bytes

$_=[split ':',@*ARGS];substr-rw(.[2],.[0],0)=.[1];.[2].say
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.