将标签分成两半


31

圣战已经在空间与标签之间展开。(当然还有赢得客观上的优势的空间。)— Alex A.

小号青梅PEO p文件仍然拒绝一个 ccept该 WHI Ç h是CL Ë阿尔利 š upreme。你刚刚收到 一个使用INCOR文件重新克拉,b广告,和INF ē的WHI rior形式牛逼协商,现在牛逼他续Ë一个文件的NTS [R Ë污染和破坏。

您决定还可以向发送文件的人显示他们的错误程度。

描述

顾名思义,您面临的挑战是获取一个包含一个或多个标签的文件:

this is an evil tab    onoes

无情地将它们粉碎成碎片:

this is an evil tab

                     o
                     n
                     o
                     e
                     s

请注意,Stack Exchange软件将文字选项卡转换为四个空格(因为它是正确的),因此本文中的选项卡将显示为四个空格。但是,程序的输入将包含实际的选项卡。

挑战

解决方案应采用单个字符串作为输入,其中可能包含可打印的ASCII,换行符和制表符。输入中将始终至少有一个选项卡。

输出应为相同的字符串,并应用以下规则:

  • 在坐标(0,0)处并向右方向启动光标。坐标是(列,行),零索引,方向是打印字符后应移动光标的方向。

  • 对于字符串中的每个字符:

    • 如果是换行符,请移至坐标(0,n),其中n是到目前为止字符串中的换行符数目(包括该行),然后将方向重置为右。

    • 如果是选项卡,则输出两个空格,将光标方向顺时针旋转90度,然后再输出两个空格,从而有效地将选项卡“分成两半”。这是一个可视示例,其中选项卡表示为--->,空格表示为·

      foo--->bar--->baz
      

      变成

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • 否则,只需在光标处输出字符,然后将光标向当前方向移动一步。

由于您是从头到尾读取字符串的,因此您可能必须在现有字符的“顶部”书写—可以。例如,输入

foo--->bar


spaces are superior

应该导致输出

foo

     b
spaces are superior
     r

您可以选择是否使用“残破的标签”覆盖其他字符-最初的目的是不要覆盖其他字符,但是规范不明确,因此这是您的决定。

此外,应用这些规则后,您还可以

  • 添加或删除任意数量的尾随空格。

  • 最多添加一个尾随换行符。

输入将永远不会包含尾随空格;它也绝不会包含前导或尾随的换行符。您可能还始终假设您永远不需要写小于0的列或行(即不在屏幕上)。

测试用例

此测试用例中的选项卡表示为,--->因为否则SE会将它们吞噬。

输入:

Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah

输出:

Test case. Here's a tab
blah
blah                     t
blah blah blah blah blah blah
                        blaablah
                         r     b
                         e     l  b
                      h  'h    a  l
                      a  sa    a  a
                      l   l    h  h
       this is some mobe tbxt

                         haalhalb
     b                   a
     a                   b
     t

        bat a erehwyreve

花式动画:

规则


当您说光标必须开始于时(0,0),您是说我们需要首先清除控制台,还是只不过是指光标的默认位置?
马丁·恩德

18
我投票结束这个题为离题的问题,因为它充满了仇恨和亵渎。
aditsu

1
您的动画看起来非常像> <>解释器,我现在想看到一个自我修改的> <>条目。
Sanchises

1
我喜欢开篇中的隐藏消息,但我不同意。
wf4

@MartinBüttner这只是默认位置。
门把手

Answers:


8

MATLAB,144字节

处理字符串的首选武器当然是一种用于操纵数字的语言[需要引用]。顺便说一句,Matlab的妙处在于它不在乎是否将数组分配给“边界”:它只会生成一个更大的矩阵。此外,默认的矩阵元素0呈现为空格而不是null ASCII规范规定字符。

制表符只是坐标的跳跃,因此制表符不会输出空格。

function o=q(t)
u=2;v=0;x=1;y=1;n=1;for s=t
if s==9 x=x+u-v;y=y+v+u;a=v;v=u;u=-a;elseif s<11
n=n+1;x=1;y=n;else
o(y,x)=s;x=x+u/2;y=y+v/2;end
end

我从209字节开始,但是大部分打高尔夫球都消除了其中的大部分。这段代码中有很多重复,所以我做了一些反复试验,哪种方法效果最好。我认为此代码没有太多空间进行更多优化,但是我总是很高兴被证明是错误的。编辑:汤姆·卡彭特(Tom Carpenter)设法证明我错了;他设法节省了9个字节,而我优化后节省了29个字节。假设输入中没有控制字符(ASCII <9),则保存的最后一个字节-MATLAB字符串不null终止。


似乎不起作用。我试过了q('hello<tab>my name<tab>is tom<tab>c'),但是有点像Attempted to access o(11,-2); on line 7。尽管这可能与问题中的一个问题有关-如果光标向后移动并超出了第一列,则行的其余部分会发生什么。
汤姆·卡彭特

是的,我不好,我错过了这一点。我现在就走了;)
汤姆·卡彭特

