Xe lửa Lego


13

Lấy cảm hứng từ thử thách tỷ số thiết bị Lego của Keith Randall.

Tôi cũng có kế hoạch xây dựng một robot lego khổng lồ mà cuối cùng sẽ có thể tiêu diệt các robot khác trong cuộc cạnh tranh chưa từng được đề cập. * Trong quá trình chế tạo robot, tôi sẽ sử dụng rất nhiều tàu bánh răng để kết nối các bộ phận khác nhau của robot. Tôi muốn bạn viết cho tôi chương trình ngắn nhất sẽ giúp tôi xây dựng các đoàn tàu bánh răng phức tạp cần thiết cho một nhiệm vụ phức tạp như vậy. Tất nhiên, tôi sẽ chỉ sử dụng các bánh răng với bán kính 1, 2, 3 và 5 đơn vị lego tùy ý.

Mỗi bánh răng trong bộ truyền bánh răng có tọa độ nguyên cụ thể trên lưới 2D. Bánh răng đầu tiên được đặt ở (0,0) và bánh răng cuối cùng sẽ được đặt ở tọa độ không âm. Vị trí và kích thước của các bánh răng đầu tiên và cuối cùng sẽ được cung cấp làm đầu vào, chương trình của bạn phải cho biết các bánh răng đi đâu để điền vào các khoảng trống.

Ngoài ra, chương trình của bạn phải sử dụng số lượng bánh răng tối thiểu có thể có trong bộ truyền bánh răng. Ít bánh răng / tàu hơn = nhiều tàu hơn ** = robot hủy diệt lớn hơn và tốt hơn.

Đầu vào sẽ bao gồm một dòng:

X,Y,B,A

X và Y là tọa độ của bánh răng cuối cùng. Bánh răng đầu tiên luôn nằm ở (0,0). B và A lần lượt là bán kính của bánh răng cuối cùng và ban đầu. Để thêm một số khó khăn, bạn cần đảm bảo rằng bánh răng đầu ra quay đúng hướng. Nếu A và B có cùng dấu, thì bánh răng đầu ra cần quay cùng hướng và phải sử dụng số bánh răng lẻ. Nếu chúng có dấu hiệu ngược lại, thì cần sử dụng số bánh răng chẵn.

Đầu ra phải là một danh sách các vị trí X, vị trí Y và bán kính của từng bánh răng bổ sung, một bánh răng trên mỗi dòng. Nếu có nhiều giải pháp thiết bị tối thiểu, chỉ in một trong những lựa chọn của bạn. Thứ tự của các bánh răng trong đầu ra không quan trọng.

Ví dụ (có thể có nhiều giải pháp tương đương hơn):

in
4,0,1,1
out
2,0,1

in
7,7,-2,-2
out
4,3,3
OR
0,7,5
OR
the above reflected over y=x line

in
7,8,-1,2
out
7,0,5
7,6,1
OR
7,0,5
1,8,5

in
7,7,2,-2
out
4,-3,3
7,1,2
12,1,3
12,7,3
OR
any permutation of the above, or reflected over y=x line
Now you're thinking with gear trains!

Đây là giải pháp cho các ví dụ trên, được hình dung:

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

Theo tôi biết, không có vấn đề gì là không thể trừ khi hai bánh răng đầu vào trùng nhau hoặc kết nối trực tiếp. Bạn sẽ không phải đối phó với điều này.

Đây là mã golf, câu trả lời ngắn nhất thắng.


* Một KOTH tương lai, có ai không?

**CHOO CHOO!!


Tôi sẽ có nó để cả bán kính ban đầu và bán kính cuối cùng có thể âm.
wizzwizz4

9
Chào mừng bạn đến với thử thách Lego Gear Train của Phi. Sau 4 năm trong Sandbox, hy vọng nó sẽ có giá trị trọng lượng.
một spaghetto

@ wizzwizz4 Thực hiện thay đổi.
PhiNotPi

Điều này thực sự đã ở trong hộp cát trong 4 năm?
Rɪᴋᴇʀ

@RikerW Giống như 3 1/3.
PhiNotPi

Câu trả lời:


1

C #, 660 byte

using System.Linq;using System;class P{int p=1,x,y,r;P l;static void Main(){var Q="$&.$'7$(@$*R$'/$(8$)A'(A('A$+S$(0$)9'(9('9$*B$,T$*2$+;$,D$.V*,V,*V";var I=Console.ReadLine().Split(',').Select(int.Parse).ToList();int i=0,t,s=7,u,v,w,p=I[3]*I[2];for(var D=new[]{new P{r=Math.Abs(I[3]),l=new P{r=Math.Abs(I[2]),x=I[0],y=I[1],p=3}}}.ToList();i>=0;){P c=D[i++],l=c.l;for(;(l=l?.l)!=null&&(s=(t=c.x-l.x)*t+(t=c.y-l.y)*t-(t=c.r+l.r)*t)>0;);if(s==0&&l.p>2&p*c.p<0)for(i=-1;c.l.p<3;c=c.l)Console.WriteLine(c.x+","+c.y+","+c.r);for(t=0;s>0&t<66;t++)for(u=Q[t++]-36,v=Q[t++]-36,s=1;s++<5&Q[t]%9==c.r;w=u,u=v,v=-w,D.Add(new P{l=c,r=Q[t]/9-4,x=c.x+u,y=c.y+v,p=-c.p}));}}}

Dùng thử trực tuyến

Đây là rất nhiều niềm vui !! Hoàn thành chương trình, chấp nhận đầu vào từ STDIN, xuất ra STDOUT. Đầu ra là các bánh răng theo thứ tự từ đầu đến cuối. Sử dụng:

Thực hiện Tìm kiếm Đầu tiên đơn giản, giải quyết vấn đề 4 bánh trong chưa đầy một giây. Yếu tố phân nhánh không thực sự lớn như vậy, vì vậy nó sẽ tốt hơn đáng kể (không thực sự được thử nghiệm). Đáng buồn thay, nó sử dụng Linq.

Các Qchuỗi là một bảng của tất cả các kết nối thiết bị cho phép (tức là một r=3và kết nối với một r=1nếu dx=4dy=0) trong một góc phần tư, sau đó được luân chuyển để tìm những người khác. Mỗi bộ 3 byte là dx, dyvà các thông tin bán kính cho một kết nối hợp pháp. Sự lựa chọn (như một sự bù đắp rất có chủ ý: thật vui khi một lần được chọn một ký tự ASCII cho các thuộc tính đẹp, thay vì tuyệt vọng cố gắng tìm các thuộc tính đẹp cho các ký tự ASCII bị áp đặt.

Tôi có thể có thể làm tốt hơn việc đọc đầu vào, nhưng tôi chưa gặp may, nhất là vì Linq được trả tiền vì nhu cầu cho một danh sách. Tôi cũng rất thất vọng bởi mã xoay vòng, tôi cảm thấy như thế có thể được thực hiện với số lượng byte ít hơn đáng kể.

Mã được định dạng và nhận xét với trình Qtạo:

using System.Linq; // seems to pay today
using System;

class P
{
    static void GenQ()
    {
        int t, k = 0, m = 0;
        Func<P, P, int> C = (P c, P l) => (t = c.x - l.x) * t + (t = c.y - l.y) * t - (t = c.r + l.r) * t; // ==0 -> touching, <0 -> not touching, >0 -> overlap

        string str = "";

        string T(int i) => "" + (char)('$' + i); // $ is zero, '$' == 36, so we can mod and div by 9, and greater than " so we don't have to escape it

        foreach (int r in new[] { 1, 2, 3, 5 }) // at 0,0 (current gear)
            foreach (int s in new[] { 1, 2, 3, 5 }) // gear to place
                for (int i = 0; i <= r + s; i++) // x
                    for (int j = 1; j <= r + s; j++, m++) // y
                        if (C(new P { r = r }, new P { r = s, x = i, y = j }) == 0) // 
                        {
                            str += T(i) + T(j) + T(r + s * 9);
                            k++;
                        }

        System.Console.WriteLine("K : " + k);
        System.Console.WriteLine("M : " + m);
        System.Console.WriteLine(str);
        System.Console.ReadKey(true);
        return;
    }

    int p=1, // parity
        x, // x
        y, // y
        r; // radias (TODO: store radias^2 ?)
    P l; // previous in search list

    static void Main()
    {
        //GenQ();

        // '$' == 36 (4*9)
        // 3char blocks: x,y,r+9*s
        var Q="$&.$'7$(@$*R$'/$(8$)A'(A('A$+S$(0$)9'(9('9$*B$,T$*2$+;$,D$.V*,V,*V"; // quarter table

        // primative read ints
        var I=Console.ReadLine().Split(',').Select(int.Parse).ToList();

        int i=0, // position in Due
            t, // check differential cache, position in Q
            s=7, // check cache, rotation counter (>0)
            u, // rotation x
            v, // rotation y
            w, // rotation x cache
            p=I[3]*I[2]; // parity (>0 -> same, even ; <0 -> different, odd)

        // due (not point using a queue, the search space grows exponentially)
        for(var D=new[]{
                new P{r=Math.Abs(I[3]), // start (p==1)
                    l=new P{r=Math.Abs(I[2]),x=I[0],y=I[1],p=3} // terminal (detect with p==3)
                }}.ToList();
            i>=0;) // infinite number of configurations, no bounds, i is escape term
        {
            P c=D[i++], // current
                l=c.l; // check, initially the one before the previous (we know we are touching last already)

            // 'checks' c against l
            //Func<int>C=()=>(t=c.x-l.x)*t+(t=c.y-l.y)*t-(t=c.r+l.r)*t; // ==0 -> touching, >0 -> not touching, <0 -> overlap

            // check we arn't touching any before us (last thing we check is terminal)
            for(;(l=l?.l)!=null&& // for each before us (skipping the first one)
                (s=(t=c.x-l.x)*t+(t=c.y-l.y)*t-(t=c.r+l.r)*t)>0;); // check c against l and cache in s, ==0 -> touching, >0 -> not touching, <0 -> overlap

            if(s==0&& // touching last checked?
                l.p>2& // stopped on terminal?
                p*c.p<0) // correct parity? -> win
                for(i=-1; // escape
                    c.l.p<3;c=c.l) // for each that wasn't the first
                    Console.WriteLine(c.x+","+c.y+","+c.r);

            // enumerate possible additions, and queue them in due
            for(t=0;
                s>0& // not touching or overlapping anything (including terminal)
                t<66;t++) // 66 = Q.Length
                for(
                    u=Q[t++]-36, // '$'
                    v=Q[t++]-36,
                    s=1;s++<5& // rotate 4 times
                    Q[t]%9==c.r; // our raidus matches
                        w=u, // chache y value
                        u=v, // rotate
                        v=-w,
                        D.Add(new P // add
                        {
                            l=c,
                            r=Q[t]/9-4, // radius
                            x=c.x+u,
                            y=c.y+v,
                            p=-c.p // flip parity
                        }));
        }
    }
}
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.