Đếm từ 1 đến n mà không có bất kỳ số liên tiếp nào


19

Mục tiêu

Bạn được cung cấp một số nguyên n( n > 1). Bạn phải xuất ra bao nhiêu hoán vị của các số nguyên 1đến nđó bắt đầu từ 1, kết thúc tại nvà không có hai số nguyên liên tiếp khác nhau 1.

Ngoài ra, nếu bạn lấy biểu đồ hoàn chỉnh K_nvà loại bỏ các cạnh của đường dẫn, 1-2-3-...-nbạn phải đếm các đường dẫn Hamilton từ 1đến ntrong biểu đồ còn lại.

Các ví dụ sẽ sử dụng f(n)cho một hàm nhận nvà xuất số lượng hoán vị hợp lệ, nhưng trình của bạn có thể là một hàm hoặc một chương trình.


Ví dụ

Đối với n = 6, một giải pháp có thể là1-3-5-2-4-6

Tuy nhiên, 1-3-5-2-6-4không phải là một giải pháp hợp lệ vì nó không kết thúc với 6.

Trong thực tế, n = 6chỉ có 2 giải pháp ( 1-4-2-5-3-6là giải pháp khác).

Do đó f(6) = 2.


Đối với n = 4hoán vị duy nhất bắt đầu 1và kết thúc 41-2-3-41-3-2-4. Trong cả hai đều 2liền kề với 3, cho các số nguyên liên tiếp khác nhau bằng 1. Do đó f(4) = 0.


Các trường hợp thử nghiệm

f(6) = 2
f(4) = 0
f(8) = 68
f(13) = 4462848

Tiêu chí chiến thắng

Đây là môn đánh gôn, câu trả lời ngắn nhất sẽ thắng.


7
Bạn thấy đấy, những đứa trẻ, bạn không thể kiểm tra xem có bao nhiêu hoán vị [2..n-1]không chứa đồng bằng 1hay -1, bạn cũng phải kiểm tra xem không ai trong số chúng bắt đầu bằng 2hoặc kết thúc bằng n-1...
ETHproductions

1
Danh sách có phải bắt đầu bằng 1 và kết thúc bằng số không?
Okx

3
Có lẽ OP có nghĩa là "liền kề" không "liên tiếp"?
Stilez

6
Điều kỳ lạ là trình tự ở đây: algo.inria.fr/lologists/autocomb/graphs99.ps trong đó trên trang 6 được viết, Q_ser:=z + 2 z^6 + 10 z^7 + 68 z^8 + 500 z^9 + 4174 z^10 + 38774 z^11 + 397584z^12 + 4462848 z^13 + 54455754 z^14tôi dành một chút thời gian để cố gắng sử dụng các công thức, nhưng tôi không thể soạn một công cụ tạo ra trình tự. Thật ngạc nhiên khi thấy số mũ của z là đầu vào của công thức và kết quả là hệ số nhân. Một trong những cách có thể suy ra công thức từ đó có thể là một câu trả lời ngắn nhất tính bằng byte
Christiaan Westerbeek

1
@ChristiaanWesterbeek được gọi là hàm tạo cho chuỗi. Tồn tại nhiều chuỗi với một hàm tạo có dạng đóng đẹp hơn chính chuỗi đó, đó là thứ tuyệt vời!
Carmeister

Câu trả lời:


6

MATL , 16 byte

qtq:Y@0&Yc!d|qAs

Hãy thử trực tuyến!

Đối với đầu vào vượt quá 12nó hết bộ nhớ.

Giải trình

q      % Implicitly input n. Push n-1
tq     % Duplicate and subtract 1: pushes n-2
:      % Range [1 2 ... n-2]
Y@     % Matrix with all permutations, each in a row
0      % Push 0
&Yc    % Append n-1 and predend 0 to each row
!      % Tranpose
d      % Consecutive differences along each column
|      % Absolute value
q      % Subtract 1
A      % All: true if all values in each column are non-zero
s      % Sum. Implicitly display

1
Làm việc tốt, hoàn thành tốt :)
Philippe

1
Mặc dù có một số tiến bộ thực sự tốt đẹp trong vấn đề này, giải pháp của bạn vẫn là ngắn nhất. Nó cũng nhanh hơn Jelly one. Xin chúc mừng!
Philippe

