Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given an input of a list of slices of a string, output the original string.

Each slice will be given as a list of length 2, containing the start position of the slice (an integer ≥0) and the slice itself. If your language does not support arrays of arbitrary types, you may also take this as a struct or similar, or simply a string consisting of the number, a space, and then the slice.

The order of the two elements of each slice is up to you. Furthermore, if you choose to use the representation of slices as a length-2 array, you may take input as either a 2-dimensional array or a single flat array. Finally, the integer representing position may be either zero-indexed or one-indexed (all the examples here are zero-indexed).

The input will always be sufficient to determine the entire string up to the highest position given. That is, there will be no "holes" or "gaps." Therefore, the output must not contain any extra trailing or leading characters (other than the typical optional trailing newline). The input will always be consistent, and no slices will conflict with each other.

Since this is , the shortest code in bytes will win.

Test cases:

In                                                Out
-----------------------------------------------------------
[[2, "CG"], [0, "PP"], [1, "PC"]]               | PPCG
[[0, "foobarbaz"]]                              | foobarbaz
[[0, "foobar"], [6, "baz"]]                     | foobarbaz
[[2, "ob"], [5, "rba"], [0, "fooba"], [8, "z"]] | foobarbaz
[[0, "fo"], [0, "fooba"], [0, "foobarbaz"]]     | foobarbaz
share|improve this question
    
Is there any restrictions on what characters the string will contain? – GamrCorps Feb 22 at 18:01
    
@GamrCorps Nope, no special restrictions. – Doorknob Feb 22 at 18:06
1  
Are there any restrictions on the length of the output string? – Mego Feb 22 at 18:43
    
@Mego None aside from natural limits imposed by memory/storage. – Doorknob Feb 22 at 19:58
1  
HA! This is the undo mechanism in my text editor :D – slebetman Feb 23 at 2:45

15 Answers 15

Python 2, 49 bytes

lambda l:`map(max,*[' '*n+s for n,s in l])`[2::5]

First, lines up the strings by padding their offsets with spaces (shown as underscores for clarity)

[[2, "CG"], [0, "PP"], [1, "PC"]] 

__CG
PP
_PC

Then, uses map to zip and take the maximum of each column, which ignores the smaller values of spaces (the smallest printable character) and Nones where some strings were too short.

__CG
PP
_PC

PPCG

Finally, ''.join to a string using the [2::5] trick.

share|improve this answer
    
Whats the 2::5 trick? How does that join a string? Isn't that every 5th index starting at 2? – Robert Fraser Feb 29 at 12:35
    
@RobertFraser See here. – xnor Feb 29 at 23:30

Perl, 25

Added +2 for -lp

Get the input from STDIN, e.g.

perl -lp slices.pl
2 CG
0 PP
1 PC

(Close with ^D or ^Z or whatever closes STDIN on your system)

slices.pl:

