文字右对齐


27

您的工作是获取一个字符串输入和一个数字,然后将字符串向右对齐,使文本的宽度成为数字。当一行太长时,请将其断开,然后将其余部分放在下一行,重复进行直到不需要。如果一条线比宽度短,则用空格填充。可能会出现多个换行符,并且应将其与其他任何单个字符一样对待。

例如,字符串

Programming
Puzzles
&
Code
Golf

该数字5将产生:

Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

而相同的字符串和数字10将产生:

Programmin
         g
   Puzzles
         &
      Code
      Golf

字符串

a

b

而数字5会产生:

    a
      <-- note the 5 spaces
    b

最短的代码胜出!


1
文本说“ 在必要时中断行[...]”,但是您的示例建议您在每个单词之后打断,即使它合适。请说明:我们将每个单词放在换行符上还是实现实际的自动换行算法?
Timwi's

输入行中间是否可以有空格,例如Programming Puzzles\n&\nCode Golf
Sp3000

@ sp3000可以有任何字符,包括空格。
Trebuchette

@Timwi:该示例每行只有一个单词。最好包含一些多字行,以明确一行中的空格不是特别的。(即只有换行符和非换行符。)
Peter Cordes

Answers:



10

Python 2,84

s,n=input()
for w in s.split('\n'):
 w=w or' '
 while w:print w[:n].rjust(n);w=w[n:]

将带有换行符和数字的字符串作为输入,并打印结果。对于输入中的每一行,n一次使用并打印字符,使用内置功能在rjust打印前在左边用空格填充。

我用黑客修理了空箱w=w or' '。也许有更好的方法,但我不会对此进行过多考虑。


8

CJam,21个字节

