Tra cứu hình vuông


9

Marching Squares là một thuật toán từ đồ họa máy tính, được sử dụng để khôi phục các isocontours 2D từ một lưới các mẫu (xem thêm, người anh lớn của nó Marching Cubes cho cài đặt 3D). Ý tưởng là xử lý từng ô của lưới một cách độc lập và xác định các đường viền đi qua ô đó dựa trên các giá trị ở các góc của nó.

Bước đầu tiên trong quy trình này là xác định các cạnh được kết nối bằng các đường viền, dựa trên việc các góc nằm trên hay dưới giá trị của đường viền. Để đơn giản, chúng tôi sẽ chỉ xem xét các đường viền dọc theo giá trị 0, sao cho chúng tôi quan tâm đến việc các góc là dương hay âm. Có những trường hợp để phân biệt:24 = 16

nhập mô tả hình ảnh ở đây
Nguồn hình ảnh: Wikipedia

Việc xác định màu trắng và màu đen không thực sự quan trọng ở đây, nhưng chắc chắn nói rằng màu trắng là dương và màu đen là âm tính. Chúng tôi sẽ bỏ qua các trường hợp một trong những góc là chính xác 0.

Các điểm yên ngựa (trường hợp 5 và 10) cung cấp thêm một chút khó khăn: không rõ đường chéo nào nên được sử dụng chỉ bằng cách nhìn vào các góc. Điều này có thể được giải quyết bằng cách tìm trung bình của bốn góc (tức là xấp xỉ giá trị trung tâm) và chọn các đường chéo sao cho các đường viền tách trung tâm khỏi các góc với dấu ngược lại. Nếu trung bình là chính xác 0, một trong hai trường hợp có thể được chọn.

Thông thường, 16 trường hợp này được lưu trữ đơn giản trong một bảng tra cứu. Điều này rất tốt cho hiệu quả, nhưng tất nhiên, chúng tôi muốn mã là ngắn hơn ở đây. Vì vậy, nhiệm vụ của bạn là thực hiện bước tra cứu này và in một đại diện ASCII của vụ án với càng ít mã càng tốt.

Các thách thức

Bạn được cung cấp các giá trị của bốn góc (số nguyên khác không) theo thứ tự cố định mà bạn chọn. Sau đó, bạn nên tạo bố cục chính xác của các đường viền, giải quyết chính xác các trường hợp điểm yên.

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Đầu vào có thể được thực hiện trong bất kỳ định dạng chuỗi hoặc danh sách thuận tiện.

16 trường hợp sẽ được thể hiện trong nghệ thuật ASCII bằng một trong các khối 5x5 sau:

o---o  o---o  o---o
|   |  |   |  | | |
|   |  |---|  | | |
|   |  |   |  | | |
o---o  o---o  o---o

o---o  o---o  o---o  o---o
|/  |  |  \|  |   |  |   |
|   |  |   |  |   |  |   |
|   |  |   |  |\  |  |  /|
o---o  o---o  o---o  o---o

o---o  o---o
|/  |  |  \|
|   |  |   |
|  /|  |\  |
o---o  o---o

Bạn không được in bất kỳ khoảng trắng hàng đầu hoặc dấu, nhưng bạn có thể in một dòng mới tùy chọn.

Đây là mã golf, vì vậy câu trả lời ngắn nhất (tính bằng byte) sẽ thắng.

Các trường hợp thử nghiệm

Các trường hợp kiểm tra giả định rằng đầu vào được đưa ra theo thứ tự trên cùng bên trái , trên cùng bên phải , dưới cùng bên trái , dưới cùng bên phải . Các trường hợp thử nghiệm được trình bày trong 9 nhóm, một nhóm tương ứng với mỗi 9 đại diện được đưa ra ở trên (theo cùng một thứ tự, bắt đầu từ ô trống, kết thúc bằng hai điểm yên ngựa).

[1, 2, 1, 3]
[-9, -2, -2, -7]

[4, 5, -1, -2]
[-1, -2, 3, 4]

[7, -7, 7, -7]
[-5, 5, -5, 5]

[1, -6, -4, -1]
[-2, 3, 3, 4]

[-1, 6, -4, -1]
[2, -3, 3, 4]   

[-1, -6, 4, -1]
[2, 3, -3, 4]

[-1, -6, -4, 1]
[2, 3, 3, -4]

[3, -8, -9, 2]
[-3, 8, 9, -2]

[8, -3, -2, 9]
[-8, 3, 2, -9]

Ngoài ra, các trường hợp kiểm tra sau đây có thể trả về một trong hai điểm yên ngựa (sự lựa chọn của bạn):

[1, -4, -2, 5]
[-1, 4, 2, -5]

