There, I fixed it (with rope)

10

Related: Rather similar (but much easier) challenge horizontally: There I fixed it (with tape)

Challenge:

Given a string only containing upper- and/or lowercase letters (whichever you prefer) and new-lines, put rope vertically to fix it. We do this by checking the difference of two adjacent letters in the alphabet (ignoring wrap-around and only going downward), and filling the space with as much ROPE/rope as we would need.
NOTE: One other key difference between this challenge and the There I fixed it (with tape) challenge is that we're not wasting rope this time like we did with the tape (suggested by @JonathanAllan in part one of the challenge).

Example:

Input:

abc
bcd
ddd
eex
gfz
hka
imh

Output:

abc
bcd
Rdd
deE
efR
OPO
gEP
hRE
iOR
 kO
 PP
 mE
  R
  O
  P
  E
  R
  O
  P
  E
  R
  O
  x
  P
  z
  a
  E
  R
  O
  P
  E
  R
  h

Why?

  • Between b and d in column 1 should be c (length 1), so we fill this with R;
  • Between e and g in column 1 should be f (length 1), so we fill this with O;
  • Between f and k in column 2 should be ghij (length 4), so we fill this with PERO;
  • Between k and m in column 2 should be l (length 1), so we fill this with P;
  • Between d and c in column 3 should be efghijklmnopqrstuvw (length 19), so we fill this with EROPEROPEROPEROPERO;
  • Between x and z in column 3 should be y (length 1), so we fill this with P;
  • Between a and h in column 3 should be bcdefg (length 6), so we fill this with EROPER.

Challenge rules:

  • The difference only applies downwards, so no rope between za (column 3 in the example above).
  • It is possible to have multiple of the same adjacent letters like dd (column 3 in the example above).
  • You will continue using the ROPE one column at a time to not waste parts (suggested by @JonathanAllan in part 1 of the challenge).
  • You are allowed to take the input in any reasonable format. Can be a single string, string-array/list, character-matrix, etc. Output has the same flexibility.
  • You are allowed to use lowercase and/or uppercase any way you'd like. This applies both to the input, output, and ROPE.
  • Trailing spaces are optional (note that the correct amount of leading spaces are mandatory so the columns are correct).
    Any amount of trailing and/or leading new-lines are also optional.
  • You can assume that all test cases will have the same length across all rows, so a\naa/[[a][a,a]] wouldn't be a valid input.
  • It is possible no ROPE is necessary, in which case the input remains unchanged.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, please add an explanation if necessary.

Test cases:

As string:
 Input:  "abc\nbcd\nddd\neex\ngfz\nhka\nimh"
 Output: "abc\nbcd\nRdd\ndeE\nefR\nOPO\ngEP\nhRE\niOR\n kO\n PP\n mE\n  R\n  O\n  P\n  E\n  R\n  O\n  P\n  E\n  R\n  O\n  x\n  P\n  z\n  a\n  E\n  R\n  O\n  P\n  E\n  R\n  h"
As array-matrix:
 Input:  [[a,b,c],[b,c,d],[d,d,d],[e,e,x],[g,f,z],[h,k,a],[i,m,h]]
 Output: [[a,b,c],[b,c,d],[R,d,d],[d,e,E],[e,f,R],[O,P,O],[g,E,P],[h,R,E],[i,O,R],[ ,k,O],[ ,P,P],[ ,m,E],[ , ,R],[ , ,O],[ , ,P],[ , ,E],[ , ,R],[ , ,O],[ , ,P],[ , ,E],[ , ,R],[ , ,O],[ , ,x],[ , ,P],[ , ,z],[ , ,a],[ , ,E],[ , ,R],[ , ,O],[ , ,P],[ , ,E],[ , ,R],[ , ,h]]

As string:
 Input:  "a\nz\na"
 Output: "a\nR\nO\nP\nE\nR\nO\nP\nE\nR\nO\nP\nE\nR\nO\nP\nE\nR\nO\nP\nE\nR\nO\nP\nE\nz\na"
