Văn bản bên phải


27

Công việc của bạn là lấy một đầu vào chuỗi và một số và căn chỉnh chuỗi bên phải, làm cho chiều rộng của văn bản thành số. Khi một dòng quá dài, hãy ngắt nó và đặt phần còn lại vào dòng tiếp theo, lặp lại cho đến khi không cần thiết. Nếu một dòng ngắn hơn chiều rộng, sau đó đệm nó bằng khoảng trắng. Nhiều dòng mới có thể xảy ra và nên được xử lý như bất kỳ ký tự đơn nào khác.

Ví dụ: chuỗi

Programming
Puzzles
&
Code
Golf

và số lượng 5sẽ tạo ra:

Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

Trong khi đó cùng một chuỗi và số 10sẽ tạo ra:

Programmin
         g
   Puzzles
         &
      Code
      Golf

Chuỗi

a

b

và số 5 sẽ sản xuất:

    a
      <-- note the 5 spaces
    b

Mã ngắn nhất sẽ thắng!


1
Văn bản nói rằng Hãy phá vỡ các dòng khi cần thiết [...], nhưng các ví dụ của bạn cho thấy bạn ngắt sau mỗi từ, ngay cả khi nó phù hợp. Vui lòng làm rõ: chúng tôi có đặt từng từ trên một dòng mới hay chúng tôi thực hiện thuật toán gói từ thực tế?
Timwi

Có thể có khoảng trắng ở giữa một dòng đầu vào, ví dụ Programming Puzzles\n&\nCode Golf?
Sp3000

@ sp3000 Có thể có bất kỳ ký tự nào, kể cả khoảng trắng.
Trebuchette

@Timwi: Ví dụ có một từ trên mỗi dòng. Sẽ tốt hơn nếu bao gồm một số dòng nhiều từ để làm rõ rằng không gian trong một dòng không phải là đặc biệt. (tức là chỉ có dòng mới và không phải dòng mới.)
Peter Cordes

Câu trả lời:



10

Con trăn 2, 84

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

Lấy đầu vào là một chuỗi với dòng mới và một số, và in kết quả. Đối với mỗi dòng trong đầu vào, lấy và in nký tự một lần, sử dụng tích hợp rjustđể đệm bên trái với khoảng trắng trước khi in.

Tôi đã sửa trường hợp dòng trống với hack w=w or' '. Có lẽ có một phương pháp tốt hơn nhưng tôi sẽ không nghĩ nhiều về nó.


8

CJam, 21 byte

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

Cảm ơn @ Sp3000 vì đã chơi golf 1 byte và mở đường cho 3 người nữa.

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

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

Bình thường, 16

jm>Q+*\ QdscRQ.z

Dùng thử trực tuyến tại đây

Giải trình

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 byte

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

36 byte + 3 byte cho -ni. Chiều rộng bọc được truyền làm đối số -i.

Xử lý các dòng trống đúng cách bằng cách đệm chúng với khoảng trắng:

$ 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

Làm thế nào nó hoạt động

Giải pháp này sử dụng toán tử thay thế để lặp qua đầu vào, lưu một byte qua forvòng lặp tương đương . Mặc dù vậy, mánh khóe thực sự nằm trong regex về LHS của sự thay thế:

^$|.{1,$^I}

Với công cụ sửa đổi toàn cầu, điều này sẽ khớp với các $^Iký tự cùng một lúc; khi có ít hơn các $^Iký tự còn lại trong chuỗi, nó sẽ khớp mọi thứ cho đến hết. Sự xen kẽ với ^$là cần thiết để xử lý các dòng trống. Ví dụ:

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

RHS của sự thay thế chỉ đơn giản là sử dụng printfđể đệm bên trái phần phù hợp với khoảng trắng.


Tôi luôn quên về $^I!
Dom Hastings

@DomHastings Tôi đã học được mẹo đó từ chilemagic, người đã đề cập đến nó trong một bình luận về một thử thách khác .
ThisSuitIsBlackNot

3

Javascript (ES6), 107

Tôi muốn JS có một hàm pad tích hợp. Ồ tốt

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

Giải trình:

