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

In this challenge, you will be given a text block, and you need to perform reflection on the text.

Input:

  1. A string to be reflected. The text may not be supplied as an array whose elements are the lines of text. For example, "ab\ncd" and ['a','b','\n','c','d'] are allowed, but ['ab','cd'] or [['a','b'],['c','d']] are not. You can assume that all of the lines have the same number of characters (padded with whitespace where needed).
  2. A boolean where True indicates Y reflection and False indicates X reflection

The two inputs can be passed in any order.

Output:

The reflected string. The characters do not change, only their position. The resulting image block should be aligned to the top right (the first row and column must each contain a non-whitespace character). Trailing whitespace (on any of the lines) is allowed.

Test cases:

False
  o /
--|/
  |
 / \

/ o
 /|--
  |
 \ /

True
  o /
--|/
  |
 / \

 / \
  |
--|/
  o /

True
text

text

False
text

txet

True
P
P
C
G

G
C
P
P

False
P
P
C
G

P
P
C
G

True
abcde
fghij
kl mn
opqrs
tuvwx

tuvwx
opqrs
kl mn
fghij
abcde

This is a , so answer with the shortest answer in your favorite language!

share|improve this question
2  
Can we take the boolean in any format (eg. 1 and 0) or we must use True and False? – TùxCräftîñg 7 hours ago
1  
Putting each line in an array is not allowed For some languages that would be the only way, if they don't allow multiline strings – Luis Mendo 7 hours ago
2  
@LuisMendo If a language natural string representation can't contain an \n I would go as far as to say that it's not a string representation. – Fatalize 7 hours ago
1  
So i'm confused, doesn't that Array rule disallow any use of string splitting? – Phaeze 6 hours ago
1  
Can you clarify the boolean input a bit? Do I get to pick any two values, one of which is falsey and the other of which is truthy, and make my program work with those; or should my program handle all falsey values one way and all truthy values the other way? – Lynn 6 hours ago

13 Answers 13

Pyke, 7 bytes

!I_)ncX

Try it here!

!I )    - if not boolean:
  _     -  input = reversed(input)
    nc  - input.split("\n")
      X - splat(input)
        -  (print lines backwards)
share|improve this answer

C#, 168 Bytes

using System.Linq;string r(string i,bool y){var a=i.Split('\n');return y?string.Join("\n",a.Reverse()):a.Aggregate("",(c,n)=>c+new string(n.Reverse().ToArray())+"\n");}

Ungolfed:

using System.Linq;

string Reverse(string input, bool IsYReflect)
{
    var array = input.Split('\n');
    return IsYReflect
     //Y Reflect, just reverse the array and return it as a new string
     ? string.Join("\n" ,array.Reverse()) 
     //X Reflect, reverse each individual line and use aggregate to join and add new lines, aggregate saves one character over string.join
     : array.Aggregate("", (current, next) => current + new string(next.Reverse().ToArray()) + "\n"); 
}
share|improve this answer
    
A feel a little bad that this is basically the same as my only other answer on this site... – Phaeze 6 hours ago

MATL, 11 bytes

10&Ybc2i-&P

Try it online!

The first input is the multiline string. Since MATL doesn't recognize \n as linefeed, the multiline string should be defined as a concatenation of substrings, or individual characters, and 10 (ASCII for line feed, which is interpreted as a character). Concatenation in MATL is [... ...] or [..., ...] (commas are optional). So for example, input can be as follows (concatenation of a string, linefeed, and another string):

['first line' 10 'second']

or equivalently (concatenation of individual characters)

['f' 'i' 'r' 's' 't' ' ' 'l' 'i' 'n' 'e' 10 's' 'e' 'c' 'o' 'n' 'd']

or (same with commas)

['f', 'i', 'r', 's', 't', ' ', 'l', 'i', 'n', 'e', 10, 's', 'e', 'c', 'o', 'n', 'd']

The second input can be entered as 1/0 or equivalently as T/F for true/false respectively.

Explanation

10     % Push 10 (ASCII for linefeed)
&Yb    % Take input string implicitly. Split at linefeeds. Gives a cell array
c      % Convert to a 2D char array, right-padding with spaces
i~Q    % Input Boolean value. Negate and add 1. Gives 1/2 for true/false resp.
&P     % Flip along that dimension (1: vertically; 2: horizontally). Display implicitly
share|improve this answer
    
