Cứu ngỗng khỏi sự tuyệt chủng


13

Các loài ngỗng được gọi là Alex A được biết đến vì cư trú trong lưới hình tam giác bao gồm 64 tế bào:

Tế bào
(Ảnh chụp từ vấn đề Project Euler không liên quan này .)

Chúng tôi sẽ đặt tên mỗi tế bào với các con số 0để 63bắt đầu từ dòng đầu tiên và sau đó di chuyển từ trái sang phải trên mỗi hàng bên dưới đó. Vì vậy, ô trên cùng là 0và ô dưới cùng bên phải là 63.

Mỗi ô có ba viền. Chúng ta có thể dán nhãn cho mỗi biên giới theo hình thức a,bnơi ablà số lượng các tế bào cổ phiếu biên giới đó. Chẳng hạn, đường viền giữa ô 02sẽ được gọi 0,2hoặc 2,0(không quan trọng bạn đặt chúng vào thứ tự nào).

Hệ thống ghi nhãn cho các đường viền ở chính rìa của lưới là khác nhau, vì các ô trên cạnh của lưới có đường viền mà chúng không chia sẻ với các ô khác. Nếu một đường viền chỉ là một phần của một ô, chúng tôi sẽ sử dụng chữ cái X. Ví dụ, ba biên giới của tế bào 00,2, 0,X, và 0,X.

Một số tế bào chứa ngỗng . Tuy nhiên, những con ngỗng này sẽ bị giết bởi những con cáo xấu xa (đến từ bên ngoài biên giới của lưới điện) nếu bạn không bảo vệ chúng. Và nếu tất cả những con ngỗng chết thì BrainSteel sẽ buồn. Do đó, chúng tôi sẽ viết một chương trình xây dựng hàng rào xung quanh ngỗng để bảo vệ chúng khỏi những con cáo. Những con ngỗng nên tồn tại trong một đơn đa giác khép kín hoàn toàn hàng rào. Ngân sách hàng rào của chúng tôi khá thấp nên sử dụng số lượng hàng rào ít nhất có thể.

Mô tả đầu vào

Một danh sách các số, được phân tách bằng dấu phẩy, từ 0đến 63, đại diện cho các ô có chứa ngỗng. Thí dụ:

6,12

Mô tả đầu ra

Một danh sách các biên giới cần phải có hàng rào được xây dựng trên chúng để bảo vệ ngỗng thành công. Đây phải là số lượng hàng rào nhỏ nhất có thể. Thí dụ:

5,6 6,7 11,12 12,13 

"Những con ngỗng nên tồn tại trong một đa giác của hàng rào kín." Tất cả các con ngỗng phải sống trong cùng một đa giác, hoặc có thể có nhiều (hoặc 0) đa giác?
frageum

@feersum Tất cả những con ngỗng nên sống trong cùng một đa giác. Tôi đã chỉnh sửa câu hỏi để làm cho nó rõ ràng.
absinthe

@Katya Có thể đa giác có các phần tự giao nhau hoặc phần không có chiều rộng? Hãy suy nghĩ như một hình dạng đồng hồ cát.
orlp

@orlp Phần không có chiều rộng là gì?
absinthe

2
@orlp Đa giác không được chứa các phần có chiều rộng bằng không.
absinthe

Câu trả lời:


10

C #, 530 byte

Hoàn thành chương trình C #, nhận đầu vào dưới dạng một dòng từ STDIN và xuất một dòng đơn sang STDOUT, với dấu "".

Việc này khá dài ... và có quá nhiều lần lặp lại x / y / z, nhưng tôi đã không thể giảm nó thành bất cứ điều gì hợp lý cho đến nay, và có một bài kiểm tra trong 2 giờ, có thể quay lại vào ngày mai.

using Q=System.Console;class P{static void Main(){int q=9,w=0,e=9,r=0,t=9,u=0,i=0,x=0,y=0,z=0,p=0;System.Action V=()=>{z=(int)System.Math.Sqrt(i);p=(x=i-z*z)%2;x/=2;y=(++z*z--+~i)/2;},W=()=>{Q.Write(i+","+(x<0|y++<0|z>7?"X":""+(z*z+2*x+1-p))+" ");};foreach(var g in Q.ReadLine().Split(',')){i=int.Parse(g);V();q=q>x?x:q;w=w<x?x:w;e=e>y?y:e;r=r<y?y:r;t=t>z?z:t;u=u<z?z:u;}for(i=64;i-->0;){V();if(!(x<q|x>w|y<e|y>r|z<t|z>u))if(p>0){if(y==r)W();if(x++==w)W();x--;if(z--==t)W();}else{if(y--==e)W();if(x--==q)W();x++;if(z++==u)W();}}}}

Sơ đồ này giải thích hầu hết những gì đang xảy ra.

Lưới được mô tả là x / y / z / (p), hiển thị giải pháp ví dụ

Hãy nhận ra rằng vì chúng ta không thể có các phần có chiều rộng 0, "hình lục giác" sẽ luôn có hình dạng rẻ nhất (và có lợi ích là cho ngỗng tối đa không gian để di chuyển vào).

