Nehirlerden Kaçınmak


48

Arka fon

Tipografide nehirler , rastlantısal boşlukların hizalanmasından dolayı oluşan bir metin bloğundaki görsel boşluklardır. Bunlar özellikle sinir bozucu çünkü beyniniz onları sürekli rahatsız eden periferik görüşte daha kolay alıyor gibi görünüyor.

Örnek olarak, aşağıdaki metin bloğunu alın, satır genişliği 82 karakteri geçmeyecek şekilde kesilmiş satırlar :

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor
incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eismod tempor incididunt ut labore et dolore
maga aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
est laborum.

Aşağıdaki satırda vurguladığım sağ alt kısımda altı çizgiyi kapsayan bir nehir var:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor
incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum. Lorem█ipsum dolor sit amet,
consectetur adipisicing elit, sed do eismod tempor█incididunt ut labore et dolore
maga aliqua. Ut enim ad minim veniam, quis nostrud█exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute█irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla█pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui█officia deserunt mollit anim id
est laborum.

Biraz farklı bir sütun genişliği seçerek bunu hafifletebiliriz. Örneğin, aynı metni 78 karakterden uzun olmayan satırları kullanarak düzenlersek, iki satırdan daha uzun nehir olmaz:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor
incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt
in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor
sit amet, consectetur adipisicing elit, sed do eismod tempor incididunt ut
labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.

Unutmayın ki bu sorunun amacı sadece monospaced yazı tiplerini göz önünde bulunduracağız. Bir nehrin uzunluğu, yaydığı hat sayısıdır.

Bir kenara: Eğer orantılı yazı tiplerinde nehir algılamasında ilginçseniz, ağın etrafında bazı ilginç yazılar var.

Meydan okuma

Size yazdırılabilir bir ASCII karakter dizisi (kod noktası 0x20 - 0x7E) verilir - yani tek bir satır. Metin içindeki herhangi bir nehrin maksimum uzunluğu en aza indirilecek şekilde, 70 ile 90 karakter (dahil) arasında bir çizgi genişliğiyle bu metni yazdırın . Aynı (minimum) maksimum nehir uzunluğuna sahip birden fazla metin genişliği varsa, daha dar genişliği seçin. 78 karakterden oluşan yukarıdaki örnek, bu metin için doğru çıktıdır.

Satırları kesmek için, boşluk karakterlerini (0x20) satır sonları ile değiştirmelisiniz, böylece sonuçta ortaya çıkan satırlar mümkün olduğu kadar karaktere sahip olur, ancak seçilen metin genişliğinden daha fazla olmaz. Ortaya çıkan satır sonu kendisinin bu sayının bir parçası olmadığını unutmayın. Örnek olarak, yukarıdaki son satırda Lorem[...]tempor, metnin genişliği olan 78 karakter var.

Girişin ardışık boşluklar içermeyeceğini ve baştaki veya takip eden boşluklara sahip olmayacağını varsayabilirsiniz. Ayrıca hiçbir kelimenin (ardışık olmayan boşlukların alt dizesi) 70'den fazla karakter içermeyeceğini de varsayabilirsiniz.

STDIN, komut satırı argümanı veya işlev argümanı üzerinden giriş alarak ve sonucu STDOUT'a yazdırarak bir program veya işlev yazabilirsiniz.

Bu kod golf, yani en kısa cevap (bayt cinsinden) kazanır.


78 ve 82 sütun sarma örneklerinde, son ve ikinci-son çizgilerin yanlış olduğunu düşünüyorum. 82 örnekte, son mola id ve est arasında olmalı ve 78 örnekte ise in ve culpa arasında olmalıdır . Yoksa yanlış bir şey mi yapıyorum?
Cristian Lupascu

@Optimizer Bağlantı kopması, nehir uzunluğu değil metin uzunluğudur.
FryAmTheEggman

Sanırım resmi bir nehir sayılmaz, ancak en fazla 78 karakter uzunluğunda, en üst sol-sol alan bölgesinde oldukça uzun bir çapraz nehir var gibi görünüyor
markasoftware

Biz gibi durumlarda göz önünde bulunduruyor musunuz bu kadar nehirleri devam?
Doktoru

Büyük zorluk! Hm, bir sonraki bilinçaltı harfleri şekillendiren (tamamen dikey olmayan) nehirlere sahip olmakla ilgili olabilir;)
Tobias Kienzler 6:14

Yanıtlar:


7

CJam, 116 106 99 84 77 72 bayt