1
您可以通过删除d变量来代替另存4个变量,以保留另外9个字符,这样循环就可以使[1 0 -1 0]模式变成这样:(function o=q(t) u=1;v=0;w=-1;z=0;x=0;y=1;n=1;for s=t if s==9 x=x+2*u-2*v;y=y+2*v+2*u;a=z;z=w;w=v;v=u;u=a;elseif s==10 n=n+1;x=0;y=n;else x=x+u;y=y+v;o(y,x)=s;end end 显然,在注释中它删除了所有行,因此像您一样重新格式化,看看我做了什么)
Tom Carpenter

@TomCarpenter真是太丑了。我喜欢它。
Sanchises

5

Python 3中,272个 270 266 262 255 253 244字节

I=[]
try:
 while 1:I+=[input()]
except:r=m=0
M=sum(map(len,I))
O=[M*[' ']for _ in[0]*M]
for l in I:
 x=b=0;y=r;a=1;r+=1
 for c in l:
  if'\t'==c:a,b=-b,a;x+=a+2*b;y+=b-2*a
  else:O[y][x]=c
  x+=a;y+=b;m=max(m,y)
for l in O[:m+1]:print(*l,sep='')

\t应是一个实际的制表符。

该代码的工作方式类似于Zach Gates的答案,首先生成一个MbyM网格,其中M x是线的长度之和。(这是一个很大的数量,但会使代码更短。)然后,它循环遍历字符,将它们放置在正确的位置,并跟踪最底部的访问行。最后,它打印到该行的所有行。

输出包含(通常是大量的)尾随空格和1个尾随换行符。


3

Javascript(ES6),264 245字节

尝试了“创建巨大的空格,填充和修剪网格”方法,该方法最终比其他方法缩短了19个字节。

a=t=>(o=`${' '.repeat(l=t.length)}
`.repeat(l).split`
`.map(q=>q.split``),d=x=y=z=0,s=c=>o[d>2?y--:d==1?y++:y][d?d==2?x--:x:x++]=c,[...t].map(c=>c=='\t'?(s` `,s` `,++d,d%=4,s` `,s` `):c==`
`?(x=d=0,y=++z):s(c)),o.map(p=>p.join``).join`
`.trim())

通过像这样修改倒数第二行,可以删除每行上的大量尾随空格:

...o.map(p=>p.join``.trimRight())...

在这里尝试:

解释即将到来;建议欢迎!


3

的JavaScript(ES6),180 183

使用模板字符串,有些重要的换行符很重要。

这是一个返回请求输出的函数(用大量尾随空格填充)

几乎没有什么可解释的:行是根据需要构建的。没有方向变量,只有x和y的2个偏移量,因为在顺时针旋转中它们很容易管理:dx <= -dy, dy <= dx

测试在Firefox中运行以下代码段

f=s=>[...s].map(c=>c<`
`?(x+=2*(d-e),y+=2*(e+d),[d,e]=[-e,d]):c<' '?(y=++r,e=x=0,d=1):(t=[...(o[y]||'')+' '.repeat(x)],t[x]=c,o[y]=t.join``,x+=d,y+=e),o=[r=x=y=e=0],d=1)&&o.join`
`

// TEST  

// Avoid evil tabs even in this source 
O.innerHTML = f(`Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah`
 .replace(/--->/g,'\t'))
<pre id=O></pre>


我希望所有语言都具有[x,y] = [expr1,expr2] ...
Sanchises

1

Python 2中,370个 369 368字节

感谢@sanchises@ edc65分别为我节省了一个字节。

J=''.join
u=raw_input().replace('\t','  \t  ')
w=u[:]
G=range(len(u))
d,r=0,[[' 'for _ in G]for _ in G]
u=u.split('\n')
for t in G:
 x,y=0,0+t
 for c in u[t]:
  if c=='\t':d=(d+1)%4
  if c!='\t':
   if c.strip():r[y][x]=c
   if d<1:x+=1
   if d==1:y+=1
   if d==2:x-=1
   if d>2:y-=1
r=r[:max(i for i,n in enumerate(r)if J(n).strip())+1]
for i in r:print J(i).rstrip()

它会生成最大的网格,然后在每个选项卡上逐个字符地循环切换方向。


提示:if !dif d>2
Sanchises

!d是无效的语法。@sanchises不过,感谢您的d>2提示。
扎克·盖茨

抱歉,我实际上并不了解python :)只是假设它会那样工作。
Sanchises

我也不太理解python,但是如果d在0 ... 3,d==0->d<1
edc65

是的,你是对的。感谢您的字节。@ edc65
扎克·盖茨
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.