シンプルなワードラッパーを作成する


22

(注:これは私の初めてのコードゴルフの質問ですが、私が知る限り、誰もこれを正確に行っていないので、私は良いはずです。)

あなたの仕事は、文字列sと整数を取り込んで、n複数の行に折り返されたテキストを返すか出力するプログラムまたは関数を作成することです。各単語は完全に1行である必要があります。つまり、途中で単語が分割されません。各行はn文字より長くすることはできません。また、各行にできるだけ多くの単語を収める必要があります。

例:

s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat." 
n = 50

output:
Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed eget erat lectus. Morbi mi mi, fringilla
sed suscipit ullamcorper, tristique at mauris.
Morbi non commodo nibh. Pellentesque habitant
morbi tristique senectus et netus et malesuada
fames ac turpis egestas. Sed at iaculis mauris.
Praesent a sem augue. Nulla lectus sapien, auctor
nec pharetra eu, tincidunt ac diam. Sed ligula
arcu, aliquam quis velit aliquam, dictum varius
erat.

出力は、文字列の配列または改行を含む単一の文字列です。また、がを超える単語はないと想定できるnため、奇妙なケースに対処する心配はありません。

標準のI / Oルールが適用され、標準の抜け穴は禁止されています。末尾のスペースは許可されます。

これはであるため、バイト単位のショーツソリューションが優先されます。

ここで働くだろうPythonでプログラム例です。



3
nは最大行長ですか?または改行する前に到達しなければならない長さ?
デヴィッド・

1
@david、または行数?
ピーターテイラー

1
28バイトのPythonは関係がありますか?
デヴィッド・

3
nは行の最大長です。残念ながら、これは明確ではありませんでした。明確にします。また、ルールが更新されたため、単純な分割は機能しません。
ATMunn

回答:



5

PHP、8バイト

確かに、最も独創的なソリューションではありませんが、PHPには、要件に完全に一致するネイティブ関数があります!

wordwrap

string wordwrap ( string $str [, int $width = 75 [, string $break = "\n" [, bool $cut = FALSE ]]] )

文字列区切り文字を使用して、指定された文字数に文字列をラップします。

次のように使用します:

$str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.";
echo wordwrap($str, 50);

または、オンラインでお試しください!


5

JavaScript(ES6)、 75 73  72バイト

入力をとして受け取ります(string)(n)

s=>n=>s.split` `.map(w=>r=(u=r?r+' '+w:w)[n]?(o+=r+`
`,w):u,o=r='')&&o+r

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

変数

フォーマットされた出力は(下の緑)に保存されます。o

更新された行は、次の連結として定義されます。あなたは

  • 現在の行(下の黒)r
  • が空でない場合はスペース、それ以外の場合は何もない(下のオレンジ色)r
  • 新しい単語(下の青色)w

番目の文字が設定されるたびに改行を挿入する必要があります(下に赤で0インデックスが付けられます)。nあなたは

n=16および = "LOREM IPSUM DOLOR"s

「LOREM」の追加:

0001020304050607080910111213141516LOREM

「IPSUM」の追加:

0001020304050607080910111213141516LOREMPSうんM

「DOLOR」の追加:

0001020304050607080910111213141516LOREMPSうんMDOLOR

0001020304050607080910111213141516LOREMPSうんMDOLOR


末尾のスペースは許可されます。多分r+w+' '
l4m2

5

Perl 6の46の 29バイト

{;*.comb(/.**{1..$_}[\s|$]/)}

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

カリー化された入力を取得し、f(n)(s)行のリストを返す正規表現ベースのソリューション。最後を除く各行には末尾に空白があります

説明:

{;*                         }   # Anonymous code block that returns a Whatever lambda
   .comb(/                /)    # Split the string by
          .**{1..$_}            # Up to n characters
                    [\s|$]      # Terminated by a whitespace char or the end of the string

4

Vim、15バイト/キーストローク

DJ:se tw=<C-r>"
gq_

テキストのフォーマットに関する質問ですか?私は仕事のためのツールだけを知っています!そして、それは最初の2つのキーストロークで私の名前さえ持っています:D

<C-r>を意味しctrl-rます。

これができた今までにそうわずかに短いVで、私は本当に正しいの挑戦のためにすることができますどのように簡潔なvimの誇示答えをバニラのvimに答えることを好みます。とにかく違いはとても小さいです。

