22
\$\begingroup\$

Task: Given an input consisting of exactly one of the characters <>^v, output a second input consisting of the printable ASCII characters (from space to tilde), oriented with the arrow.

Let's assume the second input to the program is ABC. This is what it should do:

  • Input >: print ABC.
  • Input <: print CBA.
  • Input ^: print C\nB\nA, or the input rotated -90°.
  • Input v: print A\nB\nC, or the input rotated 90°.

Test cases

input => \n output
---
">", "thanks!" =>
thanks!
---
"<", "Hello, World!" =>
!dlroW ,olleH
---
"^", "This is text." =>
.
t
x
e
t

s
i

s
i
h
T
---
"v", "Tokyo" =>
T
o
k
y
o
---
"<", ">>>" =>
>>>

This is a , so the shortest program in bytes wins.

\$\endgroup\$
  • \$\begingroup\$ Full code or function? \$\endgroup\$ – HyperNeutrino Feb 27 '16 at 22:37
  • 1
    \$\begingroup\$ @AlexL. You can write either afaik \$\endgroup\$ – Downgoat Feb 27 '16 at 22:38
  • \$\begingroup\$ Is input all as one string OK? >ABC \$\endgroup\$ – Digital Trauma Feb 27 '16 at 22:56
  • \$\begingroup\$ @DigitalTrauma Yes, that's fine. \$\endgroup\$ – Conor O'Brien Feb 27 '16 at 23:13
  • \$\begingroup\$ No, I'm implying that it doesn't matter. You have no test case for the > orientation. \$\endgroup\$ – mbomb007 Mar 2 '16 at 22:24

21 Answers 21

14
\$\begingroup\$

MATL, 10 6 bytes

4 bytes saved thanks to Martin!

19\qX!

Try it online!

19\            % implicitly take input (a character) and compute mod-19 of its ASCII code
   q           % subtract 1. Gives 17, 2, 3, 4 for the characters '^<v>' respectively.
               % These numbers correspond to 1, 2, 3, 4 modulo 4, and so are the numbers
               % of 90-degree rotations required by each character
    X!         % implicitly take input (string). Rotate the computed number of times
               % in steps of 90 degrees. Implicitly display

Old version, without modulo operations: 10 bytes

'^<v>'=fX!

Try it online!

'^<v>'         % push string
      =        % implicitly take input (a char) and test for equality
       f       % find index of matching character
        X!     % implicitly take input (string). Rotate that number of times
               % in steps of 90 degrees. Implicitly display
