Kaç bölümüm var?


16

Pozitif bir tamsayının bölüm numarası, pozitif tamsayıların toplamı olarak ifade edilme yollarının sayısı olarak tanımlanır. Başka bir deyişle, sahip olduğu tamsayı bölümlerinin sayısı. Örneğin, sayı 4aşağıdaki bölümlere sahiptir:

[[1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2], [4]]

Bu nedenle 5bölümleri vardır. Bu OEIS A000041 .


Görev

Pozitif bir tamsayı verildiğinde N bölüm numarasını belirler.

  • Tüm standart kurallar geçerlidir.

  • Giriş ve çıkış herhangi bir makul yolla ele alınabilir.

  • Bu , bu nedenle bayttaki en kısa kod kazanır.


Test Durumları

Girdi | Çıktı

1 | 1
2 | 2
3 | 3
4 | 5
5 | 7
6 | 11
7 | 15
8 | 22
9 | 30
10 | 42

1
Neredeyse pozitifim bu bir kopya ...
DJMcMayhem

@DJMcMayhem Umm, tamam. Bir kopya bulursanız bana bildirin. Üzgünüm, tüm bunlara yeniyim!

1
@DJMcMayhem belki "sorduktan " saymaya "kısa bir adım olduğu için sorduğunuz bu soru, ancak onları saymak için tüm bölümleri oluşturmak zorunda değilsiniz ...
Giuseppe

1
Bu bir dupe, bir popcon (?) hariç ve çok geniş kapalı. IMHO bu daha iyi yazılmış ve açık tutulmalı, eskisi ise dupe olarak (yeniden açılmalı ve kapatılmalıdır)
Rod

