Twisting Words!

34

2

Twisting Words!

Given a string and a positive integer. You must twist the string, back and forth.

Example Input / Output

Input

Programming Puzzles & Code Golf
4

Output

Prog
mmar
ing 
zzuP
les 
oC &
de G
 flo

Input

The input can be taken in through STDIN, or function argument. The input will consist of a string and a positive integer, n. The integer will determine the length of each twisted line.

The string is twisted back-and-forth. An input of HELLO, WORLD! and 5 would look like:

HELLO, WORLD!

Output

The output will be the twisted text. It may not any trailing whitespace. If the input string length is not divisible be the line length, add a space until the line is filled:

An example of this:

Input

Hello, World!
5

Output (Note the whitespace at the very end)

Hello
roW ,
ld!  

Downgoat

Posted 2015-08-20T21:45:38.140

Reputation: 27 116

Related: a readable implementation at CodeReview

– Caridorc – 2015-08-23T20:59:13.217

It may not any trailing whitespace. Golfed away a verb? – Adám – 2018-05-13T21:19:08.307

May we return a list of lines? – Adám – 2018-05-13T21:19:18.130

Answers

10

Pyth, 19 15

VPc+z*dQQ_W~!ZN

Pre-pads the string, then reverses each other line as it prints it. The padding is equal to the size of the box, but the last line after chopping up the input is discarded.

Try it here

FryAmTheEggman

Posted 2015-08-20T21:45:38.140

Reputation: 16 206

6

CJam, 19 bytes

