ホワイトスペースゴルファーを実装する


15

などのいくつかの二次元esolangs、フォークなど、およびいくつかの非esolangs、Pythonは、時々 、コードの行の前にスペースを必要とすることができます。これはあまりゴルフではありません。また、私は怠け者で、コードの前に多くのスペースを必要とする2D言語を書いています。あなたの仕事は、これらの言語をゴルファーにするツールを書くことです。

もちろん、これは完璧ではありません。たとえば、ソースの行の最初の文字が数字の場合は使用できません。ただし、通常は有用です。

チャレンジ

次のいずれかのプログラムまたは関数を作成します...

  • ... 1つの引数、ファイル名または文字列、または...
  • ...標準入力から読み取ります。

あなたのプログラムは次のような動作catをします:

  • 行の最初の文字が数字の場合、コードはx個のスペースを出力します。xはその数字です。
  • それ以外の場合は、単に印刷されます。
  • 入力内の他のすべての文字と同様に。

テストケース

入力:

foo bar foo bar
1foo bar foo bar foo bar
2foo bar foo bar foo bar foo bar

出力:

foo bar foo bar
 foo bar foo bar foo bar
  foo bar foo bar foo bar foo bar

入力:

--------v
8|
8|
80
8,
7&

出力:

--------v
        |
        |
        0
        ,
       &

入力:

foo bar
bar foo
foo bar

出力:

foo bar
bar foo
foo bar

入力:

0123456789
1234567890
2345678901
3456789012
4567890123

出力:

123456789
 234567890
  345678901
   456789012
    567890123

ルール

  • 最初の文字が数字である行を除き、出力は入力とまったく同じでなければなりません。
  • プログラムは、必要に応じて末尾の改行を除いて、ファイルに何かを追加/追加することはできません。
  • あなたのプログラムは、入力に関して何の仮定もしません。空行、数字なし、Unicode文字などを含む場合があります。
  • 1桁以上の数字で行が始まる場合(例523abcdefg:)、最初の数字(この例では5)のみがスペースになります。

勝者

各言語の最短コードが優先されます。楽しさと幸運を!



6
Of course, this will not be perfect; it cannot be used, for instance, when a number is the first character on a line of source.真実ではありません。最初の文字を0にしてください(最後のテストケース)
HyperNeutrino

stdinから文字列のリストを読み取れますか(これは有効ですか?)
ライリー

回答:



10

通常、69バイト

R1B1R3B1~(+50<7?6{+54>7?6{-002+7~?6{(@5*1-1/1)6}}}(-6>7?6&@7+70-4~)6)

オンラインでお試しください!

説明:

まず、この初期化を行います。

R1B1R3B1

このキューブを設定するには:

   533
   004
   000
411223455441
311222331440
311222331440
   555
   555
   200

このキューブについて最も重要なことは、面の5合計が32であるということです。これは、スペースを印刷するために必要な値です。偶然にも、他のすべての計算ではかなり短いものです。それが終わったら:

~( . . . )                                    Takes the first input, then loops indefinitely

  +50<7?6{+54>7?6{-002+7~?6{(@5*1-1/1)6}}}    Handle leading digit:
  +50<7?6{                               }    If input is greater than 47 ('0' is 48)
          +54>7?6{                      }     And input is less than 58 ('9' is 57)
                                              Then input is a digit
                  -002+7                      Set notepad equal to value of input digit
                        ~                     Take next input (only convenient place for it)
                         ?6{           }      If the notepad isn't 0
                            (        )6       While the notepad isn't 0:
                             @5                 Print a space
                               *1-1/1           Decrement the notepad by one
                                              Leading digit handled

     (-6>7?6&@7+70-4~)6                       Handle rest of line:
     (               )6                       While the notepad isn't 0:
      -6>7?6&                                   Exit if End of Input
             @7                                 Print the next character
               +70-4                            Set notepad to 0 if it was a newline
                    ~                           Take the next character

1
うわー、ネストされた...すべての良い使用です。+1
MD XF