li_qN/Sfe|f/ff{\Se[N}

感谢@ Sp3000为1个字节打高尔夫球并为3个字节铺平道路。

CJam解释器中在线尝试。

怎么运行的

li                     Read an integer L from the first line of input.
  _                    Push a copy.
   qN/                 Split the remaining input at linefeeds.
      Sfe|             Map `OR " "'; the replaces empty lines with a space.
          f/           Split each line into chunks of length L.
            ff{     }  For each chunk, push L and the chunk; then:
               \         Swap L with the chunk.
                Se[      Left-pad the chunk to length L by prepending " ".
                   N     Push a linefeed.

5

珀斯,16岁

jm>Q+*\ QdscRQ.z

在这里在线尝试

说明

jm>Q+*\ QdscRQ.z             : Q is the number on the first line, .z takes the rest
           cRQ.z             : chop each line of .z into chunks of Q characters
 m        s                  : remove nested lists and map over the result
    +*\ Qd                   : add Q spaces to each line d
  >Q                         : take the last Q characters of that result
j                            : join results on newlines

4

Perl,39个字节

perl -ni5 -e 's!^$|.{1,$^I}!printf"%${^I}s
",$&!ge'

36个字节+ 3个字节(用于)-ni。换行宽度作为参数传递给-i

通过使用空格填充空白行来正确处理它们:

$ echo -e "Programming\nPuzzles\n\n&\n\nCode\nGolf" | perl -ni5 -e 's!^$|.{1,$^I}!printf"%${^I}s
",$&!ge'
Progr
ammin
    g
Puzzl
   es

    &

 Code
 Golf

怎么运行的

该解决方案使用替换运算符循环输入,从而在等效for循环上节省了一个字节。但是,真正的技巧是在替代LHS的正则表达式中:

^$|.{1,$^I}

使用全局修饰符,可以一次匹配$^I字符;当$^I字符串中剩余的字符少于个时,它将匹配所有内容。^$处理空白行时需要与交替显示。例如:

$ echo -e "foo\n\nbar" | perl -ni2 -E 'say "<$_>" for /^$|.{1,$^I}/g'
<fo>
<o>
<>
<ba>
<r>

替换的RHS仅用于printf将匹配的块用空格左键填充。


我总是忘了$^I
Dom Hastings

@DomHastings我从chilemagic那里学到了这个技巧,他在评论另一个挑战时提到了这一点。
ThisSuitIsBlackNotNot

3

Javascript(ES6),107

我希望JS具有内置的pad函数。那好吧。

(a,b)=>a.replace(eval(`/(.{${b}})(?!\\n)/g`),`$1
`).split`
`.map(c=>(Array(b).join` `+c).slice(-b)).join`
`

说明:

(a, b)=>

  // searches for sequences of characters longer than b without a newline after them and
  // adds a newline after every b characters of the sequence
  a.replace(eval(`/(.{${b}})(?!\\n)/g`), '$1\n')
    .split('\n')
    .map(c=>

      // prepends b spaces to each string then slices it from the right down to length b
      ( Array(b).join(' ') + c ).slice(-b)

    ).join('\n')

3

朱莉娅126字节

f(s,n)=for i=split(s,"\n") while length(i)>0 println(lpad(i[1:min(n,end)],n));length(i)<n?break:(i=i[min(n+1,end):end])end;end

取消高尔夫:

function f(s::String, n::Int)
    for i in split(s, "\n")
        while length(i) > 0
            println(lpad(i[1:min(n,end)], n))
            length(i) < n ? break : (i = i[min(n+1,end):end])
        end
    end
end

2

击,6261 +特征,59

如果N可以由调用方设置,则更短,而不必将其读取为输入的第一行。

# width as a function arg: 59 chars
f()while read -rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done
# width on stdin: 64 chars  (not updated with later suggestions&ideas)
read N;while read -rn$N r;do [[ $r ]]&&printf %$N's\n' "$r";done

这无法处理输入中的空行。否则,这不会使输入数据受到单词拆分,路径名扩展的影响,或者将其视为原始数据以外的其他内容。

read -n$N保存一个字符,但让readmunge保留\

[[ $r ]]&&因为需要read -n4不能前瞻地看到,下一个字符是一个换行符。因此将其设置r为4个字符的字符串,下一次读取将产生一个零字符的空字符串。筛选这些错误的换行而不筛选实际的换行将需要跟踪状态:前一行是否为max-length。要么需要更多代码,要么需要完全不同的方法。

[[ $r ]][ -n "$r" ]如果行以-z foo,或is 开头*(如果使用),则它比避免错误所需的长度短[ $r ]

对齐发生在标准printf“%4s”格式字符串中。

测试

f()(while read -rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done); (echo 4; echo -e "*\n\\"; cat /tmp/lines) | f 4

1.我将包括-r在字节数中。2. f()(while ... done)要短一点。
丹尼斯

@Dennis:如果不使用[[ $r ]]&&,则如果N = 4,则长度为4的输入线将产生一条空白输出线,以前没有该线。由于read回报率的4个字符的字符串,然后看到下次调用和返回马上换行。另外,感谢您的()提示。我不知道您可以用这种方式定义fns。
彼得·科德斯

我建议阅读Bash打高尔夫球的技巧。这是一个很棒的资源。
丹尼斯

实际上,由于while已经很复杂了,您甚至不需要括号:f()while ... done
Dennis

@丹尼斯:哇,哈克斯。感谢您的链接。其中一些对我来说是新鲜事物,我在另一个答案中修正了一些问题:)我通常不打高尔夫球,但是作为命令行迷的15年以上的经历教会了我一两个问题:)
彼得Cordes

2

Haskell,108个字节

import Data.List.Split
k[]=[""]
k x=x
f n=unlines.(map(\l->([1..n-length l]>>" ")++l).k.chunksOf n=<<).lines

用法示例:

*Main> putStr $ f 5 "a\n\nb\ncd\nMatamorphosis"
    a

    b
   cd
Matam
orpho
  sis

怎么运行的

                              .lines   -- split input string at newlines
                           =<<         -- for every line
                  chunksOf n           --    split into chunks of length n
                k                      --    fix empty lines
    map                                --    for every chunk
        \l->([1..n-length l]>>" "      --      make a string of missing spaces
                        ++l            --      and append the chunk
unlines                                -- join padded chunks with newlines in-between

1

GNU awk + ​​bash,70岁

f()(awk -vFPAT=.\{,$1} '{for(i=0;i++<NF;){printf "%'$1's\n",$i}}/^$/')

使用bash将计数放入awk程序是很可能的。小于使用NR==1{N=$0}块读取它。

一次读取一行。使用FPAT分成最多4个字符的块。(匹配字段,而不是分隔符。GNU扩展。)分别打印每个字段。(默认ORS = \ n)。

/^$/此处的规则是打印空行,这些行的NF = 0,因此在其他程序段中根本不打印。因此,与我的纯bash解决方案不同,这实际上在一般情况下都有效。

半无关的,但到目前为止我对perl的想法仅是perl代码的112个字符:

(echo 4; echo -e 'foo\nbar'; echo -e "*\n\\"; echo '~$(true)'; cat /tmp/lines) |  # test input
perl -e '$N=<>;$/=\1;print "$N\n"; while(<>){if(/\n/ or length($l)>=$N){printf("%$4s\n",$l);$l=/\n/?"":$_;}else{$l.=$_;}}'

这会吃掉换行符之一,而且太长了。 $/=\1一次读取一个字节。我们附加到$ l。采用固定宽度拆分方法的一次一行可能会更短。


1

Bash + GNU utils,41

fold -$1|sed ":;s/^.\{,$[$1-1]\}\$/ &/;t"

字符串通过STDIN输入,宽度通过命令行arg输入:

ubuntu@ubuntu:~$ echo 'Programming
Puzzles
&
Code
Golf'|./ralign.sh 10
Programmin
         g
   Puzzles
         &
      Code
      Golf
ubuntu@ubuntu:~$

1

Python 2,151字节

s,n=input();N='\n'
for w in[i.lstrip()if i.replace(' ','').isalpha()else i for i in s.replace(N,'\n ').split(N)]:
 while w:print w[:n].rjust(n);w=w[n:]

这是@xnor上面答案的改编,因为他无法正确处理换行符。


for循环由改变:

for w in s.split('\n'):

至:

for w in[i.lstrip()if i.replace(' ','').isalpha()else i for i in s.replace(N,'\n ').split(N)]:

$ python main.py
"Programming\n\n\nPuzzles\n\n&\n\nCode\nGolf", 5
Progr
ammin
    g


Puzzl
   es

    &

 Code
 Golf

1

C#,143个字节

(s,n)=>Join("\n",s.Split('\n').SelectMany(l=>(l.Any()?l:" ").Select((c,i)=>new{c,i}).GroupBy(o=>o.i/n,o=>o.c).Select(g=>Concat(g).PadLeft(n))))

Linq使您可以做出漂亮的表情。GroupBy在这里很有用,但是很遗憾他们无法创建使用索引的函数重载。

将lambda分配给a Func<string, int, string>以运行它

少打高尔夫球:

Func<string, int, string> Align = (s, n) => Join("\n", 
    s.Split('\n')
     .SelectMany(l => (l.Any() ? l : " ")
         .Select((c, i) => new { c, i })
         .GroupBy(o => o.i / n, o => o.c)
         .Select(g => Concat(g).PadLeft(n))));

1

Groovy,63个字节

返回正确指定的字符串。直到现在为止,还不知道有padLeft(和padRight,padCenter)功能。

f={s,n->s.split("(?<=\\G.{$n})|\n")*.padLeft(n," ").join("\n")}

1

的JavaScript 174 136

function R(s,x){return s.replace(new RegExp(".{"+x+"}","g"),"$&\n").replace(/[^\n]*/g,function(m){
while(m.length<x)m=" "+m;return m;})}

1

锡兰,107

String w(String s,Integer n)=>"\n".join{for(l in s.lines)for(p in l.partition(n))String(p).padLeading(n)};

1

Matlab,99个字节

感谢@beaker删除6个字节!

使用和匿名功能:

@(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0))) 

定义函数并用于ans调用它:

>> @(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0)))

ans =

@(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0)))

>> ans(['Programming' 10 'Puzzles' 10 '&' 10 'Code' 10 'Golf'], 5) %% 10 is line feed

ans =

Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

1

滑稽,28字节

与下面的版本相同,但是将第1行视为数字,将其他行视为字符串。

lng_riPpun{pPco{pP' lp}mu}Wl

用法如下:

$ cat input.txt | blsq --stdin "lng_riPpun{pPco{pP' lp}mu}Wl"
Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

旧版本(16字节):

{5co{5' lp}mu}Wl

例:

blsq ) "Programming\nPuzzles\n&\nCode\nGolf"{5co{5' lp}mu}Wl
Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf
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.