19

Toán học, 58 byte, thời gian đa thức ( n )

Abs[Sum[(k-1)Hypergeometric2F1[k,k-#,2,2](#-k)!,{k,#}]-1]&

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

Thay vì lặp đi lặp lại các hoán vị với lực lượng vũ phu, chúng tôi sử dụng nguyên tắc loại trừ đưa vào để tính chúng một cách kết hợp.

Đặt S là tập hợp tất cả các hoán vị của [1, Mạnh, n] với σ 1 = 1, σ n = n và đặt S i là tập các hoán vị σ ∈ S sao cho | σ i - σ i + 1 | = 1. Sau đó, số lượng chúng tôi đang tìm kiếm là

| S | - | S 1 ∪ ⋯ S n - 1 | = ∑ 2 ≤ kn + 1; 1 ≤ i 2 <⋯ < i k - 1 < n (1) k - 2 | S i 2 ∩ ⋯ S i k - 1 |.

Bây giờ, | S i 2 ∩ ⋯ S i k - 1 | chỉ phụ thuộc vào k và vào số j chạy của các chỉ số liên tiếp trong [ i 1 , i 2 , Tiết, i k - 1 , i k ] trong trường hợp thuận tiện, chúng tôi sửa i 1 = 0 và i k = n . Đặc biệt,

| S i 2 ∩ ⋯ S i k - 1 | = 2 j - 2 ( n - k )!, Với 2 jkn ,
| S i 2 ∩ ⋯ S i k - 1 | = 1, với j = 1, k = n + 1.

Số lượng bộ chỉ mục như vậy [ i 1 , i 2 , Mạnh, i k - 1 , i k ] với j chạy là

( k - 1 C j - 1 ) ( n - k C j - 2 ), với 2 ≤ jkn ,
1, với j = 1, k = n + 1.

Kết quả là sau đó

(−1) n - 1 + 2 kn2 ≤ jk (1) k - 2 ( k - 1 C j - 1 ) ( n - k C j - 2 ) 2 j - 2 ( n - k )!

Tổng bên trên j có thể được viết bằng cách sử dụng hypergeometric 2 F 1 chức năng :

(1) n - 1 + 2 kn (1) k ( k - 1) 2 F 1 (2 - k , k - n ; 2; 2) ( n - k )!

mà chúng tôi áp dụng phép biến đổi Pfaff cho phép chúng tôi loại bỏ các quyền hạn của -1 bằng một giá trị tuyệt đối:

(1) n - 1 + 2 kn (1) n ( k - 1) 2 F 1 ( k , k - n ; 2; 2) ( n - k )!
= | 1 + 1 kn ( k - 1) 2 F 1 ( k , k - n ; 2; 2) ( n - k )! |.

Bản giới thiệu

In[1]:= Table[Abs[Sum[(k-1)Hypergeometric2F1[k,k-#,2,2](#-k)!,{k,#}]-1]&[n],{n,50}]

Out[1]= {1, 0, 0, 0, 0, 2, 10, 68, 500, 4174, 38774, 397584, 4462848, 

>    54455754, 717909202, 10171232060, 154142811052, 2488421201446, 

>    42636471916622, 772807552752712, 14774586965277816, 297138592463202402, 

>    6271277634164008170, 138596853553771517492, 3200958202120445923684, 

>    77114612783976599209598, 1934583996316791634828454, 

>    50460687385591722097602304, 1366482059862153751146376304, 

>    38366771565392871446940748410, 1115482364570332601576605376898, 

>    33544252621178275692411892779180, 1042188051349139920383738392594332, 

>    33419576037745472521641814354312790, 

>    1105004411146009553865786545464526206, 

>    37639281863619947475378460886135133496, 

>    1319658179153254337635342434408766065896, 

>    47585390139805782930448514259179162696722, 

>    1763380871412273296449902785237054760438426, 

>    67106516021125545469475040472412706780911268, 

>    2620784212531087457316728120883870079549134420, 

>    104969402113244439880057492782663678669089779118, 

>    4309132147486627708154774750891684285077633835734, 

>    181199144276064794296827392186304334716629346180848, 

>    7800407552443042507640613928796820288452902805286368, 

>    343589595090843265591418718266306051705639884996218154, 

>    15477521503994968035062094274002250590013877419466108978, 

>    712669883315580566495978374316773450341097231239406211100, 

>    33527174671849317156037438120623503416356879769273672584588, 

>    1610762789255012501855846297689494046193178343355755998487686}

3
Tâm trí của tôi bị thổi bay, công việc tốt
Philippe

6

Thạch , 17 16 byte

ṖḊŒ!ð1;;⁹IỊṀðÐḟL

Một liên kết đơn âm.

Hãy thử trực tuyến!

Làm sao?

ṖḊŒ!ð1;;⁹IỊṀðÐḟL - Link: number n
Ṗ                - pop (implicit range build) -> [1,n-1]
 Ḋ               - dequeue -> [2,n-1]
  Œ!             - all permutations of [2,n-1]
    ð       ðÐḟ  - filter discard those entries for which this is truthy:
     1;          -   1 concatenated with the entry
       ;⁹        -   ...concatenated with right (n)
         I       -   incremental differences
          Ị      -   is insignificant (absolute value <=1)
           Ṁ     -   maximum
               L - length (the number of valid arrangements)

Xin lỗi nhưng nó không đáp ứng các trường hợp thử nghiệm
Philippe

1
Vâng, bạn đã mắc lỗi tương tự Okx và tôi đã mắc phải lúc đầu. Bạn phải tính đến thực tế là số thứ hai không thể là 2 và số thứ hai đến số cuối cùng có thể là n-1
Sản phẩm ETH

@Philippe đã sửa nó lên.
Jonathan Allan

Tôi không nghĩ sử dụng IỊṀlà hợp lệ. Cụ thể, nếu -2một trong những đồng bằng ở đó chẳng hạn thì sao? Bạn có thể sửa với IAỊṀ+1.
Erik the Outgolfer

1
@Jonathan ALLan Ooh tôi nghĩ nó đã trở lại x <= 1.
Erik the Outgolfer

5

Japt , 19 18 byte

o2 á è_pU äÉ m²e>1

Kiểm tra nó trực tuyến! Tôi sẽ không đề nghị thử nghiệm trên bất cứ điều gì lớn hơn 10.

Giải trình

o2 á è_  pU äÉ  m²  e>1
o2 á èZ{ZpU ä-1 mp2 e>1}
                          : Implicit: U = input integer
o2                        : Create the range [2..U-1].
   á                      : Generate all permutations of this range.
     èZ{               }  : Check how many permutations Z return a truthy value:
        ZpU               :   Push U to the end of Z.
            ä-1           :   Push 1 to the beginning of Z, then take the difference
                          :   of each pair of items.
                m         :   Map each item X to
                 p2       :     X ** 2. This gives a number greater than 1 unless the
                          :     item is 1 or -1.
                    e>1   :   Return whether every item in this list is greater than 1.
                          :   This returns `true` iff the permutation contains no
                          :   consecutive pairs of numbers.
                          : Implicit: output result of last expression

Làm tốt lắm! Thật buồn cười là mã vũ phu của tôi không thể vượt qua n = 13 hay ahah
Philippe

@Philippe Tôi không khuyên bạn nên chấp nhận nhanh như vậy, tôi chắc chắn rằng điều này sẽ ngắn hơn trong 05AB1E hoặc Jelly ;-)
ETHproductions

Thất bại trên testcase 1.
Okx

2
@Okx OP đã chỉ định rằng chúng tôi có thể giả định n > 1.
Sản xuất ETH


5

Haskell, 76 65 byte

Đã lưu 11 byte nhờ @xnor.

Sử dụng kết quả cho Q_rectrang 7 của @ ChristiaanWesterbeek, chúng tôi nhận được

f 1=1
f n|n<6=0
f n=sum$zipWith((*).f)[n-5..][n-4,1,10-2*n,4,n-2]

Tôi không hiểu kết quả tiếp theo của họ haliên quan đến điều này như thế nào , nhưng sau khi tăng tốc (đầu tiên bằng cách ghi nhớ, hãy xem các phiên bản trước đó, sau đó như bên dưới) tôi nhận được số của họ.

Mặc dù ở trên là ổn n=20, nhưng đây là một ví dụ cần thiết để không thực hiện đệ quy. Đây là phiên bản nhanh hơn (chỉ dành cho n>=6) mà cũng chỉ cần bộ nhớ không đổi - nếu chỉ các con số không tiếp tục tăng ...

f n=last$foldl(#)[1,0,0,0,0][6..n]
l#n=tail l++[sum$zipWith(*)l[n-4,1,10-2*n,4,n-2]]

Điều đó mang lại

Prelude> f 50
1610762789255012501855846297689494046193178343355755998487686
Prelude> f 500
659178618863924802757920269977240274180092211041657762693634630044383805576666007245903670780603497370173231423527767109899936008034229541700392144282505597945561328426013937966521561345817045884498867592832897938083071843810602104434376305964577943025310184523643816782047883794585616331928324460394146825636085453532404319881264974005968087265587062691285454120911586459406436421191277596121471930913837355151842093002557978076653884610826296845041929616496533544124347765641367732716560025553179112645454078955409181466212732427071306363820080109636358537270466838558068527692374178581063316309789026101221004745226182671038004326069705775312654329754698423385241664984156235692539255677944294995403233446243315371404887473868003155621849544566385172835597260848972758443874423271017007843907015007416644383573987606586308556317833384896267539628278571497402655322562624217658332870157802254043614726316296058329670971054977099155788604175817828380564156329839201579006169173002756295957371639199917376529472990059986681882194726437566769717959443857298155265292535858523609764515938314672724480762724541633037484152303637096

Không có vấn đề gì để nhận f 5000nhưng tôi không muốn dán kết quả ...


BTW, có thể không sử dụng toán học ưa thích và vẫn không sử dụng vũ lực (cực kỳ). Đầu tiên, thay vì nhìn vào tất cả các hoán vị, hãy nhìn vào các hoán vị một phần và chỉ mở rộng chúng khi chúng chưa hợp lệ. Không có ích gì khi nhìn vào tất cả các hoán vị bắt đầu bằng 1 6 5. Thứ hai, một số hoán vị một phần thích 1 3 5 71 5 3 7có chính xác các phần tiếp theo hợp lệ, vì vậy hãy xử lý chúng cùng nhau. Sử dụng những ý tưởng này, tôi có thể tính toán các giá trị lên đến n=16 0,3 giây.


Bạn có thể viết biểu thức đệ quy ngắn hơn như dấu chấm bằng cách trích ra các hệ số : f n=sum$zipWith((*).f)[n-5..][n-4,1,10-2*n,4,n-2].
xnor

@xnor Đúng rồi, cảm ơn!
Christian Sievers

Đây là một số công việc tốt, tôi ngạc nhiên với kết quả mà cộng đồng này đã đưa ra! Thật tệ, đó là một sân golf ^^
Philippe

4

Python, 125 byte

from itertools import*
lambda n:sum(p[-1]-p[0]==n-1and all(~-abs(x-y)for x,y in zip(p,p[1:]))for p in permutations(range(n)))

Trông khá nhanh, làm tốt lắm!
Philippe


3

Toán học, 66 byte

Count[Permutations@Range@#,x:{1,__,#}/;FreeQ[Differences@x,1|-1]]&

Giải trình

Functionvới lập luận đầu tiên #.

Count[                                                             (* Count the number of *)
      Permutations@                                                (* permutations of *)
                   Range@#,                                        (* the list {1, ..., #} *)
                           x:{1,__,#}                              (* of the form {1, __, #} *)
                                     /;                            (* such that *)
                                             Differences@x,        (* the list of differences of consecutive elements *)
                                       FreeQ[                      (* is free of elements of the form *)
                                                           1|-1    (* 1 or -1 *)
                                                               ]]&

3

Javascript (ES6), 100 74 72 60 byte

f=n=>n--<6?!n|0:f(n)*--n+4*f(n--)-2*f(n--)*--n+f(n)*++n+f(n)

Dưới đây là phiên bản trước khi thành thạo golf của @PeterTaylor

f=n=>n<6?n==1|0:(n-4)*f(n-5)+f(n-4)-2*(n-5)*f(n-3)+4*f(n-2)+(n-2)*f(n-1)

Nhờ câu trả lời từ @ChristianSievers đã quản lý để phác thảo một giải pháp Haskell từ một bài báo mà tôi tìm thấy sau khi googling '0, 2, 10, 68, 500, 4174, 38774, 397584', đây là phiên bản Javascript không thấm.

Sử dụng

for (i=1; i<=20; i++) {
  console.log(i, f(i))
}

1 1 
2 0 
3 0 
4 0 
5 0 
6 2 
7 10 
8 68 
9 500 
10 4174 
11 38774 
12 397584 
13 4462848 
14 54455754 
15 717909202 
16 10171232060 
17 154142811052 
18 2488421201446 
19 42636471916622 
20 772807552752712

1
Mô tả nhiệm vụ chỉ yêu cầu f(n)khi nào n>1, vì vậy nó không quan trọng bạn trở lại để làm gì n=1. Ngoài ra tôi nghĩ f(1)=1là chính xác.
Christian Sievers

Bạn có thể kết hợp các trường hợp đặc biệt như n<6?n==1|0:để tiết kiệm thêm hai ký tự.
Peter Taylor

Tuyệt quá. Tôi điều chỉnh cho 2 bình luận.
Christiaan Westerbeek

1
Và bằng cách sắp xếp lại các điều khoản và dựa vào thứ tự đánh giá, có thể giảm xuống còn 60:f=n=>n--<6?!n|0:f(n)*--n+4*f(n--)-2*f(n--)*--n+f(n)*++n+f(n)
Peter Taylor

1

Brachylog , 26 byte

{⟦₁pLh1&~tLs₂ᶠ{-ȧ>1}ᵐ}ᶜ|∧0

Hãy thử trực tuyến!

Giải trình

{                    }ᶜ       Output = count the number of outputs of:
 ⟦₁pL                           L is a permutation of [1, …, Input]
    Lh1                         The head of L is 1
       &~tL                     The tail of L is the Input
          Ls₂ᶠ                  Find all sublists of length 2 of L
              {    }ᵐ           Map on each sublist:
               -ȧ>1               The elements are separated by strictly more than 1
                       |      Else (no outputs to the count)
                        ∧0    Output = 0

1

Python 3 , 109 107 102 byte

q=lambda s,x,n:sum(q(s-{v},v,n)for v in s if(v-x)**2>1)if s else x<n;f=lambda n:q({*range(2,n)},1,n-1)

Hãy thử trực tuyến!

Đã xóa bốn byte bằng cách không thử một dòng hàm (như được đề xuất bởi @shooqie) và một byte khác bằng cách thay thế absbằng một hình vuông. (Yêu cầu Python 3.5+)




0

Toán học, 134 byte

(s=Permutations@Range[2,#-1];g=Table[Join[Prepend[s[[i]],1],{#}],{i,Length@s}];Length@Select[Union@*Abs@*Differences/@g,FreeQ[#,1]&])&


trường hợp thử nghiệm n: 2 đến 12

{0, 0, 0, 0, 2, 10, 68, 500, 4174, 38774, 397584}


0

Python 2 , 105 byte

lambda n:reduce(lambda a,i:a+[i*a[-5]+a[-4]+2*(1-i)*a[-3]+4*a[-2]+(i+2)*a[-1]],range(2,n),[0,1]+4*[0])[n]

Hãy thử trực tuyến!

Điều này dựa trên bài báo của Philippe Flajolet được phát hiện bởi @Christiaan Westerbeek ; nó nhanh hơn nhiều và ngắn hơn hai byte so với giải pháp Python 3 của tôi , trong đó liệt kê các hoán vị có thể có. (Trong Python 3, reduceđã được chuyển đến một cách khó chịu functools.)

Có một phiên bản ngắn hơn nhiều bằng cách sử dụng sản phẩm chấm của numpy, nhưng nó tràn ra khá nhanh và đòi hỏi phải được nhập khẩu. Nhưng với những gì đáng giá:

lambda n:reduce(lambda a,i:a+[dot([i,1,2-2*i,4,i+2],a[-5:])],range(2,n),[0,1]+4*[0])[n]
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.