\$\endgroup\$
  • 1
    \$\begingroup\$ Damn I was really proud of my 13 bytes, but needing 3 bytes for input and 6 for rotating... oh well... maybe you can also save something with the mod 11 trick (you'll have to rotate the other way round though). \$\endgroup\$ – Martin Ender Feb 27 '16 at 20:01
  • \$\begingroup\$ @MartinBüttner Good idea! In my case (in yours?) I think mod 19 is better, because then subtracting 1 directly gives 1,2,3,4 (mod 4). Thanks for the tip! \$\endgroup\$ – Luis Mendo Feb 27 '16 at 20:15
  • 6
    \$\begingroup\$ 4 bytes shorter, what on earth... \$\endgroup\$ – Martin Ender Feb 27 '16 at 20:17
  • 2
    \$\begingroup\$ I am officially putting MATL on the "list of language that are insanely short." \$\endgroup\$ – Conor O'Brien Feb 27 '16 at 20:23
12
\$\begingroup\$

Python 3, 64 51 48 bytes

Saved 6 bytes thanks to xnor.

Saved 7 bytes thanks to Lynn.

Saved 3 bytes thanks to DSM and Morgan from sopython.

lambda c,s:'\n'[c<'?':].join(s[::1|-(c in'<^')])

The function accepts one of the characters from <>^v as the first argument and the string that needs to be rotated as the second argument.


Here's a more readable version:

lambda c, s: ('\n' if c in '^v' else '').join(s[::-1 if c in'<^' else 1])
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! If it helps, you are allowed to take two separate inputs as well. (Me not knowing python, this is just a guess.) \$\endgroup\$ – Conor O'Brien Feb 27 '16 at 20:09
  • \$\begingroup\$ Maybe s[1|-(c in'<^')] and sep='\n'*(c in'^v') \$\endgroup\$ – Lynn Feb 27 '16 at 22:33
  • \$\begingroup\$ I think you could do the whole thing as a lambda if you use join with your sep rather than printing. \$\endgroup\$ – xnor Feb 27 '16 at 22:48
  • \$\begingroup\$ Why did you make it cw? \$\endgroup\$ – Conor O'Brien Feb 28 '16 at 0:01
  • 1
    \$\begingroup\$ I love this answer, this is my favourite answer. \$\endgroup\$ – cat Feb 29 '16 at 22:05
8
\$\begingroup\$

Haskell, 57 bytes

f">"=id
f"<"=reverse
f"v"=init.((:"\n")=<<)
f _=f"<".f"v"

Usage example: f "v" "ABC" -> "A\nB\nC".

Direction > is the idendity function, < reverses it's argument, v appends a newline to each character in the string and drops the last one and ^ is v followed by <.

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

Japt, 9 bytes

VzUc %B+1

Inspired by @DonMuesli's answer, although I just noticed the CJam one uses exactly the same technique. Test it online!

How it works

           // Implicit: U = arrow char, V = text
  Uc %B    // Take the char code of U, mod 11.
           // This converts ">", "v", "<", and "^" to 7, 8, 5, and 6, respectively.
Vz     +1  // Add one and rotate V by 90° clockwise that many times.
\$\endgroup\$
  • \$\begingroup\$ o_o nice job! You outgolfed jolf by over 200% o_O \$\endgroup\$ – Conor O'Brien Feb 27 '16 at 21:42
  • \$\begingroup\$ But I'm getting errors? Error: Japt.stdout must be sent to an HTMLElement etc. \$\endgroup\$ – Conor O'Brien Feb 27 '16 at 21:43
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Not sure why that happens, but it happens a lot >:( Reloading always fixes this for me. \$\endgroup\$ – ETHproductions Feb 27 '16 at 21:46
  • \$\begingroup\$ Sure enough, the issue is fixed. I am impressed! \$\endgroup\$ – Conor O'Brien Feb 27 '16 at 21:47
  • \$\begingroup\$ I knew those rotate functions would eventually be useful +1 \$\endgroup\$ – Downgoat Feb 27 '16 at 22:32
4
\$\begingroup\$

CJam, 13 bytes

l(iB%{W%z}*N*

Input is the orientation character followed directly by the string to be rotated.

Test it here.

Explanation

Yay for modulo magic. Taking the four characters modulo 11 maps them to:

> 7 
v 8 
< 5
^ 6

These are all distinct modulo 4 and more importantly they are neatly increasing: 3, 0, 1, 2. That means we can just use the result of the mod 11 to determine how often to rotate (without needing an explicit mod 4, since four rotations are a no-op anyway). We'd normally have to offset these numbers by 1, such that > actually yields 8 and becomes a no-op, but the way I'm rotating them, actually reverses the string on the first application such that we always get one rotation for free.

l    e# Read input.
(i   e# Pull off the first character and convert to its character code.
B%   e# Modulo 11.
{    e# That many times...
 W%  e#   Reverse... on the first iteration this reverses the string. Afterwards
     e#   we'll have an Nx1 or 1xN grid of characters on the stack, where
     e#   this reverses the rows instead.
 z   e#   Transpose. On the first iteration, this simply wraps the string in
     e#   array, turning it into a grid without changing its orientation further
     e#   beyond the reversal that just happened. On subsequent iterations, a
     e#   transpose combined with reversing the rows rotates the grid 90 degrees
     e#   clockwise.
}*
N*   e# Join with linefeeds.
\$\endgroup\$
4
\$\begingroup\$

Pyth, 17 15

jWgz\^_W}z"<^"w

Try it here or run the Test Suite

2 bytes saved thanks to Jakube!

Alternatively using mod tricks:

@s_MBjBz)h%Cw11

Try it here.

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

Julia, 51 bytes

f(d,s)=join(d∈"<^"?reverse(s):s,d∈"^v"?"\n":"")

This is a function that accepts a Char and a string and returns a string.

Let d be the character denoting the direction and s be the string. If d is left or up, we use the reverse of s, otherwise we use s as given. We construct a separator as the empty string if d is left or right, or a newline if d is up or down. The pass the string and the separator to join, which will insert the separator between each character of the string and return a string.

Verify all test cases online

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

Bash + GNU Utilities, 67

(egrep -q '>|v'<<<$1&&cat||rev)|(egrep -q '<|>'<<<$1&&cat||fold -1)
\$\endgroup\$
  • \$\begingroup\$ I wouldn't have guessed you need a space after the -q's, but you do \$\endgroup\$ – cat Feb 29 '16 at 22:17
3
\$\begingroup\$

JavaScript (ES6), 76 67 65 bytes

(a,b)=>(/v|>/.test(a)?[...b]:[...b].reverse()).join(a>`>`?`
`:``)

Port of @Alex A.'s Julia answer. Edit: Saved 9 bytes thanks to @ETHproductions. Saved two bytes separately thanks to @edc65.

\$\endgroup\$
  • \$\begingroup\$ /[v^]/.test(a) => 'Z'<a \$\endgroup\$ – ETHproductions Feb 28 '16 at 1:44
  • \$\begingroup\$ +1 ?"reverse":"slice" genius \$\endgroup\$ – edc65 Feb 28 '16 at 13:21
  • \$\begingroup\$ @edc65 Whoops, I accidentally copied an old version; the boring ?: version was 1 byte shorter. \$\endgroup\$ – Neil Feb 28 '16 at 13:35
  • \$\begingroup\$ (/v|>/.test(a)?[...b]:[...b].reverse())... should be 65 \$\endgroup\$ – edc65 Feb 28 '16 at 14:06
3
\$\begingroup\$

Perl, 54 51 + 1 = 52 bytes

@.=<>=~/./g;@.=reverse@.if/[<^]/;$,=$/x/[v^]/;say@.

Requires the -n flag and the free -M5.010|-E. Takes input as the following: direction\nline:

$ perl -nE'@.=<>=~/./g;@.=reverse@.if/[<^]/;$,=$/x/[v^]/;say@.' <<< $'^\nhello'
o
l
l
e
h

I like that $/x/[v^]/ looks like a substitution.

How it works:

                                                    # -n read first line into $_
@.=<>=~/./g;                                        # Read next line and split
            @.=reverse@.if/[<^]/;                   # Reverse `@.` if matches 
                                                    # `<` or `^`
                                 $,=                # An array will be concatena-
                                                    # ted with the value of 
                                                    # `$,` when printed. 
                                     $/             # Contains a newline
                                        /[v^]/      # boolean 
                                       x            # "\n" x 1 -> "\n"
                                                    # "\n" x 0 -> ""
                                              say@. # Print the array
\$\endgroup\$
2
\$\begingroup\$

PowerShell, 84 bytes

param([char]$a,$b)($b[($c=$b.length)..0],$b[0..$c])[$a%7-eq6]-join("","`n")[90-lt$a]

This is going to be complete gibberish to people not familiar with PowerShell. Let's go through it.

Takes input param([char]$a,$b), with an explicit cast to character for $a. The rest of the program is one statement. We'll start with the first half, up to the -join.

We're creating a new dynamic array (...,...) and indexing into it with $a%7-eq6. The ASCII values for v and > are 116 and 62, respectively, and 116%7 = 62%7 = 6, and those are the two directions that "increase" down and to the right. So, if that -eq is $true, we'll take the second value, which is $b[0..$c], or an array of the characters of $b up to the end. We get the value $c from the first value, $b[($c=$b.length)..0], which gets selected if the input char is ^ or < (i.e., so it goes through the string backwards). Important to note is that even if the second value is selected, the $c value is still calculated and stored, so we can re-use it as a shortcut like this.

So, we've now got an array of characters either going forwards or backwards. We then -join those characters together with the result of another dynamic array index. This time we're selecting based on whether the ASCII value for $a is below 90 (really lots of values would work, I selected this one just because). Since > and < both have a value below 90, the -lt is $false, so we select the empty string "", and thus the char-array is simply concatenated. Otherwise, we select the newline character "`n" to join the char-array together with newlines.

This resultant string is left on the pipeline, and output is implicit.

Example

PS C:\Tools\Scripts\golfing> .\orthogonal-orientation.ps1 "^" "TimmyD"
D
y
m
m
i
T
\$\endgroup\$
2
\$\begingroup\$

C, 123 119 117 114 bytes

Golfed:

f(char*d,char*a){char*b=a,c=*d%21,s[3]={0,c&8?10:0};while(*++b);while(*s=c&4?*a++:*--b)printf(s);if(c&16)puts(b);}

Test program, with explanations & somewhat ungolfed code:

#include <stdio.h>
#include <stdlib.h>

// c     c%21   
// <    10010     => if(c&8), vertical; if(c&16), horizontal
// >    10100     => if(c&4), backwards
// ^    01010
// v    01101
int f(char*d,char*a){
    char *b=a,c=*d%21,s[3]={0,c&8?10:0};
    while(*++b);     // b = a + strlen(a) - 1; this is shorter
    while(*s=c&4?*a++:*--b)printf(s);
    if(c&16)puts(b); // single trailing newline if horizontal
}

int main() {
    char *c="<>^v";
    for(;*c;c++) { 
        printf("--- %c ---\n", *c); 
        f(c,"hello world!"); 
    }
    return 0;
}

Tips welcome!

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

Retina, 60 bytes

Needs golfing...

$
¶
+`^([<^].*)(.)(¶.*)
$1$3$2
¶

.
$&¶
+`([<>].*)¶
$1
^.¶?

Input is all as one string, e.g. ^ABC.

  • If ^ or <, reverse the string
  • Insert newlines after every character
  • If < or >, remove the newlines

Try it online.

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

Dyalog APL, 15 bytes

⌽∘⍉⍣(11|⎕UCS⍞)⍪

make string into 1-column table
⍣(‍) repeat (n) times get string input
⎕UCS convert to UCS code point
11| division rest when divided by 11
⌽∘⍉ rotate -90° (flip-transpose)

Alternate method (same length):

⌽∘⍉⍣('<^>v'⍳⎕)⍪

get evaluated input (so one must input, e.g. '^' or the name of a program/variable that returns the desired character)
'<^>v'⍳ index into the string

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

Jolf, 22 bytes

Try it here! You should replace ƒ with \x9f. Takes the sting, then the directional character.

.‘I_IγƒGIE_γ’ i"><v^"i
 ‘                      golfy array
  I                     the input
   _I                   input reversed
      ƒGIE              split by "" and join by newlines
     γ                  γ = that
          _γ            gamma reversed
.            _i"><v^"i  get the respective index
\$\endgroup\$
1
\$\begingroup\$

JavaScript ES6, 91 83 84 bytes

(a,b)=>[b,(c=[...b].reverse()).join``,[...b].join`
`,c.join`
`]["><v^".indexOf‌​(a)]

Constructs the necessary strings and obtains the index of which a lies in. indexOf is used because ^ is a regex token. Thanks to ETHproductions for the bug fix and shaved bytes!

\$\endgroup\$
  • \$\begingroup\$ f("v","abc") returns c\nb\na for me. \$\endgroup\$ – ETHproductions Feb 27 '16 at 21:52
  • \$\begingroup\$ Here's an 84-byte one that works for me: (a,b)=>[b,(c=[...b].reverse()).join``,[...b].join`\n`,c.join`\n`]["><v^".indexOf(a)] \$\endgroup\$ – ETHproductions Feb 27 '16 at 21:55
  • \$\begingroup\$ @ETHproductions Thanks! I forgot c is literally d. \$\endgroup\$ – Conor O'Brien Feb 27 '16 at 21:58
  • \$\begingroup\$ Out of interest I tried indexing an object... and it turned out to be exactly the same length! \$\endgroup\$ – Neil Feb 28 '16 at 1:00
1
\$\begingroup\$

JavaScript (ES6) 71

(a,b)=>([...b].map(c=>(a>'A'?c+=`
`:0,r=/v|>/.test(a)?r+c:c+r),r=''),r)

Test

F=(a,b)=>([...b].map(c=>(a>'A'?c+=`
`:0,r=/v|>/.test(a)?r+c:c+r),r=''),r)  

console.log=x=>O.textContent+=x+'\n';

for(d of '<>^v') console.log(d+'\n'+F(d,'ABCDE')+'\n')
<pre id=O></pre>

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

Perl 5, 67 bytes

66 plus one for -p

$_=reverse if/^[<^]/;$&?s/.$//:s/.//;$&=~/[v^]/&&s/(.)(?=.)/$1\n/g

The input is a single string whose first character defines the orientation.

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

DUP, 48 bytes

[`5/%$$a:4<&[1$][1_]?\1-[$;$][,^+a;2>['
,][]?]#]

Try it here.

Anonymous lambda that takes both argument and STDIN input. Usage:

0"asdf"[`5/%$$a:4<&[1$][1_]?\1-[$;$][,^+a;2>['
,][]?]#]! {make sure to put one of <>^v in STDIN}

Explanation

[                                               ] {lambda}
 `5/%$$a:                                         {store STDIN char (mod 5) to a}
         4<&                                      {is 0<a<4?}
            [  ][  ]?                             {conditional}
             1$                                     {if so, push 2 1's}
                 1_                                 {otherwise, push -1}
                                                    {determines whether to output in reverse or not}
                     \1-                          {swap, -1}
                        [   ][                ]#  {while loop}
                         $;$                        {if there is a char at index}
                              ,                     {output that char}
                               ^+                   {increment/decrement index}
                                 a;2>               {check if a>2}
                                     [    ][]?      {conditional}
                                      '\n,          {if so, output newline}
\$\endgroup\$
1
\$\begingroup\$

Seriously, 41 bytes

,' 9uc#;+"? R #'{}j #R'{}j"fs,"><v^"í@E£ƒ

Takes the string as the first input and the direction (><v^) as the second input.

Try it online!

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

D, 198 bytes

import std.stdio,std.array,std.algorithm;void main(string[]a){auto x=a[2].split("");char[]y;if(canFind(["^","<"],a[1]))x.reverse;if(canFind(["v","^"],a[1]))y=x.join("\n");else y=x.join("");y.write;}

:c


Less golfed:

import std.stdio;
import std.array;
import std.algorithm;

void main(string[]a) {

  auto x=a[2].split("");
  string y;

  if(canFind(["^","<"],a[1]))
    x.reverse;

  if(canFind(["v","^"], a[1]))
    y=join(x,"\n");

  else
    y=join(x,"");

  y.write;
}
\$\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.