Tính số quanh co


15

Số quanh co là số nguyên của các vòng quay ngược chiều kim đồng hồ mà một người quan sát phải thực hiện để đi theo một đường dẫn đã cho. Lưu ý rằng bất kỳ vòng quay theo chiều kim đồng hồ nào đều được tính âm đối với số quanh co. Con đường được phép tự giao nhau.

Một số ví dụ (không biết xấu hổ lấy từ Wikipedia) được đưa ra dưới đây:

nhập mô tả hình ảnh ở đây

Mục tiêu của bạn là tính toán số quanh co cho một đường dẫn nhất định.

Đầu vào

Người quan sát được giả định là ở điểm gốc (0,0).

Đầu vào là một chuỗi các điểm hữu hạn (giống như số nguyên) từ bất kỳ nguồn đầu vào mong muốn nào mô tả đường dẫn tuyến tính mảnh. Bạn có thể làm phẳng số này thành một chuỗi số nguyên 1D nếu muốn và cũng có thể làm mờ đầu vào để lấy tất cả tọa độ x trước tất cả các tọa độ y / vise-Versa. Bạn cũng có thể lấy đầu vào là một số phức a+b i. Đường dẫn có thể tự giao nhau và có thể chứa các đoạn có độ dài bằng không. Điểm đầu tiên là điểm bắt đầu của đường dẫn và được cho là nằm ở đâu đó trên trục x dương.

Không có phần nào của đường dẫn sẽ giao nhau với điểm gốc. Đường dẫn sẽ luôn được đóng (tức là điểm đầu tiên và điểm bị mất là như nhau). Mã của bạn có thể ngụ ý điểm cuối cùng hoặc yêu cầu nó được đưa vào.

Ví dụ: tùy thuộc vào sở thích của bạn, cả hai yếu tố đầu vào đều chỉ định cùng một hình vuông:

điểm cuối ngụ ý

1,0
1,1
-1,1
-1,-1
1,-1

điểm cuối rõ ràng

1,0
1,1
-1,1
-1,-1
1,-1
1,0

Đầu ra

Đầu ra là một số nguyên duy nhất cho số quanh co. Điều này có thể là bất kỳ nguồn nào (giá trị trả về, thiết bị xuất chuẩn, tệp, v.v.).

Ví dụ

Tất cả các ví dụ có điểm cuối được xác định rõ ràng và được đưa ra dưới dạng cặp x, y. Ngẫu nhiên, bạn cũng có thể cung cấp trực tiếp các ví dụ này vào bất kỳ mã nào giả sử các điểm cuối được xác định ngầm định và các đầu ra phải giống nhau.

1. Kiểm tra cơ bản

1,0
1,1
-1,1
-1,-1
1,-1
1,0

Đầu ra

1

2. Kiểm tra điểm lặp lại

1,0
1,0
1,1
1,1
-1,1
-1,1
-1,-1
-1,-1
1,-1
1,-1
1,0

Đầu ra

1

3. Kiểm tra theo chiều kim đồng hồ

1,0
1,-1
-1,-1
-1,1
1,1
1,0

Đầu ra

-1

4. Kiểm tra bên ngoài

1,0
1,1
2,1
1,0

Đầu ra

0

5. quanh co

1,0
1,1
-1,1
-1,-1
1,-1
1,0
1,-1
-1,-1
-1,1
1,1
1,0
1,1
-1,1
-1,-1
1,-1
1,0
1,1
-1,1
-1,-1
1,-1
1,0

Đầu ra

2

Chấm điểm

Đây là mã golf; mã ngắn nhất thắng. Tiêu chuẩn áp dụng. Bạn có thể sử dụng bất kỳ hàm dựng sẵn nào miễn là chúng không được thiết kế riêng để tính số cuộn dây.


2
Đầu vào có thể được lấy dưới dạng số phức (hoặc đại diện chuỗi của chúng, chẳng hạn như "1-i"hoặc "1-1i"?)
Level River St

có, bất kỳ loại cặp được cho phép.
hellowworld922

Câu trả lời:


10

ES6, 83 byte

a=>a.map(([x,y])=>r+=Math.atan2(y*b-x*c,y*c+x*b,b=x,c=y),b=c=r=0)&&r/Math.PI/2

Lấy đầu vào là một mảng các cặp điểm được hiểu là số phức. Thay vì chuyển đổi từng điểm thành một góc, các điểm được chia cho điểm trước đó, Math.atan2 sau đó chuyển đổi thành một góc giữa -π và π, do đó tự động xác định đường đi quanh co. Tổng các góc sau đó gấp 2 lần số cuộn dây.