Chương trình hoạt động bằng cách trước tiên dịch tất cả các chỉ mục ô đầu vào thành các chuỗi x / y / z và tìm min / max của mỗi x / y / z.

z = floor(root(i))
x = floor((i - z^2) / 2)
y = floor((z+1)^2 - i - 1) / 2)
p = (i - z^2) % 2

Tiếp theo, nó đi qua từng chỉ số ô và kiểm tra xem nó có khớp với 'hình lục giác' mà chúng tôi đã mô tả hay không. Nếu đúng thì nó sẽ kiểm tra xem nó có nằm ở bất kỳ cạnh cực nào của giới hạn không (ví dụ x = xmin hoặc y = ymax) và thêm các cạnh tương ứng nếu có. Nó phải tìm ra chỉ số của cạnh bên cạnh. Đối với x và z, chúng ta chỉ cần tăng / giảm chúng theo cách chúng ta muốn và sau đó sử dụng công thức sau:

i = z^2 + 2*x + (1-p)

Lưu ý rằng "chẵn lẻ" luôn thay đổi và y không liên quan. Đối với y, chúng ta không phải thay đổi bất cứ điều gì, nhưng mã hơi lộn xộn vì nó phải thực hiện kiểm tra giới hạn "tam giác" để phát hiện xem ô bên cạnh có phải là "X" hay không.

Giải pháp ví dụ (Các ô có ngỗng chỉ từ ba góc):

Input
2,50,62

Output
62,63 61,X 59,X 57,X 55,X 53,X 51,X 50,49 48,X 36,X 35,X 25,X 24,X 16,X 15,X 9,X 8,X 4,X 3,X 2,0 1,X 

Mã Tidier với ý kiến:

using Q=System.Console;

class P
{
    static void Main()
    {
        int q=9,w=0,e=9,r=0,t=9,u=0, // min/max x/y/z/ (init min high, and max low)
        i=0, // index of cell we are looking at
        x=0,y=0,z=0,p=0; // x,y,z dimension

        System.Action V=()=>
            { // translates the index into x/y/z/p
                z=(int)System.Math.Sqrt(i);
                p=(x=i-z*z)%2; // 'parity'
                x/=2; // see p assignment
                y=(++z*z--+~i)/2; // ~i == -i - 1
            },
            W=()=>
            { // writes out the edge of i, and the cell described by x/z/inverse of p   (the inversion of p handles y +/-)
                Q.Write(i+","+ // write out the edge
                        (x<0|y++<0|z>7?"X":""+(z*z+2*x+1-p)) // either X (if we go out of 'trianlge' bounds), or we translate x/z/inverse of p into an index
                        +" "); // leaves a trailing space (as shown in example output)
            };

        foreach(var g in Q.ReadLine().Split(',')) // for each cell with geese
        {
            i=int.Parse(g); // grab index of cell
            V(); // compute x/y/z/p
            q=q>x?x:q; // sort out mins/maxes
            w=w<x?x:w;
            e=e>y?y:e;
            r=r<y?y:r;
            t=t>z?z:t;
            u=u<z?z:u;

            // code like the above suggests a solution with a couple of arrays would be better...
            // I've not had success with that yet, but maybe in a couple of days I will try again
        }

        for(i=64;i-->0;) // for each cell
        {
            V(); // compute x/y/z/p
            if(!(x<q|x>w|y<e|y>r|z<t|z>u)) // if we are inside the 'hex' bounds
                if(p>0)
                { // x max, y max, z min
                    // these checks check that we are on the extremes of the 'hex' bounds,
                    // and set up the appropriate vars for W calls to put the edges in
                    // must do y first, because W modifies it for us (saves 2 bytes in the next block)
                    if(y==r) // don't need the ++ (can't go out of 'trianlge' bounds)
                        W();
                    if(x++==w)
                        W();
                    x--;
                    if(z--==t)
                        W();
                    //z++; not used again
                }
                else
                { // x min, y min, z max
                    if(y--==e) // do need the -- (used for 'trianlge' bounds checking)
                        W();
                    // y is reset in W, as such
                    if(x--==q)
                        W();
                    x++;
                    if(z++==u)
                        W();
                    //z--; not used again
                }
        }
    }
}

Bạn có thể lưu một byte với using System;.
LegionMammal978

@ LegionMammal978, anh ta có được hai việc đó .. Anh ta chỉ sử dụng nó cho Q.Write và Q.ReadLine. những cái đó, cộng với câu lệnh sử dụng mà anh ta có bây giờ là using Q=System.Console;Q.Write();Q.ReadLine()(45 Byte) so với đề xuất của bạn using System;Console.Write();Console.ReadLine()(47 Byte).
Kade

Ngoài ra, bạn có thể thả 10 byte bằng cách không không cần thiết khởi tạo i, x, y, z, và pđến 0.
LegionMammal978

@ LegionMammal978 bạn có chắc không? Tôi đã thử điều đó và nó đưa ra lỗi khi sử dụng một vai không thể gán.
Kade

@ Vioz- Biến nào? Những dòng trên phiên bản chú thích?
LegionMammal978
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.