Câu trả lời:


4

Ruby, 201 180 176

Đây là một hàm lambda ẩn danh, được gọi theo cách hiển thị trong ví dụ không được phép.

Điều này không chứa biến s. Trong phiên bản không được chỉnh sửa, một biểu thức phức tạp được gán scho rõ ràng, trước khi nó được sử dụng. 4 byte được lưu trong phiên bản golf bằng cách đặt nội tuyến. Sự khác biệt duy nhất giữa các phiên bản là khoảng trắng và bình luận.

Nếu có thể trả về đầu ra dưới dạng một mảng gồm năm chuỗi gồm năm ký tự, thay vì in ra thiết bị xuất chuẩn, có thể lưu thêm một byte.

->a{p=t=0
4.times{|i|t+=a[i]*=a[3];p+=a[i]>>9&1<<i}
q=p==6&&t>0?19:'@AC@P*10'[p].ord
puts c='o---o',(0..2).map{|i|b=p*i==3?'|---|':'|   |';b[q%4]='|/|\|/'[q%4+(i&2)];q/=4;b},c}

Tôi hài lòng với việc phân tích cú pháp mảng, nhưng tôi nghĩ có thể có những cách ngắn hơn để tạo đầu ra.

Tất cả bốn phần tử của mảng đầu vào được nhân với phần tử cuối cùng. Điều này đảm bảo rằng phần tử cuối cùng là dương và giảm số trường hợp từ 16 xuống còn 8. Các phần tử được phân quyền 9 vị trí, sao cho tất cả các số dương trở thành 0 và tất cả các số âm trở thành -1 (ít nhất là trong phạm vi đầu vào được đưa ra trong các trường hợp thử nghiệm.) Sau đó, chúng được ANDed bằng cách 1<<array indexđưa ra số nhị phân 3 bit chỉ ra mẫu (thực tế là 4 bit, nhưng vì phần tử cuối cùng luôn dương, bit thứ 4 luôn bằng không.)

Số này từ 0..7 sau đó được đưa vào bảng tra cứu (thở dài) để xác định các ký tự của mỗi hàng không phải là khoảng trắng. Ở giai đoạn này, hai màn hình khác nhau cho vỏ yên được xử lý, với một thay thế cho số trong bảng tra cứu được sử dụng nếu tổng số là dương (câu hỏi nói là xem xét "trung bình", nhưng vì chúng tôi chỉ quan tâm đến dấu hiệu, không có vấn đề gì nếu chúng ta xem xét tổng số thay thế.)

Cách hiển thị của đầu ra hoạt động hy vọng rõ ràng từ các ý kiến ​​trong mã.

vô dụng trong chương trình thử nghiệm

f=->a{p=t=0
  4.times{|i|                      #for each number in the input
    t+=a[i]*=a[3];                   #multiply each number by a[3]; totalize the sum in t
    p+=a[i]>>9&1<<i                  #shift right to find if negative; AND with 1<<i to build index number for pattern 
  }                                #q is a 3-digit base 4 number indicating which character of each line is non-whitespace (if any). 
  q=p==6&&t>0?19:'@AC@P*10'[p].ord #It's encoded in the magic string, except for the case of saddles with a positive total, which is encoded by the number 19.
  s=(0..2).map{|i|                 #build an array of 3 strings, indexes 0..2
    b=p*i==3?'|---|':'|   |';        #IF p is 3 and we are on row 1, the string is |---| for the horizontal line case. ELSE it is |   |.
    b[q%4]='|/|\|/'[q%4+(i&2)];      #The numbers in q indicate which character is to be modified. The characters in the string indicate the character to replace with.
    q/=4;                            #If q%4=0, the initial | is replaced by | (no change.) i&2 shifts the string index appropriately for the last row.
    b                                #divide q by 4, and terminate the loop with the expression b so that this is the object loaded into array s.  
  }
puts c='o---o',s,c}                #print the array s, capped with "o---o" above and below.


[[1, 2, 1, 3],
[-9, -2, -2, -7],

[4, 5, -1, -2],
[-1, -2, 3, 4],

[7, -7, 7, -7],
[-5, 5, -5, 5],

[1, -6, -4, -1],
[-2, 3, 3, 4],

[-1, 6, -4, -1],
[2, -3, 3, 4],

[-1, -6, 4, -1],
[2, 3, -3, 4],

[-1, -6, -4, 1],
[2, 3, 3, -4],

[3, -8, -9, 2],
[-3, 8, 9, -2],

[8, -3, -2, 9],
[-8, 3, 2, -9],

[1, -4, -2, 5],
[-1, 4, 2, -5]].each{|k|f.call(k)}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.