As array-matrix:
 Input:  [[a],[z],[a]]
 Output: [[a],[R],[O],[P],[E],[R],[O],[P],[E],[R],[O],[P],[E],[R],[O],[P],[E],[R],[O],[P],[E],[R],[O],[P],[E],[z],[a]]

As string:
 Input:  "zz\nyy\nxx\nxx\ncc\ncc\nbb\nad"
 Output: "zz\nyy\nxx\nxx\ncc\ncc\nbb\naR\n d"
As array-matrix:
 Input:  [[z,z],[y,y],[x,x],[x,x],[c,c],[c,c],[b,b],[a,d]]
 Output: [[z,z],[y,y],[x,x],[x,x],[c,c],[c,c],[b,b],[a,R],[ ,d]]

As string:
 Input:  "a\nb\nc\nc\nx\nx\ny\nz"
 Output: "a\nb\nc\nc\nR\nO\nP\nE\nR\nO\nP\nE\nR\nO\nP\nE\nR\nO\nP\nE\nR\nO\nP\nE\nx\nx\ny\nz"
 As array-matrix:
  Input:  [[a],[b],[c],[c],[x],[x],[y],[z]]
  Output: [[a],[b],[c],[c],[R],[O],[P],[E],[R],[O],[P],[E],[R],[O],[P],[E],[R],[O],[P],[E],[R],[O],[P],[E],[x],[x],[y],[z]]

As string:
 Input:  "zai\nybj\nxcq\nxcu\ncxw\ncxw\nbyr\nazw"
 Output: "zai\nybj\nxcR\nxcO\ncRP\ncOE\nbPR\naEO\n Rq\n OP\n PE\n ER\n Ru\n OO\n Pw\n Ew\n Rr\n OP\n PE\n ER\n RO\n Ow\n P \n E \n x \n x \n y \n z "
As array-matrix:
  Input:  [[z,a,i],[y,b,j],[x,c,q],[x,c,u],[c,x,w],[c,x,w],[b,y,r],[a,z,w]]
  Output: [[z,a,i],[y,b,j],[x,c,R],[x,c,O],[c,R,P],[c,O,E],[b,P,R],[a,E,O],[ ,R,q],[ ,O,P],[ ,P,E],[ ,E,R],[ ,R,u],[ ,O,O],[ ,P,w],[ ,E,w],[ ,R,r],[ ,O,P],[ ,P,E],[ ,E,R],[ ,R,O],[ ,O,w],[ ,P, ],[ ,E, ],[ ,x, ],[ ,x, ],[ ,y, ],[ ,z, ]]

As string:
 Input:  "asdljasdjk"
 Output: "asdljasdjk"
As array-matrix:
 Input:  [[a,s,d,l,j,a,s,d,j,k]]
 Output: [[a,s,d,l,j,a,s,d,j,k]]

As string:
 Input:  "asdljasdjk\nlkawdasuhq\nasjdhajksd"
 Output: "asdljasdjk\nRkaOdasPhR\nOPOPEajEPO\nPEPER  REP\nERERO  ORE\nROROh  POR\nOPOP   EPq\nPEPE   ROd\nERER   OR \nRsRO   PO \nO jP   EP \nl  w   RE \na  d   Os \n       P  \n       E  \n       R  \n       O  \n       u  \n       k  "
As array-matrix:
 Input:  [[a,s,d,l,j,a,s,d,j,k],[l,k,a,w,d,a,s,u,h,q],[a,s,j,d,h,a,j,k,s,d]]
 Output: [[a,s,d,l,j,a,s,d,j,k],[R,k,a,O,d,a,s,P,h,R],[O,P,O,P,E,a,j,E,P,O],[P,E,P,E,R, , ,R,E,P],[E,R,E,R,O, , ,O,R,E],[R,O,R,O,h, , ,P,O,R],[O,P,O,P, , , ,E,P,q],[P,E,P,E, , , ,R,O,d],[E,R,E,R, , , ,O,R, ],[R,s,R,O, , , ,P,O, ],[O, ,j,P, , , ,E,P, ],[l, , ,w, , , ,R,E, ],[a, , ,d, , , ,O,s, ],[ , , , , , , ,P, , ],[ , , , , , , ,E, , ],[ , , , , , , ,R, , ],[ , , , , , , ,O, , ],[ , , , , , , ,u, , ],[ , , , , , , ,k, , ]]

