강 피하기


48

배경

타이포그래피에서 은 텍스트 블록의 시각적 간격으로 우연히 공백이 정렬되어 발생합니다. 뇌가 말초 시력에서 더 쉽게 포착되어 눈을 끊임없이 산만하게하므로 특히 성가신 일입니다.

예를 들어, 줄 너비가 82자를 초과하지 않도록 줄 바꿈 된 다음 텍스트 블록을 사용하십시오 .

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.

오른쪽 아래 부분에 6 줄로 된 강이 있는데, 다음 블록에서 강조했습니다.

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.

약간 다른 열 너비를 선택하여이를 완화 할 수 있습니다. 예를 들어 78자를 넘지 않는 줄을 사용하여 동일한 텍스트를 배치하면 두 줄을 넘지 않는 강이 없습니다.

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.

이 질문의 목적을 위해 강은 단순히 수직 공간의 열과 같이 고정 폭 글꼴 만 고려하고 있습니다. 강의 길이는 강의 길이입니다.

따로 : 비례 글꼴로 강을 감지하는 데 흥미가 있다면 , 네트워크 주변에 흥미로운 게시물 이 있습니다.

도전

인쇄 가능한 ASCII 문자 (코드 포인트 0x20 ~ 0x7E)가 제공됩니다. 즉, 한 줄입니다. 텍스트에서 강의 최대 길이가 최소화되도록 70 ~ 90 자 (포함) 사이의 선 너비로이 텍스트를 인쇄하십시오 . 최대 강 길이가 동일한 (최소) 텍스트 너비가 여러 개인 경우 더 좁은 너비를 선택하십시오. 78 자로 된 위의 예는 해당 텍스트에 대한 올바른 출력입니다.

줄 바꿈을하려면 공백 문자 (0x20)를 줄 바꿈으로 바꿔 결과 줄에 가능한 한 많은 문자가 있지만 선택한 텍스트 너비를 초과하지 않아야합니다. 결과 줄 바꿈 자체는 해당 수의 일부가 아닙니다. 예를 들어, 위의 마지막 블록 Lorem[...]tempor에는 텍스트의 너비이기도 한 78자를 포함합니다.

입력에 연속 공백이없고 선행 또는 후행 공백이 없다고 가정 할 수 있습니다. 또한 공백이 아닌 연속 된 하위 문자열 인 단어가 70자를 초과하지 않는다고 가정 할 수 있습니다.

STDIN, 명령 행 인수 또는 함수 인수를 통해 입력을 받고 결과를 STDOUT에 인쇄하는 프로그램 또는 함수를 작성할 수 있습니다.

이것은 코드 골프이므로 가장 짧은 대답 (바이트)이 이깁니다.


78 및 82 열 줄 바꿈 예제에서 마지막 줄과 마지막 줄이 잘못되었다고 생각합니다. 82 예제에서 마지막 중단은 idest 사이 있어야하고 78 예제에서는 inculpa 사이 있어야합니다 . 아니면 내가 잘못하고 있습니까?
Cristian Lupascu

@Optimizer 타이 브레이크는 강 길이가 아니라 텍스트 길이입니다.
FryAmTheEggman

나는 공식 강으로 계산하지 않습니다 생각하지만, 예를 들어 78 개 문자 최대 길이, 상단 틱 왼쪽 틱 지역에 꽤 긴 대각선 강있을 것 같습니다
markasoftware

우리는 같은 경우를 생각 함 강을 계속?
Optimizer

큰 도전! ) 흠, 다음 하나는 잠재 의식 편지를 형성 (안 순전히 수직) 강 문제에 대해 수
토비아스 Kienzler

답변:


7

CJam, 116106 99 84 77 72 바이트

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

단일 라인 입력을 가져 와서 올바른 출력을 STDOUT에 인쇄합니다.

업데이트 : 정렬 루프 자체에서 모든 계산을 수행하여 로트를 개선하고 중복 루프를 제거했습니다. 강 길이 계산에서 버그가 수정되었습니다.

곧 설명 (내가 더 골프 후)

여기 사용해보십시오


@Optimizer ARGV의 입력을 사용할 수 있지만 매번 ea~대신 할 수 있습니다 X. 2 바이트를 저장합니다.
Martin Ender

12

루비 162 160 158 152 160 157 ( 데모 )

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

골프화되지 않은 버전 :

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{...}를 사용하면 문자열 보간을 사용할 수 있습니다. 방금 시도 21.times했지만 더 많은 영향을 미쳤으며 더 짧은 솔루션에 도달하지 못했습니다.
Cristian Lupascu

