34
\$\begingroup\$

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!  
\$\endgroup\$
  • \$\begingroup\$ Related: a readable implementation at CodeReview \$\endgroup\$ – Caridorc Aug 23 '15 at 20:59
  • \$\begingroup\$ It may not any trailing whitespace. Golfed away a verb? \$\endgroup\$ – Adám May 13 '18 at 21:19
  • \$\begingroup\$ May we return a list of lines? \$\endgroup\$ – Adám May 13 '18 at 21:19

36 Answers 36

10
\$\begingroup\$

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

\$\endgroup\$
6
\$\begingroup\$

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
\$\endgroup\$
5
\$\begingroup\$

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
\$\endgroup\$
5
\$\begingroup\$

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) 
\$\endgroup\$
4
\$\begingroup\$

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!

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

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
\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ How does binding the let expression work? \$\endgroup\$ – xnor Aug 21 '15 at 2:04
  • \$\begingroup\$ 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. \$\endgroup\$ – Lynn Aug 21 '15 at 2:05
  • \$\begingroup\$ I didn't know this was allowed, taking putStrLn out of the program! \$\endgroup\$ – Leif Willerts Aug 21 '15 at 18:37
  • 1
    \$\begingroup\$ @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 (). \$\endgroup\$ – Lynn Aug 21 '15 at 20:16
2
\$\begingroup\$

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)
\$\endgroup\$
2
\$\begingroup\$

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)
\$\endgroup\$
2
\$\begingroup\$

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.

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

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);
\$\endgroup\$
2
\$\begingroup\$

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... :-)

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

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 ""}
\$\endgroup\$
  • 1
    \$\begingroup\$ Awesome 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. \$\endgroup\$ – AdmBorkBork Aug 21 '15 at 19:27
  • \$\begingroup\$ 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) \$\endgroup\$ – JohnLBevan Aug 21 '15 at 19:31
  • \$\begingroup\$ 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! \$\endgroup\$ – AdmBorkBork Aug 25 '15 at 19:20
  • 1
    \$\begingroup\$ Also, 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. \$\endgroup\$ – AdmBorkBork Aug 25 '15 at 19:32
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ – AdmBorkBork Aug 26 '15 at 13:14
2
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ This is nice but it doesn't seem to have the required whitespace at the end of ld! . \$\endgroup\$ – Ørjan Johansen May 13 '18 at 16:04
  • \$\begingroup\$ You are most correct. Added a pad collection which should fix the issue...and cost me 8 bytes... \$\endgroup\$ – Matias Bjarland May 13 '18 at 17:44
  • \$\begingroup\$ 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. \$\endgroup\$ – Matias Bjarland May 14 '18 at 8:15
  • \$\begingroup\$ Yes, the import is counted. \$\endgroup\$ – Ørjan Johansen May 14 '18 at 16:33
  • \$\begingroup\$ 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. \$\endgroup\$ – Ørjan Johansen May 14 '18 at 16:40
2
\$\begingroup\$

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!

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

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)]))
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – mbomb007 May 15 '18 at 18:58
  • \$\begingroup\$ haha, you're so right. fixing this is gonna cost a lot but i'm on it. thanks \$\endgroup\$ – bobrobbob May 15 '18 at 19:08
  • 1
    \$\begingroup\$ Tips for golfing in Python \$\endgroup\$ – mbomb007 May 15 '18 at 19:30
  • \$\begingroup\$ Also, you beat my answer from quite a while ago: codegolf.stackexchange.com/a/55082/34718 \$\endgroup\$ – mbomb007 May 15 '18 at 19:32
  • \$\begingroup\$ reading the tips. thanks again \$\endgroup\$ – bobrobbob May 15 '18 at 20:03
1
\$\begingroup\$

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);
\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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

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

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
\$\endgroup\$
  • \$\begingroup\$ 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! :) \$\endgroup\$ – h.j.k. Aug 21 '15 at 17:50
1
\$\begingroup\$

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

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

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

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Willem Aug 21 '15 at 13:08
  • \$\begingroup\$ Hi willem, you are right, I corrected the code and found that you have an error in yours: ideone.com/GOmMrE There should be a t on the right side. \$\endgroup\$ – Alexander Nigl Aug 21 '15 at 17:51
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ Sorry, posted a bit too fast. It's fixed. \$\endgroup\$ – DankMemes Aug 22 '15 at 18:25
1
\$\begingroup\$

Perl 5, 51 bytes

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

Try it online!

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

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

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

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 =(

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

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).
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Adam Katz Aug 22 '15 at 21:51
0
\$\begingroup\$

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`
`
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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