Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
    
Full code or function? – Alex L. Feb 27 at 22:37
1  
@AlexL. You can write either afaik – Downgoat Feb 27 at 22:38
    
@Downgoat Okay thanks. – Alex L. Feb 27 at 22:39
    
Is input all as one string OK? >ABC – Digital Trauma Feb 27 at 22:56
    
@DigitalTrauma Yes, that's fine. – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 27 at 23:13

21 Answers 21

up vote 14 down vote accepted

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
share|improve this answer
1  
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). – Martin Ender Feb 27 at 20:01
    
@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! – Luis Mendo Feb 27 at 20:15
6  
4 bytes shorter, what on earth... – Martin Ender Feb 27 at 20:17
2  
I am officially putting MATL on the "list of language that are insanely short." – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 27 at 20:23

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])
share|improve this answer
    
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.) – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 27 at 20:09
    
@CᴏɴᴏʀO'Bʀɪᴇɴ: thanks :) – vaultah Feb 27 at 20:18
    
Maybe s[1|-(c in'<^')] and sep='\n'*(c in'^v') – Lynn Feb 27 at 22:33
    
I think you could do the whole thing as a lambda if you use join with your sep rather than printing. – xnor Feb 27 at 22:48
1  
I love this answer, this is my favourite answer. – cat Feb 29 at 22:05

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

share|improve this answer

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.
share|improve this answer
    
o_o nice job! You outgolfed jolf by over 200% o_O – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 27 at 21:42
    
But I'm getting errors? Error: Japt.stdout must be sent to an HTMLElement etc. – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 27 at 21:43
    
@CᴏɴᴏʀO'Bʀɪᴇɴ Not sure why that happens, but it happens a lot >:( Reloading always fixes this for me. – ETHproductions Feb 27 at 21:46
    
Sure enough, the issue is fixed. I am impressed! – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 27 at 21:47
    
I knew those rotate functions would eventually be useful +1 – Downgoat Feb 27 at 22:32

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.
share|improve this answer

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.

share|improve this answer

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

share|improve this answer

Bash + GNU Utilities, 67

(egrep -q '>|v'<<<$1&&cat||rev)|(egrep -q '<|>'<<<$1&&cat||fold -1)
share|improve this answer
    
I wouldn't have guessed you need a space after the -q's, but you do – cat Feb 29 at 22:17

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.

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

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
share|improve this answer

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
share|improve this answer

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!

share|improve this answer

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.

share|improve this answer
    
retina.tryitonline.net/… saves a byte (and gets rid of the additional trailing linefeed) – Martin Ender Feb 28 at 0:29

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

share|improve this answer

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
share|improve this answer

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!

share|improve this answer
    
f("v","abc") returns c\nb\na for me. – ETHproductions Feb 27 at 21:52
    
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)] – ETHproductions Feb 27 at 21:55
    
@ETHproductions Thanks! I forgot c is literally d. – Cᴏɴᴏʀ O'Bʀɪᴇɴ Feb 27 at 21:58
    
Out of interest I tried indexing an object... and it turned out to be exactly the same length! – Neil Feb 28 at 1:00

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>

share|improve this answer

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.

share|improve this answer

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}
share|improve this answer

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!

share|improve this answer

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;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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