Ardışık sayılar olmadan 1'den n'ye sayma


19

Hedef

Size bir tamsayı n( n > 1) verilir . Sen gerekir tamsayılar birçok permütasyon nasıl çıktı 1için norada başlayacak 1de sonuna n, 1'e ve farklı olan iki ardışık tamsayı yok.

Alternatif olarak, grafiğin tamamını alır ve K_nyolun kenarlarını kaldırırsanız , kalan grafikte ile arasındaki 1-2-3-...-nHamilton yollarını saymanız gerekir .1n

Örnekler , geçerli permütasyon sayısını f(n)alan nve çıktısını alan bir işlev için kullanılacaktır , ancak gönderiminiz bir işlev veya program olabilir.


Örnekler

Çünkü n = 6olası bir çözüm1-3-5-2-4-6

Ancak, 1-3-5-2-6-4bitmediği için geçerli bir çözüm değildir 6.

Aslında, n = 6sadece 2 çözüm vardır ( 1-4-2-5-3-6diğeri).

Dolayısıyla f(6) = 2.


For n = 4başlaması sadece permütasyon 1ve son yılında 4olan 1-2-3-4ve 1-3-2-4. Her ikisinde de 2bitişiktir ve 1 ile 3birbirini izleyen ardışık tamsayılar verir f(4) = 0. Bu nedenle .


Test senaryoları

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

Kazanan kriter

Bu kod golfü, en kısa cevap kazanıyor.


7
Gördüğünüz gibi, çocuklar, [2..n-1]delta içermeyen kaç permütasyon olduğunu kontrol edemezsiniz , 1ya -1da hiçbirinin başlamaması 2veya bitmesi olmadığını da kontrol etmeniz gerekir n-1...
ETHproductions

1
Liste 1 ile başlayıp numarayla bitmeli mi?
Okx

3
Belki OP "ardışık" anlamına gelir "ardışık" değil?
Stilez

6
Tuhaf bir şekilde sıra buradadır: algo.inria.fr/libraries/autocomb/graphs99.ps Burada sayfa 6 yazılmıştır 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^14Şimdi formülleri kullanmaya çalışırken biraz zaman harcıyorum, ancak sekansı üreten bir kompozisyon oluşturamıyorum. Z'nin üssünün formülün girdisi ve sonuç çarpım faktörü olduğunu görmek şaşırtıcı. Formülü oradan nasıl çıkaracağımız, baytlarda en kısa cevabı veren bir tane olabilir
Christiaan Westerbeek

1
@ChristiaanWesterbeek , dizi için oluşturma işlevi olarak adlandırılır . Dizinin kendisinden daha güzel bir kapalı forma sahip bir oluşturma işlevine sahip birçok dizi var, bu harika şeyler!
Carmeister

Yanıtlar:


6

MATL , 16 bayt

qtq:Y@0&Yc!d|qAs

Çevrimiçi deneyin!

Aşan girişler 12için bellek yetersiz.

açıklama

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
İyi çalışıyor, aferin :)
Philippe

1
Bu problemde gerçekten güzel gelişmeler olmasına rağmen, çözümünüz hala en kısa süredir. Ayrıca Jelly'den daha hızlıdır. Congratz!
Philippe

19

Mathematica, 58 bayt, polinom ( n ) süresi

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

Nasıl çalışır

Kaba kuvvetli permütasyonları tekrarlamak yerine, bunları birleştirici olarak saymak için dahil etme-hariç tutma ilkesini kullanıyoruz.

S, σ 1 = 1, σ n = n ile [1,…, n] tüm permütasyonlarının kümesi olsun ve S i | σ i - σ olacak şekilde σ i S permütasyonları kümesi olsun. i + 1 | = 1. O zaman aradığımız sayı

| 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 |.

