Fill in the Blanks, Please!

11

(No, not this nor any of these)

Given a string and a list of strings, fill in the all blanks in the input string with corresponding strings.

Input/Output

The input string contains only alphabetic characters, spaces, and underscores. It is nonempty and does not start with an underscore. In other words, the input string matches the regex ^[a-z A-Z]([a-z A-Z_]*[a-z A-Z])?$

Every string in the input list is nonempty and contains only alphanumeric characters and spaces. In other words, they match the regex ^[a-z A-Z]+$.

A blank is a contiguous sequence of underscores (_) which is neither preceded nor proceeded by an underscore.

The input string contains n blanks for some positive integer n, and the list of strings contains exactly n strings.

The output is obtained by replacing each k-th blank in the input string by the k-th string in the input list of strings.

Example

Given an input string "I like _____ because _______ _____ing" and a list of strings ["ice cream", "it is", "satisfy"], we can find the output as follows:

  • The first blank comes directly after "like ". We fill that in with "ice cream" to get "I like ice cream because ______ _____ing".
  • The second blank comes directly after "because ". We fill that in with "it is" to get "I like ice cream because it is _____ing".
  • The third blank comes directly after "is ". We fill that in with "satisfy" to get "I like ice cream because it is satisfying".

We output the final string "I like ice cream because it is satisfying".

Test Cases

input string, input list => output
"Things _____ for those who ____ of how things work out _ Wooden",["work out best","make the best","John"] => "Things work out best for those who make the best of how things work out John Wooden"
"I like _____ because _______ _____ing",["ice cream","it is","satisfy"] => "I like ice cream because it is satisfying"
"If you are ___ willing to risk _____ you will ha_o settle for the ordi_____Jim ______n",["not","the usual","ve t","nary ","Roh"] => "If you are not willing to risk the usual you will have to settle for the ordinary Jim Rohn"
"S____ is walking from ____ to ____ with n_oss of ___ W_____ Churchill",["uccess","failure","failure","o l","enthusiasm","inston"] => "Success is walking from failure to failure with no loss of enthusiasm Winston Churchill"
"If_everyone_is_thinking ____ ____ somebody_isnt_thinking G____e P____n",[" "," "," ","alike","then"," "," ","eorg","atto"] => "If everyone is thinking alike then somebody isnt thinking George Patton"
"Pe_________e __say ____motivation does__ last Well___her doe_ bathing____thats why we rec____nd it daily _ __________lar",["opl","often ","that ","nt"," neit","s","  ","omme","Zig","Zig"] => "People often say that motivation doesnt last Well neither does bathing  thats why we recommend it daily Zig Ziglar"

fireflame241

Posted 2017-09-21T02:47:36.473

Reputation: 7 021

5A lot of explanations for trivial task. – None – 2017-09-21T03:07:33.160

Answers

5

Convex, 5 bytes

'_%.\

Try it online!

Convex is a CJam-based language, and this answer is almost the same as my CJam answer, except for l~ which is unneeded here, since Convex does automatic argument evaluation at the start of the program.

Explanation:

'_%.\ e# Full program only
'_    e# Push '_'
  %   e# Split and remove empty chunks
   .\ e# Vectorize by Swap

Erik the Outgolfer

Posted 2017-09-21T02:47:36.473

Reputation: 38 134

4

Japt, 8 bytes

r"_+"@Vv

Test it online!

I feel I missed some hidden catch in the rules because this is extremely simple: "replace each run of underscores in the string with the next item in the array."

ETHproductions

Posted 2017-09-21T02:47:36.473

Reputation: 47 880

3

JavaScript, 35 bytes

a=>b=>a.replace(/_+/g,a=>b.shift())

Try it online

user72349

Posted 2017-09-21T02:47:36.473

Reputation:

1Same thing I had. Alternatively, a=>b=>String.raw({raw:a.split(/_+/)},...b) – ETHproductions – 2017-09-21T03:03:23.163

2

Proton, 42 bytes

a=>b=>re.sub("_+",_=>b.pop(0),a)
import re

Try it online!

