Bresenham의 라인 래스터 화를 통해 모든 매트릭스에 대한 매트릭스 추적


12

영감을받은 .

실제로 래스터 그래픽을 다루는 2 학년 인 Agatha Stephendale은 선형 대수 과정을 수강했습니다. 이제 그녀는 행렬을 사각형으로 상상하지만 예술적으로는 사각형에 대각선을 연결하고 그에 따라 트레이스를 계산하려고합니다. 실제로, 그녀는 정사각 행렬뿐만 아니라 모든 행렬의 트레이스를 계산하려고합니다.

Agatha는 아티스트이기 때문에 좋아하는 이미지 편집기에서 선을 그리는 방법을 알고 있으며 후자는 Bresenham의 알고리즘 을 사용 하여 선을 그립니다. 그녀는 Wikipedia를 확인하고 의사 코드를 발견했습니다.

여기에 이미지 설명을 입력하십시오

 function line(x0, y0, x1, y1)
     real deltax := x1 - x0
     real deltay := y1 - y0
     real deltaerr := abs(deltay / deltax)    // Assume deltax != 0 (line is not vertical),
           // note that this division needs to be done in a way that preserves the fractional part
     real error := 0.0 // No error at start
     int y := y0
     for x from x0 to x1 
         plot(x,y)
         error := error + deltaerr
         while error ≥ 0.5 then
             y := y + sign(deltay) * 1
             error := error - 1.0

(이 의사 코드는 1보다 작은 경사에 대해서만 작동합니다. 키가 큰 격자의 경우 유사한 처리를 수행해야하지만 루프 오버가 발생합니다. 두 경우에 y대해서는 이 섹션 을 참조하십시오 .)

Agatha는 행렬을 직사각형으로 상상하고 대각선을 그립니다. Bresenham의 알고리즘은 행렬의 어느 요소가 대각선에 속하는지를 결정합니다. 그런 다음 그녀는 합계를 취합니다. 이는 학생이 적고 코드를 저장하기 위해 대용량 HDD를 감당할 수 없기 때문에 가능한 적은 바이트로 구현하려는 것입니다.

직무

행렬 A가 주어지면 래스터 화 된 주 대각선 (왼쪽에서 오른쪽 아래로)에있는 요소의 합을 반환합니다. 여기서 왼쪽은 Bresenham의 선 알고리즘에 의해 결정됩니다. 즉, 행렬이 m × n 격자를 나타내고 있다고 가정하면 Bresenham의 알고리즘을 사용하여 A [1, 1]에서 A [m, n]까지 격자에 선을 그리고 선의 모든 요소의 합을 가져옵니다. 참고 것을 1 × NN × 1 개 (이는 하나의 마지막 행의 마지막 요소의 첫 번째 행의 첫 번째 요소의 선을 그리는 것 방법이기 때문에) 매트릭스 전체 매트릭스 자체 대각선된다.

입력 : 실제 행렬은 (a 될 수 1 × 1 행렬의 행 행렬 열의 행렬, 또는 직사각형 행렬). 출력 : 숫자.

일부 소스 (예 : 위의 Wikipedia의 의사 코드)는 조건 검사를 사용하고 error≥0.5다른 소스는을 사용 error>0.5합니다. 원래 게시 된 것 ( error≥0.5)을 사용해야 하지만 대안 error>0.5이 코드에서 더 짧은 경우 코드 골프이므로 구현 할 수는 있지만 명시 적으로 언급하십시오 . 테스트 사례 4를 참조하십시오.

도전 규칙

  • I / O 형식은 유연합니다. 행렬은 줄 바꿈, 행 벡터 배열 또는 열 벡터 배열 등으로 구분 된 공백으로 구분 된 여러 줄의 행일 수 있습니다.
  • 이것은 이므로 바이트 단위의 최단 답변이 이깁니다.
  • 표준 규칙이 답변에 적용 되므로 STDIN / STDOUT, 적절한 매개 변수 및 반환 유형의 전체 프로그램과 함께 함수 / 방법을 사용할 수 있습니다.
  • 기본 허점 은 금지되어 있습니다.

테스트 사례

  1. [[1,2,3],[4,5,6],[7,8,9]]1+5+9→ 출력 : 15.

테스트 사례 1

  1. [[1,2,3,4],[5,6,7,8]]1+2+7+8→ 출력 : 18.

테스트 사례 2

  1. [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24]]1+8+9+16+17+24→ 출력 : 75.