As string:
 Input:  "re\nop\npo\ner"
 Output: "re\noR\npO\neP\n E\n R\n O\n P\n E\n R\n O\n p\n o\n P\n E\n r"
As array-matrix:
 Input:  [[r,e],[o,p],[p,o],[e,r]]
 Output: [[r,e],[o,R],[p,O],[e,P],[ ,E],[ ,R],[ ,O],[ ,P],[ ,E],[ ,R],[ ,O],[ ,p],[ ,o],[ ,P],[ ,E],[ ,r]]

Kevin Cruijssen

Posted 2018-03-08T11:29:10.767

Reputation: 67 575

8Can I fix it with hope instead? Hope is stronger than rope. (This is a poor attempt at humor, not a real question) – Magic Octopus Urn – 2018-03-08T14:47:31.757

@KevinCruijssen did you mean this is easier of the TAPE is easier?? – Dat – 2018-03-08T15:24:15.873

3@MagicOctopusUrn Nope, rope is our only hope. – Steadybox – 2018-03-08T15:53:38.827

Can I ouput and array of columns?? – Dat – 2018-03-08T15:56:24.923

@Dat The tape challenge is a lot easier (imho). And yes, you can output an array of column. – Kevin Cruijssen – 2018-03-08T15:59:30.470

Just to doublecheck - if we can output an array of columns, I suppose we are also allowed to take input in columnwise manner, right? – Kirill L. – 2018-03-09T09:04:25.317

@KirillL. Yep, completely fine by me. – Kevin Cruijssen – 2018-03-09T09:06:55.787

Answers

3

Jelly, 21 bytes

ZµOI’R“¡nⱮ»ṁż@"µF€z⁶Y

Try it online!

Explanation

ZµOI’R“¡nⱮ»ṁż@"µF€z⁶Y  Main Link
Z                      Transpose the input so the columns are now rows
 µ                     New monadic chain
  O                    [Vectorizing] Convert each letter to its character code
   I                   [Vectorizing] Get the differences (gap size)
    ’                  [Vectorizing] Add one
     R                 [Vectorizing] Range from 1 .. x
           ṁ           Mold the string        into the ranges
      “¡nⱮ»                            "rope"
            ż@"        Vectorizing zip the rope strings with the original string (place ropes in gaps)
               µ       New monadic chain
                F€     Flatten Each
                  z⁶   Zip and fill with spaces
                    Y  Join on newlines for output

-1 byte thanks to Mr. Xcoder
-2 bytes thanks to Erik the Outgolfer

HyperNeutrino

Posted 2018-03-08T11:29:10.767

Reputation: 26 575

21 bytes using rope – Mr. Xcoder – 2018-03-08T12:15:15.757

@KevinCruijssen fixed – HyperNeutrino – 2018-03-08T13:24:52.283

21 bytes – Erik the Outgolfer – 2018-03-08T13:42:47.203

@EriktheOutgolfer oh yeah thanks idk why I was each-ing auto-each things :P – HyperNeutrino – 2018-03-08T14:11:13.147

@KevinCruijssen done – HyperNeutrino – 2018-03-23T16:05:51.503

4

05AB1E, 38 37 25 bytes

Saved 10 bytes with suggestions from Magic Octopus Urn and another byte changing output format.

Outputs a list of strings.
Footer pretty prints.

'ÙºUζεDÇ¥<)ζε`FX¬sÀU}J]Jζ

Try it online!

Explanation

