Làm thế nào mà gà băng qua đường?


16

Nắm chặt. Không ai biết tại sao con gà băng qua đường, có thể có một con gà trống đẹp trai ở phía bên kia. Nhưng chúng ta có thể tìm ra làm thế nào. Viết một chương trình, từ trái sang phải, băng qua "con đường" này (hoặc bất kỳ).

1356 | 1738
3822 | 1424
3527   3718
9809 | 5926
0261 | 1947
7188   4717
6624 | 9836
4055 | 9164
2636   4927
5926 | 1964
3144 | 8254

Chương trình của bạn "vượt qua" nó, di chuyển từ trái sang phải. Bạn bắt đầu vào bất kỳ số nào trên cột ngoài cùng bên trái mà bạn thích. Từ đó, bạn có thể di chuyển đến bất kỳ nhân vật liền kề bên phải. Nếu bạn bắt đầu ở góc trên cùng bên trái, 1, bạn có thể chuyển sang 3 hoặc 8. Mỗi số bạn đến, bao gồm cả số bắt đầu, được thêm vào một tổng. Không gian không thêm vào tổng của bạn. "|" buộc bạn phải di chuyển lên hoặc xuống, thay vì ở đâu đó bên phải. (Bạn không thể tiến lên phía trước nhân vật này) Mục tiêu của bạn là sang bên kia với số tiền nhỏ nhất có thể. Chương trình của bạn phải in ra số tiền ở cuối và nó phải có khả năng giải quyết bất kỳ con đường nào. Tốt hơn là, nó cũng có thể có đầu vào cho một con đường, nhưng nó không bắt buộc. Chương trình của bạn phải in cả đường dẫn và tổng. Ít byte mã nhất sẽ thắng.

Để làm rõ, bạn có thể di chuyển chẩn đoán trừ khi bạn ở trên một thanh dọc. Bạn chỉ có thể di chuyển lên và xuống khi bạn ở trên một thanh dọc.

Đối với một đặc điểm kỹ thuật rõ ràng hơn về đường, về cơ bản, đó là một chuỗi văn bản (Hoặc một mảng các cột hoặc hàng, nếu bạn muốn nghĩ theo cách đó) tuân theo quy tắc của các ký tự và không thể có bất cứ điều gì NHƯNG các ký tự đó trong con đường. Có thể có bất kỳ số nào, dấu cách, thanh ("|") hoặc dòng mới. Nếu một con đường được lát bởi một người say rượu, như trong câu trả lời của Lập trình viên, thì đó vẫn là một con đường hợp lệ và chương trình của bạn phải có thể giải quyết một con đường như vậy. Nó không được coi là một con đường nếu không thể đi sang phía bên kia (Ví dụ, không có cách nào thoát khỏi một đường thẳng của các thanh).

Chương trình của bạn không bắt buộc để xác định xem đường có hợp lệ không.

Phím:
Bất kỳ số nào - thêm số vào tổng của bạn, di chuyển về phía trước.
Không gian - Di chuyển về phía trước, không có gì được thêm vào tổng của bạn.
"|" - Di chuyển lên hoặc xuống, không có gì được thêm vào tổng của bạn.

EDIT: Một giải pháp ví dụ, như đề xuất. Tôi không thể tạo ra một cái lớn khủng khiếp, tôi không thể lấy IDE để giải quyết nó cho tôi ATM.

Đi con đường nhỏ này:

9191 | 8282
1919 | 2727
5555   5555

Giải pháp sẽ là một đường dẫn 1, 1, 1, 1, không gian, chia, chia, không gian, không gian, 2, 2, 2, 2 với tổng số 12.

EDIT # 2: Giải pháp cho con đường đầu tiên cho câu hỏi này, như được xác định bởi các chương trình Geobits và người, là 0,2,0,1 ,,,, 1,4,1,4 cho tổng số 13.


4
Bạn có thể bao gồm ít nhất một trường hợp thử nghiệm với một giải pháp chính xác? Ngoài ra, có thể có nhiều hơn ba |liên tiếp?
Martin Ender