2
@Rod, kötü bir pop-con, ancak yakın nedeni dupe olarak değiştirmek bir gelişme olmaz. Performans gereksinimi bazı cevapları taşımak için bir engel olacaktır (hiç kimse birkaç dakika içinde 1000'in 24061467864032622473692149727991 bölümlerini üretmeyecektir ); ve Hardy-Ramanujan-Rademacher uygulaması tam olarak golf oynamamıştır ... Ancak, bu soru ve bu soru ile ne yapılacağı konusunda meta olarak bir tartışma başlatmaya değer olabilir.
Peter Taylor

Yanıtlar:


13

Pyth , 3 bayt

l./

Burada deneyin! veya Bir test paketini deneyin.

Yanıtın biçimlendirilmesi kodun kendisini yazmaktan çok daha uzun sürdü: P.


Nasıl?

Pyth iş için doğru araçtır.

l. / Örtük girdili tam program.

 . / Tamsayı bölümleri. Girdiye eklenmiş tüm pozitif tamsayı listelerini döndürür.
l Uzunluk.
      Sonucu dolaylı olarak çıktı.

34

Mathematica, 11 bayt

PartitionsP

açıklama

¯\_(ツ)_/¯


8

Emojicode 0.5, 204 201 bayt

🐋🚂🍇🐖🅰️➡🚂🍇🍊⬅🐕1🍇🍎1🍉🍮s 0🔂k⏩0🐕🍇🍦t➖🐕k🍮r t🔂i⏩1 t🍇🍊😛🚮t i 0🍇🍮➕r i🍉🍉🍮➕s✖r🅰️k🍉🍎➗s🐕🍉🍉

Çevrimiçi deneyin!

"2'den küçük" yerine "1'den küçük veya 1'e eşit" kullanarak -3 bayt, çünkü "küçüktür" emojisi oldukça uzun bir UTF-8 kodlamasına sahiptir. Ayrıca tbayt sayısını etkilemeden bir uyarıyı susturmak için dondurulmuş hale getirildi .

🚂 (integer) sınıfını 🅰️ adlı bir yöntemle genişletir. Girişten bir sayı alan basit bir program yazabilir, numaraya 🅰️ çağırabilir ve sonucu şöyle yazdırabilirsiniz:

🏁🍇
 🍦str🔷🔡😯🔤Please enter a number🔤
 🍊🍦num🚂str 10🍇
  😀🔡🅰️num 10
 🍉🍓🍇
  😀🔤Learn what a number is, you moron!🔤
 🍉
🍉

Bu bölüm, mesajları ve hata işlemeyi atlayarak çok fazla golf oynayabilir, ancak skorda yer almaz, bu yüzden yol boyunca okunabilirliği geliştirirken Emojicode'un daha fazla özelliğini göstermeyi tercih ederim.

Ungolfed

🐋🚂🍇
 🐖🅰️➡🚂🍇
  🍊◀️🐕2🍇
   🍎1
  🍉
  🍮sum 0
  🔂k⏩0🐕🍇
   🍦nmk➖🐕k
   🍮sig nmk
   🔂i⏩1 nmk🍇
    🍊😛🚮nmk i 0🍇
     🍮➕sig i
    🍉
   🍉
   🍮➕sum✖sig🅰️k
  🍉
  🍎➗sum🐕
 🍉
🍉

açıklama

Not: Çok fazla emoji seçeneği emojicode 0.5'te pek bir anlam ifade etmez. Ne de olsa 0.x. 0.6 bunu düzeltir.

Emojicode jenerikler, protokoller, opsiyonel ve kapanışları içeren nesne yönelimli bir programlama dilidir, ancak bu program hiçbir kapanma kullanmaz ve I / O saplamasında tek isteğe bağlı görünürken tüm jenerikler ve protokoller örtülü olarak kabul edilebilir.

Program sadece birkaç tipte çalışır: 🚂 tamsayı tipidir, 🔡 dize tipidir ve ⏩ aralık tipidir. Birkaç boolean (👌) da görünür, ancak bunlar yalnızca koşullarda kullanılır. Booleans, sırasıyla doğru ve yanlış değerlerine karşılık gelen 👍 veya 👎 değerini alabilir.

Şu anda Emojicode'da operatör yoktur, bu nedenle normalde operatör olan ekleme, karşılaştırmalar ve diğer işlemler işlev olarak uygulanır ve ifadelerin etkili bir şekilde önek gösterimini kullanmasını sağlar . Operatörler de 0.6'da planlanıyor.

Önce test programını ele alalım.

🏁

Bu, diğer dillerdeki ana metinlerle karşılaştırılabilen 🏁 bloğudur.

🍇 ... 🍉

Üzüm ve karpuz emoji kodunda kod blokları bildirir.

🍦str🔷🔡😯🔤Please enter a number🔤

Bu, "dondurulmuş" olarak adlandırılır strve değerini, başlatıcı (yapıcı) 😯 kullanılarak oluşturulan yeni bir dizeye ayarlar; bu, dize olarak bir istem alır ve daha sonra kullanıcıdan bir satır girer. Neden bir değişken yerine dondurulmuş kullanılır? Değişmez, bu yüzden bir değişken uyarı verir.

🍊🍦num🚂str 10

Hadi yıkalım. dondurulmuş 🚂str 10üzerinde 🚂 yöntemini str10 bağımsız değişkeniyle çağırır. Kural olarak , bir tür adıyla adlandırılan yöntemler nesneyi bu türe dönüştürür. 10 tamsayı dönüştürme için kullanılacak bazdır. Bu yöntem isteğe bağlı bir 🍬🚂. Opsiyoneller baz tipinde bir değer veya hiçlik içerebilir, ⚡. Dize bir sayı içermiyorsa, ⚡ döndürülür. Değeri kullanmak için, ⚡ kullanılarak isteğe bağlı paketin açılması gerekir, bu da değer ⚡ ise bir çalışma zamanı hatası oluşturur. Bu nedenle, isteğe bağlı bir paketi açmadan önce hiçbir şey olup olmadığını kontrol etmek iyi bir uygulamadır. Aslında, Emojicode'un bunun için bir stenografi olması çok yaygın. Normalde, 🍊bir "if" dir.🍊🍦 variable expressionşu anlama gelir: ifadeyi değerlendirmek. İsteğe bağlı bir hiçlik içeriyorsa, koşul 👎 (yanlış) olarak değerlendirilir. Aksi takdirde, variableisteğe bağlı olanın kaydırılmamış değeriyle dondurulmuş bir ad oluşturulur ve koşul 👍, (true) olarak değerlendirilir. Bu nedenle, normal kullanımda, 🍇 ... 🍉koşulu takip eden blok girilir.

😀🔡🅰️num 10

🅰️ ana kodun bölüm sayısını hesaplayan 🚂 kullanarak 🐋 yöntemine eklediği yöntemdir. Bu, koşullu olarak numbeyan ettiğimiz dondurulmuş 🅰️'yi çağırır ve sonucu 🔡 yöntemi ile base 10'u kullanarak bir dizeye dönüştürür. Ardından, 😀 sonucu yazdırır.

🍓🍇 ... 🍉

🍓 "else" anlamına gelir, bu nedenle kullanıcı doğru bir sayı girmediğinde bu blok girilir.

😀🔤Learn what a number is, you moron!🔤

Dize hazır bilgisini yazdırır.

Şimdi ana programa bakalım. Kurtulmamış versiyonu açıklayacağım; golfed sürümü sadece boşluk kaldırıldı ve değişkenler tek harfli isimlerle yeniden adlandırıldı.

🐋🚂🍇 ... 🍉

🚂 sınıfını genişletin. Bu, programlama dillerinde yaygın olarak bulunmayan bir özelliktir. Üst sınıf olarak 🚂 ile yeni bir sınıf oluşturmak yerine, 🐋 doğrudan 🚂 değiştirir.

🐖🅰️➡🚂🍇 ... 🍉

🅰 döndüren 🅰️ adında yeni bir yöntem oluşturur. Formül kullanılarak hesaplanan bölüm sayısını döndürüra(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)

🍊⬅🐕1🍇
 🍎1
🍉

🐕 diğer dillere benzer thisveya selfdillerden farklıdır ve yöntemin çağrıldığı nesneyi belirtir. Bu uygulama özyinelemeli, bu nedenle sonlandırma şartıdır: yöntemin çağrıldığı sayı 1'den küçük veya 1'e eşitse, 1 döndürün.

🍮sum 0

Yeni bir değişken oluşturun sumve 0 olarak ayarlayın. Örtük olarak type türünü alır.

🔂k⏩0🐕

🔂, protocol️ protokolünü uygulayan her şeyi yineler, ⏩ ise 🔂🐚🚂 uygulamak için bir aralık değişmezidir. Bir aralığın bir başlangıç ​​değeri, bir durdurma değeri ve bir adım değeri vardır; bu değer, eğer 1 start < stop, aksi takdirde -1 olarak kabul edilir . Aralık değerini oluşturmak için ⏭ tuşunu kullanarak adım değerini de belirtebilirsiniz. Başlangıç ​​değeri kapsayıcıdır, ancak durdurma değeri münhasırdır, bu nedenle bu formülde for k in range(n)veya Sum_{k=0..n-1}formüle eşdeğerdir .

🍦nmk➖🐕k

Sigma (n - k) veya n - kbaşka bir deyişle bölenlerin toplamını hesaplamamız gerekir ve argüman birkaç kez gereklidir, bu nedenle bu n - k, nmkbazı baytları kaydetmek için değişkeni depolar .

🍮sig nmk
🔂i⏩1 nmk

Bu, sigdeğişkeni sigma argümanına ayarlar ve 1'den 1'e kadar tüm sayılar üzerinde yineleme yapar nmk - 1. Değişkeni 0 olarak başlatabilir ve 1..nmk üzerinde yineleyebilirim ama bu şekilde yapmak daha kısadır.

🍊😛🚮nmk i 0

🚮 geri kalanını veya modülünü hesaplar ve 😛 eşitliği kontrol eder, böylece koşul ibir bölücü ise be olur nmk.

🍮➕sig i

Bu, += -= >>=bazı emoji içermeyen dillerin bazılarında operatör ailesine benzeyen çağrı yoluyla bir ödevdir. Bu satır olarak da yazılabilir 🍮 sig ➕ sig i. Bu nedenle, iç döngü tamamlandıktan sonra, sigbir bölenler toplamını içerir n - k, ya dasigma(n - k)

🍮➕sum✖sig🅰️k

Çağrı ile başka bir atama, böylece bu sigma(n - k) * A(k)formülde olduğu gibi toplamı ekler .

🍎➗sum🐕

Son olarak, toplam n'ye bölünür ve bölüm döndürülür. Bu açıklama muhtemelen kodun kendisini yazmak kadar üç zaman aldı ...



3

Oktav, 18 bayt

partcnt(input(''))

Yerleşik işlevi partcnt kullanır.

@ Kullanarak anonim bir işlev kullanarak doğru olamaz, bazı yardım mutluluk duyacağız.


3

Retina , 34 bayt

.+
$*
+%1`\B
;$'¶$`,
,

%O`1+
@`.+

Çevrimiçi deneyin!

açıklama

.+
$*

Girişi tekli olarak dönüştürün.

+%1`\B
;$'¶$`,

Bu , tekli rakam listesinin 2 n-1 bölümünün tamamını hesaplar . Bunu , her satırdaki ( ) +ilk ( 1) sözcük olmayan sınırla ( \Byani iki 1s arasındaki bir konum ) tekrar tekrar ( ) eşleştirerek ve arkasından gelen her şey ( ), bir satır besleme ( ), önündeki her şeyle değiştirerek yaparız . it ( ) ve%;$'$`, . Misal:

1;1,111

Oluyor

      vv
1;1,1;11
1;1,1,11
^^^^^

Nerede vişaretleri sonucu $'ve ^işaretleri sonuç$` . Bu, aynı anda iki farklı değiştirmenin sonucunu elde etmek için yaygın bir deyimdir (temel olarak iki tam ikameyi tamamlamak için hem dizeyi hem ;de ,değiştirmeyi ve eksik "yarıları" ekleriz).

;Gerçek bölümler olarak ve ,sonradan \Beşleşmeyi engelleyen yer tutucular gibi davranacağız . Sıradaki ...

,

... virgülleri kaldırıyoruz. Bu bize tüm bölümleri verir. Örneğin girdi için 4şunu elde ederiz:

1;1;1;1
1;1;11
1;11;1
1;111
11;1;1
11;11
111;1
1111

Siparişi umursamıyoruz:

%O`1+

Bu, 1 , her satırdaki s böylece sırasız bölümler alırız.

@`.+

Son olarak, benzersiz ( @) eşleşmelerini .+, yani kaç farklı çizgi / bölüm elde ettiğimizi sayıyoruz . Bu @seçeneği yıllar önce ekledim , sonra tamamen unuttum ve sadece son zamanlarda yeniden keşfettim. Bu durumda, satırların ilk tekilleştirilmesi üzerine bir bayt kaydeder D`.


3

Python 2 , 54 53 bayt

f=lambda n,k=1:1+sum(f(n-j,j)for j in range(k,n/2+1))

Çevrimiçi deneyin!

Nasıl çalışır

Her bölüm , n , bir liste olarak temsil edilebilir , x = [x 1 , ⋯ x m ] öyle ki x 1 + ⋯ + x m = n . Bu temsil x 1 ≤ ⋯ ≤ x m .

Biz bir yardımcı fonksiyon tanımlama f (n, k) alt sınır ile sayımları bölümleri bu k , yani, listeler x öyle ki x 1 + ⋯ + x m = n ve k ≤ x 1 ≤ ⋯ ≤ x m . Giriş n için , bu nedenle zorluk f (n, 1) çıktısını ister .

N ve k pozitif tamsayıları için k ≤ n olacak şekilde , alt k bağlı en az bir bölüm vardır : tekil liste [n] . Eğer n = k (özellikle eğer n = 1 ), bu sadece uygun bölüm. Öte yandan, k> n ise ise hiç bir çözüm yoktur.

Eğer k <n , biz yinelemeli soldan sağa doğru, onları inşa ederek kalan bölümleri sayabilir olarak izler. Her biri için j , öyle ki k ≤ j ≤ n / 2 , biz bölümleri inşa edilebilir [x 1 , ⋯ x m ] = [j, Y 1 , ⋯ y , m-1 ] . Biz bu x 1 + ⋯ + x m = n ancak ve ancak Y 1 + ⋯ + y , m-1 = n - j . Ayrıca, x 1 ≤ ⋯ ≤ x m ve yalnızca j ≤ y 1 ≤ ⋯ ≤ y m-1 ise .

Bu nedenle, bölmeler x ait n ile başlayan j olarak hesaplanabilir - (j j n) f geçerli bölümleri sayar, y . J ≤ n / 2'yi zorunlu kılarak, j - n - j olmasını sağlarız , bu yüzden en az bir y vardır . Biz böylece sayabiliriz tüm ait bölümleri n toplayarak 1 (için [n] ve) - (j j n) f tümünün geçerli değerleri için j .

Kod f matematiksel fonksiyonunun basit bir uygulamasıdır . Buna ek olarak, yapar k için varsayılan 1 yüzden f(n)değerini hesaplar f (n, 1) giriş için n .


Oh vay, bu inanılmaz! Bunun nasıl çalıştığına dair bir açıklama ekleyebilir misiniz?

Cevabımı düzenledim. Anlaşılmayan bir şey varsa lütfen bana haber verin.
Dennis

3

J , 37 35 bayt

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:

Çevrimiçi deneyin!

açıklama

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:  Input: n
                                 1:  Constant 1
  ]                                  Get n
   1&(                          )    Repeat n times on x = [1]
                          \            For each prefix
                         #               Length
                      q:@                Prime factors
                 /.~&                    Group equal factors
              #.~                        Compute p+p^2+...+p^k for each group
           >:@                           Increment
                    &.q:                 Product
                           %           Divide
                            #          Length
         ]                             Get x
          *                            Times
   1   #.                              Sum
                              ,        Joim
                               ]       Get x
                                       Set this as next value of x
0{                                   Select value at index 0

Ben şaşkınım ve şaşkınım, bir açıklama yayınlamak ister misiniz?
cole

1
@cole Bu, p (0) = 1 çözeltisi ile başlayan ve bir sonraki formülü kullanarak bir yinelemeli yaklaşımdır p(n) = sum(sigma(n-k) * p(k) for k = 0 to n-1) / n. Önemli ölçüde kısaltılamayacağına inandığımda daha sonra kodun bir açıklamasını ekleyeceğim.
mil

2

JavaScript, 125 121 bayt

n=>(z=(a,b)=>[...Array(a)].map(b))(++n**n,(_,a)=>z[F=z(n,_=>a%(a/=n,n)|0).sort().join`+`]=b+=eval(F)==n-1&!z[F],b=0)|b||1

Çevrimiçi deneyin!

Uyarı: zaman ve mekan karmaşıklığı üsteldir. Büyük sayılar için çok yavaş çalışır.


2

Python 2 , 89 bayt

-9 bayt Mr.Xcoder tarafından -1 byte notjagan tarafından

lambda n:len(p(n))
p=lambda n,I=1:{(n,)}|{y+(x,)for x in range(I,n/2+1)for y in p(n-x,x)}

Çevrimiçi deneyin!



@ Mr.Xcoder Neden lambda D kullanmadığımı bile bilmiyorum:
Dead Possum

Hehe, ¯\_(ツ)_/¯- BTW, eğer tam işlevini korumak istiyorsan, değişkene ihtiyacın olmazdı, 94 bayt
Bay Xcoder

@ Mr.Xcoder Evet .. Codegolf'dan uzak kaldıktan sonra paslı hissediyorum: c
Dead Possum



0

Java 8 (229 bayt)

import java.util.function.*;class A{static int j=0;static BiConsumer<Integer,Integer>f=(n,m)->{if(n==0)j++;else for(int i=Math.min(m,n);i>=1;i--)A.f.accept(n-i,i);};static Function<Integer,Integer>g=n->{f.accept(n,n);return j;};}

Ungolfed:

import java.util.function.*;

class A {
    static int j = 0;
    static BiConsumer<Integer, Integer> f = (n, m) -> {
        if (n == 0)
            j++;
        else
            for (int i = Math.min(m, n); i >= 1; i--)
                A.f.accept(n - i, i);
    };
    static Function<Integer, Integer> g = n -> {
        f.accept(n, n);
        return j;
    };
}

0

Jöle , 3 bayt

ŒṗAtom son zamanlarda eklenmiş ve "Tamsayı bölümleri" anlamına gelir.

ŒṗL

Çevrimiçi deneyin!

ŒṗL - Tam program.

Œṗ - Tamsayı bölümleri.
  L - Uzunluk.
      - Örtük olarak çıktı.


0

JavaScript ES7, 69 Bayt

n=>(f=(i,s)=>i?[for(c of Array(1+n))f(i-1,s,s-=i)]:c+=!s)(n,n,c=0)&&c

JavaScript ES6, 71 Bayt

n=>(f=(i,s)=>i?[...Array(1+n)].map(_=>f(i-1,s,s-=i)):c+=!s)(n,n,c=0)&&c

Zaman karmaşıklığı O (n ^ n), bu yüzden dikkatli olun (bilgisayarımda açık bir gecikme görünüyor F(6))

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.