ASCII艺术反射


26

在此挑战中,将为您提供一个文本块,并且您需要对文本进行反射。

输入:

  1. 要反映的字符串。文本不能作为其元素为文本行的数组提供。例如,"ab\ncd"并且['a','b','\n','c','d']是允许的,但['ab','cd']还是[['a','b'],['c','d']]没有。您可以假定所有行都具有相同数量的字符(在需要时用空格填充)。
  2. 一个布尔值,其中True指示Y反射并False指示X反射

这两个输入可以任何顺序传递。

输出:

反映的字符串。字符不会改变,只会改变位置。生成的图像块应与左上角对齐(第一行和第一列必须分别包含非空格字符)。允许尾随空格(在任何行上)。

测试用例:

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

这是一个,所以用您喜欢的语言回答最短!


2
我们可以采用任何格式的布尔值(例如10)还是必须使用TrueFalse
TuxCrafting '16

5
不允许将每一行放置在数组中对于某些语言,如果它们不允许多行字符串,这将是唯一的方法
Luis Mendo

7
@LuisMendo如果语言的自然字符串表示形式不能包含\nI,那么我会说这不是字符串表示形式。
致命

2
您能否澄清一下布尔输入?我是否可以选择任意两个值(其中一个是false,另一个是true),并使我的程序可以使用这些值?还是应该我的程序处理所有 falsey值的一种方式和所有 truthy值的其他方式?
林恩

2
同样,很多答案似乎都假设输入是矩形的(所有行都使用空格填充为相同的长度)。这样的假设可以吗?无论哪种方式,您都应该在问题中加以澄清。
林恩

Answers:


11

C#,168 144 141 120个字节

using System.Linq;i=>y=>string.Join("\n",y?i.Split('\n').Reverse():i.Split('\n').Select(x=>string.Concat(x.Reverse())));

新版本使用明显的字符串.Join重载需要一个IEnumerable,第一个解决方案是无意中使用了它,我也能够将其用于三元组的另一端。

更新:

新版本是匿名lambda,使用curring总共节省了21个字节。这会将用法更改为f("text")(false)f是匿名函数。

取消高尔夫:

using System.Linq;

//Using currying to save one byte
input => IsYReflect =>
         //Lambda makes return implicit
         string.Join("\n", IsYReflect
            //Y Reflect, just need to reverse the array
            ? input.Split('\n').Reverse()
            //X Reflect, reverse each line into an IEnumerable
            : input.Split('\n').Select(x => string.Concat(x.Reverse())));

斯科特·凯伊(Scott Kaye)留下了一条评论,此评论已被删除,这触发了我尝试一些新事物并删除了24个字节。
JustinM-恢复莫妮卡

C#6表达式身体函数可再保存3个字节
JustinM-恢复莫妮卡

10

Pyke,7个字节

!I_)ncX

在这里尝试!

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

9

Brainfuck,143个 140 131字节

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

小号 C#。

对于Brainfuck来说,挑战很容易,而且我显然已经累了,只好去做。

0x00在输入的开头将布尔值当作(虚假的)或任何其他(真实的)字节,然后是一个矩形填充的字符串。

为Y翻转输出尾随换行符,为X翻转输出尾随换行符。

需要一个解释器,该解释器支持开头左侧的存储位置(不确定是否仍然需要),并将EOF表示为0x00。一个这样的翻译在这里。因此,显然不支持输入中的空字节。

代码中有很多带有10 +或的块-;这些可能可以减少。

评论版本