6

ハスク15 13バイト

@Zgarbのおかげで-2バイト

mΓo+?oR' i;±¶

オンラインでお試しください!

@Jonathan Allanと同じ手法を使用します

説明

             ¶  -- split input into a list of lines
m               -- apply the following function to each line
 Γ              --   deconstruct the string into a head and a tail
  o+            --   prepend to the tail of the string ...
    ?      ±    --     if the head is a digit (n)
     oR' i      --       the string of n spaces
                --     else
          ;     --       the head of the string
                -- implicitly print list of strings line-by-line

2
使用した13バイトΓ
ズガルブ

5

JavaScript(ES8)、38 37バイト

a=>a.replace(/^\d/gm,a=>''.padEnd(a))

これ以上改善できるとは思いません。Shaggyの
おかげで1バイト節約 -ES8機能を使用。


これ以上改善できるとは思わない。」-ES8を次のpadEndように使用すると、1バイト節約できます。s=>s.replace(/^\d/gm,m=>"".padEnd(m))
Shaggy

@Shaggy。ES8がすでに許可されていることを知りませんでした。ありがとう。

1
機能をサポートするインタープリター(ブラウザなど)が1つしかない場合、その機能はここで公平なゲームです:)
シャギー

4

Pythonの298の 74 67 65バイト

ジョナサンアランのおかげで-24バイト。Xcoder氏のおかげで-7バイト。

for i in open('f'):print' '*int(i[0])+i[1:]if'/'<i[:1]<':'else i,

オンラインでお試しください!

という名前のファイルに入力を取りますf


また、行の最初の文字に数字がない場合(すべての要素が評価されるアイテムを選択する方法としてリストを使用する場合)エラー
ジョナサンアラン


87バイト -TIOリンクのヘッダーはm笑していopenます。コードは「f」という名前のファイルを予期しています。大丈夫だと思う?
ジョナサンアラン

ああ、' '*0本当は偽です。[:1]ただし、使用することは依然として節約です。のデフォルトの動作は行を繰り返すreadことなので、私は信じる必要はありません(そしてそうなるでしょうreadlinesopen。また'r'、デフォルトであるため、モードは必要ありません。私が正しいなら、それは73です!
ジョナサンアラン



3

1
空の行を持つ1つの入力はどうですか?
ジョナサンアラン

わからないよ...調べてみよう
オリバーNi

|vy¬dićú}, 10バイトで動作します。
ライリー

OK、空の行を入力できないわけではありません。空の行ではコードが機能しないということです:単一のゼロを使用すると機能するので、存在しない頭に関するものでなければなりません(@Rileyの提案10にも同じことが言えます)ところでバイター)。
ジョナサンアラン

@JonathanAllan動作の仕方と関係があります|。これは想定されてpush the rest of input as an array with stringsいますが、空行(TIO)で停止します。私はこれを詳細を知りたい場合 05AB1Eチャットルーム
ライリー


2

ゼリー、19 バイト

V⁶ẋ
Ḣǹe?ØD;
ỴÇ€Yḟ0

文字のリストを取得して返すモナドリンク、または結果を出力する完全なプログラム。

オンラインでお試しください!

どうやって?

V⁶ẋ - Link 1, make spaces: character (a digit)
V   - evaluate as Jelly code (get the number the character represents)
 ⁶  - a space character
  ẋ - repeat

Ḣǹe?ØD; - Link 2, process a line: list of characters
Ḣ        - head (get the first character and modify the line)
         -   Note: yields zero for empty lines
     ØD  - digit characters = "0123456789"
    ?    - if:
   e     - ...condition: exists in? (is the head a digit?)
 Ç       - ...then: call the last link as a monad (with the head as an argument)
  ¹      - ...else: identity (do nothing; yields the head)
       ; - concatenate with the beheaded line

ỴÇ€Yḟ0 - Main link: list of characters
Ỵ      - split at newlines
 Ç€    - call the last link (1) as a monad for €ach
   Y   - join with newlines
    ḟ0 - filter out any zeros (the results of empty lines)