@ MartinBüttner 당신은 맞습니다, 그것은 작동 합니다! 내 답변을 편집했습니다. 감사!
Cristian Lupascu

이 작동하지 않습니다 pastebin.com/vN2iAzNd
Joshpbarron

@Joshpbarron 아주 잘 발견되었습니다! 나는 지금 고쳤다.
Cristian Lupascu

8

APL (105)

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

설명:

  • (K⊂⍨' '=K←' ',⍵): 앞에 공백을 추가 한 다음 공백으로 분할 하십시오. 각 단어는 시작하는 공간을 유지합니다.
  • ∘{... }¨70+⍳21: 해당 값을 사용하여 범위의 각 숫자에 대해 [71, 91]: (단어가 분리되는 방식으로 인해 각 '행'은 처음에 여분의 공백으로 끝나고 나중에 제거됩니다. 범위는 여분의 공간을 보완하기 위해 하나).
    • ×⍴⍺:: 여전히 단어가 남아 있으면
      • z←⍵>+\≢¨⍺: 각 단어의 길이를 구하고 단어 당 길이의 누계를 계산합니다. 1다음 줄을 채울 수있는 단어를 모두 표시 하고에 저장하십시오 z.
      • (⊂z/⍺),⍵∇⍨⍺⍨~z: 그 단어들을 가지고 남은 것을 처리하십시오.
    • ⋄⍺: 그렇지 않은 경우, 리턴합니다 (현재 비어 있음).
  • G←: 라인리스트리스트를 G(가능한 각 라인 길이마다 하나씩) 저장합니다.
  • V←{... }¨G: 각 가능성에 대해 가장 긴 강의 길이를 계산하여 다음에 저장하십시오 V.
    • +\↑≢¨¨⍵: 각 단어의 길이를 (다시) 얻고 길이에서 행렬을 만듭니다. 행렬의 행에서 각 줄의 누적 합계를 계산하십시오. 따라서 각 줄의 시작 부분에있는 추가 공간은 무시됩니다.
    • 2≠⌿: 행렬의 각 열에 대해 해당 지점의 현재 줄 길이가 그 이후의 줄과 일치하지 않는지 확인하십시오. 그렇다면,이 없다 가 강.
    • ⊂⍨¨↓⍉: 행렬의 각 열을 1s로 나눕니다 . 이것은 강의 [1, 0, 0, ...]길이에 따라 각 강마다 목록이있는 목록의 목록을 제공합니다 . 강이 없으면 목록은입니다 [1].
    • ⌈/≢¨: 각 강의 길이를 얻고 최대 값을 얻습니다.
  • ⊃G/⍨V=⌊/V:에서 G가장 긴 강의 길이가 모든 항목의 최소 길이와 동일한 첫 번째 항목을 선택하십시오.
  • {1↓∊⍵,3⊃⎕TC}¨: 각 줄마다 모든 단어를 결합하고 주먹 항목 (처음부터 여분의 공간)을 제거하고 끝에 줄 바꿈을 추가하십시오.
  • : 모든 라인을 결합하십시오.

105가 아닌 200 바이트입니다.
user11153

3
@ user11153 UTF-8을 인코딩으로 지정하지 않았습니다. APL 문자 세트는 단일 코드 페이지에 적합하며 해당 코드 페이지 가 존재 합니다. 즉, 해당 문자 각각이 바이트에 맞는 기존 인코딩이 있으므로 105가 완벽합니다.
Martin Ender

알아 둘만 한! :)
user11153

8

배시로 coreutils +, 236 157 바이트

다른 접근 방식으로 편집-이전보다 약간 짧았습니다.

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

명령 행에서 입력 문자열을 읽습니다.

3 개의 중첩 된 정렬을 사용하면 큰 O 시간 복잡성이 무엇인지 생각하기를 두려워하지만 내 컴퓨터에서 10 초 안에 예제를 완료합니다.


3

파이썬, 314 바이트

SP3000, grc 및 FryAmTheEggman 덕분에 많은 감사를드립니다 :

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과 유사
Optimizer

3

자바 스크립트 (ES6) 194 202

반복적 솔루션, 재귀적일 경우 더 짧을 수 있음

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)
}

설명

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 콘솔에서 테스트하십시오 .

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.')

산출

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

파이썬 3, 329 바이트

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

언 골프 버전 :

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