Metin sağa hizala


27

İşiniz bir dize girişi ve bir sayı almak ve dize sağa doğru hizalamak, metnin genişliğini sayı yapmaktır. Bir çizgi çok uzun olduğunda, onu kırın ve gerisini bir sonraki satıra koyun, gerekmedikçe tekrar edin. Bir çizgi genişliğinden kısaysa, boşlukla doldurun. Birden çok yeni satır oluşabilir ve herhangi bir tek karakter gibi ele alınmalıdır.

Örneğin, dize

Programming
Puzzles
&
Code
Golf

ve sayı 5üretecek:

Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf

Oysa aynı dizge ve sayı 10üretecekti:

Programmin
         g
   Puzzles
         &
      Code
      Golf

Dize

a

b

ve 5 sayısı şöyle olacaktır:

    a
      <-- note the 5 spaces
    b

En kısa kod kazanır!


1
Metin “ Gerektiğinde satırları kes […]” diyor, ancak örnekleriniz uygun olduğunda bile her kelimeden sonra kesmenizi önerir . Lütfen açıklayınız: Her bir kelimeyi yeni bir satıra mı yerleştiriyoruz yoksa gerçek bir kelime sarma algoritması uyguluyor muyuz?
Timwi

Bir giriş hattının ortasında örneğin boşluklar olabilir Programming Puzzles\n&\nCode Golfmi?
Sp3000

@ sp3000 Boşluklar dahil herhangi bir karakter olabilir.
Trebuchette

@Timwi: Örnek, satır başına bir kelime içeriyor. Bir satır içindeki boşluğun özel olmadığını açıklığa kavuşturmak için bazı çok kelimeli satırları eklemek daha iyi olurdu. (yani sadece yeni satırlar ve yeni satırlar yok.)
Peter Cordes

Yanıtlar:



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

Girdiyi yeni satırlara ve sayılara sahip bir dize olarak alır ve sonucu yazdırır. Girişteki her satır için, yazdırmadan önce soldaki boşlukları doldurmak için nyerleşikleri kullanarak bir seferde karakterleri alır ve yazdırır rjust.

Boş hat çantasını kesmekle düzelttim w=w or' '. Muhtemelen daha iyi bir yöntem var ama bu konuda fazla düşünmeyeceğim.


8

CJam, 21 bayt

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

1 byte'lık golf attığı ve 3 yol daha bıraktığı için @ Sp3000'e teşekkürler.

CJam tercümanında çevrimiçi olarak deneyin .

Nasıl çalışır

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

Pyth, 16

jm>Q+*\ QdscRQ.z

Burada çevrimiçi deneyin

açıklama

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 bayt

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

İçin 36 bayt + 3 bayt -ni. Kaydırma genişliği, argüman olarak iletilir -i.

Boş satırları boşlukla doldurup düzgün şekilde işler:

$ 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

Nasıl çalışır

Bu çözüm, girdi içinde döngü oluşturmak için ikame operatörünü kullanır ve eşdeğer fordöngüde bir bayt tasarrufu sağlar . Yine de asıl püf nokta, oyuncu değişikliği LHS'sinin regex'inde:

^$|.{1,$^I}

Genel değiştirici ile bu $^I, bir kerede karakterlerle eşleşecektir ; $^Idizede kalan karakterlerden daha az olduğunda , her şeyi sonuna kadar eşleştirir. ^$Boş satırları işlemek için ile birlikte gereklidir. Örneğin:

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

İkamenin RHS'si basitçe printfeşleşen öbeği boşluklarla doldurmak için kullanılır.


Her zaman unutuyorum $^I!
Dom Hastings

@DomHastings Bu hileyi chilemagic'ten öğrendim , başka bir zorlukla ilgili bir yorumda bahsetti .
ThisSuitIsBlackNot

3

Javascript (ES6), 107

JS yerleşik bir pad işlevi olsaydı. Oh iyi.

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

Açıklama:

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

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

Ungolfed:

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

Bash, 62 , 61 + özellik, 59

Eğer kısa Nyerine girişin birinci hattı olarak okumak zorunda kalmadan, bir arayan tarafından ayarlanabilir.

# 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

Bu, girdideki boş satırları işleyemez. Aksi takdirde, bu girdi verilerini kelime bölmeye, yol adını genişletmeye maruz bırakmaz veya başka bir deyişle ham veriden daha fazlası olarak değerlendirmez.

read -n$Nbir karakter kaydeder, ancak readkoşmaya izin verir \.