/ /;$r|=v0 x$`.$'}{*_=r
share|improve this answer
    
Wouldn't the null byte instead of v0 save you two bytes (because you could also omit the space before the x)? Edit: Hm, no, when I tried it, I got Can't locate object method "x" via package "2" (or whatever the number is on my first line) for some reason. – msh210 Feb 24 at 22:17
1  
Only names like C variables can be unquoted literals. So v0 is the shortest way to get \0 (or a \0 between quotes for a tie in this case due to the extra space) – Ton Hospel Feb 24 at 22:24

JavaScript (ES6), 61 bytes

a=>a.map(([o,s])=>[...s].map(c=>r[o++]=c),r=[])&&r.join``

Edit: Saved 4 bytes thanks to @edc65.

share|improve this answer
    
a=>a.map(([o,s])=>[...s].map(c=>r[o++]=c),r=[])&&r.join`` saves 4 bytes – edc65 Feb 29 at 8:41

Haskell, 57 bytes

import Data.List
map snd.sort.nub.(>>= \(n,s)->zip[n..]s)

Usage example:

*Main> map snd.sort.nub.(>>= \(n,s)->zip[n..]s) $ [(2,"CG"),(0,"PP"),(1,"PC")]
"PPCG"

How it works: make pairs of (index,letter) for every letter of every slice, concatenate into a single list, remove duplicates, sort by index, remove indices.

share|improve this answer

MATL, 15 bytes

''i"@Y:Y:tn:b+(

Works with current version (13.0.0) of the language/compiler.

Input is with curly braces and single quotes. (Curly braces in MATLAB/MATL define cell arrays, which are lists that can have contents of arbitrary, possibly different types.) The test cases are thus:

{{2, 'CG'}, {0, 'PP'} {1, 'PC'}}
{{0, 'foobarbaz'}}
{{0, 'foobar'}, {6, 'baz'}}
{{2, 'ob'}, {5, 'rba'}, {0, 'fooba'}, {8, 'z'}}
{{0, 'fo'}, {0, 'fooba'}, {0, 'foobarbaz'}}

Try it online!

''      % push empty string. This will be filled with the slices to produce the result
i       % take input: cell array of cell arrays. For example: {{0, 'foobar'}, {6, 'baz'}}
"       % for each (1st-level) cell
  @     %   push that cell. Example: {{0, 'foobar'}}
  Y:    %   unpack (1st-level) cell, i.e. push its contents. Example: {0, 'foobar'}
  Y:    %   unpack (2nd-level) cell array: gives number and substring. Example: 0, 'foobar'
  tn:   %   duplicate substring and generate vector [1,2,...,n], where n is length of
        %   current substring (in the example: 6)
  b+    %   add input number that tells the position of that substring within the whole
        %   string (in the example: 0; so this gives [1,2,...,6] again)
  (     %   assign substring to the total string, overwriting if necessary. Note that
        %   MATL uses 1-indexing
        % end for each
        % implicit display
share|improve this answer
1  
This answer's a bute! – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 22 at 17:44

Jelly, 10 9 bytes

Ḣ0ẋ;Fµ€o/

Try it online!

How it works

Ḣ0ẋ;Fµ€o/  Main link. Input: A (list of pairs)

     µ€    Convert the chain to the left into a link, and apply it to each pair.
Ḣ          Pop the first element.
 0ẋ        Yield a list of that many zeroes.
   ;F      Concatenate the list of zeroes with the popped, flattened pair.
       o/  Reduce the generated lists by logical OR.
           Since all characters are truthy, this overwrites zeroes with characters,
           but never characters with zeroes.
share|improve this answer

DUP, 14 bytes

[0[$;$][,1+]#]

Try it here.

Anonymous lambda. Usage:

2"CG"0"PP"1"PC"[0[$;$][,1+]#]!

NOTE: DUP does not really have arrays, so I hope this input format is okay.

Explanation

Well, DUP's string comprehension is... interesting. Strings are stored as a series of number variables, each of which holds a charcode from the string. Something like 2"CG" works as pushing 2 to the stack, then creating a string with index starting from 2.

Because these indexes are really variables, they can be overwritten. That's what the input is really doing: overriding! Try pressing Step on the interpreter site to get a better idea for this. After this, we get an unsliced string.

This is where the outputting comes in.

[            ] {lambda}
 0             {push 0 to the stack as accumulator}
  [   ][   ]#  {while loop}
   $;$         {duplicate, get var at TOS value, see if that var is defined}
        ,1+    {if so, output charcode at TOS and increment accumulator}
share|improve this answer
    
Hooray for DUP! – cat Feb 25 at 23:22

PHP, 146 chars

Note: Evaling user input is always a good idea.

Golfed

<?$a=[];$f=0;eval("\$b={$argv[1]};");foreach($b as$d){$f=$d[0];$e=str_split($d[1]);foreach($e as$c){$a[$f++]=$c;}}ksort($a);echo join('',$a)."\n";

Ungolfed

<?php
$array = array();
$p = 0;
eval("\$input = {$argv[1]};");
foreach($input as $item)
{
    $p = $item[0];
    $str = str_split($item[1]);
    foreach($str as $part)
    {
        $array[$p++] = $part;
    }
}
ksort($array);
echo join('', $array)."\n";
?>

You can see that I'm just writing the input into an array with the specific key each char has and then output it all.

Tests

php unslice.php '[[0, "foobar"], [6, "baz"]]' -> foobarbaz

php unslice.php '[[2, "CG"], [0, "PP"], [1, "PC"]]' -> PPCG

php shorten.php unslice.php -> Shortened script by 107 chars. :D

share|improve this answer
    
"Evaling user input is never a good idea" Code Golf is about worst-practices :D – cat Feb 25 at 23:26
    
$a[$f]=$c;$f++; I don't know PHP but can't this be $a[$f++]=c; ? – cat Feb 25 at 23:27
    
Ill try it.. :D – timmyRS Feb 27 at 7:25
    
@cat Thx mate, shorted it by 3 chars. :D – timmyRS Feb 27 at 9:20

Seriously, 48 bytes

,`i@;l(;)+(x@#@k`M;`i@X@M`MMu' *╗`iZi`M`i╜T╗`MX╜

Seriously is seriously bad at string manipulation.

Try it online!

Explanation:

,`i@;l(;)+(x@#@k`M;`i@X@M`MMu' *╗`iZi`M`i╜T╗`MX╜
,                                                 get input
 `              `M;                               perform the first map and dupe
                   `     `MM                      perform the second map, get max element
                            u' *╗                 increment, make string of that many spaces, save in reg 0
                                 `   `M           third map
                                       `    `M    fourth map
                                              X╜  discard and push register 0

Map 1:

i@;l(;)+(x@#@k
i@;l            flatten, swap, dupe string, get length
    (;)+(       make stack [start, end, str]
         x@#@k  push range(start, end), explode string, make list of stack

Map 2:

i@X@M
i@X     flatten, swap, discard (discard the string)
   @M   swap, max (take maximum element from range)

Map 3:

iZi  flatten, zip, flatten (make list of [index, char] pairs)

Map 4:

i╜T╗  flatten, push reg 0, set element, push to reg 0

In a nutshell, this program makes a string with n spaces, where n is the minimum length the string can be based on the input. It determines the index in the result string of each character in each slice, and sets the character in the result string at that index to the character.

share|improve this answer

Python, 91 bytes.

Saved 1 byte thanks to cat.

It's a bit long. I'll golf it down more in a bit.

def f(x):r={j+i:q for(i,s)in x for j,q in enumerate(s)};return"".join(map(r.get,sorted(r)))
share|improve this answer

Python, 119 115 bytes

def f(x,s=""):
 x.sort()
 for e in x:
  a=e[0];b=e[1]
  for i,c in enumerate(b):
   if len(s)<=(i+a):s+=c
 return s

Test cases

enter image description here

share|improve this answer

CJam, 26 bytes

q~{~0c*\+}%{.{s\s|}}*e_0c-

Try it online!. Takes input in form [["CG"2]["PP"0]["PC"1]].

Explanation:

q~           Read and eval input

{~0c*\+}%    Convert input strings into workable format
{      }%     Map onto each input
 ~            Evaluate
  0c          Null character
    *\+       Multiply by input number and concat to string

{.{s\s|}}*   Combine strings
{       }*    Fold array
 .{    }       Vectorize, apply block to corresponding elements of arrays
   s\s         Convert elements to strings
      |        Set Union

e_0c-        Remove null characters
share|improve this answer

R, 181 bytes

n=nchar;m=matrix(scan(,'raw'),ncol=2,byrow=T);w=rep('',max(n(m[,2])+(i<-strtoi(m[,1]))));for(v in 1:nrow(m)) w[seq(i[v]+1,l=n(m[v,2]))]=unlist(strsplit(m[v,2],''));cat("",w,sep="")

With line breaks:

n=nchar
m=matrix(scan(,'raw'),ncol=2,byrow=T)
w=rep('',max(n(m[,2])+(i<-strtoi(m[,1]))))
for(v in 1:nrow(m)) w[seq(i[v]+1,l=n(m[v,2]))]=unlist(strsplit(m[v,2],''))
cat("",w,sep="")

Works in R Gui (single line one, or sourcing for the multi-line one) but not in ideone, example:

> n=nchar;m=matrix(scan(,'raw'),ncol=2,byrow=T);w=rep('',max(n(m[,2])+(i<-strtoi(m[,1]))));for(v in 1:nrow(m)) w[seq(i[v]+1,l=n(m[v,2]))]=unlist(strsplit(m[v,2],''));cat("",w,sep="")
1: 2 ob 5 rba 0 fooba 8 z
9: 
Read 8 items
foobarbaz

Note on the input method:

or simply a string consisting of the number, a space, and then the slice.

I assume I comply with this part of the spec with this kind of input, it can be given on multiple lines, this has no impact as long as there a blank line to end the input.

I think 2 chars can be saved by removing the +1 and using 1 based indexing but I started with challenge input.

share|improve this answer

C, 110 bytes

c,i,j;char s[99];main(){while(~scanf("%i ",&i))for(;(c=getchar())>10;s[i++]=c);for(;s[j]>10;putchar(s[j++]));}

This program takes the slice after its index in one line of input each.

Ungolfed:

c,i,j;char s[99];

main(){
    while(~scanf("%i ",&i))
        for(;(c=getchar())>10;s[i++]=c);
    for(;s[j]>10;putchar(s[j++]));
}

Test on ideone.com

share|improve this answer

Lua, 113 bytes

z=loadstring("return "..io.read())()table.sort(z,function(a,b)return a[1]<b[1]end)for a=1,#z do print(z[a][2])end

This is probably some of the more secure code I've written. The idea is simple. The user will enter an array formatted as so: {{1, "1"}, {3, "3"}, {2, "2"}} and then the table will be sorted by the first index and the second index will be printed.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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