7
\$\begingroup\$

The basic idea is to write a program that twists itself, and the twisted version untwists itself. The first program will just be the twisting algorithm described here, and when given its own source code as input, outputs a program that reverses the twisting algorithm.

How strings are twisted

The twisting algorithm is very simple. Each column is shifted down by its index (col 0 moves down 0, col 1 moves 1, ...). The column shift wraps to the top. It kinda looks like this:

a
ba
cba
----
 cba
  cb
   c

With everything under the line wrapping to the top. Real example:

Original:
\\\\\\\\\\\\
............
............
............

Twisted:
\...\...\...
.\...\...\..
..\...\...\.
...\...\...\

(Further examples are here)

Input

Input is either an array of strings, or a multi-line string. All lines have the same length.

Output

The (un)twisted string, multi-line output to std-out (or closest alternative).

Example

I'm not quite sure what this is written in but oh well ;)

Twisting:
magic  TwistingAlgo
magic ntwistingAlgo
magicU twistingAlgo

Untwisting:
magic  twistingAlgo
magicUnTwistingAlgo
magic  twistingAlgo

Other notes

  • Your first and second program must be in the same language.
  • The programs must work for any input, not just itself.
  • Your program must have at least 2 rows and 2 columns.
\$\endgroup\$
1
\$\begingroup\$

CJam, 21 bytes

qN/zee::m>
zN*z e#: <

Test it here.

When you twist it, you get:

qN/zee::m<
zN*z e#: >

Explanation

This is based on my CJam answer to the original challenge and works basically the same.

The e# is a comment, so we can ignore it and the stuff after it. The means the code boils down to

qN/zee::m>zN*z

Which is the same as in the previous answer, plus a trailing z which just wraps the string in an array but that doesn't affect the output.

Notice that the two rows match up in all columns which are rotated (N, z, e, :) except for the last one. That means all the twisting will do is swap > and < which switches the direction of the column rotation.

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

Japt, 63 bytes

Uy m@XsV=(Y*Xl +Y %Xl)+X¯V}R y;
Uy m@XsV=(Y*Xl -Y %Xl)+X¯V}R y;

Twisted:

Uy m@XsV=(Y*Xl -Y %Xl)+X¯V}R y;
Uy m@XsV=(Y*Xl +Y %Xl)+X¯V}R y;

Test it online: Original, Twisted

How it works

I hadn't posted yet on the original twisting challenge, but the shortest answer I could come up with is 31 bytes:

Uy m@XsV=(Y*Xl -Y %Xl)+X¯V}R y;

The untwisting algorithm I came up with is a lot shorter:

Uy m@XsV=Y%Xl)+X¯V}R y;

However, this won't work very well when intertwined with the other program. Fortunately, there's a way to make the two more similar:

Uy m@XsV=(Y*Xl -Y %Xl)+X¯V}R y;
Uy m@XsV=(Y*Xl +Y %Xl)+X¯V}R y;

Now all that's different between the two is the +/-, which is already properly aligned to switch places when twisted!

Uy m@XsV=(Y*Xl -Y %Xl)+X¯V}R y;
Uy        // Transpose rows and columns in U.
m@     }R // Map each item X and index Y in the result, split at newlines, to:
Y*Xl -Y   //  Take Y times X.length and subtract Y.
%Xl)      //  Modulate the result by X.length.
XsV=      //  Set V to the result of this, and slice off the first V chars of X.
+X¯V      //  Concatenate this with the first V chars of X.
y;        // Transpose the result again.
          // Implicit: output *last* expression
\$\endgroup\$
  • \$\begingroup\$ I really didn't envision this being that simple... When I was thinking about how to do this I was writing in groovy, not a golfing language. \$\endgroup\$ – J Atkin Feb 2 '16 at 21:56
  • \$\begingroup\$ @JAtkin Yep, I didn't realize it at first, but the best way to go about this seems to be make flipping the +/- the only difference between the algorithms, then align the programs so that this will happen. This might not work in languages like Groovy though, because of the manual output. \$\endgroup\$ – ETHproductions Feb 2 '16 at 22:07
0
\$\begingroup\$

Haskell, 235 bytes

main=interact$unlines.g.lines;g l@("":_)=l; g l|t<-tail<$>l,n<-length t=zipWith(:)(head<$>l)$ g$take n$drop(n-1)$t++t
maim=interact$unlines.h.lines;h l@("":_)=l; h l|t<-tail<$>l,n<-length t=zipWith(:)(head<$>l)$ h$take n$drop(2-1)$t++t

and twisted by itself:

maim=interact$unlines.g.lines;g l@("":_)=l; g l|t<-tail<$>l,n<-length t=zipWith(:)(head<$>l)$ g$take n$drop(n-1)$t++t
main=interact$unlines.h.lines;h l@("":_)=l; h l|t<-tail<$>l,n<-length t=zipWith(:)(head<$>l)$ h$take n$drop(2-1)$t++t

This is a full program. Both lines are mostly the same so that they are not messed up. The differences are:

normal  twisted
=================================
main=   maim=     -- after twisting the second lines defines the main function
maim=   main=     -- the other defines an unused function maim

g       g         -- As I cannot define a function (say f) multiple times,
h       h         -- I need different names for the function in both lines

n-1     n-1       -- this is for the different functionalities (twisting up / 
2-1     2-1       -- twisting down). When calling g/h recursively I go with the
                  -- rest of each input line. To twist down, I drop (length n) -1
                  -- chars of two copies of the line. To twist up, I drop 2-1 chars
                  -- Then cut to the original length.
                  --
                  -- e.g.  2222    two     2222    twist   4444    twist   3333
                           3333    copies  3333    down    2222    up      4444
                           4444            4444    ->      3333    ->      2222
                                           2222    drop 2          drop 1
                                           3333
                                           4444 
\$\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.