텍스트를 오른쪽 정렬


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

입력 라인의 중간에 공백이있을 수 Programming Puzzles\n&\nCode Golf있습니까? 예 : ?
Sp3000

@ sp3000 공백을 포함한 모든 문자가있을 수 있습니다.
Trebuchette

@Timwi :이 예에는 한 줄에 한 단어가 있습니다. 한 줄 내의 공간이 특별하지 않다는 것을 분명히하기 위해 여러 단어로 된 줄을 포함하는 것이 좋습니다. (즉, 줄 바꿈과 줄 바꿈이 없습니다.)
Peter Cordes

답변:



10

파이썬 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}

1 바이트로 골프를 치고 3 개 더 길을 포장하는 @ Sp3000에 감사합니다.

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

펄, 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으로부터 그 트릭을 배웠습니다 .
ThisSuitIsBlackNot

3

자바 스크립트 (ES6), 107

JS에 내장 패드 기능이 있었으면 좋겠습니다. 오 잘

(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

배쉬, 62 , 61 + 피처, 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다음 문자가 줄 바꿈 것을 볼 내다 수 없습니다. 따라서 r4 문자 문자열로 설정되고 다음 읽기는 0 문자 빈 문자열을 생성합니다. 실제 줄 바꿈을 필터링하지 않고 이러한 잘못된 줄 바꿈을 필터링하려면 이전 줄이 최대 길이인지 여부와 같은 추적 상태가 필요합니다. 더 많은 코드 또는 완전히 다른 접근 방식이 필요합니다.

[[ $r ]]보다 짧은 [ -n "$r" ]줄로 시작하는 경우 오류를 방지 할 필요가있는 -z foo, 또는이 *또는 뭔가 사용한 경우 [ $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

@Dennis :없는 [[ $r ]]&&경우 N = 4 인 경우 길이 4의 입력 라인은 이전에 없었던 빈 출력 라인을 생성합니다. 때문에 read반환 4 개 문자의 문자열은 다음 바로 다음 호출 및 반환에 줄 바꿈을 본다. 또한 ()팁 주셔서 감사합니다 . 그런 식으로 fns를 정의 할 수 있다는 것을 몰랐습니다.
Peter Cordes

Bash에서 골프 팁을 읽는 것이 좋습니다 . 훌륭한 자료입니다.
Dennis

실제로 while는 이미 복합적이므로 괄호도 필요하지 않습니다.f()while ... done
Dennis

@ 데니스 : 와우, haxx. 링크 주셔서 감사합니다. > 명령 줄 마약 중독자 나에게 한 두 가지 :) 강의하고있는 15 년의 것들 중 몇은 나에게 새로운했고, 나는 다른 답변 : 내가 골프 일반적으로하지 않습니다에 몇 가지 고정,하지만
피터 Cordes

2

하스켈, 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 솔루션과 달리 이것은 일반적인 경우에 실제로 작동합니다.

semi-unrelated, 그러나 지금까지 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

배쉬 + GNU 유틸리티, 41

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

문자열은 STDIN을 통해 입력되고 너비는 명령 줄 인수로 입력됩니다.

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

1

파이썬 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여기서는 유용하지만 인덱스를 사용하는 함수 과부하를 만들 수 없다는 것은 부끄러운 일입니다.

람다를 할당하여 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

그루비, 63 바이트

올바르게 할당 된 문자열을 반환합니다. 지금까지 padLeft (및 padRight, padCenter) 기능이 있는지 몰랐습니다.

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

1

자바 스크립트 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 바이트

6 바이트를 제거해 주신 @beaker에게 감사드립니다!

사용 및 익명 기능 :

@(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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.