Số phân hạch


47

Tôi đã tìm thấy trình tự này trong khi làm việc trên Evolution of OEIS , nhưng không bao giờ có thể đăng nó như một câu trả lời. Sau khi viết một triển khai tham chiếu trong Mathematica, tôi nghĩ rằng đây là một bài tập thú vị để thực hiện như một thử thách riêng biệt, vì vậy chúng tôi đi đây.

Hãy xây dựng một lò phản ứng phân hạch số! Xét một số nguyên dương N. Ví dụ, chúng ta sẽ xem xét 24. Để phân hạch số này, chúng ta phải tìm số lớn nhất của các số nguyên dương liên tiếp có tổng N. Trong trường hợp này, đó là 7 + 8 + 9 = 24. Vì vậy, chúng tôi đã chia 24thành ba số mới. Nhưng đây sẽ không phải là một lò phản ứng phân hạch mà không có phản ứng dây chuyền. Vì vậy, hãy lặp lại một cách đệ quy quy trình cho các thành phần này:

       24
       /|\
      / | \
     /  |  \
    7   8   9
   / \     /|\
  3   4   / | \
 / \     /  |  \
1   2   2   3   4
           / \
          1   2

Lưu ý rằng chúng tôi dừng quá trình bất cứ khi nào số không thể bị phân tách thành các số nguyên liên tiếp nhỏ hơn. Cũng lưu ý rằng chúng ta có thể đã viết 9như 4 + 5, nhưng 2 + 3 + 4có nhiều thành phần hơn. Các số Fission của Nbây giờ được định nghĩa là số các số nguyên thu được trong quá trình này, bao gồm cả Nbản thân. Cây trên có 13 nút, vì vậy F(24) = 13.

Trình tự này là mục nhập OEIS A256504 .

40 điều khoản đầu tiên, bắt đầu từ N = 1, là

1, 1, 3, 1, 5, 6, 5, 1, 6, 7, 12, 10, 12, 11, 12, 1, 8, 16, 14, 17, 18, 18,
23, 13, 21, 18, 22, 23, 24, 19, 14, 1, 22, 20, 23, 24, 31, 27, 25, 26

1000 thuật ngữ đầu tiên có thể được tìm thấy trong pastebin này .

Các thách thức

Cho một số nguyên dương N, xác định số phân hạch của nó F(N). (Vì vậy, bạn không cần phải bao gồm các mục hàng đầu 0được liệt kê trên OEIS.)

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Đây là mã golf, vì vậy câu trả lời ngắn nhất (tính bằng byte) sẽ thắng.

Câu hỏi thưởng: Bạn có thể tìm thấy bất kỳ tính chất thú vị của chuỗi này?


Tôi nhận thấy rằng OEIS dường như có lỗi tại n = 34: bắt đầu từ n = 32, nó (hiện tại) liệt kê 1, 22, 22, 23, 24, 31, thay vì 1, 22, 20, 23, 24, 31.
mathmandan

1
@mathmandan Bắt tốt, có lẽ tôi sẽ đề xuất một sự điều chỉnh (cùng với sơ đồ đầu tiên).
Martin Ender

Thử thách liên quan: codegolf.stackexchange.com/questions/5703/ (và cùng một câu hỏi về toán học.SE: math.stackexchange.com/questions/139842/ trộm )
Ilmari Karonen

@mathmandan FYI, tôi đã sửa lỗi trình tự và ví dụ bây giờ, và cũng đã thêm triển khai tham chiếu của tôi và các điều khoản 10k đầu tiên.
Martin Ender

Có vẻ tốt! Cám ơn việc làm của bạn!
mathmandan

Câu trả lời:


16

Pyth, 23 22 21 byte

Lh&lJfqbsT.:tUb)syMeJ

Điều này xác định một hàm đệ quy y. Dùng thử trực tuyến: Trình diễn

Giải trình:

L                      define a function y(b): return ...
            tUb          the list [1, 2, ..., b-1]
          .:   )         generate all consecutive sub-sequences
     f                   filter for sub-sequences T, which satisfy:
      qbsT                   b == sum(T)
    J                    and store them in J

                         return 
   lJ                        len(J)
  &                        and (if len(J) == 0 then 0 else ...)
                    eJ       last element of J (=longest sub-sequence) 
                  yM         recursive calls for all these numbers
                 s           sum
 h                         incremented by one (counting the current node)

52

Phân hạch , 1328 989 887 797 byte

Câu trả lời này hơi dài một cách vô lý (tôi ước chúng ta có những vùng bị sụp đổ ) ... xin đừng quên cuộn qua cái này và cho những câu trả lời khác một số tình yêu!

Làm việc trên mã này là những gì đã truyền cảm hứng cho thách thức này. Tôi muốn thêm một câu trả lời trong Phân hạch vào EOEIS, điều này dẫn tôi đến trình tự này. Tuy nhiên, thực sự học Phân hạch và thực hiện việc này mất vài tuần để thực hiện và tắt nó. Trong khi đó, trình tự đã thực sự phát triển trong tôi nên tôi quyết định đăng một thử thách riêng cho nó (cộng với, điều này sẽ không đặc biệt ở xa cây trên EOEIS).