q~1$S*+/W<{(N@Wf%}h

Input example:

5 "Hello, World!"

Explanations

q~         e# Input n and the string.
1$S*+      e# Append n spaces to the string.
/W<        e# Split by each n characters, and remove the last chunk.
{          e# While the array of chunks isn't empty:
    (N     e# Extract the first chunk and push a newline.
    @Wf%   e# Reverse every chunk left in the array.
}h

jimmy23013

Posted 2015-08-20T21:45:38.140

Reputation: 34 042

5

Snowman 1.0.1, 91 bytes

{vg10vg|sB*#.'aGal'NdE'aaAaL|al!*+#5nS" "'aR'!#aCwR|.aC2aG:0aa|sP"
"sP'NdE|1aA.aNsP"
"sP;aE

Or all on one line (for aesthetics, or more specifically, anti-aesthetics), at the cost of 2 bytes:

{vg10vg|sB*#.'aGal'NdE'aaAaL|al!*+#5nS" "'aR'!#aCwR|.aC2aG:0aa|sP10wRsP'NdE|1aA.aNsP10wRsP;aE

This is way too short, for Snowman. (It's probably the shortest it can get, though; I worked on golfing this for a pretty long time.)

This has one caveat: it will exit with an error (but still produce the correct output) 50% of the time, when the last line is not reversed. (This is because I use ag to group the array elements in groups of two so that I can reverse every other one, but I don't check whether the last element has both expected elements, so it'll try to access a nonexistent element if there are an odd number of lines.)

Ungolfed / explanation:

{vg10vg|sB*#      // get input, convert second string to number and store
.'aG              // split string into groups of n chars
al'NdE'aaAaL      // take out the last element of the array
|al!*+#5nS" "'aR  // subtract its length from 5, repeat that many spaces
'!#aCwR|.aC       // concat spaces to last el. and that back to the array
2aG               // split in groups of 2, so we can reverse every other string
// for each sub-group in the array of groups...
:
    0aa|sP10wRsP         // print the first element as is
    'NdE|1aA.aNsP10wRsP  // print the second element, reversed
;aE

Doorknob

Posted 2015-08-20T21:45:38.140

Reputation: 68 138

5

Python 2, 60

s,n=input()
d=1
while s:print(s+n*' ')[:n][::d];s=s[n:];d=-d

Takes n characters at a time from the from of s, printing them with a direction d that alternates between 1 and -1. For spacing on the last line, s is padded with n spaces at the end before it is chopped, which only affects it when it has fewer than n characters remaining.

A recursive solution would save a char (59) except that it leaves a trailing newline, which is not allowed.

f=lambda s,n,d=1:s and(s+n*' ')[:n][::d]+"\n"+f(s[n:],n,-d) 

xnor

Posted 2015-08-20T21:45:38.140

Reputation: 115 687

4

Haskell, 83 75 bytes

(id!)
(f![])_=[]
(f!l)n=f(take n$l++cycle" ")++'\n':((f.reverse)!drop n l)n

Simple chunksOf implementation with take and drop, applying an even or odd number of reverses to the output as we go.

Thanks to @BMO for five bytes and @ØrjanJohansen for three bytes!

Try it online!

Angs

Posted 2015-08-20T21:45:38.140

Reputation: 4 825

2

Using cycle saves 5 bytes, try it online!

– ბიმო – 2018-05-14T21:53:19.793

Save three more bytes by removing g and swapping n and l: Try it online!

– Ørjan Johansen – 2018-05-15T01:23:06.000

3

Stuck, 42 41 40 38 Bytes

This is a wee bit too long, probably will try to golf more!

tg;_lu_@%u;-_0G<*' *+0GKE"];2%;Y_Y?p":

Input should be like "string"|n.

Explanation:

tg                 # Take input, place each item on stack, save the int to variable stack                                        
;_l                # Swap the top two items, duplicate the string and obtain length
u_@%               # Rotate to the left, duplicate, rotate right and take mod
u;-                # Rotate left, swap the top two and subtract from each other
_0G<*              # duplicate this value, check if less than stored int and multiply
' *+               # Push space onto stack n times, append to starting string
0GKE               # Split this string into segments, and enumerate
"];2%;Y_Y?p":      # For each segment, determine if should be reversed, and print

Kade

Posted 2015-08-20T21:45:38.140

Reputation: 7 463

2

Clojure, 83 bytes, 87 bytes, 79 bytes

(fn[n s](map #(apply str(% %2))(cycle[#(or %)reverse])(partition n n(repeat\ )s))))

several corrections after comments below, thank you Ørjan.

Try it online!

Clojure seems often sadly absent from code golfing answers. It certainly can not compete in byte length with golfing languages, but I think the total absence is somewhat unwarranted.

Explanation:

  • in-data, two arguments a number and a string
  • start by running clojure built-in function partition on string s chunking it into a sequence of lists of characters where the lists have length n. The last chunk will be padded with spaces to length n using the "pad collection" returned from (repeat " ") which returns an infinite lazy sequence of spaces
  • we then call map with three arguments:
    • an anonymous function (the #(..))
    • an infinite alternating lazy sequence of functions #(or %) which functions like the identity function and reverse (i.e. [#(or %) reverse #(or %) reverse ...]) as returned by cycle.
    • the chunked up lazy sequence of lists returned by partition.
  • finally the anonymous function #(apply ...):
    • calls either identity or reverse alternatingly on a chunk. This is done via the (% %2) expression which calls the function sent in as the first argument to the anonymous function [i.e. identity or reverse] using the second argument [i.e. the chunk] to the anonymous function as the argument to the call.
    • calls (apply str ...) to convert the list of characters into a string
  • the outer function returns a lazy sequence of strings

one trick we use here is that a lot of clojure functions like map take an arbitrary number of collections as args, i.e. (map f coll1 coll2 coll3 ...) where the function f just needs to accept as many arguments as there are collections. In this case we send in two collections, a collection of alternating function references and the chunked up string.

Matias Bjarland

Posted 2015-08-20T21:45:38.140

Reputation: 420

1This is nice but it doesn't seem to have the required whitespace at the end of ld!. – Ørjan Johansen – 2018-05-13T16:04:13.550

You are most correct. Added a pad collection which should fix the issue...and cost me 8 bytes... – Matias Bjarland – 2018-05-13T17:44:51.983

I have a question on golfing rules: if you are using a built-in function which would require an import or similar statement (require in clojure, import in java, etc), does the importing of that built-in need to be part of the golfing solution byte count? I assume yes, but it feels a tad like a gray area. – Matias Bjarland – 2018-05-14T08:15:22.980

Yes, the import is counted. – Ørjan Johansen – 2018-05-14T16:33:56.383

Oh but there's another rule you're breaking: You cannot take input in predefined variables, you need to make the solution either a whole program or a function. (Using either fn or defn is fine.) On the flip side your function is allowed to just return the result rather than print it. – Ørjan Johansen – 2018-05-14T16:40:55.583

I suppose #() is also fine, I don't really know Clojure. – Ørjan Johansen – 2018-05-14T16:48:45.123

Thanks for the pointers and apologies for noobness with golfing rules. Added function and now return a sequence of strings instead of printing them. – Matias Bjarland – 2018-05-14T18:32:05.747

2

APL (Dyalog Unicode), 19 bytes

{↑⊢∘⌽\↓↑⍵⊆⍨⌈⍺÷⍨⍳≢⍵}

Try it online!

Took the ⊢∘⌽\ trick from ngn's brilliant answer to the boustrophedonise challenge.

After realising that my submission breaks for lines with leading newlines, I have added two more bytes. Below is the older submission.

APL (Dyalog Unicode), 17 bytes

{↑⊢∘⌽\⍵⊆⍨⌈⍺÷⍨⍳≢⍵}

Try it online!

user41805

Posted 2015-08-20T21:45:38.140

Reputation: 16 320

2

Python 3, 110 108 107 103 bytes

def a(s,n):l=len(s)//n+1;s+=' '*(len(s)-l);print('\n'.join([s[x*n:n*x+n][::(-1)**x]for x in range(l)]))

(looking at other answers), with rjust: 95 93 92 90 bytes

def a(s,n):print('\n'.join([s[x*n:n*x+n][::(-1)**x].rjust(n)for x in range(len(s)//n+1)]))

bobrobbob

Posted 2015-08-20T21:45:38.140

Reputation: 160

The last line of your output is wrong. Run it here. It's a great first post, and once you fix that I will suggest some ways to golf some bytes off, the first being that you can remove all the spaces/tabs from your answer.

– mbomb007 – 2018-05-15T18:58:18.650

haha, you're so right. fixing this is gonna cost a lot but i'm on it. thanks – bobrobbob – 2018-05-15T19:08:34.313

1Tips for golfing in Python – mbomb007 – 2018-05-15T19:30:25.790

Also, you beat my answer from quite a while ago: https://codegolf.stackexchange.com/a/55082/34718

– mbomb007 – 2018-05-15T19:32:22.827

reading the tips. thanks again – bobrobbob – 2018-05-15T20:03:33.283

Make sure you count your bytes correctly. – mbomb007 – 2018-05-15T21:10:22.430

i forgot the newline. sorry and thanks for editing – bobrobbob – 2018-05-15T22:11:19.487

2

Lua, 91 88 88 84 83 82 bytes

Old version:

a=arg for i=1,#a[1],a[2]do s=a[1]:sub(i,i+a[2]-1)print(d and s:reverse()or s)d=not d end

New version:

arg[1]:gsub((".?"):rep(arg[2]),function(s)print(d and s:reverse()or s)d=not d end)

Trebuchette

Posted 2015-08-20T21:45:38.140

Reputation: 1 692

2

Perl, 87 bytes

sub f{$_=@_[0].$"x(@_[1]-1);$a.=(($i++&1?reverse$1:$1).$/)while/(.{@_[1]})/g;chop$a;$a}

Old version (prints a trailing newline):

sub f{$_=@_[0].$"x(@_[1]-1);print(($i++&1?reverse$1:$1).$/)while/(.{@_[1]})/g}

String is passed as a function argument with no trailing newline. Call like this:

$_=<>;chomp;print f($_,5);

samgak

Posted 2015-08-20T21:45:38.140

Reputation: 1 577

2

Haskell, 108 bytes

(#)=splitAt
s!n=let(a,t)=n#s;(b,u)=n#t in a:reverse b:(u!n)
s%n=unlines$takeWhile(any(>' '))$(s++cycle" ")!n

That's sort of long, jeez. Here it is in action:

*Main> putStrLn $ "Programming Puzzles & Code Golf" % 4
Prog
mmar
ing
zzuP
les
oC &
de G
 flo

Lynn

Posted 2015-08-20T21:45:38.140

Reputation: 55 648

How does binding the let expression work? – xnor – 2015-08-21T02:04:58.843

It's a two-in-one let statement separated by a semicolon -- normally you'd use newlines and indentation, but Haskell also allows you to write let a=b; c=d in expr. – Lynn – 2015-08-21T02:05:58.027

I didn't know this was allowed, taking putStrLn out of the program! – Leif Willerts – 2015-08-21T18:37:26.167

1@LeifWillerts, recently, challenges on here tend to allow you to either perform I/O via function arguments/results or stdin/stdout -- here, my solution is a function (%) :: String -> String -> String instead of IO (). – Lynn – 2015-08-21T20:16:38.093

2

Python 2, 109 bytes

Had to add padding with spaces for the last line to be correct.

Try it here

I,c=input()
I+=(c-len(I)%c)*" "
L=[]
i=0
while I:s=I[:c];L+=[[s,s[::-1]][i%2]];i+=1;I=I[c:]
print"\n".join(L)

mbomb007

Posted 2015-08-20T21:45:38.140

Reputation: 21 944

2

O, 60 bytes

z""/rlJ(Q/{n:x;Q({+}dxe{`}{}?p}drQJQ%-{' }dJQ/e{r}{}?Q({o}dp

My very first O program, and a long one at that!

Live demo.

kirbyfan64sos

Posted 2015-08-20T21:45:38.140

Reputation: 8 730

2

PowerShell, 102 Bytes

param($s,$i)$l=$s.Length;$s+' '*($i%$l)-split"(.{$i})"|?{$_}|%{$r=-not$r;@($_,($_[$l..0]-join''))[$r]}

Invoked as follows (if saved to file CodeGolf55051.ps1)

.\CodeGolf55051.ps1 -s '1234567890' -i 4

Previous Attempts

(longer or invalid)

PowerShell, 110 Bytes

param($s,$i)$l=$s.Length;$s+' '*(($i-$l%$i)%$i)-split"(.{$i})"|?{$_}|%{$r=-not$r;@($_,($_[$l..0]-join''))[$r]}

PowerShell, 111 Bytes

param($s,$i)$s+' '*(($i-$s.Length%$i)%$i)-split"(.{$i})"|?{$_}|%{$r=-not$r;@($_,($_[$_.length..0]-join''))[$r]}

Explanation

param($s,$i)                         #Take input text (s) and column width (i)
$s                                   #take the user entered string
+ ' ' * (($i - $s.Length % $i) % $i) #add the least number of spaces required to make its length divisible by i
-split"(.{$i})"                      #break it into chunks of i characters in length
| ?{$_}                              #skip any blank lines created in the process
| %{                                 #for each line
    $r = -not $r;                    #    toggle a boolean value
    @(                               #    define an array
        $_                           #    index 0 = the string going forwards
        ,($_[$_.length..0] -join '') #    index 1 = the string reversed (by taking each character from the last to the first, then joining them)
    )[$r]                            #    if our boolean value is false take the forward string (index 0), if true take the backwards one (index 1)
}                                    #next

PowerShell, 180 Bytes

param($s,$i)$x="`${0}|{1}|`${2}";$w=$x;1..$i|%{$w=$w-f$_,$x,($i+$_)};$w=$w-replace'\||\${.*}';$r=$w-replace'\$\d+','(.)?';$s+' '*($i-$s.Length%$i)-replace$r,$w-split"(.{$i})"|?{$_}

PowerShell, 196 Bytes

param($s,$i)$x="{0}|{1}|{2}";$w=$x;1..$i|%{$w=$w-f$_,$x,($i+$_)};$w=$w-replace'(\d+)','$$$1'-replace'\||{.*}';$r=$w-replace'\$\d+','(.)?';$s+' '*($i-$s.Length%$i)-replace$r,$w-split"(.{$i})"|?{$_}

Explanation

param ($s, $i)                      #Take input text (s) and column width (i)

$x = "{0}|{1}|{2}"                  #Define string format which takes 3 entries and pipe delimits them

$w = $x                             #initialise our replacement regex with this format
1..$i | %{                          #for 1 to the specified column width
    $w = $w -f $_, $x, ($i + $_)    #update the regex 1|{...}|5, 1|2|{...}|6|5, etc
}                                   #resulting in w = 1|2|3|4|{...}|8|7|6|5
$w = $w -replace '(\d+)', '$$$1'    #now prefix the numbers with a dollar (so they're regex replacement variables)
        -replace '\||{.*}'          #and remove the delimiters and superfluous `{...}` left from our middle insertion routine

$r = $w -replace '\$\d+', '(.)?'    #then create the match pattern by replacing the variables with optional single character captures

$s                                  #now take the user entered string
    + ' ' * ($i - $s.Length % $i)   #add the least number of spaces required to make its length divisible by i
    -replace $r, $w                 #perform a replacement using the regex match and replace patterns created above
    -split "(.{$i})"                #then split the string into blocks of length i
    | ?{$_}                         #removing any blank lines created in the process

({...} in the above comments is actually {0}|{1}|{2}; I put {...} for improved readability.

Powershell, 120 Bytes (invalid)

param($s,$i)$s + ' ' * ($i-$s.Length%$i) -replace '(.{4})?(.)(.)(.)(.)',"`$1`n`$5`$4`$3`$2`n" -split "`n" | ?{$_ -ne ""}

JohnLBevan

Posted 2015-08-20T21:45:38.140

Reputation: 151

1Awesome to see another PowerShell slinger! An easy start is to get rid of dang near every space param($s,$i)$s+' '*($i-$s.Length%$i)-replace'(.{4})?(.)(.)(.)(.)',"`$1`n`$5`$4`$3`$2`n"-split"`n"|?{$_-ne""} which will get you down to 108. – AdmBorkBork – 2015-08-21T19:27:42.027

Thanks @TimmyD; just spotted a couple of fundamental errors with my script though (it doesn't meet the requirements / is hardcoded to only work for 4... fixing now) – JohnLBevan – 2015-08-21T19:31:32.797

While testing, to get the flow back and forth to start in the correct direction, I needed to swap the final [$r] index with [-not$r] ... else the first line reads the opposite (i.e., right-to-left) than in the examples provided. Otherwise, really slick execution! – AdmBorkBork – 2015-08-25T19:20:13.540

1Also, since we're given that the input number n is positive, and we're guaranteed that the length of the string is non-negative (by definition), that means that (($i-$l%$i)%i) is equivalent to ($i-$l%$i), saving four characters. – AdmBorkBork – 2015-08-25T19:32:09.107

Thanks @TimmyD; though is that true (i.e. I=3;L=6 gives 0 with the original and 3 with the shortened version). – JohnLBevan – 2015-08-25T21:07:36.253

1

Whoops, I somehow typo'd that, I originally meant (-$l)%$i. Don't know where that came from. Interesting, however, that it's not equivalent, though it should be. It's apparently a quirk of how PowerShell (among other languages) implements the modulo function, which is different than either I (being a math major) or Wolfram-Alpha expected. Apparently, you'll need to stick with the longer version. Reference

Proof --> ((y-x%y)%y) ==> ((y%y)-(x%y%y))%y ==> ((0)-(x%y))%y ==> (-x%y)%y ==> (-x)%y

– AdmBorkBork – 2015-08-26T13:14:02.087

2

Mumps, 86 bytes

R I,S,! S P=$L(I),$P(I," ",P)=P F Q=1:S:P S F=$E(I,Q,Q+S-1),P='P W $S('P:F,1:$RE(F)),!

Although it could be 2 bytes shorter if you remove the first ',!' characters in the R statement (read from STDIN); that adds a carriage return between the input and output. If that wasn't there, the output is technically correct, but the first line would appear appended to the input string. [[ The standard Mumps terminal that I use has no local echo. ]]   As it sits, here's the test:

R I,S,! S P=$L(I),$P(I," ",P)=P F Q=1:S:P S F=$E(I,Q,Q+S-1),P='P W $S('P:F,1:$RE(F)),!
ABCDEFGHIJKLMNOPQRSTUVWXYZ1236
ABCDEF
LKJIHG
MNOPQR
XWVUTS
YZ123 

Also note, there's actually a carriage return / Enter keypress between the '123' and the '6' at the end of the input. [[ The local echo thing again. ]]

If anyone's interested I can describe what's going on with the code; but I do realize there's not a ton of Mumps enthusiasts out there... :-)

user43315

Posted 2015-08-20T21:45:38.140

Reputation: 21

1

Perl 5, 51 bytes

$_.=$"x(($-=<>)-1);say--$|?$_:~~reverse for/.{$-}/g

Try it online!

Dom Hastings

Posted 2015-08-20T21:45:38.140

Reputation: 16 415

1

PHP, 135 bytes

Takes two command-line arguments as shown with $argv.

<? foreach($a=str_split($s=$argv[1],$n=$argv[2])as$k=>&$v)$v=$k%2?$v:strrev($v);echo implode("\n",$a).str_repeat(' ',$n-strlen($s)%$n);

rink.attendant.6

Posted 2015-08-20T21:45:38.140

Reputation: 2 776

1

CoffeeScript, 131 bytes

This seems too long.

f=(s,n,r=l=s.length,i=0,z='')->(t=s[i...i+=n].split '';t=t.reverse()if r=!r;z+=t.join('')+(i<l&&'\n'||' '.repeat n-l%n))while i<l;z

rink.attendant.6

Posted 2015-08-20T21:45:38.140

Reputation: 2 776

1

Julia, 104 bytes

f(s,n)=(L=length(s);L+=L÷n;j=0;for i=1:n:L-n+1 x=rpad(s,L)[i:i+n-1];println(j%2<1?x:reverse(x));j+=1end)

Ungolfed:

function f(s::String, n::Int)
    L = length(s) + length(s) ÷ n
    j = 0
    for i = 1:n:L-n+1
        x = rpad(s, L)[i:i+n-1]
        println(j % 2 == 0 ? x : reverse(x))
        j += 1
    end
end

Alex A.

Posted 2015-08-20T21:45:38.140

Reputation: 23 761

1

Q, 64 56 bytes

{c::neg y;-1(til(#)l){$[x mod 2;c$(|:)y;y]}'l:y cut x;}
  • {} is a function that should be called as {}[x;y].
    • x will be the string.
    • y will be the length of the resulting lines.

Test:

{c::neg y;-1(til(#)l){$[x mod 2;c$(|:)y;y]}'l:y cut x;}["Programming Puzzles & Code Golf";4]
Prog
mmar
ing
zzuP
les
oC &
de G
 flo

edit: Used shorter functions as inspired by the other q answer by @tmartin

h.j.k.

Posted 2015-08-20T21:45:38.140

Reputation: 589

1

Python 3, 101 bytes

t,x=eval(input())
print("\n".join([t[c:c+x].ljust(x)[::1-2*(int(c/x)%2)] for c in range(0,len(t),x)]))

Try it here

Alexander Nigl

Posted 2015-08-20T21:45:38.140

Reputation: 121

1

Python 2, 82 75 bytes

s,n=input()
k=0
while k<=len(s):print s[k:k+n].ljust(n)[::1-2*(k/n%2)];k+=n

I couldn't comment on @willem but I made his code smaller.

Try here Try here

Alexander Nigl

Posted 2015-08-20T21:45:38.140

Reputation: 121

Hi AlexN, nice one. I think that your last line in the 'Try here' example is not correct. It should be justified right. Also I count 86 chars? See my entry for the update.

– Willem – 2015-08-21T13:08:37.337

Hi willem, you are right, I corrected the code and found that you have an error in yours: http://ideone.com/GOmMrE

There should be a t on the right side.

– Alexander Nigl – 2015-08-21T17:51:59.563

1

q, 46

{-1@neg[y]$@[a;(&)(til(#)a:y cut x)mod 2;|:];}

.

q){-1@neg[y]$@[a;(&)(til(#)a:y cut x)mod 2;|:];}["Programming Puzzles & Code Golf";4]
Prog
mmar
ing
zzuP
les
oC &
de G
 flo

tmartin

Posted 2015-08-20T21:45:38.140

Reputation: 3 917

This is incorrect when the last line is shorter and not twisted, I wanted to post the bug fix in my answer but I think it'll be better if you can update yours instead: {-1@[l;(&)(til(#)l:y cut x)mod 2;'[neg[y]$;|:]];} (49 bytes). Thanks for the inspiration! :) – h.j.k. – 2015-08-21T17:50:08.263

1

JavaScript ES6, 123 bytes

var t=(s,n)=>{for(var d=1,i=0,o='',l=s.length;i<l;i++){o+=d?s[i]:s[i-i%n+n-1-i%n]||' ';if(i%n==n-1){d=!d;o+='\n'}}return o}

Call with t(input_string, twist_length), which returns the output string.

DankMemes

Posted 2015-08-20T21:45:38.140

Reputation: 2 769

1Sorry, posted a bit too fast. It's fixed. – DankMemes – 2015-08-22T18:25:28.070

1

Perl, 72 bytes

perl -p0e's/\n(.*)/$"x($1-$-[0]%$1)/e;s/.{$1}/($i++%2?reverse$&:$&)."\n"/ge;chop'

70 bytes, plus 2 bytes for -p0.

Demo:

$ echo -en 'Hello, World!\n5' | perl -p0e's/\n(.*)/$"x($1-$-[0]%$1)/e;s/.{$1}/($i++%2?reverse$&:$&)."\n"/ge;chop'
Hello
roW ,
ld!  $

Note that the input read from STDIN cannot end with a newline (that would cost 2 extra bytes).

Explanation:

perl -p0e'  # Read from STDIN, splitting on null bytes,
            # and print $_ automatically at the end

    s/
        \n(.*)  # Replace everything after first newline,
                # capturing wrap length in $1...
     /
        $"x($1-$-[0]%$1)  # ...with spaces until the total length of $_ is
                          # a multiple of $1 (i.e. right-pad with spaces)
     /e;

    s/
        .{$1}  # Replace series of $1 contiguous chars...
     /
        ($i++%2?reverse$&:$&)."\n"  # ...alternately with themselves or in
                                    # reverse, with a trailing newline
     /ge;

    chop'  # Remove final newline

ThisSuitIsBlackNot

Posted 2015-08-20T21:45:38.140

Reputation: 1 050

0

C (gcc), 145 141 bytes

Not allowing trailing whitespace made it clunkier than otherwise.

Thanks to ceilingcat for the tip that led me on the track to save 4 bytes.

f(s,n,l,i,j)char*s;{for(l=strlen(s),i=0;i<l;i+=2*n)if(printf("%-*.*s\n",n,n,s+i),i+n<l){for(j=i+2*n;j>i+n;)putchar(l/j--?s[j]:32);puts("");}}

Try it online!

gastropner

Posted 2015-08-20T21:45:38.140

Reputation: 3 264

0

Groovy, 68 bytes

f=-n;s.eachMatch(/.{1,$n}/){printf "%${f}s%n",f>0?it[-1..0]:it;f=-f}

revised after I realized the initial version didn't handle padding correctly.

Try it online!

Matias Bjarland

Posted 2015-08-20T21:45:38.140

Reputation: 420

0

Java 8, 197 146 136 bytes

s->n->{String r="",t,u;for(int l=s.length,i=0,j;i<l/n*n+n;r+=t+"\n",i=j)for(t="",j=i;j<i+n;t=j++/n%2<1?t+u:u+t)u=j<l?s[j]:" ";return r;}

Try it online.

Explanation:

s->n->{                 // Method with String and integer parameters and String return-type
  String r="",          //  Result-String, starting empty
         t,u;           //  Temp-Strings
  for(int l=s.length,   //  Length of the input-String
      i=0,j;i<l/n*n+n   //  Loop `i` in the range [0, `l` + whatever to make blocks of `n`)
      ;                 //    After every iteration:
       r+=t+"\n",       //     Append the result-String with `t` and a new-line
       i=j)             //     And set `i` to `j`
    for(t="",           //   Reset `t`
        j=i;j<i+n;      //   Inner loop `j` in the range [i, i+n)
        ;t=j++/n%2<1?   //     After every iteration: If the k'th block of `n` is even:  
            t+u         //      Append `u` to `t`
           :            //     Else (it's odd):
            u+t)        //      Prepend `u` to `t`
      u=j<l?            //    If `j` is still within bounds:
         s[j]           //     Set `u` to the current character
        :               //    Else:
         " ";           //     Set `u` to a space
  return r;}            //  Return the result-String

Kevin Cruijssen

Posted 2015-08-20T21:45:38.140

Reputation: 67 575

0

Japt, 14 bytes

óV y £Yv ?X:Xw

Try it online!

Oliver

Posted 2015-08-20T21:45:38.140

Reputation: 7 160

0

Python 2, 86 bytes

Here's my answer (borrowing some input processing from @mbomb007). Unfortunately can't define the len(s) as a variable as the length of the string changes after padding with spaces. Now also using rjust() instead of ljust() as @AlexN suggested.

s,n=input()
k=n
while k<=len(s):print s[k-n:k]+'\n'+s[k+n-1:k-1:-1].rjust(n);k+=2*n  

Willem

Posted 2015-08-20T21:45:38.140

Reputation: 1 528

0

Shell/Bash, 135 bytes

s=0;while true;do ((s%($2*2)))&&{ echo "${1:s:$2}"|rev;s=$((s+$2)); }||{ echo "${1:s:$2}";s=$((s+$2)); };((s>=${#1}))&&{ exit 1; };done

智障的人

Posted 2015-08-20T21:45:38.140

Reputation: 111

Would it be possible to replace the true with either 1 or 1=1? – Taylor Scott – 2018-05-19T22:51:35.643

Yes, you can do while :. I didn't see this answer when I composed my answer, but it has very similar logic, and I borrowed the more concise arithmetic evaluation to reduce my version from 83 bytes to 74.

– Adam Katz – 2018-08-24T18:51:01.690

0

Ruby, 80

->s,l{s+=' '*(l-s.size%l)
(s.size/l).times{|i|puts [x=s[i*l,l],x.reverse][i%2]}}

Online demo: http://ideone.com/w6o8PI

Cristian Lupascu

Posted 2015-08-20T21:45:38.140

Reputation: 8 369

0

Coffeescript, 151 bytes

f=(s,n)->r="";d=n;i=0;_="\n";u=" ";l=s.length;(d--and(r+=s[i]or u;++i)or(r+=_;r+=s[c]or u for c in[i+n-1..i];i+=d=n;r+=_ if i<l))while i<(l/n+1>>0)*n;r

Too much =(

Ignacio Lago

Posted 2015-08-20T21:45:38.140

Reputation: 141

0

Bash, 83 74

for((i=0;i<${#1};i+=$2));do b=cat;((i/$2%2))&&b=rev;echo ${1:i:$2}|$b;done

This alternates between cat and rev for substrings of the first argument with a length of the second argument.

Special variables used include

  • ${#1} (the length of the string $1)
  • ((i/$2%2)) (an arithmetic expression dividing incrementor $i by $2 and then taking its modulo to determine odd vs even, which dictated whether or not to use rev)
  • ${1:i:$2} (substring of $1 starting at position $i with a length of $2).

Adam Katz

Posted 2015-08-20T21:45:38.140

Reputation: 306

Hm, I did this independent of the other bash answer, which I only just saw now. We have effectively the same logic. ... actually, viktorahlström's answer just let me shave off another 9 characters.

– Adam Katz – 2015-08-22T21:51:26.157

0

JavaScript ES6, 113 bytes

Just my own crack at my own question. It will add spaces so it is divisible by n, that way it's simply splitting and reversing.

(s,n)=>(s+' '.repeat(n-s.length%n)).match(eval(`/.{1,${n}}/g`)).map((l,i)=>i%2?[...l].reverse().join``:l).join`
`

Downgoat

Posted 2015-08-20T21:45:38.140

Reputation: 27 116