做一个简单的自动包装


22

(注意:这是我有史以来第一个关于高尔夫的代码问题,但是据我所知,没有人能完全做到这一点,所以我应该很好。)

您的任务是制作一个程序或函数,该程序或函数接受一个字符串s和一个整数n,并返回或输出包装成多行的文本。每个单词必须全部在一行上;即中间没有字。每行的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

Answers:



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

在线尝试!

变数

格式化后的输出存储在Ø(以下绿色)。

更新的行ü定义为以下内容的串联:

  • 当前行[R(下方黑色)
  • 如果[R不为空,则为一个空格,否则为空(下面的橙色)
  • 新单词w(下面的蓝色)

每当设置u的ñ个字符(索引为0,在下面的红色为红色)时,我们都需要插入换行符。ü

ñ=16s =“ LOREM IPSUM DOLOR”

添加“ LOREM”:

0001020304050607080910111213141516大号Ø[RË中号

添加“ IPSUM”:

0001020304050607080910111213141516大号Ø[RË中号一世P小号ü中号

添加“ DOLOR”:

0001020304050607080910111213141516大号Ø[RË中号一世P小号ü中号dØ大号Ø[R

0001020304050607080910111213141516大号Ø[RË中号一世P小号ü中号dØ大号Ø[R


允许尾随空格。也许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_

文本格式问题?我只知道这份工作的工具!在前两次按键中它甚至都有我的名字:D

<C-r>意味着ctrl-r

这可能曾经在V SO略短,但我更喜欢香草VIM回答的答案,真正炫耀如何简洁Vim可以为右挑战。而且无论如何差异都很小。

对于15个字节,也可能是以下内容:

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

在线尝试!


1
说明::DJ:该程序由DJ制作,DJ是我们最喜欢的猫,脖子上戴着钻石。[...]
暴民埃里克(Erik the Outgolfer)'18年

4

R36 27字节

R将其作为内置(strwrap),我们返回分割线的向量。

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

在线尝试!


1
是的,应该允许。允许使用行数组,因此我看不出为什么会有任何不同。
ATMunn

4

Haskell,70个字节

s!n|length s<=n=[s]|(t,_:d)<-splitAt(until((<'!').(s!!))pred n)s=t:d!n


3

Java(JDK)46 44字节

基本上,这是Java中的纯正则表达式解决方案,几乎可以肯定是我写的最短的正则表达式解决方案。

感谢Kevin帮助进一步减少正则表达式中的字节!

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

在线尝试!

感谢Bubbler和Shaggy的帮助

说明:

¸                       #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(...)
Bubbler '18


1

视网膜0.8.2,37字节

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

在线尝试!注意到sn在单独的行。说明:

.+$
$*

转换n为一元。

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

匹配非空格,然后向前看n并算作$#1。然后返回并使用一个平衡组来匹配最多n字符,后跟空格。

!`

将匹配项输出为行列表。


Retina中是否有一种方法可以将第一个输入放入与第二个输入一起使用的正则表达式中?像这样的东西:.{1,50} $0¶,但是在哪里50接收作为输入呢?
凯文·克鲁伊森

@KevinCruijssen在Retina 1中,您可能可以使用Eval舞台来给出类似的结果,但这很无聊,所以我没有打扰。
尼尔

1

木炭,19字节

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

在线尝试!链接是详细版本的代码。分别输入n和的输入s。说明:

Nθ

输入n

将光标向左移动一个正方形,以平衡循环第一次迭代后的向右移动。

F⪪S «

在空格处分割字符串,然后在单词上循环。

¿‹⁺Lιⅈθ

计算下一个单词是否会到达右边缘。

M→

如果不会,则向右移动一个正方形。

⸿

如果它将开始新的一行。

ι

输出单词。



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

在线尝试!

⎕CYdfns库c op y

 然后

wrap[c]  使用wrap [n]函数

[c]  该功能的代码
[n]  该功能的注意事项


的高尔夫版本wrap,59 字节SBCS

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

在线尝试!

{} dfn;是左参数(宽度),是右参数(字符串)

≢⍵ 字符串计数(字符数)

⍺≥: 如果宽度大于或等于该宽度,则:

   返回字符串

 除此以外:

  ' '=⍵ 布尔掩码,其中空格等于字符串

  b← 存储在b(对于b lanks)

  ()↑ 从中选择以下元素:

   ⍺+1 比宽度多一

  发现真正的地方

  g← 储存在g(用于g aps)

  ⍺≥ 宽度大于或等于该宽度的布尔蒙版

  g/⍨ 以此过滤间隙指数

  ⍺, 附加到宽度

  ⊃⌽ 选择该元素的最后一个元素(点亮。选择反转的第一个元素)

  t← 存储在t(对于 AKE)

  b⊃⍨ 用它来从该掩模选择一个元素b lanks

  t+ 加上 t

  ⍵↓⍨ 从字符串中删除那么多字符

  ⍺∇ 用相同的left-left参数递归

  ⎕TC, 追加,为的列表端子Ç ONTROL字符(8:HT,10:NL,13:CR)

  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,不返回)。
暴民埃里克(Erik the Outgolfer)'18年

0

JavaScript + HTML + CSS,117 64字节

-53字节@Neil提供

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; 铬70的计算50ch400px
公式

这个答案是错误的。elit. Sed eget erat lectus. Morbi mi mi, fringilla sed(第二行)超过50个字符。我正在使用最新的Chrome。
mbomb007 '18

我可以通过将<p>里面的内容放在Chrome上,来调整我最初的建议<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个字符。您希望“之前”而不是“附近”,并且一处的分割必须取决于较早分割的位置。
与Orjan约翰森

0

C#(Visual C#交互式编译器),78字节

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

在线尝试!

感谢@LukeStevens提出Java版本...显然.NET使您导入RegularExpressions名称空间以进行替换:(

这是我的原始版本,该版本拆分空格字符并使用LINQ将它们重新结合在一起:

C#(Visual C#交互式编译器),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”行,因为不会更改其长度(如果我们将结果视为一个字符串),因为更改了\ n中的某些空格或其中的新行地点。对于b()函数,输入字符串“ a”中也不应包含\ n字符(对于bs(),输入字符串中也可能包含\ n)

b(a,n)函数之所以可行,仅是因为此练习的局限性,即强加“ a”字符串的每个单词的长度<n,如果不正确,则该函数可以进入
一个无限循环...(非常我的看法是错误的,所以我也复制了更好的函数,因为在那种情况下将返回-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;
    }
}

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好的,以上代码也考虑了\ n ...我在代码中发现的一个错误是最后一行没有正确打印...为什么不像其他那样写C答案?它会赢得我的胜利,因为它更短...可以说是真的,我使用第一行(或语句“;”)进行输入检查仅是因为对我而言,即使输入的内容多一点也必须检查输入长; 我尝试用APL编写函数失败...
RosLuP

@ceilingcat在最后一个答案中,看到的问题不是说输入字符串是否必须包含'\ n'char,并且看到示例中没有'\ n'我想输入字符串中没有换行符...
RosLuP

只有83个...是的,我必须看看是否使用旧函数定义获得了3个字符...
RosLuP

只是81 .... .... ....
RosLuP

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.