Vì Math.atan2 không quan tâm đến quy mô của các đối số của nó, tôi thực sự không thực hiện phân chia đầy đủ z / w = (z * w*) / (w * w*)thay vào đó tôi chỉ nhân mỗi điểm với liên hợp phức tạp của điểm trước đó.

Chỉnh sửa: Đã lưu 4 byte nhờ @ edc65.


Đẹp và nhanh chóng. Và tôi không hiểu toán của bạn. Nhưng reducehầu như luôn luôn là một lựa chọn tồi.
edc65

a=>a.map(([x,y])=>r+=Math.atan2(y*b-x*c,y*c+x*b,b=x,c=y),b=c=r=0)&&r/Math.PI/2sử dụng bản đồ thay thế hoặc giảm bớt. Dù sao bạn cũng có phiếu bầu của tôi
edc65

@ edc65 Cảm ơn; Tôi đã sử dụng reducevì tôi không nhận ra rằng Math.atan2 (0,0) là 0. (Chà, điều này phụ thuộc vào việc một trong số 0 của bạn có thực sự là -0 hay không.) Toán học dựa trên sự phân chia phức tạp, thường được tính là z / w = z * w* / |w|², nhưng tôi không quan tâm đến độ lớn, vì vậy nó chỉ nhân với số liên hợp phức tạp. Cũng hơi khó hiểu Math.atan2 chấp nhận (y, x) đối số.
Neil

Tôi thừa nhận tôi không hiểu mã, nhưng nếu mô tả của bạn là chính xác, thì tôi tin rằng câu trả lời của bạn là sai. Thật vậy, nếu bạn nhập điểm từ đường dẫn này (tôi đang đưa ra một hình ảnh cho rõ ràng hơn) thì số quanh co là 1, trong khi vấn đề của bạn sẽ xuất ra 2.
Wojowu

@Wojowu Xin lỗi, ý tôi là góc giữa các điểm được đo từ gốc, chứ không phải góc ngoài của đa giác, vì vậy đối với ảnh của bạn, mã của tôi thực sự nên tính câu trả lời là 1.
Neil

3

MATL , 11 byte

X/Z/0)2/YP/

Đầu vào là một chuỗi các số phức bao gồm cả điểm cuối.

Hãy thử trực tuyến!

Giải trình

Hầu hết các công việc được thực hiện bởi Z/hàm ( unwrap), giúp giải phóng các góc theo radian bằng cách thay đổi các bước nhảy tuyệt đối lớn hơn hoặc bằng pi với bổ sung 2 * pi của chúng.

X/       % compute angle of each complex number
Z/       % unwrap angles
0)       % pick last value. Total change of angle will be a multiple of 2*pi because 
         % the path is closed. Total change of angle coincides with last unwrapped
         % angle because the first angle is always 0
2/       % divide by 2
YP/      % divide by pi

1
MATL và Jelly có khá nhiều ràng buộc hầu hết các thử thách toán học gần đây. Tôi rất ấn tượng, bạn gần như đã vượt ra ngoài ngôn ngữ của Dennis ...
ETHproductions

@ETHproductions Cảm ơn những lời tốt đẹp của bạn! Vâng, họ đã được gắn trong một số thách thức gần đây. Mặt khác, tôi đã thấy khá nhiều vấn đề trong đó số byte của Jelly chiếm khoảng một nửa là MATL :-D
Luis Mendo

2

Thạch, 11 byte

æAI÷ØPæ%1SH

Cái này lấy đầu vào là danh sách tọa độ y và danh sách tọa độ x.

Hãy thử nó ở đây .


1

Con trăn, 111

Câu trả lời dài nhất cho đến nay. Động lực của tôi là 1) học python và 2) có thể chuyển cái này sang pyth.

from cmath import *
q=input()
print reduce(lambda x,y:x+y,map(lambda (x,y):phase(x/y)/pi/2,zip(q[1:]+q[:1],q)))

Đầu vào được đưa ra dưới dạng một danh sách các số phức.

Ideone.

Tôi nghĩ rằng cách tiếp cận tương tự như câu trả lời ES6.

Khi nhân 2 số phức, đối số hoặc pha của sản phẩm là tổng của đối số hoặc pha của hai số. Do đó, khi một số phức được chia cho một số khác, thì pha của thương số là sự khác biệt giữa các pha của tử số và mẫu số. Do đó, chúng ta có thể tính toán góc đi qua cho từng điểm và điểm tiếp theo. Tính tổng các góc này và chia cho 2π cho số quanh co cần thiết.

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.