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.
|
liên tiếp?