1
@timmy bạn có thể di chuyển theo đường chéo, miễn là nó đang di chuyển về phía trước. Nó có thể được chạm vào với một vài chuyển động chéo.
CaffeineToCode

3
@ mbomb007 Nếu bắt đầu ở góc trên cùng. Vì bạn có thể bắt đầu ở bất kỳ cột nào bên trái, bạn có thể nhận được0,2,0,1, , , ,1,4,1,4 -> 13
Geobits

1
Vâng, nó làm. Bạn chỉ có thể di chuyển lên hoặc xuống trên các thanh, vì vậy bạn chỉ có thể thoát ra khỏi chúng thông qua một không gian.
CaffeineToCode

1
Đối với đầu ra, chỉ đơn giản là đủ chi phí, hoặc toàn bộ đường dẫn cần phải là đầu ra?
Lập trình viên

Câu trả lời:


3

Pyth, 168 143 141 byte [hiện tương thích với Drunken Road]

Trường hợp thử nghiệm của tôi hoạt động, nhưng vì một sự hiểu lầm từ phía tôi, nó sẽ không hoạt động đúng với ví dụ ban đầu. Tôi đang làm việc để sửa nó.

Bây giờ làm việc cho ví dụ ban đầu và những con đường say rượu

Một số mã thực sự ít xấu xí hơn :