Şimdi, | S i 2 ∩ ⋯ ∩ S i k - 1 | sadece k'ye ve [ i 1 , i 2 ,…, i k - 1 , i k ] ' de ardışık indekslerin çalışmalarının j sayısına bağlıdır, burada kolaylık sağlamak için i 1 = 0 ve i k = n'yi düzeltiyoruz . özellikle,

S i 2 ∩ ⋯ ∩ S i k - 1 | = 2 j - 2 ( n - k ) !, 2 ≤ jkn için ,
| S i 2 ∩ ⋯ ∩ S i k - 1 | = 1, j = 1 için, k = n + 1.

Bu tür dizin kümelerinin [ i 1 , i 2 ,…, i k - 1 , i k ] sayısı j ile

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

Sonuç o zaman

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

J üzerindeki iç toplam , hipergeometrik 2 F 1 fonksiyonu kullanılarak yazılabilir :

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

Mutlak bir değer kullanarak −1'in güçlerini ortadan kaldırmamızı sağlayan bir Pfaff dönüşümü uyguladık:

(−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 )! |.

gösteri

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
Aklım şişmiş, iyi iş
Philippe

6

Jöle , 17 16 bayt

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

Monadik bir bağlantı.

Çevrimiçi deneyin!

Nasıl?

ṖḊŒ!ð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)

Üzgünüz ama test
Philippe

1
Evet, aynı hatayı yaptın Okx ve ben ilk başta. İkinci sayı 2 olamaz ve ikinci sonuncu sayı n-1
olamaz gerçeğini hesaba katmalısınız

@Philippe tamir etti.
Jonathan Allan

Kullanmanın IỊṀgeçerli olduğunu düşünmüyorum . Özellikle, -2oradaki deltalardan biri varsa ne olur ? IAỊṀ+1 ile düzeltebilirsiniz .
Outgolfer Erik

1
@JonathanAllan Ooh döndüğünü sanıyordum x <= 1.
Outgolfer Erik

5

Japt , 19 18 bayt

o2 á è_pU äÉ m²e>1

Çevrimiçi test edin! Ben daha büyük bir şey üzerinde test tavsiye etmem 10.

açıklama

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

Aferin! Kaba kuvvet kodumun n = 13 üstesinden gelememesi komik değil
Philippe

@Philippe Çok hızlı kabul etmenizi tavsiye etmiyorum, bunun 05AB1E veya Jelly'de daha kısa olacağına eminim ;-)
ETHproductions 5:17 '

Test çantasında başarısız 1.
Okx

2
@Okx OP, üstlenebileceğimizi belirtti n > 1.
ETHproductions


5

Haskell, 76 65 bayt

@Xnor sayesinde 11 bayt tasarruf edildi.

Q_rec@ ChristiaanWesterbeek'in bulduğu sayfa 7'deki sonucu kullanarak,

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

Bir sonraki sonuçlarının nasıl olduğunu anlamıyorum ha ilişkili olduğunu , ancak hızlandıktan sonra (önce notla, önceki sürümlere bakın, sonra aşağıdaki gibi) numaralarını alıyorum.

Yukarıdakiler için uygun olsa da n=20, özyinelemenin nasıl yapılacağı bir örnektir. İşte n>=6sadece sabit belleğe ihtiyaç duyan daha hızlı bir sürüm (sadece için ) - sadece sayılar artmaya devam etmediyse ...

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]]

Bu verir

Prelude> f 50
1610762789255012501855846297689494046193178343355755998487686
Prelude> f 500
659178618863924802757920269977240274180092211041657762693634630044383805576666007245903670780603497370173231423527767109899936008034229541700392144282505597945561328426013937966521561345817045884498867592832897938083071843810602104434376305964577943025310184523643816782047883794585616331928324460394146825636085453532404319881264974005968087265587062691285454120911586459406436421191277596121471930913837355151842093002557978076653884610826296845041929616496533544124347765641367732716560025553179112645454078955409181466212732427071306363820080109636358537270466838558068527692374178581063316309789026101221004745226182671038004326069705775312654329754698423385241664984156235692539255677944294995403233446243315371404887473868003155621849544566385172835597260848972758443874423271017007843907015007416644383573987606586308556317833384896267539628278571497402655322562624217658332870157802254043614726316296058329670971054977099155788604175817828380564156329839201579006169173002756295957371639199917376529472990059986681882194726437566769717959443857298155265292535858523609764515938314672724480762724541633037484152303637096