Vì vậy, tôi trình bày với bạn, sự quái dị:

 R'0@+\
/  Y@</ /[@ Y]_L
[? % \  / \ J
   \$@  [Z/;[{+++++++++L
UR+++++++++>/;
9\   ;    7A9
SQS  {+L  /$     \/\/\/\/\/   5/ @  [~ &@[S\/ \  D /8/
~4X /A@[  %5                   /; &    K  } [S//~KSA /
  3    \  A$@S  S\/  \/\/\/   \/>\ /S]@A  /  \ { +X
W7           X  X    /> \      +\ A\ /   \ /6~@/ \/
        /   ~A\;     +;\      /@
    ZX [K    / {/  / @  @ }  \ X @
       \AS   </      \V /    }SZS S/
         X   ;;@\   /;X  /> \ ; X X
 ;       \@+  >/ }$S SZS\+;    //\V
           / \\  /\; X X @  @  \~K{
           \0X /     /~/V\V /   0W//
    \        Z      [K \  //\
W       /MJ $$\\ /\7\A  /;7/\/ /
       4}K~@\ &]    @\  3/\
 /     \{   }$A/1 2  }Y~K <\
[{/\  ;@\@  /   \@<+@^   1;}++@S68
@\ <\    2        ;   \    /
$  ;}++ +++++++L
%@A{/
M  \@+>/
~     @
SNR'0YK
  \  A!/

Nó hy vọng rằng không có dòng mới trên đầu vào, vì vậy bạn có thể muốn gọi nó như thế nào echo -n 120 | ./Fission oeis256504.fis.

Bố cục có thể vẫn hiệu quả hơn, vì vậy tôi nghĩ vẫn còn nhiều chỗ để cải thiện ở đây (ví dụ: cái này chứa 911 581 461 374 khoảng trắng).

Trước khi chúng tôi có được lời giải thích, một lưu ý khi kiểm tra điều này: thông dịch viên chính thức không hoàn toàn hoạt động như hiện tại. a) Mirror.cppkhông biên dịch trên nhiều hệ thống. Nếu bạn gặp phải vấn đề đó, chỉ cần nhận xét dòng vi phạm - thành phần bị ảnh hưởng (một máy nhân bản ngẫu nhiên) không được sử dụng trong mã này. b) Có một vài lỗi có thể dẫn đến hành vi không xác định (và có khả năng sẽ xảy ra đối với một chương trình phức tạp này). Bạn có thể áp dụng bản vá này để sửa chúng. Khi bạn đã thực hiện điều đó, bạn sẽ có thể biên dịch trình thông dịch với

g++ -g --std=c++11 *.cpp -o Fission

Sự thật thú vị: Chương trình này sử dụng hầu hết mọi phân hạch thành phần, ngoại trừ #(gương ngẫu nhiên), :(gương nửa) -hoặc |(gương đơn giản) và "(chế độ in).

Những gì trên trái đất?

Cảnh báo: Việc này sẽ khá lâu ... Tôi cho rằng bạn thực sự quan tâm đến cách thức Phân hạch hoạt động và cách người ta có thể lập trình trong đó. Bởi vì nếu bạn không, tôi không chắc làm thế nào tôi có thể tóm tắt điều này. (Đoạn tiếp theo đưa ra một mô tả chung về ngôn ngữ.)

Phân hạch là ngôn ngữ lập trình hai chiều, trong đó cả dữ liệu và luồng điều khiển được thể hiện bằng các nguyên tử di chuyển qua lưới. Nếu bạn đã thấy hoặc sử dụng Marbelous trước đây, khái niệm này sẽ rất quen thuộc. Mỗi nguyên tử có hai tính chất nguyên: khối lượng không âm và năng lượng tùy ý. Nếu khối lượng trở nên âm, nguyên tử được loại bỏ khỏi lưới điện. Trong hầu hết các trường hợp, bạn có thể coi khối lượng là "giá trị" của nguyên tử và năng lượng như một loại thuộc tính meta được sử dụng bởi một số thành phần để xác định dòng chảy của các nguyên tử (nghĩa là hầu hết các loại công tắc phụ thuộc vào dấu hiệu của năng lượng). Tôi sẽ ký hiệu các nguyên tử bằng (m,E), khi cần thiết. Khi bắt đầu chương trình, lưới bắt đầu với một loạt(1,0)các nguyên tử từ bất cứ nơi nào bạn đặt trên bốn thành phần UDLR(trong đó chữ cái chỉ hướng nguyên tử đang di chuyển ban đầu). Hội đồng sau đó được tập hợp với một loạt các thành phần làm thay đổi khối lượng và năng lượng của các nguyên tử, thay đổi hướng của chúng hoặc làm những việc phức tạp hơn khác. Để biết danh sách đầy đủ, hãy xem trang esolang , nhưng tôi sẽ giới thiệu hầu hết trong số đó trong phần giải thích này. Một điểm quan trọng khác (mà chương trình sử dụng nhiều lần) là lưới hình xuyến: một nguyên tử va vào bất kỳ phía nào xuất hiện ở phía đối diện, di chuyển theo cùng một hướng.

Tôi đã viết chương trình thành nhiều phần nhỏ hơn và tập hợp chúng vào cuối, vì vậy đó là cách tôi sẽ giải thích.

atoi

Thành phần này có vẻ không thú vị, nhưng nó hay và đơn giản và cho phép tôi giới thiệu rất nhiều khái niệm quan trọng về dòng số học và kiểm soát của Fudge. Do đó, tôi sẽ xem xét phần này một cách khá chi tiết, vì vậy tôi có thể giảm các phần khác để giới thiệu cơ học phân hạch mới và chỉ ra các thành phần cấp cao hơn có luồng điều khiển chi tiết mà bạn có thể tự theo dõi.

Phân hạch chỉ có thể đọc các giá trị byte từ các ký tự riêng lẻ, không phải toàn bộ số. Trong khi đó thực tế có thể chấp nhận được ở đây, tôi đã hình dung khi tôi ở đó, tôi có thể làm đúng và phân tích các số nguyên thực tế trên STDIN. Đây là atoimã:

     ;
 R'0@+\
/  Y@</ /[@ Y]_L
[? % \  / \ J 
   \$@  [Z/;[{+++++++++L
UR+++++++++>/;
           O

Hai trong số các thành phần quan trọng nhất trong phân hạch là lò phản ứng phân hạch và phản ứng tổng hợp. Lò phản ứng phân hạch là bất kỳ V^<>(mã trên sử dụng <>). Một lò phản ứng phân hạch có thể lưu trữ một nguyên tử (bằng cách gửi nó vào nêm của nhân vật), mặc định (2,0). Nếu một nguyên tử chạm vào đỉnh của nhân vật, hai nguyên tử mới sẽ được gửi sang hai bên. Khối lượng của chúng được xác định bằng cách chia khối lượng đến cho khối lượng được lưu trữ (nghĩa là giảm một nửa theo mặc định) - nguyên tử đi bên trái có giá trị này và nguyên tử đi phải lấy phần còn lại (nghĩa là khối lượng được bảo toàn trong phân hạch) . Cả hai nguyên tử đi sẽ có âm năng lượng đếnnăng lượng dự trữ. Điều này có nghĩa là chúng ta có thể sử dụng các lò phản ứng phân hạch cho số học - cả cho phép trừ và chia. Nếu một lò phản ứng phân hạch được đánh từ trang web, nguyên tử chỉ được phản xạ theo đường chéo và sau đó sẽ di chuyển theo hướng đỉnh của nhân vật.

Lò phản ứng nhiệt hạch là bất kỳ YA{}(mã trên sử dụng Y{). Chức năng của chúng tương tự nhau: chúng có thể lưu trữ một nguyên tử (mặc định (1,0)) và khi bị tấn công từ đỉnh, hai nguyên tử mới sẽ được gửi sang hai bên. Tuy nhiên, trong trường hợp này, hai nguyên tử sẽ giống hệt nhau, luôn giữ lại năng lượng đến và nhân khối lượng đến với khối lượng được lưu trữ. Theo mặc định, lò phản ứng nhiệt hạch chỉ đơn giản là sao chép bất kỳ nguyên tử nào chạm đỉnh của nó. Khi bị tấn công từ hai bên, các lò phản ứng nhiệt hạch phức tạp hơn một chút: nguyên tử cũng vậyđược lưu trữ (độc lập với bộ nhớ khác) cho đến khi một nguyên tử chạm vào phía đối diện. Khi điều đó xảy ra, một nguyên tử mới được giải phóng theo hướng của đỉnh có khối lượng và năng lượng là tổng của hai nguyên tử cũ. Nếu một nguyên tử mới chạm vào cùng một phía trước khi một nguyên tử phù hợp đến phía đối diện, nguyên tử cũ sẽ đơn giản bị ghi đè. Lò phản ứng nhiệt hạch có thể được sử dụng để thực hiện phép cộng và nhân.

Một thành phần đơn giản khác mà tôi muốn tránh ra là []đơn giản là đặt hướng của nguyên tử sang phải và trái, tương ứng (bất kể hướng đến). Tương đương dọc là M(xuống) và W(lên) nhưng chúng không được sử dụng cho atoimã. UDLRcũng hoạt động như WM][sau khi phát hành các nguyên tử ban đầu của chúng.

Dù sao, hãy nhìn vào mã trên đó. Chương trình bắt đầu với 5 nguyên tử:

  • Các RLở phía dưới chỉ đơn giản là có được tăng khối lượng của chúng (với +) để trở thành (10,0)và sau đó lưu trữ trong một phân hạch và một lò phản ứng nhiệt hạch, tương ứng. Chúng tôi sẽ sử dụng các lò phản ứng này để phân tích đầu vào cơ sở 10.
  • Lgóc trên bên phải sẽ giảm khối lượng (với _) để trở thành (0,0)và được lưu trữ ở bên cạnh lò phản ứng nhiệt hạch Y. Điều này là để theo dõi số lượng chúng ta đang đọc - chúng ta sẽ tăng dần và nhân số này khi chúng ta đọc số.
  • Góc Rtrên bên trái được đặt khối lượng của nó thành mã ký tự của 0(48) với '0, sau đó khối lượng và năng lượng được hoán đổi @và cuối cùng tăng khối lượng một lần khi +cho (1,48). Sau đó, nó được chuyển hướng với gương chéo \/được lưu trữ trong lò phản ứng phân hạch. Chúng tôi sẽ sử dụng 48phép trừ để biến đầu vào ASCII thành giá trị thực của các chữ số. Chúng tôi cũng phải tăng khối lượng 1để tránh chia rẽ 0.
  • Cuối cùng, Uở góc dưới bên trái là thứ thực sự khiến mọi thứ chuyển động và ban đầu chỉ được sử dụng cho luồng điều khiển.

Sau khi được chuyển hướng sang phải, nguyên tử điều khiển va vào ?. Đây là thành phần đầu vào. Nó đọc một ký tự và đặt khối lượng của nguyên tử thành giá trị đọc ASCII và năng lượng 0. Nếu chúng ta nhấn EOF thay vào đó, năng lượng sẽ được đặt thành 1.

Nguyên tử tiếp tục và sau đó đánh %. Đây là một công tắc gương. Đối với năng lượng không tích cực, điều này hoạt động như một /tấm gương. Nhưng đối với năng lượng tích cực, nó hoạt động như một \(và cũng làm giảm năng lượng đi 1). Vì vậy, trong khi chúng ta đọc các ký tự, nguyên tử sẽ được phản xạ lên trên và chúng ta có thể xử lý ký tự. Nhưng khi chúng ta thực hiện xong đầu vào, nguyên tử sẽ được phản xạ xuống và chúng ta có thể áp dụng logic khác nhau để lấy kết quả. FYI, thành phần ngược lại là &.

Vì vậy, bây giờ chúng ta đã có một nguyên tử di chuyển lên. Những gì chúng tôi muốn làm cho mỗi ký tự là đọc giá trị chữ số của nó, thêm nó vào tổng số đang chạy của chúng tôi và sau đó nhân tổng số chạy đó với 10 để chuẩn bị cho chữ số tiếp theo.

Nguyên tử nhân vật đầu tiên chạm vào lò phản ứng nhiệt hạch (mặc định) Y. Điều này phân tách nguyên tử và chúng tôi sử dụng bản sao bên trái làm nguyên tử điều khiển để lặp lại thành phần đầu vào và đọc ký tự tiếp theo. Các bản sao phải sẽ được xử lý. Hãy xem xét trường hợp chúng ta đã đọc nhân vật 3. Nguyên tử của chúng ta sẽ là (51,0). Chúng ta trao đổi khối lượng và năng lượng với @, để chúng ta có thể sử dụng phép trừ của lò phản ứng phân hạch tiếp theo. Lò phản ứng trừ 48đi năng lượng (không thay đổi khối lượng), do đó, nó gửi đi hai bản sao (0,3)- năng lượng hiện tương ứng với chữ số chúng ta đã đọc. Bản sao đi lên chỉ đơn giản là bị loại bỏ ;(một thành phần chỉ phá hủy tất cả các nguyên tử đến). Chúng tôi sẽ tiếp tục làm việc với bản sao hạ cấp. Bạn sẽ cần đi theo con đường của nó thông qua/\gương một chút.

Ngay @trước khi lò phản ứng nhiệt hạch hoán đổi khối lượng và năng lượng một lần nữa, như vậy chúng ta sẽ thêm (3,0)vào tổng số hoạt động của chúng ta trong Y. Lưu ý rằng tổng số chạy chính nó sẽ luôn luôn có 0năng lượng.

Bây giờ Jlà một bước nhảy. Những gì nó làm là nhảy bất kỳ nguyên tử tới bằng năng lượng của nó. Nếu đó là 0, nguyên tử cứ tiếp tục đi thẳng. Nếu nó 1sẽ bỏ qua một ô, nếu 2nó sẽ bỏ qua hai ô và cứ thế. Năng lượng được sử dụng trong bước nhảy, vì vậy nguyên tử luôn kết thúc bằng năng lượng 0. Vì tổng số chạy không có năng lượng bằng không, nên hiện tại bước nhảy bị bỏ qua và nguyên tử được chuyển hướng vào lò phản ứng nhiệt hạch {nhân khối lượng của nó lên gấp bội 10. Bản sao hạ cấp bị loại bỏ ;trong khi bản sao đi lên được đưa trở lại vào Ylò phản ứng dưới dạng tổng số mới đang chạy.

Những điều trên cứ lặp đi lặp lại (theo cách ngộ nghĩnh trong đó các chữ số mới đang được xử lý trước khi các chữ số trước được thực hiện) cho đến khi chúng ta nhấn EOF. Bây giờ %sẽ gửi nguyên tử xuống dưới. Ý tưởng là biến nguyên tử này thành (0,1)bây giờ trước khi chạm vào tổng lò phản ứng đang chạy để a) tổng số không bị ảnh hưởng (khối lượng bằng không) và b) chúng ta có được năng lượng 1để nhảy qua [. Chúng ta có thể dễ dàng chăm sóc năng lượng $, làm tăng năng lượng.

Vấn đề là ?không thiết lập lại khối lượng khi bạn nhấn EOF nên khối lượng vẫn sẽ là ký tự cuối cùng được đọc và năng lượng sẽ là 0(vì %giảm dần 1về phía sau 0). Vì vậy, chúng tôi muốn thoát khỏi khối lượng đó. Để làm điều đó, chúng tôi trao đổi khối lượng và năng lượng với @một lần nữa.

Tôi cần giới thiệu thêm một thành phần trước khi hoàn thành phần này : Z. Điều này về cơ bản giống như %hoặc &. Sự khác biệt là nó cho phép các nguyên tử năng lượng dương đi thẳng qua (trong khi làm giảm năng lượng) và làm chệch hướng các nguyên tử năng lượng không tích cực 90 độ về bên trái. Chúng ta có thể sử dụng điều này để loại bỏ năng lượng của một nguyên tử bằng cách lặp đi lặp lại Znhiều lần - ngay khi hết năng lượng, nguyên tử sẽ bị lệch và rời khỏi vòng lặp. Đó là mô hình này:

/ \
[Z/

trong đó nguyên tử sẽ di chuyển lên trên một khi năng lượng bằng không. Tôi sẽ sử dụng mô hình này ở dạng này hoặc dạng khác nhiều lần trong các phần khác của chương trình.

Vì vậy, khi các nguyên tử rời khỏi vòng lặp này chút, nó sẽ được (1,0)và hoán đổi để (0,1)theo @trước khi nhấn lò phản ứng tổng hợp để phát hành kết quả cuối cùng của các đầu vào. Tuy nhiên, tổng số hoạt động sẽ bị tắt bởi hệ số 10, vì chúng tôi đã nhân rộng nó cho một chữ số khác.

Vì vậy, bây giờ với năng lượng 1, nguyên tử này sẽ bỏ qua [và nhảy vào /. Điều này làm chệch hướng nó thành một lò phản ứng phân hạch mà chúng tôi đã chuẩn bị chia cho 10 và khắc phục sự nhân lên của chúng tôi. Một lần nữa, chúng ta loại bỏ một nửa với ;và giữ cho nửa kia là đầu ra (ở đây được biểu thị bằng Ocách đơn giản là in ký tự tương ứng và phá hủy nguyên tử - trong toàn bộ chương trình chúng ta tiếp tục sử dụng nguyên tử thay thế).

itoa

           /     \
input ->  [{/\  ;@
          @\ <\   
          $  ;}++ +++++++L
          %@A{/
          M  \@+>/
          ~     @
          SNR'0YK
            \  A!/

Tất nhiên, chúng ta cũng cần chuyển đổi kết quả trở lại thành một chuỗi và in nó. Đó là những gì phần này dành cho. Điều này giả định rằng đầu vào không đến trước 10 hoặc hơn, nhưng trong chương trình đầy đủ dễ dàng được đưa ra. Bit này có thể được tìm thấy ở dưới cùng của chương trình đầy đủ.

Mã này giới thiệu một thành phần Phân hạch rất mạnh mới: ngăn xếp K. Các ngăn xếp ban đầu là trống rỗng. Khi một nguyên tử có năng lượng không âm chạm vào ngăn xếp, nguyên tử chỉ đơn giản được đẩy lên ngăn xếp. Khi một nguyên tử có năng lượng âm chạm vào ngăn xếp, khối lượng và năng lượng của nó sẽ được thay thế bằng nguyên tử trên đỉnh của ngăn xếp (do đó được bật lên). Nếu ngăn xếp trống rỗng, hướng của nguyên tử bị đảo ngược và năng lượng của nó trở nên tích cực (tức là được nhân với -1).

Được rồi, trở lại mã thực tế. Ý tưởng của itoađoạn trích là liên tục lấy modulo đầu vào 10 để tìm chữ số tiếp theo trong khi chia số nguyên cho 10 cho lần lặp tiếp theo. Điều này sẽ mang lại tất cả các chữ số theo thứ tự ngược lại (từ ít quan trọng nhất đến quan trọng nhất). Để khắc phục thứ tự, chúng tôi đẩy tất cả các chữ số lên một chồng và cuối cùng bật chúng ra từng cái một để in chúng.

Nửa trên của mã thực hiện tính toán chữ số: Lvới các điểm cộng cho 10 mà chúng ta nhân bản và đưa vào phản ứng phân hạch và phản ứng tổng hợp để chúng ta có thể chia và nhân với 10. Vòng lặp về cơ bản bắt đầu sau [góc trên cùng bên trái . Giá trị hiện tại được phân chia: một bản sao được chia cho 10, sau đó nhân với 10 và được lưu trữ trong lò phản ứng phân hạch, sau đó được sao chép bởi bản sao khác ở đỉnh. Điều này tính toán i % 10như i - ((i/10) * 10). Cũng lưu ý rằng việc Achia kết quả trung gian sau khi chia và trước khi nhân, để chúng ta có thể i / 10đưa vào lần lặp tiếp theo.

Việc %hủy bỏ vòng lặp một khi biến lặp lặp đạt 0. Vì đây ít nhiều là vòng lặp do-while, mã này thậm chí sẽ hoạt động để in 0(mà không tạo ra các số 0 khác đi). Khi chúng ta rời khỏi vòng lặp, chúng ta muốn làm trống ngăn xếp và in các chữ số. Sngược lại Z, do đó, nó là một công tắc sẽ làm chệch hướng một nguyên tử tới với năng lượng không dương 90 độ về bên phải. Vì vậy, nguyên tử thực sự di chuyển qua các cạnh từ Sthẳng Kđến bật ra một chữ số (lưu ý rằng ~điều này đảm bảo rằng nguyên tử đến có năng lượng -1). Chữ số đó được tăng lên 48để có được mã ASCII của ký tự chữ số tương ứng. Chữ số Atách chữ số để in một bản sao với!và đưa bản sao khác trở lại vào Ylò phản ứng cho chữ số tiếp theo. Bản sao được in được sử dụng làm trình kích hoạt tiếp theo cho ngăn xếp (lưu ý rằng các gương cũng gửi nó xung quanh cạnh để đánh Mtừ bên trái).

Khi ngăn xếp trống rỗng, ý Kchí sẽ phản ánh nguyên tử và biến năng lượng của nó thành +1, sao cho nó đi thẳng qua S. Nin một dòng mới (chỉ vì nó gọn gàng :)). Và sau đó nguyên tử đi vào ngực R'0một lần nữa để kết thúc ở bên cạnh Y. Vì không còn nguyên tử nào nữa, điều này sẽ không bao giờ được phát hành và chương trình chấm dứt.

Tính toán số phân hạch: Khung

Hãy đến với phần thịt thực sự của chương trình. Mã về cơ bản là một cổng triển khai tham chiếu Mathicala của tôi:

fission[n_] := If[
  (div = 
    SelectFirst[
      Reverse@Divisors[2 n], 
      (OddQ@# == IntegerQ[n/#] 
       && n/# > (# - 1)/2) &
    ]
  ) == 1,
  1,
  1 + Total[fission /@ (Range@div + n/div - (div + 1)/2)]
]

trong đó divsố lượng số nguyên trong phân vùng tối đa.

Sự khác biệt chính là chúng ta không thể xử lý các giá trị nửa nguyên trong Phân hạch, vì vậy tôi đang làm rất nhiều thứ nhân với hai và không có đệ quy trong Phân hạch. Để giải quyết vấn đề này, tôi sẽ đẩy tất cả các số nguyên trong một phân vùng trong hàng đợi để được xử lý sau. Đối với mỗi số chúng tôi xử lý, chúng tôi sẽ tăng một bộ đếm lên một và khi hàng đợi trống, chúng tôi sẽ giải phóng bộ đếm và gửi đi để được in. (Một hàng đợi, Qhoạt động chính xác như thế K, chỉ theo thứ tự FIFO.)

Đây là một khuôn khổ cho khái niệm này:

                      +--- input goes in here
                      v 

                     SQS ---> compute div from n          D /8/
                     ~4X               |                /~KSA /
                       3               +----------->    { +X
initial trigger ---> W                               6~@/ \/
                              4                   
                     W        ^                     /
                              |              3
                     ^     generate range    |
                     |     from n and div  <-+----- S6
                     |         -then-      
                     +---- release new trigger

Các thành phần mới quan trọng nhất là các chữ số. Đây là những người dịch chuyển tức thời. Tất cả các dịch chuyển tức thời với cùng một chữ số thuộc về nhau. Khi một nguyên tử chạm vào bất kỳ dịch chuyển tức thời nào, nó sẽ ngay lập tức di chuyển dịch chuyển tức thời tiếp theo trong cùng một nhóm, trong đó tiếp theo được xác định theo thứ tự từ trái sang phải, từ trên xuống dưới thông thường. Đây không phải là cần thiết, nhưng giúp bố trí (và do đó chơi golf một chút). Ngoài ra còn Xcó cách đơn giản là sao chép một nguyên tử, gửi một bản sao thẳng về phía trước và bản kia ngược lại.

Bây giờ bạn có thể tự mình sắp xếp hầu hết các khung. Góc trên bên trái có hàng đợi các giá trị vẫn được xử lý và giải phóng từng giá trị nmột. Một bản sao nđược dịch chuyển xuống dưới cùng vì chúng ta cần nó khi tính toán phạm vi, bản sao khác đi vào khối ở trên cùng để tính toán div(đây là phần lớn nhất của mã). Khi divđã được tính toán, nó được nhân đôi - một bản sao tăng một bộ đếm ở góc trên cùng bên phải, được lưu trữ trong K. Các bản sao khác được dịch chuyển xuống dưới cùng. Nếu div1, chúng ta làm chệch hướng nó lên ngay lập tức và sử dụng nó như một trình kích hoạt cho lần lặp tiếp theo, mà không làm mất đi bất kỳ giá trị mới nào. Nếu không, chúng tôi sử dụng divn trong phần ở phía dưới để tạo phạm vi mới (nghĩa là một luồng nguyên tử có khối lượng tương ứng được đặt trong hàng đợi), sau đó giải phóng một bộ kích hoạt mới sau khi phạm vi đã hoàn thành.

Khi hàng đợi trống, kích hoạt sẽ được phản ánh, đi thẳng qua Svà xuất hiện lại ở góc trên cùng bên phải, nơi nó giải phóng bộ đếm (kết quả cuối cùng) từ Ađó, sau đó được dịch chuyển itoaqua 8.

Tính toán số phân hạch: Thân vòng

Vì vậy, tất cả những gì còn lại là hai phần để tính toán divvà tạo phạm vi. Máy tính divlà phần này:

 ;    
 {+L  /$     \/\/\/\/\/   5/ @  [~ &@[S\/ \
/A@[  %5                   /; &    K  } [S/
   \  A$@S  S\/  \/\/\/   \/>\ /S]@A  /  \ 
         X  X    /> \      +\ A\ /   \ /
    /   ~A\;     +;\      /@
ZX [K    / {/  / @  @ }  \ X @
   \AS   </      \V /    }SZS S/
     X   ;;@\   /;X  /> \ ; X X
     \@+  >/ }$S SZS\+;    //\V
       / \\  /\; X X @  @  \~K{
       \0X /     /~/V\V /   0W//
\        Z      [K \  //\
           \ /\7\A  /;7/\/

Bây giờ bạn có thể thấy đủ để đánh đố điều này với chính mình với một chút kiên nhẫn. Bảng phân tích cấp cao là thế này: 12 cột đầu tiên hoặc lâu hơn tạo ra một luồng các ước số của 2n. 10 cột tiếp theo lọc ra những cột không thỏa mãn OddQ@# == IntegerQ[n/#]. 8 cột tiếp theo lọc ra những cột không thỏa mãn n/# > (# - 1)/2). Cuối cùng, chúng tôi đẩy tất cả các ước số hợp lệ lên một ngăn xếp và sau khi hoàn thành, chúng tôi đổ toàn bộ ngăn xếp vào một lò phản ứng tổng hợp (ghi đè lên tất cả trừ ước số cuối cùng / lớn nhất) và sau đó giải phóng kết quả, sau đó loại bỏ năng lượng của nó (không phải là năng lượng của nó -zero từ việc kiểm tra bất đẳng thức).

Có rất nhiều con đường điên rồ trong đó không thực sự làm gì cả. Chủ yếu, sự \/\/\/\/điên rồ ở phía trên ( 5s cũng là một phần của nó) và một con đường xung quanh phía dưới (đi qua 7s). Tôi đã phải thêm những thứ này để đối phó với một số điều kiện cuộc đua khó chịu. Phân hạch có thể sử dụng một thành phần trì hoãn ...

Mã tạo ra phạm vi mới từ ndivlà:

 /MJ $$\
4}K~@\ &]    @\  3/\
\{   }$A/1 2  }Y~K <\
 \@  /   \@<+@^   1;}++@
  2        ;   \    /

Trước tiên, chúng tôi tính toán n/div - (div + 1)/2(cả hai thuật ngữ thả nổi, mang lại kết quả tương tự) và lưu trữ cho lần sau. Sau đó, chúng tôi tạo ra một phạm vi từ divxuống đến 1và thêm giá trị được lưu trữ cho mỗi trong số chúng.

Có hai mô hình phổ biến mới trong cả hai mô hình này, mà tôi nên đề cập: Một là SXhoặc ZXđánh từ bên dưới (hoặc các phiên bản xoay). Đây là một cách hay để sao chép một nguyên tử nếu bạn muốn một bản sao đi thẳng (vì việc chuyển hướng đầu ra của lò phản ứng nhiệt hạch đôi khi có thể trở nên cồng kềnh). Các Shoặc Zquay nguyên tử vào Xvà sau đó quay trở lại bản sao nhân đôi vào hướng ban đầu của công tác tuyên truyền.

Các mô hình khác là

[K
\A --> output

Nếu chúng ta lưu trữ bất kỳ giá trị nào trong Kchúng ta có thể lấy lại nó bằng cách đánh Kvới năng lượng âm từ trên xuống. Các Abản sao giá trị mà chúng ta quan tâm và gửi bản sao ngay vào ngăn xếp cho lần tiếp theo chúng ta cần.

Chà, đó là một cuốn sách khá hay ... nhưng nếu bạn thực sự vượt qua được điều này, tôi hy vọng bạn có ý tưởng rằng Fudge i͝s̢̘̗̗ i̟nç̮̩r̸̭̬̱͔e̟̹̟̜͟d̙i̠͙͎̖͓̯b̘̠͎̭̰̼l̶̪̙̮̥̮y̠̠͎̺͜ ͚̬̮f̟͞u̱̦̰͍n͍ ̜̠̙t̸̳̩̝o ̫͉̙͠p̯̱̭͙̜͙͞ŕ̮͓̜o̢̙̣̭g̩̼̣̝r


1
Now with 100% fewer scrollbars.vì vậy bạn nói .. và nó vẫn được tiếp tục ...
Trình tối ưu hóa

13
Vẫn dễ đọc hơn hầu hết các mã nhà phát triển cơ sở của chúng tôi bơm ra.
corsiKa

Là người tạo ra Fudge, thậm chí tôi chưa viết một chương trình lớn như vậy! Tôi rất ấn tượng! Giải thích của bạn là ngoạn mục và chắc chắn có thể phục vụ như một hướng dẫn cho ngôn ngữ.
C0deH4cker

Ngoài ra, dòng cuối cùng của câu trả lời của bạn trông giống như một chương trình Phân hạch;)
C0deH4cker

12

CJam, 42 41 byte

ri]{_{:X,:)_few:+W%{1bX=}=}%{,(},e_}h]e_,

Một Breadth đơn giản đi qua đầu tiên và một điều kiện dừng của cấp độ tiếp theo trống.

Cách thức hoạt động :

ri]                                       e# This represents the root of the fissile tree
   {                               }h     e# Now we run a do-while loop
    _{                    }%              e# Copy the nodes at the current level and map them
                                          e# via this code block to get next level nodes
      :X,:)                               e# Store the node value in X and get array [1..X]
           _few                           e# Copy the array and get continuous slices of
                                          e# length 1 through X from the array [1..X]
               :+W%                       e# Right now, we have an array of array with each
                                          e# array containing slice of same length. We join
                                          e# those arrays and reverse them to get slices of
                                          e# higher length in front of lower lengths
                   {1bX=}=                e# Choose the first slice whose sum is same as X
                                          e# The reversal above makes sure that we give
                                          e# preference to slice of higher length in case of
                                          e# multiple slices add up to X
                            {,(},         e# Filter out slices of length 1 which basically
                                          e# mean that the current node cannot be split up
                                 e_       e# Join all slices in a single array. This is our
                                          e# next level in the Fissile tree. If this is empty
                                          e# it means that all no further node can be
                                          e# decomposed. In an {}h do-while loop, this fact
                                          e# itself becomes the stopping condition for the
                                          e# loop
                                     ]e_, e# Wrap all levels in an array. Flatten the array
                                          e# and take its length

Dùng thử trực tuyến tại đây


Điều này có thể có thể được đánh gôn đến khoảng 35 byte. Tôi đang cố gắng tìm hiểu làm thế nào ..
Trình tối ưu hóa

10

Python 3, 112 byte

def f(n,c=0):
 d=n-c;s=(n-d*~-d/2)/d
 return(s%1or s<1)and f(n,c+1)or+(d<2)or-~sum(f(int(s)+i)for i in range(d))

4 byte được lưu nhờ @FryAmTheEggman.

Giải thích đến sau ...

Phần thưởng thực tế: Mỗi lũy thừa của 2 có số phân hạch là 1. Điều này là do tổng của một chuỗi có độ dài chẵn luôn là tổng của hai số giữa, là số lẻ, nhân với một nửa độ dài của chuỗi, là số nguyên . Tổng của một chuỗi độ dài lẻ là số giữa nhân với độ dài chuỗi, là số lẻ. Vì vậy, vì lũy thừa 2 không có ước số lẻ nên nó chỉ có thể được biểu thị dưới dạng tổng của chính nó.


2 + 3 + 4 + 5 = 14 không phải là số lẻ. Đối số của bạn cho các chuỗi có độ dài chẵn nên được thay đổi thành "tổng của chuỗi có độ dài chẵn là tổng của hai số ở giữa, là số lẻ, nhân với một nửa chiều dài". Phần còn lại của tuyên bố của bạn đi qua không bị ảnh hưởng.
Bruno Le Floch

@BrunoLeFloch Cảm ơn! Đã sửa.
ngẫu nhiên

Không phải tiêu đề của bạn phản ánh những cải tiến? tức là <strike> 117 </ strike> <strike> 113 </ strike> 112
corsiKa

@corsiKa Tôi thường chỉ làm điều đó cho những cải tiến lớn. Sẽ có quá nhiều con số đình công khác.
ngẫu nhiên

8

Python 2, 111 102 97 byte

Một chút có thể đọc được:

def f(n,c=0):a=n-c;b=n-a*~-a/2;return 1/a or-~sum(map(f,range(b/a,b/a+a)))if b>b%a<1else f(n,c+1)

Không dễ đọc:

def f(n,a=0):b=n-a*~-a/2;return b>0and(f(n,a+1)or b%a<1and(1/a or-~sum(map(f,range(b/a,b/a+a)))))

Cả 97 byte.

blà số ntrừ của (a-1)thsố tam giác. Nếu b % a == 0, sau đó nlà tổng của các asố liên tiếp bắt đầu từ b.


8
Tôi đã từng coi Python là ngôn ngữ thường đọc được cho đến khi tôi tham gia PPCG.
Alex A.

Tôi nghĩ bạn cần cải thiện định nghĩa về khả năng đọc của mình ..: P
Trình tối ưu hóa

Python 2 không cho phép 1else. Chỉ có giải pháp thứ 2 hoạt động. Mãi cho đến khi Python 3 elsecó thể lập tức theo một con số.
mbomb007

@ mbomb007 Theo hiểu biết của tôi, nó hoạt động tốt từ 2.7.8 trở đi
Sp3000

Ok, tôi đã sử dụng 2.7.2.
mbomb007

7

Con trăn 2, 86

f=lambda n,R={1}:n-sum(R)and f(n,R^{[min(R),max(R)+1][n>sum(R)]})or-~sum(map(f,R-{n}))

Ít chơi gôn hơn:

def f(n,R={1}):
    d=sum(R)-n
    if d==0:return (sum(map(f,R-{n}))
    if d<0:return f(n,R|{max(R)+1})
    if d>0:return f(n,R-{min(R)})

Ý tưởng là để kiểm tra các lần chạy tiềm năng của các số nguyên liên tiếp n. Việc chạy được lưu trữ trực tiếp dưới dạng một tập hợp Rhơn là thông qua các điểm cuối của nó.

Chúng tôi kiểm tra tổng của lần chạy hiện tại so với tổng mong muốn nthông qua chênh lệch của chúng.

  • Nếu tổng quá lớn, chúng ta cắt phần tử nhỏ nhất trong lần chạy.
  • Nếu tổng tiền quá nhỏ, chúng tôi sẽ mở rộng hoạt động bằng cách làm cho tối đa của nó lớn hơn 1.
  • Nếu tổng là chính xác, chúng tôi lặp lại, ánh xạ fvào chạy, tính tổng và thêm 1 cho nút hiện tại. Nếu hoạt động là {n}, chúng tôi đã thử tất cả các khoản tiền không tầm thường có thể, hãy dừng đệ quy bằng cách xóa ntrước.

Cảm ơn Sp3000 vì đã tiết kiệm được 3 ký tự.


7

Con trăn 2, 85

Tôi rất tự hào về câu trả lời này vì nó đã mất hàng chục giây cho n = 9 và 5-10 phút cho n = 10. Trong mã golf, đây được coi là một thuộc tính mong muốn của một chương trình.

f=lambda n,a=1,d=1:a/n or[f(a)+f(n-a,1+1%d*a)+1/d,f(n,a+d/n,d%n+1)][2*n!=-~d*(2*a+d)]

Ngoài ra còn có một phiên bản ngắn mạch không mất nhiều thời gian và sử dụng cùng một lượng byte:

f=lambda n,a=1,d=1:a/n or~d*(2*a+d)+n*2and f(n,a+d/n,d%n+1)or f(a)+f(n-a,1+1%d*a)+1/d 

Nó có thể nhanh hơn, nhưng ít nhất nó vượt quá giới hạn đệ quy mặc định một khi n vượt quá 40 một chút.

Ý tưởng là thực hiện một tìm kiếm vũ phu cho các số adnhư vậy a + a+1 + ... + a+d == n, trên các giá trị từ 1 đến n. Các f(n,a+d/n,d%n+1)chi nhánh của đệ quy vòng qua các (a, d)cặp. Trong trường hợp sự bình đẳng được thỏa mãn, tôi quản lý để tránh một map(range(...))cuộc gọi đắt tiền bằng cách chia thành hai nhánh bất kể chuỗi đó dài bao nhiêu. Các số a+1thông qua dđược gộp thành một cuộc gọi fbằng cách đặt atham số sao cho không thể sử dụng một cách khác để tách chuỗi.


Cái này hoạt động ra sao?
xnor

"Tôi rất tự hào về câu trả lời này vì nó đã mất hàng chục giây cho n = 9 và 5-10 phút cho n = 10. Trong môn đánh gôn, đây được coi là một thuộc tính mong muốn của một chương trình." + 1'd chỉ cho điều đó.
Soham Chowdhury

6

Haskell, 76 69 byte

f x=head$[1+sum(map f[y..z])|y<-[1..x-1],z<-[y..x],sum[y..z]==x]++[1]

Sử dụng:

*Main> map f [1..40]
[1,1,3,1,5,6,5,1,6,7,12,10,12,11,12,1,8,16,14,17,18,18,23,13,21,18,22,23,24,19,14,1,22,20,23,24,31,27,25,26]

Làm thế nào nó hoạt động:

[  [y..z] |y<-[1..x-1],z<-[y..x],sum[y..z]==x]

           make a list of lists with all consecutive integers (at least 2 elements)
           that sum up to x, sorted by lowest number, e.g. 9 -> [[2,3,4],[4,5]].

1+sum(map f[...]) 

           recursively calculate the Fission Number for each list

[...]++[1]

           always append the 1 to the list of Fission Numbers.

head

           take the first element, which is either the Fission Number of the
           longest list or if there's no list, the 1 appended in the step before.  

3

Võng mạc , 66 byte

^|$
,
(`,(1+?)(?=(?<1>1\1)+\D)
$0;
+)`,(1*);1\1
,$1,1$1;
^,|1

.
1

Đưa đầu vào và in đầu ra trong unary.

Bạn có thể đặt từng dòng trong một tệp duy nhất hoặc chạy mã như với -scờ. Ví dụ:

> echo -n 1111111|retina -s fission
11111

Giải trình:

  • Chúng tôi giữ một danh sách được phân tách bằng dấu phẩy của các số sẽ được chia.
  • Đối với mỗi số, chúng tôi lấy giá trị bắt đầu nhỏ nhất có thể tạo ra một phân tách hợp lệ và phân định nó khỏi phần còn lại bằng dấu chấm phẩy.
  • Nếu có một dấu chấm phẩy bên trong một số, chúng ta thay đổi nó thành dấu phẩy và phân cách phần tiếp theo có kích thước đúng (chiều dài của phần tử trước + 1) của số đó.
  • Chúng tôi lặp lại bước 2 và 3 cho đến khi thay đổi xảy ra.
  • Chúng tôi nhận được dấu phẩy cho mỗi lá và dấu chấm phẩy cho mỗi nút bên trong cộng với dấu phẩy phụ vì chúng tôi bắt đầu bằng hai dấu phẩy. Vì vậy, chúng tôi xóa một dấu phẩy và các phần của số 1và chuyển đổi phần còn lại thành 1's.

Các trạng thái của chuỗi trong suốt quá trình với đầu vào 11111111111111 (unary 14):

,11111111111111,
,11;111111111111,
,11,1;11,1111,11;111;,
,11,1,11;,1111,11,1;11;;,
,11,1,11;,1111,11,1,11;;;,
,,;,,,,;;;,
11111111111

Rất cám ơn @MartinButtner đã giúp đỡ trong trò chuyện!


3

CJam (43 byte)

qi,{):X),_m*{{_)*2/}/-X=}=~\,>0\{~$+}/)}%W=

Bản demo trực tuyến

Tôi chắc chắn rằng tôi là thiếu một số thủ thuật với các vòng tiên tiến, nhưng điều này không gọn gàng khai thác tài sản CJam (mà trước đây đã khó chịu với tôi) rằng bên trong một %bản đồ kết quả vẫn còn trên stack, và do đó có thể được truy cập sử dụng $với một bù âm.


Tôi sẽ có một cái nhìn gần hơn vào ngày mai, nhưng để bắt đầu, bạn không cần ,ngay từ đầu. /%một vài người khác ngầm biến số thành phạm vi.
Martin Ender

,_m*có thể được thay thế bằng 2m*. Công thức tiến trình số học có thể được thay thế bằng ~,>:Y_,+:+~\,>0\ trở thành !Y. Cuối cùng, nếu bạn sử dụng {}#thay vì {}=, bạn không cần )sau X. Kết hợp tất cả lại với nhau:ri{):X2m*{~,>:Y_,+:+X=}#!Y{~$+}/)}%W=
Dennis

2

Đi, 133 byte

func 算(n int)int{Σ:=1;for i:=0;i<n;i++{for j:=0;j<n;j++{if i*i+i-j*j-j==2*n{for k:=j+1;k<=i;k++{Σ+=算(k)};j,i=n,n}}};return Σ}

Đây là mã golf đầu tiên của tôi, xin lỗi nếu tôi có bất kỳ sai lầm.

Điều này sử dụng ý tưởng rằng "thành phần" phân hạch cũng có thể được coi là một sự khác biệt giữa hai chuỗi số nguyên có thứ tự. Ví dụ: lấy "thành phần" phân hạch cho số 13. Đó là 6,7. Nhưng nó có thể được coi là tổng của số nguyên 1 ... 7 trừ tổng số nguyên 1 ... 5

  A: 1 2 3 4 5 6 7  sum = 28
  B: 1 2 3 4 5      sum = 15 
A-B:           6 7  sum = 13, which is also 28-15 = 13

Nhớ lại công thức từ những ngày đi học của Gauss, tổng 1 ... n = (n ^ 2 + n) / 2. Vì vậy, để tìm một thành phần của các số nguyên tuần tự cho một n nhất định, chúng ta cũng có thể nói, chúng ta đang tìm kiếm 'điểm cuối' p và q dọc theo phạm vi 1 ... n sao cho (p ^ 2 + p) / 2 - ( q ^ 2 + q) / 2 = n. Trong ví dụ trên, chúng tôi sẽ tìm kiếm 'điểm cuối' 5 và 7 vì 7 ^ 2 + 7 = 56/2, 5 ^ 2 + 5 = 30/2, 56 / 2-30 / 2 = 28-15 = 13.

Bây giờ có nhiều cách có thể để soạn thảo một số, như Martin đã lưu ý 9 = 2 + 3 + 4 nhưng cũng có 4 + 5. Nhưng rõ ràng là chuỗi bắt đầu "thấp nhất" cũng sẽ dài nhất, bởi vì nó mất nhiều thời gian hơn các số nhỏ để tổng hợp thành một số lớn hơn các số có kích thước trung bình. (Tôi không có bằng chứng đáng tiếc)

Vì vậy, để tìm thành phần của 9, hãy kiểm tra mọi 'cặp điểm cuối', p và q, lặp lại cả p và q riêng biệt từ 0 đến 9 và kiểm tra xem p ^ p + p / 2 - q ^ 2 + q / 2 = 9. Hoặc, đơn giản hơn, nhân phương trình với 2, để tránh các vấn đề chia của làm tròn và giữ tất cả toán học trong các số nguyên. Sau đó, chúng tôi đang tìm kiếm p và q sao cho (p ^ p + p) - (q ^ q + q) = 9 * 2. Trận đấu đầu tiên chúng tôi tìm thấy sẽ là điểm cuối của thành phần Fissile bởi vì, như đã lưu ý, nhóm số thấp nhất cũng sẽ dài nhất và chúng tôi đang tìm kiếm từ thấp đến cao (0 đến 9). Chúng tôi thoát ra khỏi vòng lặp ngay khi chúng tôi tìm thấy một trận đấu.

Bây giờ, hàm đệ quy tìm thấy các 'điểm cuối fissile' p và q cho n đã cho, sau đó tự gọi lại cho mỗi 'con' trong cây từ p đến q. Đối với 9, nó sẽ tìm thấy 1 và 4, (20-2 = 18) sau đó nó sẽ tự gọi lại vào 2, 3 và 4, tổng hợp kết quả. Đối với các số như 4, đơn giản là không bao giờ tìm thấy kết quả khớp và vì vậy trả về '1'. Điều này có thể rút ngắn nhưng đây giống như chương trình đi thứ ba của tôi và tôi không phải là chuyên gia đệ quy.

Cảm ơn vì đã đọc.


Công việc tốt đẹp! Nhưng tại sao hàm Unicode / tên biến. Đó là chi phí byte không cần thiết và chắc chắn bạn có thể chỉ cần sử dụng một số chữ cái bình thường?
Martin Ender

Cảm ơn bình luận của bạn. Nhưng tôi đã tự hỏi mình, tại sao không đếm các ký tự thay vì byte :)
don sáng

Bởi vì đó là những quy tắc mặc định ở đây. :) Lý do chúng tôi thường đếm byte và không phải ký tự là vì nếu điều này xảy ra , đó là niềm vui nho nhỏ cho tất cả các bên liên quan. ;) (Điều đó nói rằng, bất kỳ tác giả thách thức nào cũng được tự do chỉ định đếm theo ký tự thay vì byte, nhưng tôi đặc biệt không.)
Martin Ender

1

CJam, 40 35 33 byte

ri{__,f-_few:+{1b1$=}=|{F}*}:F~],

Cảm ơn @Optimizer đã gợi ý few, đã lưu 2 byte.

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

ri      e# Read an integer from STDIN.
{       e# Define function F(X):
  _     e# Push X.
  _,    e# Push [0 ... X-1].
  f-    e# Subract each from X. Pushes Y := [X ... 1].
  _few  e# Push all overlapping slices of Y of length in Y.
  :+    e# Consolidate the slices of different lenghts in a single array.
  {     e# Find the first slice S such that...
    1b  e#   the sum of its elements...
    1$= e#   equals X.
  }=    e#   Since Y is in descending order, the first matching slice is also the longest.
  |     e# Set union with [X]. This adds X to the beginning of the S if S != [X].
  {F}*  e# Execute F for each element of S except the first (X).
}:F     e#
~       e# Execute F for the input.
],      e# Count the integers on the stack.

Nếu bạn kết hợp nửa đầu của tôi với nửa thứ hai của bạn, bạn sẽ nhận được 34:ri{_,:)_few:+W%{1b1$=}=|{F}*}:F~],
Trình tối ưu hóa

@Optimizer: Đẹp. Điều đó cho phép cải thiện thêm. Cảm ơn!
Dennis
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.