단락 패치


32

Patch the Image 의 정신으로 , 여기에 비슷한 도전이 있지만 텍스트가 있습니다.

도전

비트 부패가 당신의 소중한 텍스트를 괴롭 혔습니다! ASCII 문자로 구성된 단락이 있고 그 안에 어딘가에 직사각형 구멍이있는 경우, 프로그램은 구멍이 적절한 텍스트로 채워지도록하여 단락이 최대한 잘 혼합되도록해야합니다.

추가 정의

  • 구멍은 항상 직사각형이며 여러 줄에 걸쳐있을 수 있습니다.
  • 구멍은 하나뿐입니다.
  • 구멍이 반드시 단어 경계에 속할 필요는 없습니다 (실제로는 그렇지 않습니다).
  • 구멍은 입력 단락의 최대 25 %이지만 "일반"텍스트의 "끝"을 지나서 겹치거나 확장 될 수 있습니다 (아래 유클리드 또는 오소리 예 참조).
  • 구멍을 찾는 것이이 과제의 핵심은 아니기 때문에 #쉽게 식별 할 수 있도록 해시 마크만으로 구성됩니다 .
  • 입력 단락의 다른 위치에는 해시 마크가 없습니다.
  • 귀하의 코드는 아래 예에서 "일반"텍스트를 사용할 수 없습니다. 코드는 구멍이있는 텍스트 만 수신하고 처리합니다.
  • 입력은 단일 멀티 라인 문자열, 문자열 배열 (한 줄에 한 요소), 파일 등이 될 수 있습니다. 언어에 가장 편리한 것을 선택하십시오.
  • 원하는 경우, 홀의 좌표를 상세히 설명하는 선택적 추가 입력이 취해질 수있다 (예를 들어, 튜플 좌표 등).
  • 제출시 알고리즘을 설명하십시오.

투표

유권자는 알고리즘이 텍스트 구멍을 얼마나 잘 채우는 지에 따라 항목을 판단해야합니다. 몇 가지 제안 사항은 다음과 같습니다.

  • 채워진 영역이 단락의 나머지와 같이 대략적인 공백 및 구두점 분포와 일치합니까?
  • 채워진 영역에 잘못된 구문이 있습니까? (예를 들어, 연속 된 2 개의 공백, 마침표 뒤에 물음표, 잘못된 순서, , 등)
  • 눈을 가늘게 뜨면 (실제로 텍스트를 읽지 않는 경우) 구멍의 위치를 ​​알 수 있습니까?
  • 구멍 바깥에 CamelCase 단어가 없으면 구멍에 포함되어 있습니까? 구멍 바깥에 대문자가 없으면 구멍에 구멍이 있습니까? 구멍 바깥에 대문자가 많이있는 경우 구멍에 비례하는 양이 포함됩니까?

유효 기준

제출물이 유효한 것으로 간주 되려면 홀 외부의 단락 텍스트 (후행 공백 포함)를 변경해서는 안됩니다. 맨 끝의 단일 후행 줄 바꿈은 선택 사항입니다.

테스트 사례

형식은 코드 블록의 원래 단락이며 구멍이있는 동일한 단락입니다. 구멍이있는 단락이 입력에 사용됩니다.

1 (이미지 패치)

In a popular image editing software there is a feature, that patches (The term
used in image processing is inpainting as @minxomat pointed out.) a selected
area of an image, based on the information outside of that patch. And it does a
quite good job, considering it is just a program. As a human, you can sometimes
see that something is wrong, but if you squeeze your eyes or just take a short
glance, the patch seems to fill in the gap quite well.

In a popular image editing software there is a feature, that patches (The term
used in image processing is inpainting as @minxomat pointed out.) a selected
area of an image, #############information outside of that patch. And it does a
quite good job, co#############is just a program. As a human, you can sometimes
see that something#############t if you squeeze your eyes or just take a short
glance, the patch seems to fill in the gap quite well.

2 (게 티즈 버그 주소)

But, in a larger sense, we can not dedicate, we can not consecrate, we can not
hallow this ground. The brave men, living and dead, who struggled here, have
consecrated it, far above our poor power to add or detract. The world will
little note, nor long remember what we say here, but it can never forget what
they did here. It is for us the living, rather, to be dedicated here to the
unfinished work which they who fought here have thus far so nobly advanced. It
is rather for us to be here dedicated to the great task remaining before us-
that from these honored dead we take increased devotion to that cause for which
they gave the last full measure of devotion-that we here highly resolve that
these dead shall not have died in vain-that this nation, under God, shall have
a new birth of freedom-and that government of the people, by the people, for
the people, shall not perish from the earth.

But, in a larger sense, we can not dedicate, we can not consecrate, we can not
hallow this ground. The brave men, living and dead, who struggled here, have
consecrated it, far above our poor power to add or detract. The world will
little note, nor long remember what we say here, but it can never forget what
they did here. It is for us the living, rather, to be dedicated here to the
unfinished work which they who fought here h######################advanced. It
is rather for us to be here dedicated to the######################before us-
that from these honored dead we take increas######################use for which
they gave the last full measure of devotion-######################solve that
these dead shall not have died in vain-that ######################, shall have
a new birth of freedom-and that government of the people, by the people, for
the people, shall not perish from the earth.

3 (로렘 입숨)

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna 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 adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo conse################irure dolor in reprehenderit
in voluptate velit esse cil################giat nulla pariatur. Excepteur
sint occaecat cupidatat non################in culpa qui officia deserunt
mollit anim id est laborum.

4 (재버 워키)

'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.

'Twas brillig, and the slithy toves
Did gyre a######### in the wabe;
All mimsy #########borogoves,
And the mome raths outgrabe.

5 (피타고라스 정리에 대한 유클리드의 증거)