これは、15バイトでも次のようになります。

:se tw=<C-r><C-w>
ddgq_

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


1
説明::DJ:このプログラムは、DJが作ったもので、お気に入りの猫の首にダイヤモンドが付いています。[...]
エリック・ザ・アウトゴルファー

4

R36 27バイト

Rにはこれが組み込み(strwrap)としてあり、分割線のベクトルを返します。

function(s,n)strwrap(s,n+1)

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


1
はい、それは許可されるべきです。行の配列が許可されているため、これが異なる理由はわかりません。
ATMunn



3

Java(JDK)46 44バイト

基本的にJavaの純粋な正規表現ソリューションであり、ほぼ間違いなく私が書いたものの中で最も短いものです。

正規表現のバイト数をさらに削減するためにケビンに感謝します!

n->s->s.replaceAll(".{1,"+n+"}( |$)","$0\n")

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

カレーのlamdbaを使用して、正規表現を作成しn、スペースまたは文字列の末尾が続く文字に貪欲に一致します。次に、これらの文字をそれ自体で置き換え、その後に改行を付けます。


@KevinCruijssen [ $]$、文字列の終わりではなく、実際にスペースに一致するか、正しく覚えている場合にのみ一致します。それは動作するように見えるので、それはさらに少ないバイトのために単一のスペースにゴルフダウンすることができるように見えます。
ルークスティーブンス

改行を追加し、末尾に改行を追加する必要がないため、実際には単なるスペースになります。
ケビンクルーイッセン

1
正規表現の括弧を削除してさらに2バイトをゴルフし、の$0代わりに使用できます$1
ケビンクルーッセン

@KevinCruijssenいいね!replaceAll非常に冗長なのは残念です!
ルークスティーブンス

2
私にとっては間違っています。「... dictum varius abc erat」で終わるようにエクササイズのラテン語のフレーズを変更すると表示されます。Cの文字の後、不要な改行が...ある
RosLuP

2

Mathematica、16バイト

InsertLinebreaks

組み込み関数。入力として文字列と整数を受け取り、出力として文字列を返します。

InsertLinebreaks["string", n]
 改行文字を挿入して、n文字より長い行を作成しません。


2

Powershell、40 83バイト

n=80追加されたテストケース。

param($s,$n)$s-split' '|%{if(($o+$_|% le*)-lt$n){$o+=' '*!!$o+$_}else{$o;$o=$_}}
$o

テストスクリプト:

$f = {

param($s,$n)$s-split' '|%{if(($o+$_|% le*)-lt$n){$o+=' '*!!$o+$_}else{$o;$o=$_}}
$o

}

@(
,(50, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.",
"Lorem ipsum dolor sit amet, consectetur adipiscing",
"elit. Sed eget erat lectus. Morbi mi mi, fringilla",
"sed suscipit ullamcorper, tristique at mauris.",
"Morbi non commodo nibh. Pellentesque habitant",
"morbi tristique senectus et netus et malesuada",
"fames ac turpis egestas. Sed at iaculis mauris.",
"Praesent a sem augue. Nulla lectus sapien, auctor",
"nec pharetra eu, tincidunt ac diam. Sed ligula",
"arcu, aliquam quis velit aliquam, dictum varius",
"erat.")
,(80, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus.",
"Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non",
"commodo nibh. Pellentesque habitant morbi tristique senectus et netus et",
"malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue.",
"Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu,",
"aliquam quis velit aliquam, dictum varius erat.")
) | %{
    $n,$s,$expected = $_
    $result = &$f $s $n
    "$result"-eq"$expected"
    # $result   # uncomment this line to dispaly a result
}

出力:

True
True


ありがとう。偽の三元は表現です。このスクリプトにはreturnelse部分に暗黙的、部分にステートメントが含まれていthenます。
mazzy


2

Japt、20バイト

¸rÈ+Yi[X·ÌY]¸Ê>V?R:S

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

バブラーとシャギーに助けてくれてありがとう

説明:

¸                       #Split into words
 r                      #For each word, add them to the output in this way:
     i                  # Choose a character using this process:
       X·Ì              #  Get the last line of the output
          Y             #  And the current word
      [    ]¸           #  Join them with a space
             Ê>V?       #  If the resulting line is greater than the allowed length:
                ?R      #   Choose "/n" (newline)
                  :S    #  Otherwise choose " " (space)
     i                  # Add the chosen character to the output
  È+Y                   # Add the current word to the output

24はバイト[X,Y].join(...)
バブラー


1

Retina 0.8.2、37バイト

.+$
$*
!`(?=\S.*¶(1)+)(?<-1>.)+(?=\s)

オンラインでお試しください!受け取りsn別々の行に。説明:

.+$
$*

n単項に変換します。

(?=\S.*¶(1)+)(?<-1>.)+(?=\s)

空白以外に一致し、先読みしてnとしてカウントします$#1。次に戻って、バランスグループを使用して、n文字の後に空白を続けて一致させます。

!`

一致を行のリストとして出力します。


Retinaで、2番目の入力で使用する正規表現に最初の入力を配置する方法はありますか?このようなもの:.{1,50} $0¶、しかし、50代わりに入力としてどこで受け取られますか?
ケビンクルーイッセン

@KevinCruijssen Retina 1では、おそらくEvalステージを使用して同様の結果を得ることができますが、それは退屈なので、気にしませんでした。
ニール

1

、19バイト

Nθ←F⪪S «¿‹⁺LιⅈθM→⸿ι

オンラインでお試しください!リンクは、コードの詳細バージョンです。入力取るns別の行です。説明:

Nθ

入力n

カーソルを1マス左に移動して、ループの最初の反復からの右の動きのバランスを取ります。

F⪪S «

文字列をスペースで分割し、単語をループします。

¿‹⁺Lιⅈθ

次の単語が右端に到達するかどうかを計算します。

M→

そうでない場合は、1つの正方形を右に移動します。

⸿

その後、新しい行を開始します。

ι

単語を出力します。



1

05AB1E、18 バイト

õs#vDy«g²›i,}yðJ}?

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

説明:

õ                   # Push an empty string "" to the stack
 s                  # Swap to take the (implicit) string input
  #                 # Split it by spaces
   v            }   # For-each `y` over the words:
    D               #  Duplicate the top of the stack
                    #  (which is the empty string in the very first iteration)
     y«             #  Append the current word `y`
       g            #  Get its length
        ²›i }       #  If its lengthy is larger than the second input:
           ,        #   Pop and output the current duplicated value with trailing newline
             yð     #  Push the word `y` and a space " "
               J    #  Join the entire stack together
                 ?  # After the loop, output the last part as well (without newline)

1

Java 8、135バイト

n->s->{String r="",S[]=s.split(" "),t=r;for(int i=0;i<S.length;)if((t+S[i]).length()>n){r+=t+"\n";t="";}else t+=S[i++]+" ";return r+t;}

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

説明:

n->s->{                      // Method with integer & String parameters and String return
  String r="",               //  Result-String, starting empty
         S[]=s.split(" "),   //  Input-String split by spaces
         t=r;                //  Temp-String, starting empty as well
  for(int i=0;i<S.length;)   //  Loop `i` in the range [0, amount_of_words):
    if((t+S[i]).length()>n){ //   If `t` and the word are larger than the integer input:
      r+=t+"\n";             //    Add `t` and a newline to the result
      t="";}                 //    And reset `t` to an empty String
     else                    //   Else:
       t+=S[i++]+" ";        //    Append the word and a space to `t`
                             //    (and then increase `i` by 1 with `i++` for the next word
                             //     of the next iteration)
  return r+t;}               //  Return the result-String appended with `t` as result


1

APL(Dyalog Unicode)、14 バイトSBCS

中置関数; 左引数はn、右引数はnです。

CY'dfns'wrap

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

⎕CYCのオペYにおけるDFNSライブラリー

 それから

wrap[c]  ラップ [n]関数を使用する

[c]  その関数のコード
[n]  その関数に関する注意


ゴルフバージョンwrap、59 バイトSBCS

{⍺≥≢⍵:⍵⋄(t↑⍵),2↓⎕TC,⍺∇⍵↓⍨t+b⊃⍨t←⊃⌽⍺,g/⍨⍺≥g←⍸(⍺+1)↑b' '=⍵}

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

{} dfn; 左引数(幅)、右引数(文字列)

≢⍵ 文字列の集計(文字数)

