Viết chương trình vẽ sơ đồ 2 chiều của nút thắt dựa trên cấu trúc của nút thắt. Một nút thắt chính xác là những gì nó nghe như: một vòng dây được buộc lại. Trong toán học, một sơ đồ nút cho thấy một đoạn dây vắt qua hoặc dưới chính nó để tạo thành nút thắt. Một số ví dụ sơ đồ nút được hiển thị dưới đây:
Có một sự phá vỡ trong dòng nơi sợi dây vượt qua chính nó.
Đầu vào: đầu vào mô tả nút là một mảng các số nguyên. Một nút thắt trong đó sợi dây đi qua chính nó n lần có thể được biểu diễn dưới dạng một mảng gồm n số nguyên, mỗi số có một giá trị trong phạm vi [0, n-1]. Hãy gọi mảng này K .
Để lấy mảng mô tả một nút thắt, hãy đánh số từng đoạn từ 0 đến n-1. Phân đoạn 0 sẽ dẫn đến phân khúc 1, dẫn đến phân khúc 2, dẫn đến phân khúc 3, và cứ thế cho đến khi phân đoạn n-1 quay trở lại và dẫn đến phân khúc 0. Một phân đoạn kết thúc khi một phân đoạn dây khác đi qua nó ( đại diện bởi một ngắt trong dòng trong sơ đồ). Chúng ta hãy lấy nút thắt đơn giản nhất - nút thắt. Sau khi chúng tôi đánh số các phân số, phân đoạn 0 kết thúc khi phân đoạn 2 vượt qua nó; đoạn 1 kết thúc khi đoạn 0 đi qua nó; và đoạn 2 kết thúc khi đoạn 1 đi qua nó. Do đó, mảng mô tả nút thắt là [2, 0, 1]. Nói chung, phân đoạn x bắt đầu khi phân đoạn x-1 mod n rời khỏi và kết thúc khi phân đoạn K [x] đi qua nó.
Hình ảnh dưới đây cho thấy sơ đồ nút thắt, với các phân đoạn được gắn nhãn và các mảng tương ứng mô tả nút thắt.
Ba sơ đồ trên cùng là các nút thắt thực sự, trong khi ba biểu đồ phía dưới là các vòng dây vắt ngang qua chính chúng nhưng không thực sự thắt nút (nhưng vẫn có mã tương ứng).
Nhiệm vụ của bạn là viết một hàm lấy một mảng các số nguyên K (bạn có thể gọi nó là một số khác) mô tả một nút (hoặc vòng dây không thực sự thắt nút) và tạo ra sơ đồ nút tương ứng, như được mô tả ở trên ví dụ. Nếu bạn có thể, hãy cung cấp một phiên bản không mã hóa của mã của bạn hoặc một lời giải thích, đồng thời cung cấp các đầu ra mẫu của mã của bạn. Cùng một nút thường có thể được biểu diễn theo nhiều cách khác nhau, nhưng nếu sơ đồ nút mà đầu ra chức năng của bạn thỏa mãn có đầu vào là một trong những cách biểu diễn có thể, thì giải pháp của bạn là hợp lệ.
Đây là mã golf, vì vậy mã ngắn nhất tính bằng byte thắng. Đường biểu thị cho sợi dây có thể có độ dày 1 pixel, tuy nhiên, dưới và chéo phải được phân biệt rõ ràng (kích thước của đứt dây phải lớn hơn độ dày của dây ít nhất là một pixel ở hai bên) .
Tôi sẽ đưa ra các câu trả lời dựa trên các khả năng lý thuyết nút tích hợp, nhưng câu trả lời cuối cùng được chọn không thể dựa vào các khả năng lý thuyết nút tích hợp.
Tất cả mọi thứ tôi biết về ký hiệu của mình: Tôi tin rằng có những chuỗi giá trị dường như không tương ứng với bất kỳ nút thắt hoặc nút thắt nào. Ví dụ, chuỗi [2, 3, 4, 0, 1] dường như không thể vẽ.
Ngoài ra, giả sử rằng bạn đi qua và bắt đầu từ giao cắt đó, đi theo con đường của sợi dây theo một hướng và gắn nhãn cho mọi giao cắt không được gắn nhãn mà bạn gặp phải với các giá trị tích phân lớn hơn. Đối với các nút thắt xen kẽ, có một thuật toán đơn giản để chuyển đổi ký hiệu của tôi thành nhãn như vậy và đối với các nút thắt xen kẽ, việc chuyển đổi nhãn này thành Mã Gauss là không quan trọng
template<size_t n> array<int, 2*n> LabelAlternatingKnot(array<int, n> end_at)
{
array<int, n> end_of;
for(int i=0;i<n;++i) end_of[end_at[i]] = i;
array<int, 2*n> p;
for(int& i : p) i = -1;
int unique = 0;
for(int i=0;i<n;i++)
{
if(p[2*i] < 0)
{
p[2*i] = unique;
p[2*end_of[i] + 1] = unique;
++unique;
}
if(p[2*i+1] < 0)
{
p[2*i+1] = unique;
p[2*end_at[i]] = unique;
++unique;
}
}
return p;
}
template<size_t n> auto GetGaussCode(array<int, n> end_at)
{
auto crossings = LabelAlternatingKnot(end_at);
for(int& i : crossings) ++i;
for(int i=1;i<2*n;i+=2) crossings[i] = -crossings[i];
return crossings;
}
KnotData
trong Mathematica ...: '(
Knot
sẵn! Ví dụ sử dụng: << Units`; Convert[Knot, Mile/Hour]
sản lượng 1.1507794480235425 Mile/Hour
. (Tôi nghĩ điều này thật buồn cười bất kể nó đúng hay sai; nhưng nó thực sự đúng.)