1.Let ACB be a right-angled triangle with right angle CAB.
2.On each of the sides BC, AB, and CA, squares are drawn,
CBDE, BAGF, and ACIH, in that order. The construction of
squares requires the immediately preceding theorems in Euclid,
and depends upon the parallel postulate. [footnote 14]
3.From A, draw a line parallel to BD and CE. It will
perpendicularly intersect BC and DE at K and L, respectively.
4.Join CF and AD, to form the triangles BCF and BDA.
5.Angles CAB and BAG are both right angles; therefore C, A,
and G are collinear. Similarly for B, A, and H.
6.Angles CBD and FBA are both right angles; therefore angle ABD
equals angle FBC, since both are the sum of a right angle and angle ABC.
7.Since AB is equal to FB and BD is equal to BC, triangle ABD
must be congruent to triangle FBC.
8.Since A-K-L is a straight line, parallel to BD, then rectangle
BDLK has twice the area of triangle ABD because they share the base
BD and have the same altitude BK, i.e., a line normal to their common
base, connecting the parallel lines BD and AL. (lemma 2)
9.Since C is collinear with A and G, square BAGF must be twice in area
to triangle FBC.
10.Therefore, rectangle BDLK must have the same area as square BAGF = AB^2.
11.Similarly, it can be shown that rectangle CKLE must have the same
area as square ACIH = AC^2.
12.Adding these two results, AB^2 + AC^2 = BD × BK + KL × KC
13.Since BD = KL, BD × BK + KL × KC = BD(BK + KC) = BD × BC
14.Therefore, AB^2 + AC^2 = BC^2, since CBDE is a square.

1.Let ACB be a right-angled triangle with right angle CAB.
2.On each of the sides BC, AB, and CA, squares are drawn,
CBDE, BAGF, and ACIH, in that order. The construction of
squares requires the immediately preceding theorems in Euclid,
and depends upon the parallel postulate. [footnote 14]
3.From A, draw a line parallel to BD and CE. It will
perpendicularly intersect BC and DE at K and L, respectively.
4.Join CF and AD, to form the triangles BCF and BDA.
5.Angles CAB and BAG are both right angles; therefore C, A,
and G are #############milarly for B, A, and H.
6.Angles C#############e both right angles; therefore angle ABD
equals ang############# both are the sum of a right angle and angle ABC.
7.Since AB#############FB and BD is equal to BC, triangle ABD
must be co#############iangle FBC.
8.Since A-#############ight line, parallel to BD, then rectangle
BDLK has t############# of triangle ABD because they share the base
BD and hav#############titude BK, i.e., a line normal to their common
base, conn#############rallel lines BD and AL. (lemma 2)
9.Since C #############with A and G, square BAGF must be twice in area
to triangl#############
10.Therefo############# BDLK must have the same area as square BAGF = AB^2.
11.Similar############# shown that rectangle CKLE must have the same
area as square ACIH = AC^2.
12.Adding these two results, AB^2 + AC^2 = BD × BK + KL × KC
13.Since BD = KL, BD × BK + KL × KC = BD(BK + KC) = BD × BC
14.Therefore, AB^2 + AC^2 = BC^2, since CBDE is a square.

6 개 (바지, 오소리, 오소리 by 오소리)

Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Mushroom, mushroom, a-
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Mushroom, mushroom, a-
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Mush-mushroom, a
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Argh! Snake, a snake!
Snaaake! A snaaaake, oooh its a snake!

Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Mushroom, mushroom, a-
Badger##################badger, badger,
badger##################badger, badger
Mushro##################
Badger##################badger, badger,
badger##################badger, badger
Mush-mushroom, a
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Argh! Snake, a snake!
Snaaake! A snaaaake, oooh its a snake!

구멍이 3 자 이상이라고 가정 할 수 있습니다.
Rohan Jhunjhunwala

트윗 담아 가기 텍스트의 크기가 주어지면 상당히 안전한 가정입니다.
AdmBorkBork

게 티즈 버그 예에는 명백하게 아스키가 아닌 엠 대시가 포함되어 있습니다. 평범한 아스키 테스트 케이스를 사용한다는 답변 중 하나에서 귀하의 의견에 말한 이후로 지적하십시오.
SuperJedi224

@ SuperJedi224 감사합니다.
AdmBorkBork

답변:


15

파이썬 2

나는 알고 @atlasologist이 이미 파이썬 2에서 해결책을 게시,하지만 내 작업 방식은 조금 다르다. 위, 아래, 왼쪽에서 오른쪽으로 모든 구멍을 뚫고 위의 문자를 5 자 뒤로보고 일치하는 문자를 찾습니다. 여러 문자가 발견되면 가장 일반적인 문자를 선택합니다. 문자가 없으면 위의 문자 제한을 제거합니다. 여전히 문자를 찾을 수 없으면 다시 찾는 문자 수를 줄이고 반복합니다.

def fix(paragraph, holeChar = "#"):
    lines = paragraph.split("\n")
    maxLineWidth = max(map(len, lines))
    lines = [list(line + " " * (maxLineWidth - len(line))) for line in lines]
    holes = filter(lambda pos: lines[pos[0]][pos[1]] == holeChar, [[y, x] for x in range(maxLineWidth) for y in range(len(lines))])

    n = 0
    for hole in holes:
        for i in range(min(hole[1], 5), 0, -1):
            currCh = lines[hole[0]][hole[1]]
            over = lines[hole[0] - 1][hole[1]]
            left = lines[hole[0]][hole[1] - i : hole[1]]

            same = []
            almost = []
            for y, line in enumerate(lines):
                for x, ch in enumerate(line):
                    if ch == holeChar:
                        continue
                    if ch == left[-1] == " ":
                        continue
                    chOver = lines[y - 1][x]
                    chLeft = lines[y][x - i : x]
                    if chOver == over and chLeft == left:
                        same.append(ch)
                    if chLeft == left:
                        almost.append(ch)
            sortFunc = lambda x, lst: lst.count(x) / (paragraph.count(x) + 10) + lst.count(x)
            if same:
                newCh = sorted(same, key=lambda x: sortFunc(x, same))[-1]
            elif almost:
                newCh = sorted(almost, key=lambda x: sortFunc(x, almost))[-1]
            else:
                continue
            lines[hole[0]][hole[1]] = newCh
            break


    return "\n".join(map("".join, lines))

오소리, 오소리, 오소리의 결과는 다음과 같습니다.

Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger 
Mushroom, mushroom, a-                 
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger 
Mushroom, mushroom, a- b               
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger 
Mush-mushroom, a                       
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger 
Argh! Snake, a snake!                  
Snaaake! A snaaaake, oooh its a snake! 

증명 결과는 다음과 같습니다.