Bunu elde etmek de sorun f 5000değil ama sonucu yapıştırmak istemiyorum ...


BTW, süslü matematik kullanmak ve hala (ultra) kaba kuvvet kullanmak mümkün değildir. İlk olarak, tüm permütasyonlara bakmak yerine, kısmi permütasyonlara bakın ve bunları sadece geçersiz olmadıklarında uzatın. İle başlayan tüm permütasyonlara bakmanın bir yararı yoktur 1 6 5. İkincisi, gibi bazı kısmi permütasyon 1 3 5 7ve 1 5 3 7böylece onları bir arada ele, tam olarak aynı geçerli devamlarını var. Bu fikirleri kullanarak n=16 0,3 saniyeye kadar değerleri hesaplayabilirim .


Sen katsayıları dışarı çıkararak bir nokta gibi özyinelemeli ifade daha kısa yazabilirsiniz: f n=sum$zipWith((*).f)[n-5..][n-4,1,10-2*n,4,n-2].
xnor

@xnor Doğru, teşekkürler!
Christian Sievers

Bu iyi bir iş, bu topluluğun ortaya çıkardığı sonuçlardan şaşırdım! Çok kötü bir golf ^^
Philippe

4

Python, 125 bayt

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)))

Oldukça hızlı görünüyor, iyi iş!
Philippe


3

Mathematica, 66 bayt

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

açıklama

Functionilk argümanla #.

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 bayt

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

@PeterTaylor'ın golf ustalığından önceki sürüm aşağıdadır

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)

@ChristianSievers'in bir kağıttan Haskell çözümü hazırlamayı başardığı cevap sayesinde 0, 2, 10, 68, 500, 4174, 38774, 397584 'yi kullandıktan sonra bulduğum , burada da izin vermeyen bir Javascript sürümü var.

kullanım

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
Görev açıklaması sadece f(n)ne zaman olduğunu sorar n>1, bu nedenle ne için döndüğünüz önemli değildir n=1. Ayrıca f(1)=1doğru olduğunu düşünüyorum .
Christian Sievers

Özel durumları n<6?n==1|0:iki karakterlik bir tasarruf için birleştirebilirsiniz .
Peter Taylor

Harika. Bu 2 yorum için ayarladım.
Christiaan Westerbeek

1
Ve şartları yeniden sıralayarak ve değerlendirme sırasına dayanarak 60'a inmek mümkündür: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 bayt

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

Çevrimiçi deneyin!

açıklama

{                    }ᶜ       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 bayt

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)

Çevrimiçi deneyin!

Fonksiyonu bir satırlık (@shooqie tarafından önerildiği gibi) denemeden dört bayt ve absbir kare ile değiştirerek başka bir bayt kaldı . (Python 3.5+ gerektirir)




0

Mathematica, 134 bayt

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


test senaryoları n: 2 ila 12

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


0

Python 2 , 105 bayt

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]

Çevrimiçi deneyin!

Bu, Philippe Flajolet'in @Christiaan Westerbeek tarafından keşfedilen makalesine dayanmaktadır ; olası permütasyonları numaralandıran Python 3 çözümümden çok daha hızlı ve iki bayt daha kısa . (Python 3'te, reducecan sıkıcı bir şekildefunctools .)

Numpy'nin nokta ürününü kullanan çok daha kısa bir sürüm var, ancak bu oldukça hızlı bir şekilde taşar ve numpy'nin içe aktarılmasını gerektirir. Ama buna değer:

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]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.