, 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
    ]
]
,[ loop thru any input left
    ---------- subtract newline
    >+ set flag
    < go back to char
    [ was not newline
        ++++++++++ add newline back
        > 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
            . 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
    . print this cell
    < go to previous cell
]

6

32位x86机器代码,76字节

十六进制:

31c031c9495789f7fcf2aef7d15192b00a89f7f2ae5829f7f7f787f95f4b89c3741287d94b534b8a041eaa75f95b01dea4e2f2c348f7e101c6b00a5651f3a4595e29ce4f4b0f44c3aa75f0c3

输入::EBX方向标志(0/1),:ESI输入字符串,EDI:输出缓冲区。输入必须为矩形。

0:  31 c0               xor eax,eax         ;EAX=0
2:  31 c9               xor ecx,ecx         
4:  49                  dec ecx             ;ECX=(uint)-1
5:  57                  push edi            
6:  89 f7               mov edi,esi         
8:  fc                  cld                 
9:  f2 ae               repne scasb         ;Scan input string for terminating NULL
b:  f7 d1               not ecx             ;ECX==<input string length (including NULL)>
d:  51                  push ecx            
e:  92                  xchg edx,eax        ;EDX=0
f:  b0 0a               mov al,0x0a         ;'\n'
11: 89 f7               mov edi,esi         
13: f2 ae               repne scasb         ;Scan input string for the first newline
15: 58                  pop eax             ;EAX==<input string length (including NULL)>
16: 29 f7               sub edi,esi         ;EDI==<single line length (including '\n')>
18: f7 f7               div edi             ;EAX==<# of lines>
1a: 87 f9               xchg ecx,edi        ;ECX=EDI
1c: 5f                  pop edi             ;EDI=<dest buffer>
1d: 4b                  dec ebx             ;Test input flag (0/1)
1e: 89 c3               mov ebx,eax         ;EBX=<# of lines>
20: 74 12               je _vertical        
22: 87 d9               xchg ecx,ebx        ;Horisontal flip, exchange ECX & EBX so we can use LOOP
24: 4b                  dec ebx             ;EBX=<single line length (excluding '\n')>
_hfouter:
25: 53                  push ebx            
_hfinner:
26: 4b                  dec ebx             ;Decrement inner loop counter
27: 8a 04 1e            mov al,[esi+ebx]    ;AL=ESI[EBX]
2a: aa                  stosb               ;*EDI++=AL
2b: 75 f9               jne _hfinner        ;EBX==0 => break
2d: 5b                  pop ebx             
2e: 01 de               add esi,ebx         ;*ESI=='\n' (\0 on the last line)
30: a4                  movsb               ;*EDI++=*ESI++, ESI now points to the next line
31: e2 f2               loop _hfouter       ;--ECX==0 => break
33: c3                  ret                 ;Nothing more to do here
_vertical:
34: 48                  dec eax             ;# of strings less one
35: f7 e1               mul ecx             ;Line length (including '\n')
37: 01 c6               add esi,eax         ;ESI+=ECX*(EAX-1), ESI now points to the beginning of the last line
39: b0 0a               mov al,0x0a         ;'\n'
_vfloop:
3b: 56                  push esi            
3c: 51                  push ecx            
3d: f3 a4               rep movsb           ;Copy the whole line to the output including newline/NULL at the end
3f: 59                  pop ecx             
40: 5e                  pop esi             
41: 29 ce               sub esi,ecx         ;Set ESI to the beginning of the previous line
43: 4f                  dec edi             ;*EDI=='\n' (0 on the first iteration), should overwrite it with correct value
44: 4b                  dec ebx             ;Decrement loop counter
45: 0f 44 c3            cmove eax,ebx       ;if (EBX==0) EAX=EBX, this clears EAX on the last iteration
48: aa                  stosb               ;*EDI++=EBX?'\n':0
49: 75 f0               jne _vfloop         ;EBX==0 => break
4b: c3                  ret                 

5

Haskell,51 49 45字节

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

用法示例:

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

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

拆分成几行,或者反转行(True)或反转每行(False),然后再次加入单个字符串。在一个情况下True输入,map r:[r|b]是两个函数的列表[<reverse each line>, <reverse lines>]和用于False与一个函数输入的列表[<reverse each line>]last选择此列表的最后一个元素。



4

Python,56个字节

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

用字符串s和任何true / falsey值调用r


那样行不通。您的程序必须采用任何真实值,也可以仅True采用1。您不能将输入限制为02
mbomb007 '16

是的,我没想好答案。@ mbomb007在这里是正确的,它需要为您的语言提供任何真假值。
内森·美林

@NathanMerrill仅供参考,您可以避免输入3字节的答案,例如说输入不应编码任何其他信息。这本可以提供第二个答案(我认为这很聪明),但是当然,您希望看到的内容取决于您。
FryAmTheEggman'7

此答案是无效根据OP作为它输出测试用例#当它应该代替地输出什么是在后对于测试用例给出1(即空间填充到所述第一线的长度)。
R. Kap

4

Python 3.5,61个字节:

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

一个简单的匿名lambda函数,它假定输入矩形。通过首先命名函数,然后将其包装在里面来调用它print()。换句话说,如果函数命名H,这样称呼它print(H(<Bool value>, <String>)),在<Bool Value>任何真或假的值(即0/1true/false等),<String>为输入字符串。

在行动中看到它!(代表)

这是另一个具有相同长度的版本,它也假定使用矩形输入,但是这次是一个命名函数,即,您不必先命名它,也不必将其包装在里面print()

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

只需将此称呼为即可J(<Bool Value>,<String>)

在行动中看到这个!(代表)

但是,我不是到此为止的人。尽管允许我们假定矩形输入,但我还创建了一个假定该类型输入的版本。因此,当且仅当<Bool>输入为时False,才会基于最大长度的行将所有行间隔填充为相同的长度,因为只有X反射会导致字符串“翻转”。现在,事不宜迟,以下是正常函数形式的长度为134 129字节的非矩形假定版本:

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')]))

看到最后的行动!(代表)


3

MATL,11个字节

10&Ybc2i-&P

在线尝试!

一个输入是多行字符串。由于MATL无法识别\n为换行符,因此应将多行字符串定义为子字符串或单个字符的串联,以及10(对于换行符,将ASCII解释为字符)。MATL中的串联是[... ...][..., ...](逗号是可选的)。因此,例如,输入可以如下(字符串,换行符和另一个字符串的串联):

['first line' 10 'second']

或等效地(单个字符的串联)

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

或(与逗号相同)

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

所述第二输入可以输入1/ 0或等同地T/ Ftrue/ false分别。

说明

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


1
@Fatalize这是因为MATL和MATLAB如何读取输入。每行都是不同的输入
Luis Mendo

2

Brachylog26 24 16字节

t1,?h@nr~@nw|hrw

需要包含字符串和布尔值1或的列表0,例如

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

说明

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

2

Pyth,10个字节

j?Q_.z_M.z

测试套件。

j?Q_.z_M.z  first line evaluated as Q, all other lines as .z
 ?Q         if Q:
   _.z         yield reverse(.z)
      _M.z  else: yield map(reverse, .z)
j           join by newlines

1

Bash +常见的Linux utils,16

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

作为命令行参数传递的布尔值(零或非零)。通过STDIN / STDOUT的文本块的I / O。假定所有行的长度都相同,如注释所示


1

C(Ansi),193字节

打高尔夫球:

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));}