1.Let ACB be a right-angled triangle with right angle CAB.                 
2.On each of the sides BC, AB, and CA, squares are drawn,                  
CBDE, BAGF, and ACIH, in that order. The construction of                   
squares requires the immediately preceding theorems in Euclid,             
and depends upon the parallel postulate. [footnote 14]                     
3.From A, draw a line parallel to BD and CE. It will                       
perpendicularly intersect BC and DE at K and L, respectively.              
4.Join CF and AD, to form the triangles BCF and BDA.                       
5.Angles CAB and BAG are both right angles; therefore C, A,                
and G are the same areamilarly for B, A, and H.                            
6.Angles CAB and CA, sqe both right angles; therefore angle ABD            
equals angle ABD becaus both are the sum of a right angle and angle ABC.   
7.Since ABD because theFB and BD is equal to BC, triangle ABD              
must be construction ofiangle FBC.                                         
8.Since A-angle ABD becight line, parallel to BD, then rectangle           
BDLK has the same area  of triangle ABD because they share the base        
BD and have the base thtitude BK, i.e., a line normal to their common      
base, conngle and G, sqrallel lines BD and AL. (lemma 2)                   
9.Since C = BD × BK + with A and G, square BAGF must be twice in area     
to triangle FBC. (lemma                                                    
10.Therefore angle and  BDLK must have the same area as square BAGF = AB^2.
11.Similarly for B, A,  shown that rectangle CKLE must have the same       
area as square ACIH = AC^2.                                                
12.Adding these two results, AB^2 + AC^2 = BD × BK + KL × KC             
13.Since BD = KL, BD × BK + KL × KC = BD(BK + KC) = BD × BC             
14.Therefore, AB^2 + AC^2 = BC^2, since CBDE is a square.

그리고 Jabberwocky의 결과 :

'Twas brillig, and the slithy toves
Did gyre and the mo in the wabe;   
All mimsy toves, anborogoves,      
And the mome raths outgrabe.       

5
그 오소리 하나는 꽤 인상적이며 Jabberwocky는 합법적 인시가 될 수있는 것처럼 보입니다. 잘 하셨어요.
AdmBorkBork

6

파이썬 2

이것은 매우 간단한 솔루션입니다. 평균 단어 길이 A-( A/ 2)와 A+ (A / 2) 다음 샘플에서 패치 영역에 선행 및 후행 공백 트림 청크를 적용합니다. 대문자를 처리하지 않으며,이를 해결할 수있는 커브 볼 테스트 사례가 있다고 확신하지만 예제에서는 괜찮습니다. 모든 테스트를 실행하려면 아래 링크를 참조하십시오.

나는 또한 좋은 측정을 위해 코드에 패치를 넣었다.

def patch(paragraph):
    sample = [x.split() for x in paragraph if x.count('#') < 1]
    length = max([x.count('#') for x in paragraph if x.find('#')])
    s = sum(####################
    sample,[####################
    ])      ####################
    avg=sum(####################
    len(w)  ####################
    for w in####################
    s)//len(s)
    avg_range = range(avg-(avg//2),avg+(avg//2))
    sample = filter(lambda x:len(x) in avg_range, s)
    height=0
    for line in paragraph:
        if line.find('#'):height+=1
        print line.replace('#'*length,' '.join(sample)[(height-1)*length:height*length].strip())
    print '\n'

Lorem Ipsum, 원래 패치 :

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna 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 adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo conseore dolore magnairure dolor in reprehenderit
in voluptate velit esse cilenim minim quisgiat nulla pariatur. Excepteur
sint occaecat cupidatat nonnisi mollit aniin culpa qui officia deserunt
mollit anim id est laborum.

시도 해봐


3
Hehe mushroger...
AdmBorkBork

글쎄, 그것은 흥미로운 방식으로 코드를 패치하지 않습니다.
mbomb007

@ mbomb007 #코드 의 다른 문자 때문입니다 .
atlasologist

@atlasologist 당신이 그것들을 다른 것과 같이 바꾸더라도 @, 흥미로운 것은 없습니다.
mbomb007

4

자바 셰익스피어

표준 영어 표기법을 이해해야하는 사람은 누구입니까? 나만의 것을 만드십시오! 바드가 자신의 말을 할 수 있었던 것처럼. 이 봇은 잘린 단어를 수정하는 것에 대해 크게 걱정하지 않고 실제로 임의의 단어를 삽입합니다. 결과는 아름다운시입니다. 보너스 기능으로 바드는 더 높은 구경을 가지고 있으며 같은 크기라면 여러 개의 구멍을 처리 할 수 ​​있습니다!


샘플 입력

 가장 공정한 생물로부터 우리는 증가를 원합니다.
  그로 인해 아름다움의 장미는 결코 죽지 않을 것입니다.
  그러나 시간이 지남에 따라 익히면
  그의 입찰 ############ 그의 기억을 품다 :
  그러나 너는 C ##########
  Feed'st th ############ 자급 연료와 동일,
  풍요가있는 곳에 기근을 일으키고
  너의 자아, 너의 너무나 잔인한 자아에게 :
  그 예술은 이제 세상의 신선한 장식입니다.
  화려한 봄에 예고 만
  너의 새싹이 너의 가장 장엄한 내용 안에서
  그리고 부드러운 churl mak'st was ############ ding :
    세상을 불쌍히 여기거나 그렇지 않으면 t ############,
    세계의 만남을 먹으려면 b ############ 그리고 그대.


                     2
  겨울이 네 눈썹을 포위 할 때
  그리고 당신의 아름다움 분야에서 깊은 참호를 파십시오.
  젊음의 자랑스런 정복이 지금 너무 흥얼 거리고
  소액의 잡초가 될 것입니다.  
  그때 네 모든 아름다움이 어디에 있는지 묻고
  당신의 혹독한 날의 모든 보물이있는 곳;
  네 자신의 깊은 침몰 한 눈 속에서
  모든 것을 먹는 부끄러운 일이었고, 냉담한 칭찬이었습니다.
  당신의 아름다움을 사용할만한 가치가 얼마나 더 많은지,
  당신이 대답 할 수 없다면 '이 공정한 내 아이
  내 카운트를 합산하고 오래된 변명을하자 '
  계승하여 그의 아름다움을 증명.
    이것은 네가 늙었을 때 새로 만들어 졌어 야했다.
    차갑게 느껴질 때 피가 따뜻해지는 것을보십시오.


                     삼
  네 유리를보고 네가 본 얼굴을 말하라
  이제 얼굴이 다른 얼굴을 만들어야 할 때입니다.
  당신이 지금 갱신하지 않으면 누구의 신선한 수리,
  너는 세상에 죄를 짓고 어머니를 축복하지 말라.
  귀가없는 자궁이있는 곳은 어디입니까?
  당신의 축산의 경작을 경멸합니까?
  아니면 누가 그렇게 좋아합니까 무덤이 될 것입니다,
  후손을 멈출 자신의 사랑?  
  너는 네 어머니의 유리와 네게있는 그녀
  그녀의 총리의 사랑스러운 4 월을 다시 불러옵니다.
  그래서 네가 네 나이의 창문을 통해보아야한다.
  ############에도 불구하고 당신의 황금 시간.
    그러나 th ############이 아닌 경우
    죽어가는 너 ############

아름다운 출력

 가장 공정한 생물로부터 우리는 증가를 원합니다.
  그로 인해 아름다움의 장미는 결코 죽지 않을 것입니다.
  그러나 시간이 지남에 따라 익히면
  그의 부드러운 그의 기억은 :
  그러나 너는 모두 너의 밝은 눈을 가졌다.
  자급 연료를 공급하거나
  풍요가있는 곳에 기근을 일으키고
  너의 자아, 너의 너무나 잔인한 자아에게 :
  그 예술은 이제 세상의 신선한 장식입니다.
  화려한 봄에 예고 만
  너의 새싹이 너의 가장 장엄한 내용 안에서
  그리고 당신의 부드러운 쇠 막살은 내 딩이었다.
    세상을 불쌍히 여기십시오.
    세계의 마감일을 먹으려면 bt 너와 너.


                     2
  겨울이 네 눈썹을 포위 할 때
  그리고 당신의 아름다움 분야에서 깊은 참호를 파십시오.
  젊음의 자랑스런 정복이 지금 너무 흥얼 거리고
  소액의 잡초가 될 것입니다.  
  그때 네 모든 아름다움이 어디에 있는지 묻고
  당신의 혹독한 날의 모든 보물이있는 곳;
  네 자신의 깊은 침몰 한 눈 속에서
  모든 것을 먹는 부끄러운 일이었고, 냉담한 칭찬이었습니다.
  당신의 아름다움을 사용할만한 가치가 얼마나 더 많은지,
  당신이 대답 할 수 없다면 '이 공정한 내 아이
  내 카운트를 합산하고 오래된 변명을하자 '
  계승하여 그의 아름다움을 증명.
    이것은 네가 늙었을 때 새로 만들어 졌어 야했다.
    차갑게 느껴질 때 피가 따뜻해지는 것을보십시오.


                     삼
  네 유리를보고 네가 본 얼굴을 말하라
  이제 얼굴이 다른 얼굴을 만들어야 할 때입니다.
  당신이 지금 갱신하지 않으면 누구의 신선한 수리,
  너는 세상에 죄를 짓고 어머니를 축복하지 말라.
  귀가없는 자궁이있는 곳은 어디입니까?
  당신의 축산의 경작을 경멸합니까?
  아니면 누가 그렇게 좋아합니까 무덤이 될 것입니다,
  후손을 멈출 자신의 사랑?  
  너는 네 어머니의 유리와 네게있는 그녀
  그녀의 총리의 사랑스러운 4 월을 다시 불러옵니다.
  그래서 네가 네 나이의 창문을 통해보아야한다.
  Look에도 불구하고 당신의 황금 시간을 보냈다.
    그러나 가능하다면, 그렇지 않다면
    당신과 함께 이미지 죽는 단수 수리 죽어라.

내가 직접 말하면 마지막 몇 줄은 매우 시적입니다. 게 티즈 버그 연설에서도 놀랍게 잘 수행됩니다.

But, in a larger sense, we can not dedicate, we can not consecrate, we can not
hallow this ground. The brave men, living and dead, who struggled here, have
consecrated it, far above our poor power to add or detract. The world will
little note, nor long remember what we say here, but it can never forget what
they did here. It is for us the living, rather, to be dedicated here to the
unfinished work which they who fought here h to of rather us of advanced. It
is rather for us to be here dedicated to the who be it, vain who before us 
that from these honored dead we take increas be dead the the what use for which
they gave the last full measure of devotion  dead government The solve that
these dead shall not have died in vain that  the take nor world , shall have
a new birth of freedom and that government of the people, by the people, for
the people, shall not perish from the earth.


셰익스피어의 진드기가 무엇인지 봅시다. 코드는 다음과 같습니다. 본질적으로 그는 입력에서 어휘 기반을 구축하려고 노력합니다. 그런 다음이 단어를 사용하여 무작위로 구멍에 배치합니다 (정확하게 맞음). 그는 무작위로 고정 시드를 사용하므로 결정 론적입니다.

package stuff;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;

/**
 *
 * @author rohan
 */
public class PatchTheParagraph {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("File Name :");
        String[] text = getWordsFromFile(in.nextLine());
System.out.println("==ORIGINAL==");
        for(String s:text){
    System.out.println(s);
}
                    int lengthOfHole= 0;
        int rows = 0;
            for(String s: text){
                s = s.replaceAll("[^#]", "");

//      System.out.println(s);
                if(s.length()>0){
                    lengthOfHole = s.length();
                rows++;
                }
            }
            ArrayList<String> words = new ArrayList<>();
            words.add("I");
            for(String s:text){
                String[] w = s.replaceAll("#", " ").split(" ");
for(String a :w){
    words.add(a);
            }

            }
                        Iterator<String> j = words.iterator();
            while(j.hasNext()){
                String o;
                if((o = j.next()).equals("")){
                    j.remove();
                }
            }
            System.out.println(words);
            Stack<String> out = new Stack<>();
            String hashRow = "";
            for(int i = 0;i<lengthOfHole;i++){
                hashRow+="#";
            }

        for(int i = 0;i<rows;i++){
            int length = lengthOfHole-1; 
            String outPut = " ";
            while(length>2){
String wordAttempt = words.get(getRandom(words.size()-1));
while(wordAttempt.length()>length-1){
 wordAttempt = words.get(getRandom(words.size()-1));
}           
length -= wordAttempt.length()+1;
            outPut+=wordAttempt;
                outPut+=" ";
            }
        out.push(outPut);
    }
System.out.println("==PATCHED==");
        for(String s : text){
            if(s.contains(hashRow)){
                System.out.println(s.replaceAll(hashRow,out.pop()));
            }else{
                System.out.println(s);
            }
        }
                                    }
public static final Random r = new Random(42);
    public static int getRandom(int max){
    return (int) (max*r.nextDouble());
}
    /**
     *
     * @param fileName is the path to the file or just the name if it is local
     * @return the number of lines in fileName
     */
    public static int getLengthOfFile(String fileName) {
        int length = 0;
        try {
            File textFile = new File(fileName);
            Scanner sc = new Scanner(textFile);
            while (sc.hasNextLine()) {
                sc.nextLine();
                length++;
            }
        } catch (Exception e) {
System.err.println(e);
        }
        return length;
    }

    /**
     *
     * @param fileName is the path to the file or just the name if it is local
     * @return an array of Strings where each string is one line from the file
     * fileName.
     */
    public static String[] getWordsFromFile(String fileName) {
        int lengthOfFile = getLengthOfFile(fileName);
        String[] wordBank = new String[lengthOfFile];
        int i = 0;
        try {
            File textFile = new File(fileName);
            Scanner sc = new Scanner(textFile);
            for (i = 0; i < lengthOfFile; i++) {
                wordBank[i] = sc.nextLine();
            }
            return wordBank;
        } catch (Exception e) {
            System.err.println(e);
            System.exit(55);
        }
        return null;
    }
}


셰익스피어시의 대부분은 공개 도메인입니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Dennis

3

파이썬 2.7

다른 접근 방식을 가진 또 다른 파이썬 솔루션. 내 프로그램은 텍스트를 Markov chain 으로보고 각 문자 뒤에 특정 확률로 다른 문자가옵니다. 첫 번째 단계는 확률 표를 만드는 것입니다. 다음 단계는 해당 확률을 패치에 적용하는 것입니다.

하나의 샘플 텍스트를 포함한 전체 코드는 다음과 같습니다. 한 예제는 유니 코드 문자를 사용했기 때문에 해당 예제와의 호환성을 위해 명시 적 코드 페이지 (utf-8)를 포함 시켰습니다.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from collections import defaultdict
import numpy

texts = [
"""'Twas brillig, and the slithy toves
Did gyre a######### in the wabe;
All mimsy #########borogoves,
And the mome raths outgrabe."""
]

class Patcher:
    def __init__(self):
        self.mapper = defaultdict(lambda: defaultdict(int))

    def add_mapping(self, from_value, to_value):
        self.mapper[from_value][to_value] += 1

    def get_patch(self, from_value):
        if from_value in self.mapper:
            sum_freq = sum(self.mapper[from_value].values())
            return numpy.random.choice(
                self.mapper[from_value].keys(),
                p = numpy.array(
                    self.mapper[from_value].values(),dtype=numpy.float64) / sum_freq)
        else:
            return None

def add_text_mappings(text_string, patcher = Patcher(), ignore_characters = ''):
    previous_letter = text_string[0]
    for letter in text_string[1:]:
        if not letter in ignore_characters:
            patcher.add_mapping(previous_letter, letter)
            previous_letter = letter
    patcher.add_mapping(text_string[-1], '\n')

def patch_text(text_string, patcher, patch_characters = '#'):
    result = previous_letter = text_string[0]
    for letter in text_string[1:]:
        if letter in patch_characters:
            result += patcher.get_patch(previous_letter)
        else:
            result += letter
        previous_letter = result[-1]
    return result

def main():
    for text in texts:
        patcher = Patcher()
        add_text_mappings(text, patcher, '#')
        print patch_text(text, patcher, '#')
        print "\n"

if __name__ == '__main__':
    main()

Lorem Ipsum의 샘플 출력 :

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo conse Exe eut ccadamairure dolor in reprehenderit
in voluptate velit esse cilore indipserexepgiat nulla pariatur. Excepteur
sint occaecat cupidatat non upir alostat adin culpa qui officia deserunt
mollit anim id est laborum.

Jabberwocky의 추가 시적 라인 :

'Twas brillig, and the slithy toves
Did gyre and me the in the wabe;
All mimsy was
An inborogoves,
And the mome raths outgrabe.

어떤 예제 텍스트에 유니 코드가 있습니까? 모두 직선 ASCII 여야합니다. 알려 주시면 수정하겠습니다.
AdmBorkBork

파이썬은 첫 번째 텍스트에서 mınxomaτ에 대해 불평하며 PEP 263을 참조하십시오 .
agtoever

아-몰랐어요. 나는 그것을 직선 ASCII로 편집했다. 알려 줘서 고마워!
AdmBorkBork

2

C # 5 지금까지 거대한

나는 이것을 함께 던졌고, 약간 혼란 스럽지만 때로는 약간의 결과를 얻었습니다. 그것은 주로 결정 론적 알고리즘이지만 비슷한 간격에 대해 동일한 문자열을 생성하지 않도록 고정 (seed-seed) 무작위성이 추가되었습니다. 간격의 양쪽에 공간 열이 없도록 피하려고 노력합니다.

입력을 단어와 문장 부호로 토큰 화하여 (유니 코드가 수동으로 입력 한 목록에서 나온다. 유니 코드가 나를 위해 이것을 할 수 있다면 해결하기 위해 귀찮게 할 수 없기 때문에) 전에 단어가 아닌 공백을 넣을 수있다 문장 부호는 상당히 일반적인 것이기 때문입니다. 일반적인 공백으로 분할됩니다. 마르코프 체인의 맥락에서, 그것은 각 토큰이 서로 얼마나 자주 토큰을 따르는 지 계산합니다. 계산 대한 확률을 계산 하지 않습니다 (문서가 너무 작기 때문에 우리는 사물에 대해 편향하는 것이 좋습니다. 우리는 우리가 할 수있는 많은 것을 본다). 그런 다음 너비 우선 검색을 수행하여 해시와 '일부'단어에 의해 남겨진 공간을 양쪽으로 채우고 비용은로 계산됩니다 -fabness(last, cur) * len(cur_with_space). 여기서 fabness횟수를 반환합니다.cur 따랐다last생성 된 문자열에서 추가 된 각 토큰에 대해 당연히 비용을 최소화하려고합니다. 우리는 항상 문서에서 찾은 단어와 문장 부호로 차이를 채울 수 없기 때문에 어느 쪽의 부분 문자열을 포함하여 특정 상태의 여러 '특수'토큰도 고려합니다.

BFS가 해결책을 찾지 못하면, 우리는 순진하게 임의의 부사를 ​​선택하거나 공간을 채우기 위해 공간을 삽입하려고 시도합니다.

결과

모든 6 개는 여기에서 찾을 수 있습니다 : https://gist.github.com/anonymous/5277db726d3f9bdd950b173b19fec82a

유클리드 테스트 사례는 잘 진행되지 않았습니다 ...

이미지 패치

In a popular image editing software there is a feature, that patches (The term
used in image processing is inpainting as @minxomat pointed out.) a selected
area of an image, that patches information outside of that patch. And it does a
quite good job, co the patch a is just a program. As a human, you can sometimes
see that something In a short it if you squeeze your eyes or just take a short
glance, the patch seems to fill in the gap quite well.

재버 워키

'Twas brillig, and the slithy toves
Did gyre and the in in the wabe;
All mimsy the mome borogoves,
And the mome raths outgrabe.

오소리

Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Mushroom, mushroom, a-
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Mushroom, badger, badger
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Mush-mushroom, a
Badger, badger, badger, badger, badger,
badger, badger, badger, badger, badger
Argh! Snake, a snake!
Snaaake! A snaaaake, oooh its a snake!

_ 이것이 어떻게 나왔는지 기쁘게 생각합니다 ... "배저, 오소리"가 맞지 않거나 다행 일 것입니다.

암호

로 실행

csc ParaPatch.cs
ParaPatch.exe infile outfile

꽤 많이 있습니다. 원격으로 흥미로운 유일한 Fill방법 은 방법입니다. .NET에는 (WHY MS WHY ?!)이 없기 때문에 힙 구현을 포함시킵니다.

using System;
using System.Collections.Generic;
using System.Linq;

namespace ParaPatch
{
    class Program
    {
        private static string[] Filler = new string[] { "may", "will", "maybe", "rather", "perhaps", "reliably", "nineword?", "definitely", "elevenword?", "inexplicably" }; // adverbs
        private static char[] Breaking = new char[] { ' ', '\n', '\r', '\t' };
        private static char[] Punctuation = new char[] { ',', '.', '{', '}', '(', ')', '/', '?', ':', ';', '\'', '\\', '"', ',', '!', '-', '+', '[', ']', '£', '$', '%', '^', '—' };

        private static IEnumerable<string> TokenizeStream(System.IO.StreamReader reader)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            HashSet<char> breaking = new HashSet<char>(Breaking);
            HashSet<char> punctuation = new HashSet<char>(Punctuation);

            while (!reader.EndOfStream)
            {
                int ci = reader.Read();
                if (ci == -1) // sanity
                    break;

                char c = (char)ci;

                if (breaking.Contains(c))
                {
                    if (sb.Length > 0)
                        yield return sb.ToString();
                    sb.Clear();
                }
                else if (punctuation.Contains(c))
                {
                    if (sb.Length > 0)
                        yield return sb.ToString();
                    yield return ""+c;
                    sb.Clear();
                }
                else
                {

                    sb.Append(c);
                }
            }

            if (sb.Length > 0)
                yield return sb.ToString();
        }

        private enum DocTokenTypes
        {
            Known,
            LeftPartial,
            RightPartial,
            Unknown,
        }

        private class DocToken
        {
            public DocTokenTypes TokenType { get; private set; }
            public string StringPart { get; private set; }
            public int Length { get; private set; }

            public DocToken(DocTokenTypes tokenType, string stringPart, int length)
            {
                TokenType = tokenType;
                StringPart = stringPart;
                Length = length;
            }
        }

        private static IEnumerable<DocToken> DocumentTokens(IEnumerable<string> tokens)
        {
            foreach (string token in tokens)
            {
                if (token.Contains("#"))
                {
                    int l = token.IndexOf("#");
                    int r = token.LastIndexOf("#");

                    if (l > 0)
                        yield return new DocToken(DocTokenTypes.LeftPartial, token.Substring(0, l), l);

                    yield return new DocToken(DocTokenTypes.Unknown, null, r - l + 1);

                    if (r < token.Length - 1)
                        yield return new DocToken(DocTokenTypes.RightPartial, token.Substring(r + 1), token.Length - r - 1);
                }
                else
                    yield return new DocToken(DocTokenTypes.Known, token, token.Length);
            }
        }

        private class State : IComparable<State>
        {
            // missing readonly params already... maybe C#6 isn't so bad
            public int Remaining { get; private set; }
            public int Position { get; private set; }
            public State Prev { get; private set; }
            public string Token { get; private set; }
            public double H { get; private set; }
            public double Fabness { get; private set; }
            public string FullFilling { get; private set; }

            public State(int remaining, int position, Program.State prev, double fabness, double h, string token, string toAdd)
            {
                Remaining = remaining;
                Position = position;
                Prev = prev;
                H = h;
                Fabness = fabness;
                Token = token;

                FullFilling = prev != null ? prev.FullFilling + toAdd : toAdd;
            }

            public int CompareTo(State other)
            {
                return H.CompareTo(other.H);
            }
        }

        public static void Main(string[] args)
        {
            if (args.Length < 2)
                args = new string[] { "test.txt", "testout.txt" };

            List<DocToken> document;
            using (System.IO.StreamReader reader = new System.IO.StreamReader(args[0], System.Text.Encoding.UTF8))
            {
                document = DocumentTokens(TokenizeStream(reader)).ToList();
            }

            foreach (DocToken cur in document)
            {
                Console.WriteLine(cur.StringPart + " " + cur.TokenType);
            }

            // these are small docs, don't bother with more than 1 ply
            Dictionary<string, Dictionary<string, int>> FollowCounts = new Dictionary<string, Dictionary<string, int>>();
            Dictionary<string, Dictionary<string, int>> PreceedCounts = new Dictionary<string, Dictionary<string, int>>(); // mirror (might be useful)

            HashSet<string> knowns = new HashSet<string>(); // useful to have lying around

            // build counts
            DocToken last = null;
            foreach (DocToken cur in document)
            {
                if (cur.TokenType == DocTokenTypes.Known)
                {
                    knowns.Add(cur.StringPart);
                }

                if (last != null && last.TokenType == DocTokenTypes.Known && cur.TokenType == DocTokenTypes.Known)
                {
                    {
                        Dictionary<string, int> ltable;
                        if (!FollowCounts.TryGetValue(last.StringPart, out ltable))
                        {
                            FollowCounts.Add(last.StringPart, ltable = new Dictionary<string, int>());
                        }

                        int count;
                        if (!ltable.TryGetValue(cur.StringPart, out count))
                        {
                            count = 0;
                        }
                        ltable[cur.StringPart] = count + 1;
                    }


                    {
                        Dictionary<string, int> ctable;
                        if (!PreceedCounts.TryGetValue(cur.StringPart, out ctable))
                        {
                            PreceedCounts.Add(cur.StringPart, ctable = new Dictionary<string, int>());
                        }

                        int count;
                        if (!ctable.TryGetValue(last.StringPart, out count))
                        {
                            count = 0;
                        }
                        ctable[last.StringPart] = count + 1;
                    }
                }

                last = cur;
            }

            // build probability grid (none of this efficient table filling dynamic programming nonsense, A* all the way!)
            // hmm... can't be bothered
            Dictionary<string, Dictionary<string, double>> fabTable = new Dictionary<string, Dictionary<string, double>>();
            foreach (var k in FollowCounts)
            {
                Dictionary<string, double> t = new Dictionary<string, double>();

                // very naive
                foreach (var k2 in k.Value)
                {
                    t.Add(k2.Key, (double)k2.Value);
                }

                fabTable.Add(k.Key, t);
            }

            string[] knarr = knowns.ToArray();
            Random rnd = new Random("ParaPatch".GetHashCode());

            List<string> fillings = new List<string>();
            for (int i = 0; i < document.Count; i++)
            {
                if (document[i].TokenType == DocTokenTypes.Unknown)
                {
                    // shuffle knarr
                    for (int j = 0; j < knarr.Length; j++)
                    {
                        string t = knarr[j];
                        int o = rnd.Next(knarr.Length);
                        knarr[j] = knarr[o];
                        knarr[o] = t;
                    }

                    fillings.Add(Fill(document, fabTable, knarr, i));
                    Console.WriteLine(fillings.Last());
                }
            }

            string filling = string.Join("", fillings);

            int fi = 0;

            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(args[1]))
            using (System.IO.StreamReader reader = new System.IO.StreamReader(args[0]))
            {
                while (!reader.EndOfStream)
                {
                    int ci = reader.Read();
                    if (ci == -1)
                        break;

                    char c = (char)ci;
                    c = c == '#' ? filling[fi++] : c;

                    writer.Write(c);
                    Console.Write(c);
                }
            }

//            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(args[1], false, System.Text.Encoding.UTF8))
//            using (System.IO.StreamReader reader = new System.IO.StreamReader(args[0]))
//            {
//                foreach (char cc in reader.ReadToEnd())
//                {
//                    char c = cc;
//                    c = c == '#' ? filling[fi++] : c;
//                    
//                    writer.Write(c);
//                    Console.Write(c);
//                }
//            }

            if (args[0] == "test.txt")
                Console.ReadKey(true);
        }

        private static string Fill(List<DocToken> document, Dictionary<string, Dictionary<string, double>> fabTable, string[] knowns, int unknownIndex)
        {
            HashSet<char> breaking = new HashSet<char>(Breaking);
            HashSet<char> punctuation = new HashSet<char>(Punctuation);

            Heap<State> due = new Heap<Program.State>(knowns.Length);

            Func<string, string, double> fabness = (prev, next) =>
            {
                Dictionary<string, double> table;
                if (!fabTable.TryGetValue(prev, out table))
                    return 0; // not fab
                double fab;
                if (!table.TryGetValue(next, out fab))
                    return 0; // not fab
                return fab; // yes fab
            };

            DocToken mostLeft = unknownIndex > 2 ? document[unknownIndex - 2] : null;
            DocToken left = unknownIndex > 1 ? document[unknownIndex - 1] : null;
            DocToken unknown = document[unknownIndex];
            DocToken right = unknownIndex < document.Count - 2 ? document[unknownIndex + 1] : null;
            DocToken mostRight = unknownIndex < document.Count - 3 ? document[unknownIndex + 2] : null;

            // sum of empty space and partials' lengths
            int spaceSize = document[unknownIndex].Length
                + (left != null && left.TokenType == DocTokenTypes.LeftPartial ? left.Length : 0)
                + (right != null && right.TokenType == DocTokenTypes.RightPartial ? right.Length : 0);

            int l = left != null && left.TokenType == DocTokenTypes.LeftPartial ? left.Length : 0;
            int r = l + unknown.Length;

            string defaultPrev =
                left != null && left.TokenType == DocTokenTypes.Known ? left.StringPart :
                mostLeft != null && mostLeft.TokenType == DocTokenTypes.Known ? mostLeft.StringPart :
                "";

            string defaultLast =
                right != null && right.TokenType == DocTokenTypes.Known ? right.StringPart :
                mostRight != null && mostRight.TokenType == DocTokenTypes.Known ? mostRight.StringPart :
                "";

            Func<string, string> topAndTail = str =>
            {
                return str.Substring(l, r - l);
            };

            Func<State, string, double, bool> tryMove = (State prev, string token, double specialFabness) => 
            {
                bool isPunctionuation = token.Length == 1 && punctuation.Contains(token[0]);
                string addStr = isPunctionuation || prev == null ? token : " " + token;
                int addLen = addStr.Length;

                int newRemaining = prev != null ? prev.Remaining - addLen : spaceSize - addLen;
                int oldPosition = prev != null ? prev.Position : 0;
                int newPosition = oldPosition + addLen;

                // check length
                if (newRemaining < 0)
                    return false;

                // check start
                if (oldPosition < l) // implies left is LeftPartial
                {
                    int s = oldPosition;
                    int e = newPosition > l ? l : newPosition;
                    int len = e - s;
                    if (addStr.Substring(0, len) != left.StringPart.Substring(s, len))
                        return false; // doesn't match LeftPartial
                }

                // check end
                if (newPosition > r) // implies right is RightPartial
                {
                    int s = oldPosition > r ? oldPosition : r;
                    int e = newPosition;
                    int len = e - s;
                    if (addStr.Substring(s - oldPosition, len) != right.StringPart.Substring(s - r, len))
                        return false; // doesn't match RightPartial
                }

                if (newRemaining == 0)
                {
                    // could try to do something here (need to change H)
                }

                string prevToken = prev != null ? prev.Token : defaultPrev;
                bool isLastunctionuation = prevToken.Length == 1 && punctuation.Contains(prevToken[0]);

                if (isLastunctionuation && isPunctionuation) // I hate this check, it's too aggresive to be realistic
                    specialFabness -= 50;

                double fab = fabness(prevToken, token);

                if (fab < 1 && (token == prevToken))
                    fab = -1; // bias against unrecognised repeats

                double newFabness = (prev != null ? prev.Fabness : 0.0)
                    - specialFabness // ... whatever this is
                    - fab * addLen; // how probabilistic

                double h = newFabness; // no h for now

                State newState = new Program.State(newRemaining, newPosition, prev, newFabness, h, token, addStr);

//                Console.WriteLine((prev != null ? prev.Fabness : 0) + "\t" + specialFabness);
//                Console.WriteLine(newFabness + "\t" + h + "\t" + due.Count + "\t" + fab + "*" + addLen + "\t" + newState.FullFilling);

                due.Add(newState);
                return true;
            };

            // just try everything everything
            foreach (string t in knowns)
                tryMove(null, t, 0);

            if (left != null && left.TokenType == DocTokenTypes.LeftPartial)
                tryMove(null, left.StringPart, -1);

            while (!due.Empty)
            {
                State next = due.RemoveMin();

                if (next.Remaining == 0)
                {
                    // we have a winner!!
                    return topAndTail(next.FullFilling);
                }

                // just try everything
                foreach (string t in knowns)
                    tryMove(next, t, 0);
                if (right != null && right.TokenType == DocTokenTypes.RightPartial)
                    tryMove(next, right.StringPart, -5); // big bias
            }

            // make this a tad less stupid, non?
            return Filler.FirstOrDefault(f => f.Length == unknown.Length) ?? new String(' ', unknown.Length); // oh dear...
        }
    }

    //
    // Ultilities
    //

    public class Heap<T> : System.Collections.IEnumerable where T : IComparable<T>
    {
        // arr is treated as offset by 1, all idxes stored need to be -1'd to get index in arr
        private T[] arr;
        private int end = 0;

        private void s(int idx, T val)
        {
            arr[idx - 1] = val;
        }

        private T g(int idx)
        {
            return arr[idx - 1];
        }

        public Heap(int isize)
        {
            if (isize < 1)
                throw new ArgumentException("Cannot be less than 1", "isize");

            arr = new T[isize];
        }

        private int up(int idx)
        {
            return idx / 2;
        }

        private int downLeft(int idx)
        {
            return idx * 2;
        }

        private int downRight(int idx)
        {
            return idx * 2 + 1;
        }

        private void swap(int a, int b)
        {
            T t = g(a);
            s(a, g(b));
            s(b, t);
        }

        private void moveUp(int idx, T t)
        {
        again:
            if (idx == 1)
            {
                s(1, t);
                return; // at end
            }

            int nextUp = up(idx);
            T n = g(nextUp);
            if (n.CompareTo(t) > 0)
            {
                s(idx, n);
                idx = nextUp;
                goto again;
            }
            else
            {
                s(idx, t);
            }
        }

        private void moveDown(int idx, T t)
        {
        again:
            int nextLeft = downLeft(idx);
            int nextRight = downRight(idx);

            if (nextLeft > end)
            {
                s(idx, t);
                return; // at end
            }
            else if (nextLeft == end)
            { // only need to check left
                T l = g(nextLeft);

                if (l.CompareTo(t) < 0)
                {
                    s(idx, l);
                    idx = nextLeft;
                    goto again;
                }
                else
                {
                    s(idx, t);
                }
            }
            else
            { // check both
                T l = g(nextLeft);
                T r = g(nextRight);

                if (l.CompareTo(r) < 0)
                { // left smaller (favour going right if we can)
                    if (l.CompareTo(t) < 0)
                    {
                        s(idx, l);
                        idx = nextLeft;
                        goto again;
                    }
                    else
                    {
                        s(idx, t);
                    }
                }
                else
                { // right smaller or same
                    if (r.CompareTo(t) < 0)
                    {
                        s(idx, r);
                        idx = nextRight;
                        goto again;
                    }
                    else
                    {
                        s(idx, t);
                    }
                }
            }
        }

        public void Clear()
        {
            end = 0;
        }

        public void Trim()
        {
            if (end == 0)
                arr = new T[1]; // don't /ever/ make arr len 0
            else
            {
                T[] narr = new T[end];
                for (int i = 0; i < end; i++)
                    narr[i] = arr[i];
                arr = narr;
            }
        }

        private void doubleSize()
        {
            T[] narr = new T[arr.Length * 2];
            for (int i = 0; i < end; i++)
                narr[i] = arr[i];
            arr = narr;
        }

        public void Add(T item)
        {
            if (end == arr.Length)
            {
                // resize
                doubleSize();
            }

            end++;
            moveUp(end, item);
        }

        public T RemoveMin()
        {
            if (end < 1)
                throw new Exception("No items, mate.");

            T min = g(1);

            end--;
            if (end > 0)
                moveDown(1, g(end + 1));

            return min;
        }

        public bool Empty
        {
            get
            {
                return end == 0;
            }
        }

        public int Count
        {
            get
            {
                return end;
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public IEnumerator<T> GetEnumerator()
        {
            return (IEnumerator<T>)arr.GetEnumerator();
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.