=Z.dC,++\ `MUT\|++0UT=^T5Ltu+G]?&qeeG\|<heGhH+eGeHHtb,0hbKhohNum++hed@ZhhdtedC,H_y_y.b+N]YmhohNd.:++TGT3HCm.[d\ lh.MlZ.z.z*hl.z]]0j\,t.sK\ hK

Kiểm tra nó ở đây

Tôi đã thử nó trên một con đường 10 + 9 x 40.

6417443208|153287613
8540978161|726772300
7294922506 263609552
0341937695 498453099
9417989188 370992778
2952186385|750207767
7049868670 756968872
1961508589|379453595
0670474005 070712970
4817414691|670379248
0297779413|980515509
6637598208 090265179
6872950638 767270459
7375626432 439957105
1387683792|544956696
6974831376 545603884
0949220671|632555651
3952970630|379291361
0456363431|275612955
2973230054|830527885
5328382365|989887310
4034587060 614168216
4487052014|969272974
5015479667 744253705
5756698090|621187161
9444814561|169429694
7697999461|477558331
3822442188 206942845
2787118311|141642208
2669534759 308252645
6121516963|554616321
5509428225|681372307
6619817314|310054531
1759758306 453053985
9356970729|868811209
4208830142 806643228
0898841529|102183632
9692682718|103744380
5839709581|790845206
7264919369|982096148

Chỉ cần một lưu ý, nhận được "IndexError: liệt kê chỉ mục ngoài phạm vi" khi chạy bằng bộ kiểm tra được cung cấp.
Lập trình viên

@ProgrammerDan tôi cũng vậy
CaffeineToCode

1
@CaffeineToCode đúng, nhưng khái niệm về "con đường say rượu" đã được thêm vào sau khi tôi gửi. Sẽ rất hữu ích khi biết những gì cấu thành một con đường. Dựa trên các ví dụ tôi giả sử 2 bên có cột chia
Brian Tuck

1
@CaffeineToCode Một trong những cách tốt nhất để viết một câu hỏi hay chỉ là viết thêm ví dụ - ngay cả khi không có giải pháp. Nếu đường có chiều rộng thay đổi hoặc nhiều làn là hợp lệ, một ví dụ "điên" sẽ minh họa nó mà không có bất kỳ văn bản mô tả bổ sung nào.
Lập trình viên

1
@ProgrammerDan Bạn đã yêu cầu nó. Của tôi bây giờ tương thích với DR (và ngắn hơn ... đoán tôi đang bắt kịp)
Brian Tuck

4

Java, 955 byte

Rõ ràng là sẽ không giành được bất kỳ giải thưởng nào, là Java và tất cả, nhưng tôi yêu vấn đề này và muốn đưa vào mục của riêng tôi.

Các tính năng và giới hạn:

  • Có thể hỗ trợ các con đường bất thường (siêu say!) Bao gồm chiều rộng thay đổi, đường phức tạp, v.v.
  • Dự kiến ​​đường sẽ được nhập làm tham số khi thực hiện; phiên bản không có bản quyền cũng hỗ trợ đọc từ stdin, nhưng vì phương thức nhập liệu không được chỉ định, phiên bản golf được mong đợi nhỏ nhất!
  • Sử dụng một số kỹ thuật lập trình động mà tôi chưa sử dụng, ồ, 6 năm hoặc lâu hơn để giải quyết hiệu quả trong thời gian O (n * m), trong đó n là hàng và m là cột.
    • Giải quyết từ phải sang trái, đánh dấu hướng tốt nhất để đi từ chỉ mục hiện tại sang chỉ mục tiếp theo.
    • "Các dòng" được xử lý bằng cách giải quyết cột của chúng, sau đó xử lý chúng nếu có thể truy cập được trên cột tiếp theo. Họ giải quyết bằng cách lưu trữ hướng lên hoặc xuống, với chi phí không phải là dòng cuối cùng có thể tiếp cận.
  • Theo dõi, nhưng không in (trong phiên bản golf) chỉ số bắt đầu của giải pháp tốt nhất.

Ok, đủ jibba jabba. Phiên bản chơi gôn:

class C{public static void main(String[]a){int n=a.length,m=0,i=0,j=0,h=0,p=0,q=0,s=0,t=0,b=-1,c=2147483647,x=0,y=0;char[][]r=new char[n][];char u;for(String k:a){j=k.length();m=(j>m)?j:m;}for(String k:a)r[i++]=java.util.Arrays.copyOf(k.toCharArray(),m);int[][][]d=new int[n][m][2];for(j=m-1;j>=0;j--){for(i=0;i<n;i++){u=r[i][j];p=(u=='\0'||u==' '||u=='|'?0:u-'0');if(j==m-1)d[i][j][1]=p;else{if(u=='|')d[i][j][0]=-1;else{for(h=-1;h<2;h++){x=i+h;y=j+1;if(x>=0&&x<n){if(d[x][y][0]==-1){s=x-1;while(s>=0&&r[s][y]=='|')s--;t=x+1;while(t<n&&r[t][y]=='|')t++;if((s>=0&&t<n&&d[s][y][1]<d[t][y][1])||(s>=0&&t>=n)){t=d[s][y][1];s=4;}else{s=6;t=d[t][y][1];}d[x][y][0]=s;d[x][y][1]=t;}q=d[x][y][1]+p;if(d[i][j][0]==0||q<d[i][j][1]){d[i][j][0]=h+2;d[i][j][1]=q;}}}}}if(j==0&&(b<0||d[i][j][1]<c)){b=i;c=d[i][j][1];}}}String o="";i=b;j=0;while(j<m){u=r[i][j];if(u=='\0')j=m;else{o+=u+",";h=d[i][j][0]-2;if(h>1)i+=h-3;else{i+=h;j++;}}}System.out.println(o+"\b:"+c);}}

Theo thói quen của tôi, github với mã không được mã hóa .

Giải pháp cho con đường "đầu tiên":

$ java C "1356 | 1738" "3822 | 1424" "3527   3718" "9809 | 5926" "0261 | 1947" "7188   4717" "6624 | 9836" "4055 | 9164" "2636   4927" "5926 | 1964" "3144 | 8254"
0,2,0,1, , , ,1,4,1,4:13

Ví dụ thứ hai:

$ java C "9191 | 8282" "1919 | 2727" "5555   5555"
1,1,1,1, ,|,|, , ,2,2,2,2:12

Mẫu của Brian Tuck:

$ java C "6417443208|153287613" "8540978161|726772300" "7294922506 263609552" "0341937695 498453099" "9417989188 370992778" "2952186385|750207767" "7049868670 756968872" "1961508589|379453595" "0670474005 070712970" "4817414691|670379248" "0297779413|980515509" "6637598208 090265179" "6872950638 767270459" "7375626432 439957105" "1387683792|544956696" "6974831376 545603884" "0949220671|632555651" "3952970630|379291361" "0456363431|275612955" "2973230054|830527885" "5328382365|989887310" "4034587060 614168216" "4487052014|969272974" "5015479667 744253705" "5756698090|621187161" "9444814561|169429694" "7697999461|477558331" "3822442188 206942845" "2787118311|141642208" "2669534759 308252645" "6121516963|554616321" "5509428225|681372307" "6619817314|310054531" "1759758306 453053985" "9356970729|868811209" "4208830142 806643228" "0898841529|102183632" "9692682718|103744380" "5839709581|790845206" "7264919369|982096148"
2,1,0,1,5,1,2,1,1,1, ,1,0,1,2,1,2,3,0,1:26

Ví dụ của Brian "say sưa":

6417443208 | 153287613
8540978161 | 726772300
7294922506 263609552
0341937695 498453099
9417989188 370992778
2952186385 | 750207767
7049868670 756968872
1961508589 | 379453595
0670474005 070712970
4807414691 | 670379248
0297779413 | 980515509
6637598208 090265179
6872950638 767270459
7375626432 439957105
1387683792 | 544956
697483176 5456034
09492201 | 6325551
395297030 | 3792913
 456363431 | 275612
  73230054 | 830527885
    8382365 | 989887310
    4587060 614168216
  87052014 | 96927297
 50479667 7442537
57566980 | 621187161
944481456 | 169429694
7697999461 | 477558331
3822442188 206942845
2787118311 | 141642208
2669534759 308252645
6121516963 | 554616321
5509428225 | 681372307
6619817314 | 310054531
1759758306 453053985
9356970729 | 868811209
4208849542 806643228
0898841529 | 102183632
9692682718 | 103744380
5839709581 | 790845206
7264919369 | 982096148
$ java C "6417443208|153287613" "8540978161|726772300" "7294922506 263609552" "0341937695 498453099" "9417989188 370992778" "2952186385|750207767" "7049868670 756968872" "1961508589|379453595" "0670474005 070712970" "4817414691|670379248" "0297779413|980515509" "6637598208 090265179" "6872950638 767270459" "7375626432 439957105" "1387683792|544956" "697483176 5456034" "09492201|6325551" "395297030|3792913" " 456363431|275612" "  73230054|830527885" "    8382365|989887310" "    4587060 614168216" "  87052014|96927297" " 50479667 7442537" "57566980 | 621187161" "944481456 | 169429694" "7697999461|477558331" "3822442188 206942845" "2787118311|141642208" "2669534759 308252645" "6121516963|554616321" "5509428225|681372307" "6619817314|310054531" "1759758306 453053985" "9356970729|868811209" "4208830142 806643228" "0898841529|102183632" "9692682718|103744380" "5839709581|790845206" "7264919369|982096148"
 , , , ,0,5,2,0,1, , , ,1,1,1,3,2:16

Giải pháp trực quan:

09492201 | 6325551
395297030 | 3792913
\ 456363431 | 275612
 \ 73230054 | 830527885
  \ 8382365 | 989887310
   \ 4 \ 87060 614168216
  87/5 - \ 4 | 96927 \ 97
 50479667 \ 74425/7
57566980 | \ 62- / 87161
944481456 | \ / 69429694
7697999461 | 477558331

Thưởng thức!

Chỉnh sửa: Bây giờ tôi chỉ thể hiện (hai con đường hợp nhất! Anh ấy có thể làm được không?)

948384 | 4288324 324324 | 121323
120390 | 1232133 598732 | 123844
 293009 | 2394023 432099 | 230943
 234882 | 2340909 843893 | 849728
  238984 | 328498984328 | 230949
  509093 | 904389823787 | 439898
   438989 | 3489889344 | 438984
   989789 | 7568945968 | 989455
    568956 | 56985869 | 568956
    988596 | 98569887 | 769865
     769879 | 769078 | 678977
     679856 | 568967 | 658957
      988798 | 8776 | 987979
      987878 | 9899 | 989899
       999889 | | 989899
       989999 | | 989999
        989898 | | 998999
        989999 | | 999999
         989998 | | 899999
         989998 | | 998999

Giải pháp:

$ java C "948384 | 4288324   324324 | 121323" "120390 | 1232133   598732 | 123844" " 293009 | 2394023 432099 | 230943" " 234882 | 2340909 843893 | 849728" "  238984 | 328498984328 | 230949" "  509093 | 904389823787 | 439898" "   438989 | 3489889344 | 438984" "   989789 | 7568945968 | 989455" "    568956 | 56985869 | 568956" "    988596 | 98569887 | 769865" "     769879 | 769078 | 678977" "     679856 | 568967 | 658957" "      988798 | 8776 | 987979" "      987878 | 9899 | 989899" "       999889 |    | 989899" "       989999 |    | 989999" "        989898 |  | 998999" "        989999 |  | 999999" "         989998 || 899999" "         989998 || 998999"
 ,2,0,3,0,0, ,|,|, ,|,|, ,|,|, ,|,|, ,|,|, ,|,|, ,|,|, , , , , , , ,|, ,|, ,|, ,|, ,|, ,|, ,|,|, , ,1,0,7,2:15

(phần thưởng: đường dẫn từ không được phép):

$ java Chicken < test5.txt
best start: 3 cost: 15
  -> 2 -> 0 -> 3 -> 0 -> 0 ->   -> | -> | ->   -> | -> | ->   -> | -> | ->   -> | -> | ->   -> | -> | ->   -> | -> | ->
  -> | -> | ->   ->   ->   ->   ->   ->   ->   -> | ->   -> | ->   -> | ->   -> | ->   -> | ->   -> | ->   -> | -> | ->
  ->   -> 1 -> 0 -> 7 -> 2 -> 15
/ -> - -> - -> \ -> / -> / -> - -> , -> , -> - -> , -> , -> - -> , -> , -> - -> , -> , -> - -> , -> , -> - -> , -> , ->
- -> , -> , -> / -> \ -> - -> - -> - -> / -> / -> ^ -> / -> ^ -> / -> ^ -> / -> ^ -> / -> ^ -> / -> ^ -> / -> , -> , ->
/ -> - -> \ -> \ -> - -> \ -> across

Chi tiết về thuật toán

Một lời giải thích đầy đủ hơn về kỹ thuật Lập trình động mà tôi sử dụng đã được yêu cầu, vì vậy, đây là:

Tôi đang sử dụng một phương pháp đánh dấu và tiền xử lý. Nó có một tên thích hợp, nhưng từ lâu tôi đã quên nó; có lẽ ai khác có thể cung cấp nó?

Thuật toán:

  • Bắt đầu từ cột ngoài cùng bên phải và tiến dần sang bên trái, hãy tính toán như sau về từng ô trong cột:
    • Tổng kết của chuyển động chi phí thấp nhất, được định nghĩa là chi phí ô hiện tại + ô chi phí thấp nhất có thể truy cập trong cột tiếp theo
    • Hành động di chuyển cần thực hiện để đạt được chi phí thấp nhất này, đơn giản là một động thái hợp lệ từ ô này sang ô khác.
  • Ống được hoãn lại. Để giải quyết một đường ống, bạn cần phải tính toán cột đầy đủ, vì vậy chúng tôi không tính toán các đường ống cho đến cột tiếp theo.
    • Khi xác định chi phí thấp nhất của một ô ở bên trái của đường ống, trước tiên chúng tôi tính toán hướng tốt nhất để di chuyển dọc theo đường ống - nó sẽ luôn luôn giải quyết lên hoặc xuống, vì vậy chúng tôi tính toán nó một lần.
    • Sau đó, chúng tôi lưu trữ, như với tất cả các ô khác, chi phí tốt nhất (được định nghĩa là chi phí của ô mà chúng tôi đạt được bằng cách di chuyển lên hoặc xuống trên đường ống) và hướng di chuyển để tiếp cận nó.

Ghi chú:

Đó là nó. Chúng tôi quét từ trên xuống dưới, phải sang trái, một lần; các ô duy nhất được chạm (có khả năng) nhiều hơn một lần là các ống, tuy nhiên, mỗi ống chỉ được "giải quyết" một lần, giữ chúng ta trong cửa sổ O (m * n) của chúng ta.

Để xử lý kích thước bản đồ "lẻ", tôi chọn cách đơn giản là quét trước và chuẩn hóa độ dài của các hàng bằng cách đệm bằng các ký tự null. Các ký tự Null được tính là "chi phí bằng không" di chuyển giống như các đường ống và khoảng trắng. Sau đó, khi in giải pháp, tôi dừng in chi phí hoặc di chuyển khi đạt đến cạnh của đường chuẩn hóa hoặc đạt được ký tự null.

Cái hay của thuật toán này là rất đơn giản, áp dụng các quy tắc giống nhau cho mọi ô, tạo ra một giải pháp đầy đủ bằng cách giải các bài toán con O (m * n) và về tốc độ khá nhanh. Nó đánh đổi bộ nhớ, tạo hiệu quả hai bản sao trong bộ nhớ của bản đồ đường bộ, lần đầu tiên lưu trữ dữ liệu "chi phí tốt nhất" và lần thứ hai để lưu trữ dữ liệu "di chuyển tốt nhất" trên mỗi ô; đây là điển hình cho lập trình động.


Bạn có thể giải thích cách tiếp cận của bạn để dòng nhiều hơn một chút? Tôi cũng đã thử một cách tiếp cận lập trình động (hơi khác), nhưng bị mắc kẹt khi tìm ra chúng. Tôi cũng đã xem xét một cách tiếp cận gia tăng (từng hàng) để đối phó với những con đường cực dài không quá rộng mà không sử dụng quá nhiều bộ nhớ; Bạn có biết nếu có cách nào để làm điều đó trong thời gian O (m ^ 2 * n) không?
dfeuer

@dfeuer Đó là tất cả về sự đánh đổi, để chắc chắn. Không có cách tiếp cận nào theo hàng mà tôi cho là có thể xử lý tất cả các hoán vị của đầu vào mà không chịu khuất phục trước thời gian O (m ^ n) tại một thời điểm nào đó; đây là một vấn đề theo từng cột trong quá trình xây dựng (chuyển động, phần lớn, đi từ giải pháp DP từ trái sang phải - hiệu quả đi từ phải sang trái). Bạn có thể thực hiện phương pháp tiếp cận O (m * n) để giải quyết từng hàng với cách nhìn đơn giản và nhìn chậm về phía trước, nhưng bạn đang tăng độ phức tạp lên rất nhiều mà không có khả năng tiết kiệm nhiều bộ nhớ.
Lập trình viên

Điều tôi đã nghĩ là nếu tôi không nhầm, bạn chỉ cần theo dõi con đường tốt nhất cho đến nay và, cho mỗi hình vuông trong hàng được xử lý gần đây nhất, các đường được biết đến tốt nhất từ ​​cạnh trái, đến cạnh phải và để mỗi hình vuông bên phải của nó trong cùng một hàng. Là sai đó?
dfeuer

1
Cảm ơn! Bạn có thể rút ngắn mã của mình bằng cách xác định c-1>>>1.
dfeuer

1
Tôi đang nhắm mục tiêu Haskell, điều này sẽ khiến việc cạnh tranh về chiều dài trở nên khó khăn, nhưng đó là điều tôi biết rõ nhất từ ​​trước đến nay.
dfeuer
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.