beheaded lineそれは実際の用語ですか?xD
HyperNeutrino

1
さて、今は:)
ジョナサンアラン

Ahahaha私はあなたを試してみましたoutgolfingとあなたと本質的に同じ溶液で終わったXD
HyperNeutrino


2

Haskell、63バイト

unlines.map g.lines
g(x:r)|x<';',x>'/'=(' '<$['1'..x])++r
g s=s

オンラインでお試しください!最初の行は、指定された文字列を行に分割し、g各行に関数を適用し、結果の行を改行で結合する匿名関数です。その中で、行のg最初の文字xが数字であるかどうかがチェックされます。この場合は、['1'..x]文字列の長さは、桁の値に等しく生じるx' '<$多くのスペースなどに文字列を変換します。最後に、行の残りrが追加されます。xが数字でない場合、2番目の式にg s=sあり、変更されていない行を返します。


2

パイソン276の72 68バイト

@ovsのおかげで-4バイト

@DeadPossumはPython 2に切り替えることを提案しました。これにより4バイトも節約されました。

Python 2で、最初の文字が数字かどうかを明示的にチェックしない競争力のある完全なプログラムがあると便利だと思いました。これは、ファイルから入力を読み取りますf

for i in open('f'):
 try:r=int(i[0])*" "+i[1:]
 except:r=i
 print r,

オンラインでお試しください!@ovsの礼儀)


そのためのおかげで@ovs
氏Xcoder

@ovsあなたは何を変えましたか(私はそれを手で行います)?それはパーマリンクをデコードすることができないことを私に伝えます
氏Xcoder

すべての反復で出力する代わりに、出力を変数に割り当て、最後にすべて出力しました。
OVS

@ovsすべての反復を印刷することで72バイトを取得することができました。
氏Xcoder

Python 2バージョンは68バイトprintを提供します
デッドポッサム

2

Javaの8105 99 97 93バイト

Nevayの提案のおかげで、さらに数バイト節約できました。

s->{int i=s.charAt(0);if(i>47&i<58)s=s.substring(1);while(i-->48)s=" "+s;System.out.print(s);}

1
ゴルフバージョンには2つのバグがあります。ディジットチェックではorの代わりにandを使用する必要があります。ディジットチェックの後の角かっこがありません。それに加えて、s->{int i=s.charAt(0);if(i>47&i<58)for(s=s.substring(1);i-->48;s=" "+s);System.out.print(s);}(93バイト)を使用して数バイトを節約できます。
ネヴァイ

@Nevayあなたは正しい。ありがとう。回答を更新します。
CoderCroc

2

R138128バイト

CriminallyVulgarのおかげで-9バイト

n=readLines();for(d in grep("^[0-9]",n))n[d]=gsub('^.?',paste0(rep(' ',eval(substr(n[d],1,1))),collapse=''),n[d]);cat(n,sep='
')

これはかなり悪いですが、今では少し良くなっています... Rは再びストリングスでひどいです。

オンラインでお試しください!


2
私はCriminallyVulgarを代表してコメントしています。彼は129バイトバージョンを提案していますが、コメントするのに十分な評判はありません。
ミスターXcoder

@ Mr.Xcoderありがとう、@ CriminallyVulgar!
ジュゼッペ

123バイトどうやら担当者は、第二引数にint型の文字列を取ることができます?
CriminallyVulgar

@CriminallyVulgarハァッ。repドキュメントにありますが、今度はもう一度確認します:「他の入力が整数または二重ベクトルに強制される」。
ジュゼッペ

2

Japt(v2.0a0)、11 10バイト

ゼリー暴行JAPT 05AB1Eを?それは正しくないようです!

r/^\d/m_°ç

試して


説明

文字列の暗黙的な入力 U

r/^\d/m

Regex replace(r)を使用すると、行の先頭にあるすべての数字が出現します(m複数行フラグg-Japtではデフォルトで有効になっています)。

_

Pass each match through a function, where Z is the current element.

°

後置インクリメント演算子(++). This converts Z to an integer without increasing it for the following operation.

ç

Repeat a space character Z times.

結果の文字列を暗黙的に出力します。


Can m@ be shortened?
Oliver

Not in this case, @Oliver; the m here is the multi-line flag for the regex, not the map method.
Shaggy

1
@Oliver: r/^\d/m_î (or r/^\d/m_ç) would be 2 bytes shorter but Z is a string so, unfortunately, it wouldn't work. r/^\d/m_°ç, for a 1 byte saving, does work, though :)
Shaggy

°ç is an amazing trick :-) I'd have suggested just \d for the regex, but that leaves out the flag... perhaps I should add support for flags on single-class regexes, like \dm (oh yeah, and that leaves out the ^ too...)
ETHproductions