(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

Julia, 126 byte

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

Ung dung:

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

Tính năng Bash, 62 , 61 +, 59

Ngắn hơn nếu Ncó thể được đặt bởi người gọi, thay vì phải đọc nó như là dòng đầu tiê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

Điều này không thể xử lý các dòng trống trong đầu vào. Mặt khác, điều này không làm cho dữ liệu đầu vào bị tách từ, mở rộng tên đường dẫn hoặc xử lý nó không chỉ là dữ liệu thô.

read -n$Nlưu một ký tự, nhưng cho phép readmunge \.

Điều [[ $r ]]&&này là cần thiết bởi vì read -n4không thể nhìn để thấy rằng char tiếp theo là một dòng mới. Vì vậy, nó đặt rthành chuỗi 4 char và lần đọc tiếp theo tạo ra chuỗi rỗng zero-char. Lọc các dòng mới sai mà không lọc các dòng mới thực sự sẽ yêu cầu trạng thái theo dõi: liệu dòng trước đó có dài tối đa hay không. Hoặc nhiều mã hơn hoặc một cách tiếp cận hoàn toàn khác sẽ là cần thiết.

[[ $r ]]ngắn hơn mức [ -n "$r" ]cần thiết để tránh lỗi nếu dòng bắt đầu bằng -z foo, hoặc là *hoặc cái gì đó, nếu bạn đã sử dụng [ $r ].

Sự biện minh xảy ra với chuỗi định dạng printf "% 4s" tiêu chuẩn.

Kiểm tra với

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

1. Tôi sẽ bao gồm -rtrong số byte. 2. f()(while ... done)ngắn hơn một chút.
Dennis

@Dennis: Nếu không [[ $r ]]&&, nếu N = 4, một dòng đầu vào có độ dài 4 sẽ tạo ra một dòng đầu ra trống mà trước đó không có dòng nào. Bởi vì readtrả về một chuỗi gồm 4 ký tự, sau đó thấy một dòng mới trong cuộc gọi tiếp theo và trả về ngay. Ngoài ra, cảm ơn vì tiền ()boa. Tôi không biết bạn có thể định nghĩa fns theo cách đó.
Peter Cordes

Tôi khuyên bạn nên đọc Mẹo chơi golf ở Bash . Đó là một nguồn tài nguyên tuyệt vời.
Dennis

Trên thực tế, vì whileđã là hợp chất, bạn thậm chí không cần dấu ngoặc đơn:f()while ... done
Dennis

@Dennis: wow, haxx. Cảm ơn các liên kết. Một vài trong số những điều đó là mới đối với tôi và tôi đã sửa một vài điều trong một câu trả lời khác :) Tôi không chơi golf bình thường, nhưng> 15 năm là một người nghiện dòng lệnh đã dạy cho tôi một hoặc hai điều :)
Peter Cordes

2

Haskell, 108 byte

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

Ví dụ sử dụng:

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

    b
   cd
Matam
orpho
  sis

Làm thế nào nó hoạt động

                              .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}}/^$/')

Sử dụng bash để ghi số đếm vào chương trình awk là thăm dò. nhỏ hơn đọc nó với một NR==1{N=$0}khối.

Đọc một dòng tại một thời điểm. Chia thành nhiều nhất 4 ký tự, sử dụng FPAT. (khớp với các trường, thay vì các dấu phân cách. Phần mở rộng GNU.) printf từng trường riêng biệt. (ORS mặc định = \ n).

Các /^$/quy tắc là có in dòng sản phẩm nào, có NF = 0 và do đó không in ở tất cả các khối khác. Vì vậy, không giống như giải pháp bash thuần túy của tôi, điều này thực sự hoạt động trong trường hợp chung.

Không liên quan, nhưng ý tưởng của tôi cho perl là 112 ký tự chỉ cho mã perl:

(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.=$_;}}'

Điều này ăn một trong những dòng mới, và quá dài. $/=\1đọc một byte tại một thời điểm. Chúng tôi nối vào $ l. Có lẽ cách tiếp cận phân chia theo chiều rộng cố định sẽ ngắn hơn.


1

Đồ dùng Bash + GNU, 41

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

Chuỗi là đầu vào thông qua STDIN, chiều rộng được nhập bởi dòng lệnh arg:

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

1

Python 2, 151 byte

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:]

Đây là bản phóng tác của câu trả lời của @ xnor ở trên, vì câu trả lời của anh ta không đúng cách.


Các forvòng lặp đã được thay đổi từ:

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

đến:

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

Thí dụ

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


Puzzl
   es

    &

 Code
 Golf

1

C #, 143 byte

(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 cho phép bạn thực hiện các biểu hiện đẹp mắt. GroupByở đây rất hữu ích, nhưng thật đáng tiếc khi họ không thể tạo ra tình trạng quá tải hàm khi lấy chỉ mục.

Chỉ định lambda cho a Func<string, int, string>để chạy nó

Ít chơi gôn hơn:

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 byte

Trả về chuỗi được phân bổ chính xác. Không biết có chức năng padLeft (và padRight, padCenter) cho đến bây giờ.

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

Tích Lan, 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 byte

Cảm ơn @beaker đã xóa 6 byte!

Sử dụng và chức năng ẩn danh:

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

Xác định hàm và sử dụng ansđể gọi nó:

>> @(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

Burlesque, 28 byte

Giống như phiên bản bên dưới, nhưng coi dòng 1 là số và các dòng khác là chuỗi.

lng_riPpun{pPco{pP' lp}mu}Wl

Cách sử dụng như trong:

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

Phiên bản cũ (16 byte):

{5co{5' lp}mu}Wl

Thí dụ:

blsq ) "Programming\nPuzzles\n&\nCode\nGolf"{5co{5' lp}mu}Wl
Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.