タブを半分に分割する


31

スペース対タブをめぐって聖戦が繰り広げられてきました。(そしてもちろん、客観的に優れているスペースが勝ちました。)— アレックスA.

S青梅PEO Pルはまだ拒否していることccept WHI のC HがClである電子アルリー upreme。あなただけ受け取った incorを使用してファイルを、CT Bの広告を、そしてINF のE WHIのriorフォームトンエスパス、そして今ではt彼続きのEファイルのNTS のR eは、汚染されたと台無しに。

あなたは、あなたにファイルを送った人に、彼らがどれだけ間違っているかを示すこともできます。

説明

タイトルが示すように、あなたの課題は、1つ以上のタブを含むファイルを取得することです。

this is an evil tab    onoes

そして容赦なくそれらを粉々に砕きます:

this is an evil tab

                     o
                     n
                     o
                     e
                     s

Stack Exchangeソフトウェアはリテラルタブを4つのスペースに変換することに注意してください(正しいため)。この投稿内のタブは4つのスペースとして表示されます。ただし、プログラムへの入力には実際のタブが含まれます。

チャレンジ

ソリューションでは、入力として単一の文字列を使用する必要があります。これには、印刷可能なASCII、改行、およびタブが含まれる場合があります。入力には常に少なくとも1つのタブがあります。

出力は同じ文字列で、次の規則が適用されている必要があります。

  • カーソルを座標(0,0)で右方向に開始します。座標は(列、行)、ゼロインデックス、方向は文字を印刷した後にカーソルを移動する方法です。

  • 文字列の各文字に対して:

    • 改行の場合は、座標(0、n)に移動します(nはこれまでの文字列内の改行の数(これを含む)で、方向を右にリセットします)。

    • タブの場合、2つのスペースを出力し、カーソルの方向を時計回り90度回転し、さらに2つのスペースを出力して、タブを半分に効果的に「分割」します。以下は視覚的な例です。タブはで--->、スペースはで表されます·

      foo--->bar--->baz
      

      になる

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • それ以外の場合は、単にカーソルの位置に文字を出力し、カーソルを現在の方向に1ステップ移動します。

文字列を最初から最後まで読んでいるので、既存の文字の「上」に書く必要がある可能性があります。これは問題ありません。たとえば、入力

foo--->bar


spaces are superior

の出力になるはずです

foo

     b
spaces are superior
     r

「壊れたタブ」が他の文字を上書きするかどうかを選択できます。元々の意図はそれらを上書きしないことでしたが、仕様はあいまいだったので、これはあなたの決定です。

さらに、これらのルールを適用した後、次のこともできます

  • 末尾のスペースを必要な数だけ追加または削除します。

  • 最大で1つの末尾の改行を追加します。

入力に末尾のスペースが含まれることはありません。また、先頭または末尾の改行が含まれることはありません。また、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
この質問は憎悪と冒blに満ちているので、このトピックをオフトピックとして閉じることを投票します。
-aditsu

1
あなたのアニメーションは> <>インタプリタに非常に似ているので、自己修正型の> <>エントリを見たいと思います。
-Sanchises

1
私は冒頭の段落に隠されたメッセージが好きでしたが、私は反対しなければなりません。
wf4

@MartinBüttnerそれは単にデフォルトの位置を意味します。
ドアノブ

回答:


8

MATLAB、144バイト

文字列を扱うための選択の武器は、もちろん数字を操作するために設計された言語です[要出典]。冗談はさておき、Matlabの素晴らしい点は、配列に「境界外」を割り当ててもかまわないことです。単純に大きな行列を作成します。さらに、デフォルトのマトリックス要素が、ASCII仕様で規定されて0いるnull文字ではなくスペースとしてレンダリングされます。

タブは単に座標のジャンプであるため、タブにスペースは出力されません。

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バイトから始めましたが、いくつかのより慎重なゴルフはそのほとんどを取り除きました。このコードには多くの繰り返しがあるので、どの代替案が最も効果的かを試行錯誤しました。このコードを使用して最適化を行う余地はあまりないと思いますが、間違っていることが証明されたことはいつでも嬉しいです。編集:トム・カーペンターはなんとか私が間違っていることを証明した。彼はなんとか29バイトを節約するために最適化した9バイトを節約することができました。入力に制御文字(ASCII <9)がないと仮定して保存された最後のバイトnull-MATLAB 文字列は終了しません。


動作していないようです。私はこれを試しましたq('hello<tab>my name<tab>is tom<tab>c')が、それは何かに沿ったものですAttempted to access o(11,-2); on line 7。これは質問の問題と関係があるかもしれません-カーソルが後方に向かっていて、最初の列を超えた場合、残りの行に何が起こるか。
トムカーペンター

うん、私の悪い私はそのビットを見逃した。今すぐ
トムカーペンター

1
d変数を削除し、代わりにループで[1 0 -1 0]パターンを作成する4つの変数を使用することにより、さらに9文字を保存でき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 ます。私がやったことを見るためにあなたのように再フォーマットする)
トムカーペンター

@TomCarpenterそれは...本当にugいです。大好きです。
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の答えのように機能します。まず、行の長さの合計であるMby Mグリッドを生成Mします。(これは膨大な量ですが、コードは短くなります。)次に、文字をループ処理して正しい場所に配置し、訪問した一番下の行を追跡します。最後に、その行までのすべての行を印刷します。

出力には、(通常は大量の)末尾のスペースと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())

このように最後から2番目の行を変更することにより、すべての行で大量の後続スペースを削除できます。

...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バイト

1バイトずつ節約してくれた@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 !dおよびif d>2
-Sanchises

!d有効な構文ではありません。@sanchises d>2しかし、ヒントをありがとう。
ザック・ゲイツ

申し訳ありませんが、私は実際にPythonを知らない:)それはそのように動作すると仮定しただけです。
-Sanchises

私もPythonを理解していませんが、dが0 ... 3の場合、d==0->d<1
edc65

うん、あなたは正しい。バイトをありがとう。@ edc65
ザック・ゲイツ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.