@ETHproductions, would it be feasible/possible to make the opening / optional in RegExes?
Shaggy

1

Jelly, 19 bytes

Ḣ⁶ẋ;µ¹µḣ1ẇØDµ?
ỴÇ€Y

Try it online!

-5 bytes total thanks to Jonathan Allan's comments and by looking at his post

Explanation

Ḣ⁶ẋ;µ¹µḣ1ẇØDµ?  Main link
             ?  Ternary if
                if:
       ḣ1       the first 1 element(s) (`Head` would modify the list which is not wanted)
         ẇ      is a sublist of (essentially "is an element of")
          ØD    "0123456789"
                then:
  ẋ             repeat
 ⁶              ' '
Ḣ               n times where n is the first character of the line (head)
   ;            concatenate the "beheaded" string (wording choice credited to Jonathan Allan)
                else:
     ¹          Identity (do nothing)
    µ µ     µ   Link separators
ỴÇ€Y            Executed Link
Ỵ               Split by newlines
  €             For each element,
 Ç              call the last link on it
   Y            Join by newlines

no need to swap arguments: Ḣ⁶ẋ;
Jonathan Allan

The pop then head trick wont work if there is a line containing only a single digit character :( -- ;0Ḣ would work for one byte, maybe there is a single atom, I also tried ¹, no joy there
Jonathan Allan

1
@JonathanAllan Ah right. Thanks. ḣ1ẇØD works for the same bytecount \o/
HyperNeutrino

ṚṪ will work :)
Jonathan Allan

@JonathanAllan That works too :) But I made an explanation already for my method so I'm too lazy to change it :P But thanks anyway :)
HyperNeutrino

1

Pyth,  16  15 bytes

jm.x+*;shdtdd.z

Try it online!


Explanation

jm.x+*;shdtdd.z   - Full program that works by reading everything from STDIN.

             .z  - Read all STDIN and split it by linefeeds.
 m               - Map with a variable d.
  .x             - Try:
     *;shd           - To convert the first character to an Integer and multiply it by a space.
    +     td         - And add everything except for the first character
            d        - If the above fails, just add the whole String.
j                 - Join by newlines.

Let's take an example that should be easier to process. Say our input is:

foo bar foo bar
1foo bar foo bar foo bar
2foo bar foo bar foo bar foo bar

The program above will do the following:

  • .z - Reads it all and splits it by newlines, so we get ['foo bar foo bar', '1foo bar foo bar foo bar', '2foo bar foo bar foo bar foo bar'].

  • We get the first character of each: ['f', '1', '2'].

  • If it is convertible to an integer, we repeat a space that integer times and add the rest of the String. Else, we just place the whole String. Hence, we have ['foo bar foo bar', ' foo bar foo bar foo bar', ' foo bar foo bar foo bar foo bar'].

  • Finally, we join by newlines, so our result is:

    foo bar foo bar
     foo bar foo bar foo bar
      foo bar foo bar foo bar foo bar
    

1
Haha, we beat Jelly :)
Mr. Xcoder

1

Cubically, 82 bytes