'ÙºU                       # store the string "rope" in variable X
    ζ                      # transpose input
     ε                ]    # for each transposed row
      D   )ζ               # zip the row with
       ǥ<                 # the decremented deltas of its character codes  
            ε              # for each pair of [letter, delta-1]
             `F     }      # delta-1 times do:
               X¬          # get the first letter of X (originally "rope")
                 sÀU       # rotate the letters left by 1 and store in X 
                     J     # join the rope-letter to the current row-letter
                       J   # join to list of strings (the new columns)
                        ζ  # transpose

Emigna

Posted 2018-03-08T11:29:10.767

Reputation: 50 798

@MagicOctopusUrn: The main difference is that with Tape we started over each time we should insert it, aTAdTAg. Now with rope we continue where we left off on the rope, so aROdPEg. – Emigna – 2018-03-08T12:28:17.710

1missed that tidbit, what about "extend string to length X" and inserting spaces inbetween each character representing places where the "rope" is supposed to go, then inserting the extended string into the spaces? – Magic Octopus Urn – 2018-03-08T14:12:38.947

@MagicOctopusUrn: I think I have 32 using your suggestion above. Could still be golfable as well. – Emigna – 2018-03-08T14:28:02.867

Does 05AB1E have a: pop a,b,c | push c[b..a] type dealio? – Magic Octopus Urn – 2018-03-08T14:44:56.573

@MagicOctopusUrn: Nope. I have been thinking it needs one though. – Emigna – 2018-03-08T14:52:04.387

X¬sÀU is flipping brilliant. Is there a way to use "head_extracted" and save 1 byte? I can't see it. – Magic Octopus Urn – 2018-03-08T21:09:53.927

@MagicOctopusUrn: I don't think so. Not with this technique at least, as I only keep the original word. Might have worked in one of the previous versions. – Emigna – 2018-03-09T06:56:29.533

3

Python 2, 197 194 bytes

def f(s):
 r='ROPE'*len(`s`)*9;x=[]
 for i in zip(*s):
	x+='',
	for c,C in zip(i,i[1:]+(' ',)):l=(C>c)*(ord(C)+~ord(c));x[-1]+=c+r[:l];r=r[l:]
 print zip(*['%*s'%(-max(map(len,x)),s)for s in x])

Try it online!


  • -3 bytes thanks to ovs

TFeld

Posted 2018-03-08T11:29:10.767

Reputation: 19 246

2

Ruby, 119 bytes

->a{l=0;a.map!{|r|r.reduce{|x,y|x+("ROPE"*7)[l%4,-l+l+=[0,y.ord+~x[-1].ord].max]+y}}.map{|s|s.ljust a.map(&:size).max}}

Try it online!

Yes, this is much more difficult than the "TAPE" challenge. I tried to build up on my solution to that task, but this has a few extra twists.

Takes input as a columnwise array of characters, returns an array of strings, also in columnwise format. The code in the footer of the TIO link performs pre- and post-processing of I/O data so that we could supply a more manageable string and then print the result nicely.

Explanation

The code makes two passes through the input array.

In the first pass we apply the reduce operation that fills up the space between the characters with the required amount of ROPE (y.ord-x[-1].ord-1 characters, if positive). We also need to keep track of the used ROPE length (l).

Unlike in the TAPE case we cannot simply use rjust for filling, as it would always start from the R character. Instead, taking a proper slice of a long "ROPEROPE..." string seems lighter on byte count, especially since we also need to update l on the fly.

In the second pass we left-justify the resulting strings with spaces to match the length of the longest of them. Since we need the full results of the previous iteration here, the first pass modifies the array in place (hence map!, not map).

Kirill L.

Posted 2018-03-08T11:29:10.767

Reputation: 6 693

To my mind your columnwise I/O format already solves so much of the problem that it becomes a loophole – Ton Hospel – 2018-03-11T23:17:11.500

@TonHospel I also hesitated at first, but OP specifically confirmed this is OK in comments to the challenge – Kirill L. – 2018-03-12T08:06:20.870

Ah, not what I would have decided, but that's OK then. – Ton Hospel – 2018-03-12T08:41:25.810

1

-1 bytes thanks to Kevin Cruijssen

-70 bytes thanks to Jonathan Frech, wow.......

Python 3, 203 bytes

def f(s,c=0,x=()):
	for i in range(len(s[0])):
		p,o=" ",""
		for j in s:t=j[i];y=p>' 'and~ord(p)+ord(t);o+=('ROPE'*y)[c:y+c]+t;c,p=c%4+y*(y>=0)%4,t
		x+=o,
	for i in x:yield i.ljust(len(max(x,key=len)))

Try it online!

Dat

Posted 2018-03-08T11:29:10.767

Reputation: 879

ord(t)-ord(p)-1 can be ord(t)+~ord(p) to save a byte again. ;) Here is the relevant tip. – Kevin Cruijssen – 2018-03-08T17:39:03.740

+=[o] -> +=o,. – Jonathan Frech – 2018-03-08T17:49:15.650

@Dat Are you sure?

– Jonathan Frech – 2018-03-08T18:03:07.413

Since you only deal with printable characters, p!=' ' is also equivalent to p>' '. – Jonathan Frech – 2018-03-08T18:06:16.047

268 bytes. – Jonathan Frech – 2018-03-08T18:10:03.237

241 bytes, heavy golfs! – Jonathan Frech – 2018-03-08T18:12:15.303

k for k in is also a no-op ... – Jonathan Frech – 2018-03-08T18:15:36.133

229 bytes. – Jonathan Frech – 2018-03-08T18:15:54.607

@JonathanFrech, you might as well write your own answer man :) Thats really impressive! – Dat – 2018-03-08T18:17:00.403

204 bytes. – Jonathan Frech – 2018-03-08T18:19:16.020

1203 bytes, using a generator. – Jonathan Frech – 2018-03-08T18:22:48.957

1

Python 3, 182 bytes

from itertools import*
def f(l):r=cycle('ROPE');return zip_longest(*(''.join(c+''.join(islice(r,max(ord(n)+~ord(c),0)))for c,n in zip(z,z[1:]+(' ',)))for z in zip(*l)),fillvalue=' ')

Try it online!

The function takes its input as a list (or an iterable) of strings and also returns a generator for a sequences of strings, which is almost as good as a list.

Ungolfed

…for better readability of the nested generators.

def f(l):
    r = cycle('ROPE')
    return zip_longest(
        *(
            ''.join(
                c + ''.join(islice(r, max(ord(n) - ord(c) - 1, 0)))
                for c, n in zip(z, z[1:] + (' ',)))
            for z in zip(*l)),
        fillvalue=' ')

Explanation

  1. The function uses zip to transpose the incoming list of lines into a generator of columns.

  2. The innermost generator looks at pairs of adjacent characters and…

  3. …slices the required amount of continuous ROPE out of an (infinite) cycle generator.

  4. After copious amounts of string joining from generators the function re-transposes the list of columns back to a generator or lines and fills missing entries with zip_longest.

David Foerster

Posted 2018-03-08T11:29:10.767

Reputation: 260

0

Stax, 25 bytes

ÅiV╘ε╢+gA┘♦W[≈{`Co?-φvM«'

Run and debug online!

Input and output are given as space separated lists. Input is the list of rows as required, output is the list of columns as permitted.

Explanation

Uses the unpacked version to explain.

M"ROPE"s{2B{Ev|r%b:m~|(,m_s\mJ
M                                 Transpose
 "ROPE"                           The string "ROPE"
       s{                   mJ    Map each column (in the original input) with block, and output with space as the separator
         2B                       All contiguous pairs of current column
           {            m         Map each pair with block
            Ev|r%                     Pair [j,k] to length of range [j..k-2]
                 b:m                  Repeat current repeating string to given length
                    ~                 Last line gives the result the pair should map to, now store it on the input stack
                     |(               Rotate current repeating string `p` times, where `p` is the length of the range [j..k-1]
                       ,              Fetch back the result
                         _s\      Zip with current column, filling missing element with empty string

Weijun Zhou

Posted 2018-03-08T11:29:10.767

Reputation: 3 396