Bu [[ $r ]]&&gerekli çünkü bir read -n4sonraki karakterin yeni bir satır olduğunu görmek için bakamıyorum. Böylece r4 karakterli bir dizgeye ayarlar ve bir sonraki okuma sıfır karakterli bir boş dizge oluşturur. Bu yanlış yeni satırları gerçek yeni satırları filtrelemeden filtrelemek için izleme durumu gerekir: önceki satırın en fazla uzunlukta olup olmadığı. Ya daha fazla kod ya da tamamen farklı bir yaklaşım gerekli olacaktır.

[[ $r ]]daha kısadır [ -n "$r" ]çizgi ile başlar eğer hataları önlemek için gerekli olan -z fooveya olduğu *ya da bir şey kullandığınız takdirde, [ $r ].

Gerekçe, standart printf "% 4s" format dizgisinde olur.

İle test et

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

1. -rBayt sayısına dahil ediyorum . 2. f()(while ... done)biraz daha kısa.
Dennis,

@Dennis: [[ $r ]]&&Eğer N = 4 değilse, 4 uzunluğundaki bir giriş satırı daha önce olmadığı yerde boş bir çıktı satırı üretecektir. Çünkü read4 karakterli bir karakter döndürür, sonra bir sonraki aramada yeni bir satır görür ve hemen geri döner. Ayrıca, ()bahşiş için teşekkürler . Bunu bu şekilde tanımlayabileceğini bilmiyordum.
Peter Cordes

Bash'ta golf oynamak için ipuçları okumanızı tavsiye ederim . Harika bir kaynak.
Dennis,

Aslında, whilezaten bileşik olduğundan, parantezlere bile ihtiyacınız yoktur:f()while ... done
Dennis

@Dennis: vay, haxx. Bağlantı için teşekkürler. Bunlardan birkaçı benim için yeniydi ve başka bir cevapta birkaç şeyi düzelttim :) Normalde golf oynamıyorum, ancak> 15 yıl komut satırı bağımlısı olmak bana bir iki şey öğretti :)
Peter Kablolar

2

Haskell, 108 bayt

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

Kullanım örneği:

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

    b
   cd
Matam
orpho
  sis

Nasıl çalışır

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

Sayımı awk programına yerleştirmek için bash kullanmak probtur. bir NR==1{N=$0}blokla okumaktan daha küçük .

Bir seferde bir satır okuyun. FPAT kullanarak en fazla 4 karakter parçasına bölün. (ayırıcılar yerine alanları eşleştirir. GNU uzantısı.) her alanı ayrı ayrı yazdırır. (Varsayılan ORS = \ n).

/^$/Kural diğer blokta hiç baskı yok dolayısıyla NF = 0 olması ve boş satırları, orada yazdırmaktır. Bu yüzden benim saf bash çözümümden farklı olarak, bu aslında genel durumda işe yarıyor.

Yarı alakasız, ama perl için şu ana kadarki fikrim, sadece perl kodu için 112 karakter:

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

Bu, yeni hatlardan birini yiyor ve çok uzun. $/=\1her seferinde bir bayt okur. L $ 'a ekliyoruz. Muhtemelen sabit genişlikte bölünmüş yaklaşıma sahip her seferinde bir hat daha kısa olacaktır.


1

Bash + GNU yardımcı programları, 41

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

Dize STDIN ile girilir, genişlik komut satırı arg ile girilir:

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

1

Python 2, 151 bayt

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

Bu, @ xnor'ın cevabını, yeni satırları doğru şekilde işlememesi nedeniyle uyarlamasıdır.


forDöngü değiştirildi:

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

için:

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

Örnek

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


Puzzl
   es

    &

 Code
 Golf

1

C #, 143 bayt

(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, oldukça kaba ifadeler yapmanızı sağlar. GroupByburada faydalıdır, ancak endeksi alarak fonksiyon aşırı yükleri oluşturamadıkları için utanç vericidir.

Lambda'yı Func<string, int, string>çalıştırmak için a a

Daha az golf oynadı:

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 bayt

Doğru hizalanmış dizeyi döndürür. Şimdiye kadar bir padLeft (ve padRight, padCenter) işlevi olduğunu bilmiyordum.

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

Seylan, 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 bayt

6 baytı kaldırmak için @beaker sayesinde!

Ve anonim işlevi kullanma:

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

İşlevi tanımlayın ve ansaramak için kullanı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 Bayt

Aşağıdaki sürümle aynıdır, ancak satır 1'i sayı olarak ve diğer satırları dize olarak değerlendirir.

lng_riPpun{pPco{pP' lp}mu}Wl

Kullanım şekli:

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

Eski Sürüm (16 bayt):

{5co{5' lp}mu}Wl

Örnek:

blsq ) "Programming\nPuzzles\n&\nCode\nGolf"{5co{5' lp}mu}Wl
Progr
ammin
    g
Puzzl
   es
    &
 Code
 Golf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.