Đây là một thử thách thú vị để làm việc, bật và tắt, giữa các lễ Giáng sinh. Cảm ơn đã đăng bài viết! Chơi golf này rất thú vị vì đặc điểm kỹ thuật có đầy đủ các trường hợp ngoại lệ và trường hợp đặc biệt, đòi hỏi rất nhiều nếu có điều kiện. Ngoài ra, trong khi tôi không cần phải chuyển đổi sang và từ số thập phân lần này, tôi đã cần một hàm sắp xếp max max để xác định số chữ số lớn nhất trong mỗi số và giá trị lớn nhất của các chữ số ở mỗi nơi.
Phiên bản đầu tiên của cái này là 4844 byte, chỉ để cho bạn biết tôi đã chơi cái này bao nhiêu.
Chương trình dự kiến đầu vào là một danh sách các số nguyên được phân tách bằng dấu phẩy . Không có không gian hoặc dòng mới. Sử dụng những người sẽ tạo ra hành vi không xác định.
"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
Giải trình
Tôi sẽ hướng dẫn bạn cách chương trình hoạt động bằng cách chỉ cho bạn cách chương trình xử lý đầu vào cụ thể 202,100,1
.
Ban đầu, chúng tôi xây dựng một vài giá trị mà chúng tôi sẽ cần sau này - chủ yếu là mã ASCII của các ký tự mà chúng tôi sẽ xuất ra.
Như bạn có thể thấy, '8'
và '.'
đã có sẵn. '|'
tuy nhiên, thực sự là 124, không phải 14. Chúng tôi sử dụng vòng lặp while để thêm hai lần giá trị tạm thời vào vị trí số 1 vào đó để có được 124 (tức là 14 + 55 × 2, vì vòng lặp while chạy với giá 56−1 = 55 lặp đi lặp lại). Điều này tiết kiệm một số byte bởi vì số nguyên lớn như 124 thực sự dài. Trong sơ đồ sau, tôi hiển thị vị trí của mọi biến mà chương trình sử dụng.
Tiếp theo, chúng tôi muốn nhập tất cả các ký tự và lưu trữ chúng trên băng bắt đầu từ ô số 12 ( p là con trỏ đang chạy cho việc này). Đồng thời, chúng tôi muốn biết số dài nhất là bao lâu (bao nhiêu chữ số). Để đạt được điều này, chúng tôi giữ cho tổng số chạy trong unary đi về phía trái bắt đầu từ ô # 1 (chúng tôi sử dụng q làm con trỏ đang chạy). Sau số đầu vào đầu tiên ( 202
), băng bây giờ trông như thế này:
Bạn sẽ nhận thấy rằng các số bị tắt bởi 4. Chà, khi chúng ta lần đầu tiên nhập chúng, chúng là các giá trị ASCII của chúng, vì vậy, chúng bị tắt bởi 48 và dấu phẩy là 44. Với mỗi ký tự, chúng ta sao chép 46 từ '.'
vào r và sau đó trừ nó bằng một vòng lặp while (trừ 45) và sau đó chúng ta thêm 1. Chúng ta làm như vậy để dấu phẩy (dấu phân cách của chúng ta) bằng 0, vì vậy chúng ta có thể sử dụng một điều kiện để nhận ra nó.
Ngoài ra, bạn sẽ nhận thấy rằng chúng ta để ô số 11 ở mức 0. Chúng ta cần điều đó để nhận ra ranh giới của số đầu tiên.
Ký tự tiếp theo sẽ là dấu phẩy, vì vậy chúng tôi lưu 0 trong # 15, nhưng tất nhiên lần này chúng tôi không tiến lên q . Thay vào đó, chúng tôi đặt q trở về 0 và bắt đầu ghi đè vào số 1 mà chúng tôi đã đặt.
Sau khi tất cả các ký tự còn lại được xử lý, chúng tôi nhận được điều này:
Như bạn có thể thấy, các số 1 được viết bởi q hiện chỉ ra (bằng unary) độ dài của số dài nhất.
Bây giờ chúng ta sử dụng một vòng lặp while để di chuyển q sang bên trái, và sau đó đặt một con trỏ khác ở đó mà tôi sẽ gọi r2 . Mục đích của r2 sẽ trở nên rõ ràng sau này.
Tại thời điểm này, hãy để tôi làm rõ thuật ngữ mà tôi sẽ sử dụng trong suốt này.
- Theo số , tôi có nghĩa là một trong những số đầu vào được phân tách bằng dấu phẩy. Trong ví dụ của chúng tôi, chúng là 202, 100 và 1.
- Theo chữ số , tôi có nghĩa là một chữ số trong một số cụ thể. Số đầu tiên có 3 chữ số.
- Theo địa điểm , ý tôi là các vị trí, hàng chục, hàng trăm vị trí, v.v ... Vì vậy, nếu tôi nói thì các chữ số ở vị trí hiện tại, và vị trí hiện tại là các vị trí, các chữ số đó là 2, 0 và 1 trong đó đặt hàng.
Bây giờ trở lại chương trình thường xuyên của chúng tôi. Toàn bộ phần còn lại của chương trình là một vòng lặp lớn di chuyển q về phía trước cho đến khi đến ô # 0. Mỗi ô trên đường đi đại diện cho một địa điểm, với các ô ở phía bên phải và q sẽ bắt đầu ở mức quan trọng nhất. Trong ví dụ của chúng tôi, đó là hàng trăm nơi.
Chúng tôi tiến hành bằng cách tăng các ô q điểm tại (nghĩa là, * q ).
Hiện tại chúng tôi đang ở giai đoạn 2, trước đây cho hàng trăm nơi. Trong giai đoạn này, chúng ta sẽ tìm ra chữ số nào lớn nhất trong số tất cả các chữ số ở hàng trăm vị trí. Chúng tôi sử dụng cùng một thủ thuật đếm đơn phương cho việc này, ngoại trừ lần này con trỏ được gọi là r và con trỏ r2 đánh dấu vị trí bắt đầu của nó mà chúng tôi cần đặt lại mỗi khi chúng tôi chuyển sang số tiếp theo.
Hãy bắt đầu với số đầu tiên. Chúng tôi bắt đầu bằng cách đặt p thành 11 (vị trí bắt đầu được mã hóa cứng của tất cả các số). Sau đó chúng tôi sử dụng một vòng lặp while để tìm phần cuối của số và đặt p2 ở đó để đánh dấu vị trí. Đồng thời, chúng tôi cũng đặt q2 thành 0:
Đừng bị phân tâm bởi thực tế là q2 đang chỉ vào các bình. Chúng tôi không có phần đệm của một ô trống ở đó vì chúng tôi có thể phát hiện ô # 0 đơn giản vì đó là số không.
Tiếp theo, chúng ta đi qua số hiện tại bằng cách giảm p và q2 cùng nhau cho đến khi * p bằng không. Tại mỗi nơi, giá trị của * q2 cho chúng ta biết những gì chúng ta cần làm. 1 có nghĩa là không làm gì cả, vì vậy chúng tôi tiếp tục. Cuối cùng, chúng ta bắt gặp 2 trong ô # −3. Mỗi lần * q2 không bằng 1, q2 luôn bằng q .
Như tôi đã nói, giai đoạn 2 là xác định chữ số lớn nhất ở nơi này. Vì vậy, chúng tôi đặt r thành r2 , sử dụng vòng lặp while để giảm * p và di chuyển r sang trái và lấp đầy băng bằng 1s, sau đó sử dụng vòng lặp while khác để di chuyển r trở lại bên phải và tăng * p lần nữa để khôi phục giá trị. Hãy nhớ rằng mỗi vòng lặp while chạy cho một lần lặp ít hơn giá trị chúng ta sử dụng; bởi vì điều này, số lượng 1 chữ viết sẽ nhiều hơn 3 (chứ không phải 4 nhiều hơn) so với giá trị chữ số và giá trị cuối cùng được lưu trữ trong * p sẽ nhiều hơn 2. Do đó, điều này đã giảm hiệu quả * p xuống 2.
Sau đó, chúng tôi đặt p thành giá trị của p2 và sau đó chúng tôi làm lại tất cả. Lần thứ hai, đặt q2 thành 0, tìm điểm cuối của số bằng cách di chuyển p sang phải và sau đó đi qua các chữ số của số này bằng cách giảm p và q2 cùng nhau. Một lần nữa, chúng ta sẽ bắt gặp 2 trong ô # −3 và viết rằng nhiều số 1 còn lại của * r .
Trong trường hợp của số thứ ba, cuối cùng chúng tôi không làm gì cả vì nó không có hàng trăm vị trí (vì vậy q2 không bao giờ đạt đến q ), nhưng điều đó không sao vì điều đó không ảnh hưởng đến việc tính toán giá trị chữ số tối đa.
Chúng tôi cũng đặt ô * (r - 4) , mà tôi đã đánh dấu bằng một mũi tên chưa được gắn nhãn ở đây, thành 1 (mặc dù nó đã ở mức 1). Tôi sẽ không cho bạn biết lý do tại sao, nhưng có lẽ bạn đã đoán ra?
Gia số tiếp theo của * q đưa chúng ta đến giai đoạn 3, tức là trừ đi chữ số tối đa từ tất cả các chữ số ở vị trí hiện tại. Như trước đây, chúng tôi đặt lại p thành 11 và q2 thành 0 và sau đó đi qua tất cả các số giống như chúng tôi đã làm trong giai đoạn trước; ngoại trừ lần này, * q = 3 thay vì 2. Mỗi lần q2 gặp q và p ở vị trí hàng trăm, chúng tôi sử dụng vòng lặp while để giảm * p nhiều lần vì có 1s trong khối còn lại của * r2 (5 trong ví dụ của chúng tôi) bằng cách sử dụng rnhư một con trỏ đang chạy Chúng tôi thực sự giảm nó một lần nữa để chữ số lớn nhất kết thúc ở −2, vì một lý do sẽ trở nên rõ ràng sau:
Sau khi chúng tôi xử lý tất cả các số, bây giờ chúng tôi ở cuối giai đoạn 3. Ở đây chúng tôi thực hiện hai điều kỳ dị.
- Đầu tiên, chúng tôi cũng trừ kích thước của r -block (cộng 1) từ * q , nhưng sử dụng con trỏ r2 , để nó ở bên trái. * q trở nên tiêu cực theo cách này. Trong trường hợp của chúng tôi, r -block có năm 1 giây, vì vậy * q trở thành −3.
- Thứ hai, chúng ta thiết lập một biến ra một giá trị khác không để cho biết rằng bây giờ chúng ta đang bước vào giai đoạn đầu ra. (Về mặt kỹ thuật, thực tế là * q âm đã chỉ ra giai đoạn đầu ra, nhưng điều này quá khó để kiểm tra, do đó biến phụ.)
Bây giờ bạn hiểu rằng chúng tôi tiếp tục xem qua các số, tìm vị trí hiện tại (được biểu thị bằng giá trị không 1 của * q ) trong mỗi số và làm một cái gì đó tùy thuộc vào giá trị của * q . Chúng tôi thấy rằng * q trước tiên được tăng lên 2 (= tính giá trị chữ số tối đa), sau đó 3 (trừ giá trị chữ số tối đa từ mỗi chữ số ở vị trí này) và sau đó chúng tôi trừ đi để làm cho nó âm. Từ đó, nó sẽ tiếp tục tăng cho đến khi đạt 1, do đó khôi phục lại giá trị có nghĩa là không làm gì nữa. Tại thời điểm đó, chúng tôi chuyển sang địa điểm tiếp theo.
Bây giờ, khi * q âm, chúng tôi xuất ra. * q chính xác là đúng giá trị để chúng ta sẽ xuất đúng số lượng hàng ký tự trước khi đạt 1; nếu chữ số lớn nhất là 2, chúng ta cần xuất 3 hàng. Hãy xem điều gì xảy ra ở mỗi giá trị của * q :
- * q = −2:
- Đối với số đầu tiên, * p là −2, cho biết chúng ta cần xuất ra một
'.'
dấu chấm (dấu chấm) hoặc ':'
dấu hai chấm. Chúng tôi quyết định xem bằng cách xem q : nếu là −1, chúng tôi đang ở vị trí đó, vì vậy hãy xuất a ':'
(mà chúng tôi tính là '8'
+2), nếu không thì a '.'
.
- Đối với số thứ hai, * p là −3. Bất cứ điều gì không phải là 2 có nghĩa là chúng ta xuất ra một
'|'
(ống) và sau đó tăng giá trị. Bằng cách này, nó sẽ đạt đến −2 ở đúng vị trí và sau đó chúng ta xuất '.'
s / ':'
s cho phần còn lại của chữ số đó.
- Trong mỗi trường hợp, chúng tôi cũng đặt một biến pd thành 0 trước khi chúng tôi xử lý số và đặt pd (= In đã in) thành một giá trị khác không để cho biết rằng chúng tôi đã in một ký tự.
- Đối với số thứ ba, không có xử lý xảy ra vì số thứ ba không có hàng trăm vị trí. Trong trường hợp này, pd vẫn sẽ là 0 sau khi xử lý số, cho biết rằng chúng ta vẫn cần xuất ra một
'|'
(nhưng chỉ khi ra là khác không, bởi vì nếu không thì chúng ta vẫn ở giai đoạn 2 hoặc 3).
- Sau khi xử lý tất cả các số, nếu ra là khác không, hãy xuất một dòng mới. Lưu ý rằng chúng tôi cần biến ngoài để chúng tôi không xuất dòng mới trong giai đoạn 2 hoặc 3.
- * q = 1: Tương tự như trước, ngoại trừ * p là −2 cho cả hai số đầu tiên, vì vậy cả hai đều xuất a
'.'
(và số thứ ba xuất ra a'|'
như trước).
- * q = 0: Khi * q bằng 0, điều này có nghĩa là không làm gì nếu chúng ta ở vị trí đó, nếu không thì xuất ra một hàng
'|'
s bất kể * p . Bằng cách này, chúng ta có được phần đệm giữa các chữ số.
Bây giờ chúng ta tăng q để chuyển sang vị trí tiếp theo, vị trí hàng chục và tăng * q ở đó. Ở đầu Giai đoạn 2, đoạn băng trông như thế này:
Sau đó, chúng tôi thực hiện Giai đoạn 2 như trước đây. Hãy nhớ điều này một cách hiệu quả trừ 2 từ mỗi chữ số ở vị trí này và cũng để lại một số đơn vị còn lại là * r2 cho biết chữ số tối đa. Chúng tôi để số unary trước đó một mình và chỉ cần kéo dài băng sang bên trái; nó sẽ chỉ tốn thêm mã không cần thiết để dọn dẹp. Khi chúng tôi hoàn thành và chúng tôi tăng * q , khi bắt đầu Giai đoạn 3, băng bây giờ là:
Thật ra, đây là một lời nói dối. Hãy nhớ trước đó tôi đã nói chúng tôi đặt * (r - 4) thành 1 và tôi không nói cho bạn biết tại sao? Bây giờ tôi sẽ cho bạn biết lý do tại sao. Đối với các trường hợp như trường hợp này, trong đó chữ số lớn nhất thực tế là 0, có nghĩa là tất cả các chữ số ở vị trí này là 0. Cài đặt * (r - 4) , được biểu thị bằng mũi tên không được gắn nhãn ở trên, đến 1 kéo dài số đơn vị 1, Nhưng chỉ trong trường hợp đặc biệt này. Bằng cách này, chúng tôi giả vờ như thể chữ số lớn nhất là 1, có nghĩa là chúng tôi sẽ xuất thêm một hàng.
Sau Giai đoạn 3 (trừ chữ số tối đa từ tất cả các chữ số ở vị trí hiện tại), bao gồm cả bước bổ sung làm cho * q âm, băng trông như thế này. Lần trước, chữ số lớn nhất được biểu thị bằng −2 trong khối * p , nhưng lần này tất cả đều là because3 vì tất cả chúng thực sự là số 0 nhưng chúng tôi giả vờ như thể chữ số tối đa là 1.
Bây giờ hãy xem điều gì xảy ra khi * q tiến tới 1:
- Khi * q = −1, các giá trị * p đều là −3, có nghĩa là chúng ta xuất
'|'
s và tăng chúng.
- Khi * q = 0, chúng tôi xuất ra
'|'
vì đó là những gì chúng tôi luôn làm khi * q = 0, bất kể * p .
Như vậy, chúng ta có được hai hàng ống.
Cuối cùng, chúng tôi di chuyển * q đến nơi của một người. Điều này trở nên thú vị bởi vì chúng ta cần xuất ':'
s nếu chữ số thực là bất cứ thứ gì ngoài 1, nhưng '8'
nếu nó là 1. Hãy xem chương trình tiến hành như thế nào. Đầu tiên, chúng tôi tăng * q để bắt đầu Giai đoạn 2:
Sau Giai đoạn 2 (tính toán giá trị chữ số tối đa,), chúng ta còn lại điều này:
Sau Giai đoạn 3 (trừ đi giá trị chữ số tối đa từ tất cả các chữ số ở vị trí hiện tại), băng trông như thế này:
Bây giờ chúng ta hãy lần lượt đi qua mỗi lần lặp của * q :
- * q = −2:
- Số đầu tiên: đã ở −2, vì vậy đầu ra a
':'
(chứ không phải a '.'
vì q = 1).
- Số thứ hai: tại 4, vì vậy đầu ra a
'|'
và tăng.
- Số thứ ba: ở 3, do đó đầu ra a
'|'
. Tuy nhiên, lần này, thay vì tăng, một trường hợp đặc biệt kích hoạt. Chỉ khi chúng tôi xuất ra vị trí cuối cùng ( q = 1) và chúng tôi ở hàng cuối cùng thứ hai cho điều đó ( * q = −2), và chữ số thực sự là 1 ( * p = 3) , sau đó thay vì tăng nó lên −2, chúng tôi đặt nó thành 1. Nói cách khác, chúng tôi sử dụng −1 như một giá trị đặc biệt để chỉ ra rằng trong lần lặp tiếp theo, chúng tôi sẽ cần phải xuất ra '8'
thay vì ':'
.
- * q = −1:
- Số đầu tiên: đã ở 2, vì vậy đầu ra a
':'
.
- Số thứ hai: ở 3, nên đầu ra a
'|'
. Điều kiện đặc biệt không kích hoạt vì * q không còn 2. Do đó, gia tăng.
- Số thứ ba: tại 1, do đó đầu ra
'8'
.
- * q = 0: Thông thường, chúng tôi sẽ xuất hàng đệm của
'|'
s ở đây, nhưng trong trường hợp đặc biệt khi chúng tôi ở vị trí đó ( q = −1), chúng tôi bỏ qua điều đó.
Sau này, q được tăng lên 0 và vòng lặp while lớn kết thúc.
Bây giờ bạn biết làm thế nào một đầu vào như 202,100,1
hoạt động. Tuy nhiên, có một trường hợp đặc biệt nữa mà chúng tôi vẫn chưa được bảo hiểm. Bạn có thể nhớ rằng trong khi chúng tôi đang xử lý vị trí cuối cùng, khi * p là −3, chúng tôi đặt nó thành for1 cho 1
(thay vì tăng nó thành −2) để lần lặp tiếp theo sẽ xuất ra '8'
thay thế. Điều này chỉ hoạt động bởi vì chúng tôi có một lần lặp trong đó * p là −3 và chúng tôi đưa ra quyết định về việc có nên tăng nó hay đặt nó thành 1 hay không. Chúng tôi không có phép lặp như vậy nếu tất cả các chữ số ở vị trí đó là 0 hoặc 1. Trong trường hợp như vậy, tất cả các giá trị * p cho 1 sẽ bắt đầu ở −2; không có cơ hội để quyết định đặt nó thành 1thay vì tăng nó từ −3 . Bởi vì điều này, có một điều kiện vỏ đặc biệt khác trong Giai đoạn 3 (trừ đi chữ số tối đa từ mỗi chữ số ở vị trí hiện tại). Tôi đã tuyên bố rằng sau khi trừ giá trị chữ số tối đa từ mỗi chữ số (tại thời điểm đó chữ số tối đa là −1), chúng tôi chỉ giảm giá trị một lần nữa, nhưng thực tế có một điều kiện như sau:
Nếu chữ số chúng ta đang xem bằng chữ số tối đa ở nơi này ( * p = 1) và vị trí này là vị trí ( q = 1) và chữ số tối đa là 1 ( * (r + 5) = 0, tức là khối unary ở bên trái chỉ dài 5 ô), chỉ sau đó chúng ta để * p ở −1 để chỉ ra rằng lần lặp duy nhất của đầu ra phải xuất ra một '8'
. Trong tất cả các trường hợp khác, chúng tôi giảm nó một lần nữa.
Làm xong. Chúc mừng năm mới!
Chỉnh sửa 1 (3183 → 3001): Chơi golf chúc mừng năm mới! Tôi đã quản lý để loại bỏ hoàn toàn các biến p2 và r2 ! Bây giờ p chạy đua qua lại để tiếp tục tìm đầu và cuối của các số, nhưng dường như mã này ngắn hơn. Tôi cũng đã cố gắng loại bỏ q2 , nhưng tôi không thể làm cho mã ngắn hơn theo cách đó.
Tôi cũng tìm thấy thêm một vài nơi mà tôi có thể áp dụng các thủ thuật đánh gôn không thể đọc được điển hình như sử dụng lại giá trị cuối cùng của vòng lặp while. Để cho bạn một ví dụ, thay vì
while *(++p) { 1 } // just increment p until *p is 0; the 1 is a noop
if (pd) { x } else { y } // where pd is a variable
Tôi có thể lưu '""""
(thực hiện lần đầu tiên, sau đó lần thứ hai) và '"""
(hằng số 1) bằng cách viết nó theo cách tương tự
if (while *(++p) { pd }) { x } else { y }
Tất nhiên, điều này chỉ hoạt động nếu tôi biết rằng vòng lặp while sẽ chạy ít nhất một lần lặp, nhưng nếu có, giá trị trả về của nó là pd vì vậy tôi có thể sử dụng nó làm điều kiện cho if.