1  
@Fatalize It's because of how MATL and MATLAB read the input. Each line is a different input – Luis Mendo 6 hours ago

Haskell, 51 49 45 bytes

r=reverse
f b=unlines.last(map r:[r|b]).lines

Usage example:

f True "abc\ndef\nghi\njkl"
"jkl\nghi\ndef\nabc\n"

f False "abc\ndef\nghi\njkl"
"cba\nfed\nihg\nlkj\n"

Split into lines, either reverse the lines (True) or reverse each line (False) and join into a single string again. In case of a True input, map r:[r|b] is a list of two functions [<reverse each line>, <reverse lines>] and for a False input a list with one function [<reverse each line>]. last picks the last element of this list.

share|improve this answer

Jelly, 8 bytes

ṣ⁷ṚU⁴?j⁷

Try it here.

ṣ⁷         Split over newlines.
  ṚU⁴?     If ⁴ (2nd argument), then Ṛ (reverse rank ∞), else U (reverse rank 1).
      j⁷   Join with newlines.
share|improve this answer
1  
Could you add an explanation? – Loovjo 3 hours ago

Brachylog, 26 24 16 bytes

t1,?h@nr~@nw|hrw

Expects a list containing the string and the boolean 1 or 0, e.g.

run_from_file('code.bl',["P
|    P
|    C
|    G":1]).

Explanation

t1,              If the tail of the input is 1
   ?h@n              Split the string on \n
       r             Reverse the resulting list
        ~@n          Join the list of strings with \n
           w         Write to STDOUT
|                Or
hr                   Reverse the string
  w                  Write to STDOUT
share|improve this answer

Python, 56 bytes

lambda s,r:'\n'.join(s[::2*bool(r)-1].split('\n')[::-1])

Call with a string s and any truthy/falsey value r.

share|improve this answer
    
It doesn't work that way. Your program has to either take any truthy value, or take only True, which could also be 1. You cannot restrict input to be only 0 or 2. – mbomb007 5 hours ago
    
Yeah, I didn't think through my answer. @mbomb007 is correct here, it needs to work for any truthy/falsy value for your language. – Nathan Merrill 4 hours ago
    
@NathanMerrill Just an FYI, you can avoid stuff like the 3 byte answer by saying that the input should not encode any additional information. This would have allowed the second answer (which I thought was rather clever), but of course what you would like to see is up to you. – FryAmTheEggman 4 hours ago
    
This answer is invalid according to OP as it outputs this for test case # 1 when it should instead be outputting what is given in the post for that test case (i.e. space padded to the length of the first line). – R. Kap 3 hours ago

Pyth, 10 bytes

j?Q_.z_M.z

Test suite.

share|improve this answer

Python 3.5, 61 bytes:

lambda f,j:[print(r[::-1])for r in j[::[1,-1][f]].split('\n')]

A simple anonymous lambda function that assumes rectangular input. Call it by by first naming the function, and then calling it wrapped inside print(). In other words, if the function were named H, call it like print(H(<Bool value>, <String>)), where <Bool Value> is any true or false value (i.e. 0/1, true/false, etc.) and <String> is the input string.

See it in Action! (repl.it)

Here is another version with the same length that also assumes rectangular input, but this time a named function, i.e. you don't have to name it first nor wrap it inside print():

def J(f,j):[print(r[::-1])for r in j[::[1,-1][f]].split('\n')]

Simply call this one likeJ(<Bool Value>,<String>).

See this in Action! (repl.it)

However, I'm not the one to stop there. Although we are allowed to assume rectangular input, I also created a version that does not assume that type of input. Therefore, it will space-pad all of the lines to the same length based on the line with the maximum length if and only if the <Bool> input is False, as only a X-reflection will result in the string being "flipped". Now, without further ado, here is the non-rectangular assuming version with a length of 134 129 bytes in the form of a normal function:

def J(f,j):print('\n'.join([' '*((max([len(i)for i in j.split('\n')])-len(r))*(not f))+r[::-1]for r in j[::[1,-1][f]].split('\n')]))

See this Last One in Action! (repl.it)

share|improve this answer

Bash + common linux utils, 16

(($1))&&tac||rev

Boolean value (zero or non-zero) passed as a command-line parameter. I/O of text block via STDIN/STDOUT. Assumes that all lines are the same length, as indicated in the comments.

share|improve this answer

Brainfuck, 143 bytes

,[,[---------->+<[>-]>[->]<,]<[[<]>[++++++++++.>]++++++++++.<[<]<]]-[,[---------->+<[>-]>[-<<[++++++++++.<]++++++++++.[>]>>]<,]<[++++++++++.<]]

Beats C#.

The challenge was easy enough for Brainfuck, and I apparently was tired enough to just have to do it.

Takes the boolean as a 0x00 (falsy) or any other (truthy) byte in the start of the input, then a rectangle-padded string.

Outputs a trailing newline for the Y flip, and none for the X flip.

Requires an interpreter that supports memory locations to the left of the start (unsure if still required) and gives EOF as 0x00. One such interpreter is here. Obviously doesn't support null bytes in the input because of that.

The code has a lot of blocks with 10 +'s or -'s; those can probably be reduced.

Commented version

, get mode
[ check truthy input
    ,[ loop thru input
        ---------- subtract newline
        >+ set flag
        < go back to char
        [ was not newline
            > move to flag
            - reset flag
        ]
        > move to flag or one past flag
        [ hit flag; was newline
            - reset flag
            > skip a cell
        ]
        < go to next position
        , read next input
    ]
    < find end of line
    [ loop thru lines
        [<]> find start of line
        [ loop thru line
            ++++++++++ add newline back
            . print this cell
            > go to next cell
        ]
        ++++++++++ change to newline
        . print newline
        <[<]< find end of previous line
    ]
]
- flip flag
[ flag was set; input falsy
    ,[ loop thru input
        ---------- subtract newline
        >+ set flag
        < go back to char
        [ was not newline
            > move to flag
            - reset flag
        ]
        > move to flag or one past flag
        [ hit flag; was newline
            - clear flag
            < go back to char
            < go back to line chars
            [ loop thru line
                ++++++++++ add newline back
                . print this cell
                < go to previous cell
            ]
            ++++++++++. print newline
            [>]>> find empty cell
        ]
        < go to next position
        , read next input
    ]
    < go to line
    [ loop thru line
        ++++++++++ add newline back
        . print this cell
        < go to previous cell
    ]
]
share|improve this answer

C (Ansi), 193 Bytes

Golfed:

i,y,x;main(g,o,p)char**o;{p=(o[1][0]=='t');while(o[2][++i]!='\n');p?y=(strlen(o[2])-1)/i:(x=i);do do printf("%c",o[2][x+y*i]);while(p?++x<i:x-->0);while(p?x=0,y--:++y<(x=i-1,strlen(o[2])/i));}

Ungolfed:

i,y,x;
main(g,o,p)char**o;{
    p=(o[1][0]=='t');
    while(o[2][++i]!='\n'); 
    p?y=(strlen(o[2])-1)/i:(x=i);
    do{
        do{
            printf("%c",o[2][x+y*i]);
        }while(p?++x<i:x-->0);
    }while(p?x=0,y--:++y<(x=i-1,strlen(o[2])/i));
}

Usage:

Compilation Arguments:

gcc -O3 -ansi

Example Input:

Input is a t or not t for true of false followed by a newspace lead and trailed string.

./reverseString t "
truck
ducky
quack
moose
"

Example Output:

moose
quack
ducky
truck
share|improve this answer

JavaScript (ES 6) 83 bytes

(c,b)=>(p=c.split`
`)&&(b?p.reverse():p.map(a=>a.split``.reverse().join``)).join`
`

f=(c,b)=>(p=c.split`
`)&&(b?p.reverse():p.map(a=>a.split``.reverse().join``)).join`
`

f("abcde\nfghij\nkl mn\nopqrs\ntuvwx",1)

c="
  o / 
--|/
  | 
 / \
";

f(c,1)
" / \
   | 
 --|/
   o / "

f(c,0)
"/ o  
  /|--
   |  
  \ / "
share|improve this answer
    
I see a different output for f(c,0) when I try - maybe your c doesn't have all the spaces in the right places. – Neil 3 hours ago
    
Is the trailing white space after the first "o /" significant? – Peter Mortensen 1 hour ago

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.