테스트 사례 3

  1. [[1,2,3,4,5],[6,7,8,9,10]]1+2+8+9+10( 오류 조건 사용) → 출력 : 30.

테스트 사례 4

그러나 >코드에서 엄격한 부등식을 사용하는 것이 더 짧은 경우 허용되는 출력은 1+2+3+9+10=25이지만 별도로 언급해야합니다.

테스트 사례 5

  1. [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]1+5+8+12→ 출력 : 26.

테스트 사례 5

  1. [[-0.3,0.5]]→ 출력 : 0.2.

  2. [[3.1],[2.9]]→ 출력 : 6.

  3. [[-5]]→ 출력 : -5.

Bresenham의 알고리즘에 대한 추가 정보


요청 된 테스트 사례 : [[1,2,3,4,5],[6,7,8,9,10]].
user202729

@ user202729 모호성을 해결하기 위해 추가했습니다.
Andreï Kostyrka

너비보다 큰 테스트 케이스를 얻을 수 있습니까? 처럼[[1,2],[3,4],[5,6],[7,8],[9,10]]
주세페

@ 주세페 캐치. 지금 사례 5를 참조하십시오. 예를 들어 대답은 28( 예상 구현) 또는 27 ( >선택 구현)입니다.
Andreï Kostyrka

프로그램은 고정 된 크기 (예 : 500 × 500)의 행렬 만 지원할 수 있습니까?
user202729

답변:



3

SmileBASIC, 101 99 바이트

DEF D A,W,H
GCLS
GTRI.,0,0,0,W-1,H-1FOR I=0TO W*H-1=I MOD W
S=S+A[I/W,M]*!!GSPOIT(M,I/W)NEXT?S
END

원래 GLINE 함수를 사용하여 선을 그리는 것으로 생각했지만 올바른 알고리즘을 사용하지 않는 것 같습니다. 그러나 GTRI 는 효과가있는 것 같습니다.

테스트 케이스 4는 30을 출력합니다.

입력은 너비 / 높이와 함께 [Y, X] 형식의 2D 배열입니다 (배열의 크기를 확인할 방법이없고 총 요소 수만).



1

Python 3.X, 269 바이트

공백으로 구분 된 숫자의 쉼표로 구분 된 행으로 입력.

import math;c=math.ceil;a=[[float(k)for k in q.split(" ")]for q in input().split(",")];_=len;m=lambda f,t,x,y,e,d:sum(x[0]for x in a)if 2>_(a[0])else m(*[0]*4,*[(_(a)-1)/(_(a[0])-1)]*2)if f else m(f,t+a[y][x],x+1,y+c(e-0.5),e+d-c(e-0.5),d)if x<_(a[0])else t;m(1,*[0]*5)

프리 골프 :

def line(a):
   if len(a[0])<2: return sum([x[0] for x in a])
   e = d = abs((len(a)-1)/(len(a[0])-1))
   y=t=0
   for x in range(len(a[0])): 
       t += a[y][x]
       f = ceil(e-0.5)
       y += f
       e += d-f
   return t

c=math.ceil프로그램을 더 길게 만드는 것처럼 보입니다 ...
user202729

또한 []사이에는 필요하지 않습니다 sum(..). a if c else b종종 될 수 있습니다 c and a or b.
user202729

input("")일 수 있습니다 input().
user202729

또한 ... 입출력 형식은 무엇입니까? 화면에 인쇄 하시겠습니까?
user202729

1

FMSLogo , 136 바이트

make 1 rl
setxy -1+count :1 -1+count last :1
pu home
make 9 0
foreach :1[foreach ?[if
0=last pixel[make 9 :9+?]fd 1]setxy xcor+1 0]pr :9

전체 프로그램에서 사용자에게 입력 (대화 상자 팝업)을 요청한 다음 출력을 화면에 인쇄하십시오.

화면에 선을 그리고 출력을 계산하기 만하면됩니다. 엄격한 불평등을 사용하십시오.


FMSLogo의 캔버스 크기 (약 500 × 500)까지의 매트릭스 크기 만 지원합니다.

Ungolfed 코드 :

Make "input ReadList
SetXY (-1+Count :input) (-1+Count Last :input)
PenUp
Home
Make "sum 0
ForEach :input[
    ForEach ?[
        If 0=Last Pixel[
            Make "sum :sum+?
        ]
        Forward 1
    ]
    SetXY XCor+1 0
]
Print :sum
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.