⍺≥: 幅がそれ以上の場合:

   文字列を返します

 さもないと:

  ' '=⍵ 空白が文字列と等しいブールマスク

  b← 保管bbランクの場合)

  ()↑ その中から次の数の要素を取り出します。

   ⍺+1 幅より1つ多い

  私はどこ真ndices

  g← 格納gg aps用)

  ⍺≥ 幅がそれ以上のブールマスク

  g/⍨ それによってギャップインデックスをフィルタリングします

  ⍺, 幅に追加します

  ⊃⌽ その最後の要素を選択します(点灯。反転した最初の要素を選択します)

  t← 店舗t(のためのT AKE)

  b⊃⍨ それを使用して、b lanksのマスクから要素を選択します

  t+ それを追加する t

  ⍵↓⍨ 文字列からその数の文字を削除します

  ⍺∇ 同じ左左引数でそれを再帰する

  ⎕TC, リストにその追記T erminal C ontrol文字(:HT、10:NL、13:CR 8)

  2↓ その中から最初の2文字をドロップします(先頭の13:CRだけを残します)

  (), それを以下に追加します:

   t↑⍵t文字列の 最初の文字


0

ゴルフバージョンの@Erik the Outgolferに感謝します。

Python 3、94バイト

def f(t,n):
 while t:i=n+(t[min(len(t)-1,n)]==" "or-t[n-1::-1].find(' '));print(t[:i]);t=t[i:]

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

Pythonの3、130のバイト

def f(t,n):
 l=[]
 while len(t):
  i=(n-t[:n][::-1].find(' '),n+1)[t[min(len(t)-1,n)]==" "]
  l.append(t[:i])
  t=t[i::]
 return l

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

それほどゴルフバージョンではありません...


1
いくつかのゴルフ。(STDOUTに出力し、戻りません)。
エリック・ザ・アウトゴルファー

0

JavaScript + HTML + CSS、117 64バイト

@Neilのおかげで-53バイト

n=50
s="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat."
f=(n,s)=>document.body.innerHTML+=`<tt><p style=width:${n}ch>${s}`
f(n,s)


1
少なくとも私のブラウザでは、これ(n,s)=>document.body.innerHTML+=`<p style=width:${n}ch><tt>${s}</tt></p>` を74バイトに削減できます。Firefoxの古いバージョンを掘り下げたい場合は、でさらに8バイト節約できます(n,s)=>document.body.innerHTML+=`<pre wrap width=${n}>${s}</pre>`
ニール

@Neil chユニットの素晴らしい使用。Firefox 65は次のように計算50ch500pxます。Chromium 70は次のように計算さ50chれます400px
guest271314

この答えは間違っています。elit. Sed eget erat lectus. Morbi mi mi, fringilla sed(2行目)は50文字を超えています。最新のChromeを使用しています。
mbomb007

私は、Chromeで作業するための最初の提案を微調整することができまし<p><tt>
ニール



0

C#(.NET Core)、162バイト

string[]t(string n,int a){var g="";for(int i=0;i++<Math.Floor((double)n.Length/a);)g+=$"^.{{{i*a-1}}}|";return Regex.Split(n,$@"(?n)(?<=({g.Trim('|')})\S*)\s");}}

この関数は、n番目またはn番目の文字の倍数に近い最も近い空白に一致する正規表現を使用し、それに基づいて文字列を分割します。

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

TIOリンクは完全なプログラムであり、関数には静的キーワードがあり、関数をmainから呼び出すことができます。

テスト正規表現


これは、テストケースに適切な出力を提供しません-一部の行は50文字を超えています。「近く」ではなく「前」が必要です。また、ある時点での分割は、以前に分割された場所に依存する必要があります。
Ørjanヨハンセン

0

C#(Visual C#Interactive Compiler)、78バイト

s=>n=>System.Text.RegularExpressions.Regex.Replace(s,".{1,"+n+"}( |$)","$0\n")

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