R3D1R1D1+0(?6{?7@7~:1+2<7?6{+35>7?6{:7-120?6{(B3@5B1-0)6}:0}}}?6!@7~-60=7&6+4-3=7)

Note: This will not work on TIO. To test this, use the Lua interpreter with the experimental flag set to true (to enable conditionals). There's currently a bug with conditional blocks on the TIO interpreter. When using the TIO interpreter, you should replace ?6! with !6 and &6 with ?6&, which keeps the byte count the same.

R3D1R1D1          Set the cube so that face 0 has value 1 and the rest of the values are easy to calculate

+0                Set the notepad to 1 so that it enters the conditional below
(                 Do
  ?6{               If the notepad is 1 (last character was \n or start of input)
    ?7@7              Output the current character if it's \n
    ~                 Get the next character
    :1+2<7?6{         If the input is >= '0'
      +35>7?6{          If the input is <= '9'
        :7-120            Set the notepad to the input - '0'
        ?6{               If the notepad isn't 0
          (                 Do
            B3@5              Output a space
            B1-0              Subtract 1 from notepad
          )6                While notepad > 0
        }                 End if
        :0              Set notepad to 1
      }                 End if
    }                 End if
  }                 End if

  ?6!@7             If the notepad is 0 (did not attempt to print spaces), print current character

  ~                 Get next character
  -60=7&6           If there is no more input, exit the program
  +4-3=7            Check if current character is \n, setting notepad to result
)                 Repeat forever

This isn't as short as the other Cubically answer, but I thought I'd give this a try anyway :D


What's going on with loops in the TIO interpreter?
MD XF

@MDXF ) jumps to the most recent ( rather than the matching one I believe. EDIT: I'm in the chat.
TehPers

@MDXF Maybe it was the conditional blocks, actually. I forgot, I'll update the answer. Regardless, they weren't matching up.
TehPers

1
All right, I'll look at that later. I'm currently finishing Cubically 2.
MD XF

@MDXF That's... really exciting to hear actually o_O
TehPers

1

><>, 60 bytes

!^i:0(?;::"/")$":"(*0$.
v"0"-
>:?!v1-" "o
;>:o>a=&10&?.i:0(?

Try it online!

How It Works:

..i:0(?;... Gets input and ends if it is EOF
...
...
...

.^......::"/")$":"(*0$. If the inputted character is a digit go to the second line
...                     Else go to the fourth
...
...

....        If it was a digit
v"0"-       Subtract the character "0" from it to turn it into the corresponding integer
>:?!v1-" "o And print that many spaces before rejoining the fourth line
...

.^..               On the fourth line,
....               Copy and print the input (skip this if it was a digit)
....v              If the input is a newline, go back to the first line.
;>:o>a=&10&?.i:0(? Else get the input, ending on EOF

0

V, 9 bytes

ç^ä/x@"é 

Try it online!

Explanation

ç  /      ' On lines matching
 ^ä       ' (Start)(digit)
    x     ' Delete the first character
     @"   ' (Copy Register) number of times
       é  ' Insert a space

0

Gema, 21 characters

\N<D1>=@repeat{$1;\ }

Sample run:

bash-4.4$ gema '\N<D1>=@repeat{$1;\ }' <<< 'foo bar foo bar
> 1foo bar foo bar foo bar
> 2foo bar foo bar foo bar foo bar
> 
> --------v
> 8|
> 8|
> 80
> 8,
> 7&'
foo bar foo bar
 foo bar foo bar foo bar
  foo bar foo bar foo bar foo bar

--------v
        |
        |
        0
        ,
       &

0

PHP, 83 chars

preg_replace_callback('/^\d/m',function($m){return str_repeat(' ',$m[0]);},$argv);

I think your code is not compliant with the input rules of this challenge, you should enclose this in a function with a $s arg or populate it with the input. And it doesn't print anything
LP154

@LP154 is using argv acceptable?
Petah

@Petah If I'm correct in assuming argv is the command line args, then yes.
totallyhuman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.