Stupid imports...

Same thing in python:

Python 3, 53 bytes

lambda a,b:re.sub("_+",lambda _:b.pop(0),a)
import re

Try it online!

Stephen

Posted 2017-09-21T02:47:36.473

Reputation: 12 293

...How did I frigging miss that. ._. – totallyhuman – 2017-09-21T03:15:32.810

2

MATL, 9 bytes

'_+'i1&YX

Try it online!

Explanation

'_+'   % Push this string: regexp pattern
i      % Input cell array of replacement strings
1      % Push 1
&YX    % Four-input regexp replacement. This implicitly inputs the original
       % string, and consecutively replaces each first occurrence of the 
       % regexp pattern in that string by one of the replacement strings.
       % Implicitly display

Luis Mendo

Posted 2017-09-21T02:47:36.473

Reputation: 87 464

2

Jelly, 8 7 bytes

ṣ”_¬Ðfż

Try it online! Edit: Saved 1 byte thanks to @Erik the Outgolfer. Explanation:

ṣ”_         Split on underscores
   ¬Ðf      Discard empty values
      ż     Zip with second input
            Implicit concatenated output

Neil

Posted 2017-09-21T02:47:36.473

Reputation: 95 035

2

CJam, 7 bytes

l~'_%.\

Try it online!

-1 thanks to a clever trick by Martin Ender.

Explanation:

l~'_%.\ e# Full program only
l       e# Input line
 ~      e# Eval
  '_    e# Push '_'
    %   e# Split and remove empty chunks
     .\ e# Vectorize by Swap

Erik the Outgolfer

Posted 2017-09-21T02:47:36.473

Reputation: 38 134

.\ instead of \]z. – Martin Ender – 2017-09-21T12:20:39.237

@MartinEnder That works o_o – Erik the Outgolfer – 2017-09-21T12:22:25.260

Sure, \ is a binary operator. :) – Martin Ender – 2017-09-21T12:23:21.013

@MartinEnder Seems like I have gotten a bit too much in how mapping works in CJam then. – Erik the Outgolfer – 2017-09-21T12:32:02.030

@MartinEnder OK on second thought how didn't I think of that? Not like I didn't know how mapping behaves e.g. [1 2 3]:_ -> [1 1 2 2 3 3] likewise for .... – Erik the Outgolfer – 2017-09-21T16:22:04.183

1

Perl 5, 25 + 1 (-p) = 26 bytes

@a=eval<>;s|_+|shift@a|eg

Try it online!

Xcali

Posted 2017-09-21T02:47:36.473

Reputation: 7 671

Came up with basically the same, except using <> to negate the eval and shift: Try it online!. There's got to be a way to avoid the replacing the newlines...

– Dom Hastings – 2017-09-21T07:35:13.473

This subroutine also has 26 bytes: sub{shift=~s|_+|shift|egr}. If you reversed the arguments, you could use pop and get it down to 22 bytes.

– nwellnhof – 2017-09-21T14:18:25.123

1

Pyth, 10 bytes

s.i:E"_+"3

Try it here!

How it works?

s.i:E"_+"3   Full program.

   :E    3   Split the second input on matches of the regex...
     "_+"    The regex "_+" (matches 1 or more underscores)
 .i          Interleave the elements of the split list with the input.
s            Join to a string.

Mr. Xcoder

Posted 2017-09-21T02:47:36.473

Reputation: 39 774

1

RProgN 2, 11 bytes