Javaバージョンを思いついたのは、@ LukeStevensの功績です。どうやら.NETを使用して、 RegularExpressionsは、置換を行うために名前空間するように思われます:(

これは、スペース文字で分割し、LINQを使用してそれらを結合する元のバージョンです。

C#(Visual C#Interactive Compiler)、91バイト

s=>n=>s.Split(' ').Aggregate((a,w)=>a+(a.Length-a.LastIndexOf('\n')+w.Length>n?'\n':' ')+w)

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



0

APL(NARS)、48文字、96バイト

{⊃⍵{⍺≥≢⍵:⊂⍵⋄k←1+⍺-' '⍳⍨⌽r←⍺↑⍵⋄(⊂k↑r),⍺∇k↓⍵}⍨⍺+1}

テスト:

  f←{⊃⍵{⍺≥≢⍵:⊂⍵⋄k←1+⍺-' '⍳⍨⌽r←⍺↑⍵⋄(⊂k↑r),⍺∇k↓⍵}⍨⍺+1}
  s←"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat."
  50 f s
Lorem ipsum dolor sit amet, consectetur adipiscing 
elit. Sed eget erat lectus. Morbi mi mi, fringilla 
sed suscipit ullamcorper, tristique at mauris.     
Morbi non commodo nibh. Pellentesque habitant      
morbi tristique senectus et netus et malesuada     
fames ac turpis egestas. Sed at iaculis mauris.    
Praesent a sem augue. Nulla lectus sapien, auctor  
nec pharetra eu, tincidunt ac diam. Sed ligula     
arcu, aliquam quis velit aliquam, dictum varius    
erat.                                              

私は「⍺≥≢⍵{{⊃⍵:⊂⍵⋄...」で知らない、それは右である≥か、それは...>右がある場合
RosLuP

0

C、63バイト

b(a,n)char*a;{while(strlen(a)>n){for(a+=n;*a-32;--a);*a++=10;}}

この演習の関数b(a、n)は、演習で述べたように、「a」の行を分割します。結果を1つの文字列として見る場合、\ nのスペースまたは\場所。入力文字列「a」には、b()関数の\ n文字も含めないでください(bs()の入力文字列に\ nを含めることができます)

b(a、n)関数は、「a」文字列の各単語が長さ<nを強制するこの演習の制限が、これが真でない場合にのみ、その関数が
1つの無限ループに進むことができるという理由だけでOK です...私の見方が間違っているので、その場合は-1を返し、1つの無限ループに行かないため、関数もコピーします。以下のbs(a、n)です)両方の関数がバグになっていることを除外しません。 。

#define R(x,y) if(x)return y
#define U unsigned
U bs(char*a,U n)
{U c,q,r=1,i,j;
 R(!a||n<1||n++>0xFFFF,-1);
 for(j=c=i=0;;++i,++c)
    {R(i==-1,-1);q=a[i];
     if(q==10)goto l;
     if(c>=n){R(i-j>n,-1);a[i=j]=10;l:c=-1;++r;}
     R(!q,r);
     if(q==32)j=i;
    }
}

各行を追加する1つの関数に渡されたb()の結果

Lorem ipsum dolor sit amet, consectetur adipiscing [50]
elit. Sed eget erat lectus. Morbi mi mi, fringilla [50]
sed suscipit ullamcorper, tristique at mauris. [46]
Morbi non commodo nibh. Pellentesque habitant [45]
morbi tristique senectus et netus et malesuada [46]
fames ac turpis egestas. Sed at iaculis mauris. [47]
Praesent a sem augue. Nulla lectus sapien, auctor [49]
nec pharetra eu, tincidunt ac diam. Sed ligula [46]
arcu, aliquam quis velit aliquam, dictum varius [47]
erat. [5]

@ceilingcat OK、上記のコードは\ nも考慮に入れます...コードで見つけたバグの1つは、最後の行が正しく印刷されなかったことです...なぜCの答えを他のように書かないのですか?それはもっと短いので、私の場合は勝つでしょう...本当の場合、入力のチェックには最初の行(またはステートメント「;」)を使用しますが、それはもう少しでも入力をチェックする必要があるためです長いです; APLに関数を記述するために私の失敗試み...
RosLuP

最後の回答の@ceilingcat、入力文字列に「\ n」文字が含まれているかどうかを言わない質問と、例に「\ n」が含まれていないことがわかりました入力文字列に改行文字がないと仮定します...
RosLuP

唯一の83 ...はい、私は私が...古い関数定義を使用して3つの文字を得るかどうかを確認する必要がある
RosLuP

ちょうど81 .... .... ....
RosLuP

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