取消高尔夫:

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));
}

用法:

编译参数:

gcc -O3 -ansi

输入示例:

输入为true或不等于t的false,后跟一个新的空格和结尾的字符串。

./reverseString t "
truck
ducky
quack
moose
"

示例输出:

moose
quack
ducky
truck

1

JavaScript(ES 6)83字节

(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  
  /|--
   |  
  \ / "

f(c,0)尝试时,我会看到不同的输出-可能您c的正确位置没有所有空格。
尼尔

第一个“ o /”后面的空白是否有意义?
Peter Mortensen

@PeterMortensen&Neil:我很确定那是我的复制粘贴。javascript控制台将您的开头“放在第一行上,并使所有内容看起来都很糟糕,因此我在此处粘贴时对其进行了格式化。很有可能我也遇到了一个错误。”
Charlie Wynn


1

J,29个字节

}:@,@(,.&LF@{|."1,:|.)>@cutLF

LHS输入是布尔值,其中0为false,1为true。RHS是字符串输入。


1

JavaScript(ES6),76

s=>b=>(s=s.split`
`,b?s.reverse():s.map(r=>[...r].reverse().join``)).join`
`

F=s=>b=>(s=s.split`
`,b?s.reverse():s.map(r=>[...r].reverse().join``)).join`
`

function test()
{
  var rows=I.value, r
  
  // Trim trailing newlines, pad to blank
  rows=rows.split('\n')
  while(!(r=rows.pop()));
  rows.push(r)
  var maxlen=Math.max(...rows.map(r=>r.length))
  rows=rows.map(r=>r+' '.repeat(maxlen-r.length)).join`\n`

  var t1=F(rows)(false)
  var t2=F(rows)(true)
  
  O.textContent = 'False\n'+t1+'\n\nTrue\n'+t2
}

test()
#I { width:50%; height:10em }
<textarea id=I>
  o /
--|/
  |
 / \
</textarea>  
<button onclick=test()>Go</button>
<pre id=O></pre>


1

Java 99字节

public String[] reverse(String[]a){
  int i=-1,j=a.length;
  for(;++i<--j;){
    String b=a[i];
    a[i]=a[j];
    a[j]=b;
  }
  return a;
}

打高尔夫球:

String[] e(String[]a){int i=-1,j=a.length;for(;++i<--j;){String b=a[i];a[i]=a[j];a[j]=b;}return a;}

1

Perl,35个字节

34个字节的代码+ 1 for -n

要求输入行用空格填充。@ Dada节省了13(!)个字节。

print/T/?reverse<>:map~~reverse,<>

用法

perl -ne 'print/T/?reverse<>:map~~reverse,<>' <<< 'False
  o /
--|/ 
  |  
 / \ '

/ o  
 /|--
  |  
 \ / 

 perl -ne 'print/T/?reverse<>:map~~reverse,<>' <<< 'True
  o /
--|/ 
  |  
 / \ '
 / \ 
  |  
--|/ 
  o /

1
perl -ne 'print/T/?reverse<>:map~~reverse,<>'应该为您节省13个字节:-)
Dada

@Dada确实是一个很大的节省!不知道为什么我不会这样做,但是我会更新的,谢谢!
Dom Hastings

0

Mathematica,70个字节

If[#,Reverse,StringReverse]@ImportString[#2,l="Lines"]~ExportString~l&

匿名函数,将布尔值作为第一个参数(显式TrueFalse在Mathematica中),将(多行)字符串作为第二个参数。将字符串作为与多行字符串的行相对应的字符串列表导入(该字符串不会作为数组传递给函数)。如果为True,则反转列表。如果False StringReverse列表,则自动依次将其应用于每个元素。然后将列表导出为字符串,其中每个元素都是新行。


0

05AB1E,10个字节

U|XiRë€R}»

说明

U          Remove the first input line and store it in variable X
 |         Aggregate the rest of the input into an array
  XiR      If x is true, revert the array
     ë€R   Else revert each element
        }  End if
         » Join everything with newlines and implicitly display

在线尝试!


0

Vim,33个字节

将先前的V答案更改为Vim。任何V答案都会大相径庭,所以这并不公平。

DgJ:if@"
g/^/m0
el
se ri
en
cG"

在线尝试!

十六进制转储

00000000: 4467 4a3a 6966 4022 0a67 2f5e 2f6d 300a  DgJ:if@".g/^/m0.
00000010: 656c 0a73 6520 7269 0a65 6e0a 6347 1222  el.se ri.en.cG."
00000020: 08                                       .

您可能可以通过此映射
DJMcMayhem
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.