x='_+'³[x‘r

Takes a string and a stack of strings on the top of the stack.

The first (top) element of a stack is to the right, hence input is right to left.

Explained

x='_+'³[x‘r
x=          # Set the stack of replacements to x
  '_+'³   r # Replace each chunk of _'s with the function...
       [    # Pop off the group of _'s
        x‘  # Pop the top element off x. Use that.

Try it online!

ATaco

Posted 2017-09-21T02:47:36.473

Reputation: 7 898

1

05AB1E, 12 bytes

„__¤:sv'_y.;

Try it online!

Explanation

„__¤:          # replace all runs of multiple "_" with a single "_"
     sv        # for each y in the list of replacements
       '_y.;   # replace the first instance of "_" with y

Emigna

Posted 2017-09-21T02:47:36.473

Reputation: 50 798

1whoops fixed for +3 :p – Erik the Outgolfer – 2017-09-21T12:14:32.783

@EriktheOutgolfer: Thanks for noticing. I rolled back to my previous version which handled that. – Emigna – 2017-09-21T12:20:43.507

1

Java 8, 57 bytes

a->s->{for(String i:a)s=s.replaceFirst("_+",i);return s;}

When I read the challenge I at first thought we should make a grammatically correct sentence with the words being in random order, but just replacing lines with each sequential word is easier. ;)

Explanation:

Try it here.

a->s->{            // Method with String-array and String parameter and String return-type
  for(String i:a)  //  Loop over the input-array
    s=s.replaceFirst("_+",i);
                   //   Replace the first line (1 or more adjacent "_") with the substring
                   //  End of loop (implicit / single-line body)
  return s;        //  Return the result
}                  // End of method

Kevin Cruijssen

Posted 2017-09-21T02:47:36.473

Reputation: 67 575

1

C# (.NET Core), 97 96 + 18 bytes

Saved 1 byte thanks to Kevin Cruijssen!

The 18 bytes are for using System.Linq.

s=>l=>string.Concat(s.Split('_').Where(x=>x!="").Zip(l.Concat(new[]{""}),(x,y)=>x+y).ToArray());

Try it online!

Ian H.

Posted 2017-09-21T02:47:36.473

Reputation: 2 431

You can change (s,l)=> to s=>l=> to save a byte. Try it online!

– Kevin Cruijssen – 2017-09-21T12:53:00.403

0

Ruby, 28 + 1 = 29 bytes

$_=gsub(/_+/){|i|gets[/.*/]}

Uses -p

The first line is the format string, the rest of the lines are the array.

Try it online!

Pavel

Posted 2017-09-21T02:47:36.473

Reputation: 8 585

0

Python 2, 61 bytes

import re
s,l=input()
for i in l:s=re.sub('_+',i,s,1)
print s

Try it online!

Damn.

Python 2, 63 bytes

import re
f=lambda s,l:l and f(re.sub('_+',l[0],s,1),l[1:])or s

Try it online!

totallyhuman

Posted 2017-09-21T02:47:36.473

Reputation: 15 378

60 bytes by passing re.sub a function – Stephen – 2017-09-21T03:14:06.320

@Stephen Eh... That's just too close to your solution. I'll just stick to this and find more obscure solutions. :P – totallyhuman – 2017-09-21T03:17:53.220

53 bytes by using a function to improve @Stephen's proposal. – Jonathan Frech – 2017-09-21T07:27:16.923

@JonathanFrech yeah, but that's exactly my answer already :P

– Stephen – 2017-09-21T15:27:09.620

@Stephen Oh; did not see your answer... :d – Jonathan Frech – 2017-09-21T15:37:01.270

0

Stacked, 21 bytes

[@y'_+'[y shift]repl]

Try it online!

Replaces all runs of _ with y shift. Nothing original, as it seems.

Conor O'Brien

Posted 2017-09-21T02:47:36.473

Reputation: 36 228

0

SOGL V0.12, 7 bytes

lΔ╔*№≤ŗ

Try it Here!

Explanation:

l        get the strings length
 Δ       range
  ╔*     multiply an underscore with each of the numbers
    №    reverse vertically (so the longest underscores get replaced first)
     ≤   put the array on top - order parameters for ŗ correctly
      ŗ  replace in the original string each any occurence of the underscores with its corresponding item in the array

dzaima

Posted 2017-09-21T02:47:36.473

Reputation: 19 048

0

Python 2, 49 bytes

s,l=input();import re;print re.sub("_+","%s",s)%l

Try it online!

The list input is taken as a tuple. Allowing actual lists as input would add another seven bytes, as a conversion would be required (tuple(...)).

Jonathan Frech

Posted 2017-09-21T02:47:36.473

Reputation: 6 681