l:X;93,72>{:D;OOXS/{S+_2$+,D<{+}{@@);a+\}?}/a+}%{z'K*S/:!0a/1fb$W=}$0=N*

Tek satır girişini alır ve doğru çıkışı STDOUT'a yazdırır.

GÜNCELLEME : Sıralama döngüsünün kendisinde tüm hesaplamaları yaparak çok fazla geliştirme yapıldı ve gereksiz döngüler kaldırıldı. Ayrıca nehir uzunluğu hesaplamasında bir hata düzeltildi.

Açıklama yakında (daha da golf oynadıktan sonra)

Burada dene


@Optimizer ARGV'den gelen girişi kullanabilirsiniz, ancak her seferinde ea~yerine kullanabilirsiniz X. İki bayt kaydeder.
Martin Ender

12

Yakut 162 160 158 152 160 157 ( demo )

i=gets+' '
(69..s=r=89).map{|c|w=i.scan(/(.{1,#{c}}\S) /).flatten
m=(0..c).map{|i|w.map{|l|l[i]}+[?x]}.join.scan(/ +/).map(&:size).max
m<s&&(s=m;r=w)}
puts r

Un golfed versiyonu:

input = gets+' '

result = ''

(69..smallest_max=89).each{|w|
  #split text into words of at most w characters
  wrap = (input+' ').scan(/(.{1,#{w}}\S) /).flatten

  #transpose lines and find biggest "river"
  max_crt_river = (0..99).map{|i| wrap.map{|l|l[i]} }.flatten.join.scan(/ +/).max_by(&:size).size

  if max_crt_river < smallest_max
    smallest_max = max_crt_river
    result = wrap.join ?\n
  end
}
puts result

@ MartinBüttner %r{...}string enterpolasyonu kullanmama izin veriyor. Yeni denedim 21.timesama yolun biraz daha üzerinde sonuçları var ve daha kısa bir çözüme ulaşamadım.
Cristian Lupascu

MartinBüttner Haklısınız @, o does işi! Cevabımı düzenledim. Teşekkürler!
Cristian Lupascu


@Joshpbarron Çok iyi benekli! Şimdi tamir ettim.
Cristian Lupascu

8

APL (105)

{∊{1↓∊⍵,3⊃⎕TC}¨⊃G/⍨V=⌊/V←{⌈/≢¨⊂⍨¨↓⍉2≠⌿+\↑≢¨¨⍵}¨G←(K⊂⍨' '=K←' ',⍵)∘{×⍴⍺:(⊂z/⍺),⍵∇⍨⍺/⍨~z←⍵>+\≢¨⍺⋄⍺}¨70+⍳21}

Açıklama:

  • (K⊂⍨' '=K←' ',⍵): Önce bir boşluk ekleyin , sonra boşluklara bölün . Her kelime, başladığı alanı korur.
  • ∘{... }¨70+⍳21: bu değerle, aralıktaki her sayı için [71, 91]: (Kelimelerin ayrılmasından dolayı, her 'satır' başlangıçta daha sonra kaldırılacak olan fazladan bir boşlukla sona erer. Ekstra alan için telafi etmek için bir tane.)
    • ×⍴⍺:: Hala kelimeler kaldıysa,
      • z←⍵>+\≢¨⍺: Her bir kelimenin uzunluğunu alın ve kelime başına düşen toplam uzunluğu hesaplayın. Bir 1sonraki satırı doldurmak için alınabilecek tüm kelimeleri işaretleyin ve bunu saklayın z.
      • (⊂z/⍺),⍵∇⍨⍺⍨~z: bu kelimeleri alın ve listeden kalanları işleyin.
    • ⋄⍺: değilse, geri dön (şimdi boş).
  • G←: satır listelerinin listesini saklayın G(her satır uzunluğu için bir tane).
  • V←{... }¨G: her olasılık için en uzun nehrin uzunluğunu hesaplayın ve saklayın V:
    • +\↑≢¨¨⍵: her kelimenin uzunluğunu (tekrar) alın ve uzunluklarından bir matris yapın. Matrisin satırlarındaki her satır için koşu toplamını hesaplayın. (Böylece, her satırın başındaki fazladan boşluk göz ardı edilir.)
    • 2≠⌿: matrisin her sütunu için , o noktadaki çizginin geçerli uzunluğunun ondan sonraki çizgiyle eşleşip eşleşmediğine bakın. Eğer öyleyse, orada değil orada bir nehir.
    • ⊂⍨¨↓⍉: matrisin her sütununu kendi başına böle ( 1s). Bu, her bir nehir için nehrin [1, 0, 0, ...]uzunluğuna bağlı olarak bir liste olacak listelerin bir listesini verir . Nehir yoksa, liste olacaktır [1].
    • ⌈/≢¨: Her bir nehrin uzunluğunu ve bunun maksimum değerini al.
  • ⊃G/⍨V=⌊/V: arasından G, en uzun nehrin uzunluğunun tüm maddeler için minimum değere eşit olduğu ilk maddeyi seçin.
  • {1↓∊⍵,3⊃⎕TC}¨: her satır için, tüm kelimeleri bir araya getirin, ilk öğeyi (başlangıçtan fazladan boşluk) kaldırın ve sonuna yeni bir satır ekleyin.
  • : tüm çizgileri bir araya getirin.

Bu 200 bayt, 105 değil.
user11153

3
@ user11153 UTF-8'i kodlama olarak belirtmedim. APL karakter kümesi tek bir kod sayfasına uyar (ve bu kod sayfasının varlığı var ), yani bu karakterlerin her birinin bir bayta sığdığı mevcut bir kodlama var ve bu yüzden 105 mükemmel bir şekilde iyi durumda.
Martin Ender

Bilmek güzel! :)
user11153

8

Bash + coreutils, 236 157 bayt

Farklı bir yaklaşımla düzenlendi - öncekinden biraz daha kısa:

a=(`for i in {71..91};{
for((b=1;b++<i;));{
fold -s$i<<<$@|cut -b$b|uniq -c|sort -nr|grep -m1 "[0-9]  "
}|sort -nr|sed q
}|nl -v71|sort -nk2`)
fold -s$a<<<$@

Giriş dizesini komut satırından okur.

İç içe geçmiş 3 çeşitle, bunun için büyük O zaman karmaşıklığının ne olduğunu düşünmekten çekiniyorum, ancak örneği makinemde 10 saniyenin altında tamamlıyor.


3

Python, 314 bayt

SP3000, grc ve FryAmTheEggman'a çok teşekkürler:

b=range;x=len
def p(i):
 l=[];z=''
 for n in t:
  if x(z)+x(n)<=i:z+=n+' '
  else:l+=[z];z=n+' '
 return l+[z]*(z!=l[x(l)-1])
t=input().split();q=[]
for i in b(70,91):l=p(i);q+=[max(sum(x(l[k+1])>j<x(l[k])and l[k][j]is' '==l[k+1][j]for k in b(x(l)-1))for j in b(i))]
print(*p(q.index(min(q))+70),sep='\n')

2
Pi-thon benzeri
Optimizer

3

JavaScript (ES6) 194 202

Yinelemeli çözüm, özyinelemeli olursa belki daha kısa

F=s=>{
  for(m=1e6,b=' ',n=70;n<91;n++)
    l=b+'x'.repeat(n),x=r=q='',
    (s+l).split(b).map(w=>
      (t=l,l+=b+w)[n]&&(
        l=w,r=r?[...t].map((c,p)=>x<(v=c>b?0:-~r[p])?x=v:v,q+=t+'\n'):[]
      )
    ),x<m&&(o=q,m=x);
  alert(o)
}

Açıklaması

F=s=> {
  m = 1e9; // global max river length, start at high value
  for(n=70; n < 91; n++) // loop on line length
  {
    l=' '+'x'.repeat(n), // a too long first word, to force a split and start
    x=0, // current max river length
    q='', // current line splitted text
    r=0, // current river length for each column (start 0 to mark first loop)
    (s+l) // add a too long word to force a last split. Last and first row will not be managed
    .split(' ').map(w=> // repeat for each word 
      (
        t=l, // current partial row in t (first one will be dropped)
        (l += ' '+w)[n] // add word to partial row and check if too long
        &&
        (
          l = w, // start a new partial row with current word
          r=r? // update array r if not at first loop
          ( 
            q+=t+'\n', // current row + newline added to complete text 
            [...t].map((c,p)=>( // for each char c at position p in row t
              v = c != ' ' 
                ? 0 // if c is not space, reset river length at 0
                : -~r[p], // if c is space, increment river length
              x<v ? x=v : v // if current > max, update max
            ))
          ):[]  
        )  
      )
    )
    x < m && ( // if current max less than global max, save current text and current max
      o = q,
      m = x
    )
  }
  console.log(o,m)
}

FireFox / FireBug konsolunda test edin .

F('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')

Çıktı

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor
incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt
in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor
sit amet, consectetur adipisicing elit, sed do eismod tempor incididunt ut
labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.

3

Python 3, 329 bayt

import re,itertools as s
def b(t,n):
 l=0;o=""
 for i in t.split():
  if l+len(i)>n:o=o[:-1]+'\n';l=0
  l+=len(i)+1;o+=i+' '
 return o
t=input();o={}
for n in range(90,69,-1):o[max([len(max(re.findall('\s+',x),default='')) for x in ["".join(i) for i in s.zip_longest(*b(t,n).split('\n'),fillvalue='')]])]=n
print(b(t,o[min(o)]))

Ungolfed versiyonu:

# Iterates over words until length > n, then replaces ' ' with '\n'
def b(t,n):
    l = 0
    o = ""
    for i in t.split():
        if l + len(i) > n:
            o = o[:-1] + '\n'
            l = 0
        l += len(i) + 1
        o += i + ' '
    return o

t = input()
o = {}
# range from 90 to 70, to add to dict in right order
for n in range(90,69,-1):
    # break text at length n and split text into lines
    temp = b(t,n).split('\n')
    # convert columns into rows
    temp = itertools.zip_longest(*temp, fillvalue='')
    # convert the char tuples to strings
    temp = ["".join(i) for i in temp]
    # findall runs of spaces, get longest run and get length
    temp = [len(max(re.findall('\s+',x),default='')) for x in temp]
    # add max river length as dict key, with line length as value
    o[max(temp)] = n

print(b(t,o[min(o)]))
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.