Ardışık tek sayıların toplamı


24

Her ne kadar ilgili zorluklar sorulsa da, bu kendi sorusunu garanti etmek için farklı.


Meydan okuma

Pozitif bir tamsayı verildiğinde, toplamı verilen tamsayı olan ardışık pozitif tek tamsayıların en uzun sırasını döndür. Böyle bir dizilim yoksa, sahte bir değer döndürmek veya bir istisna atmak dahil diliniz için ne kadar anlamlı olursa olsun bir hata bildirebilirsiniz.

Test Kılıfları

  1 -> [1]
  2 -> []
  3 -> [3]
  4 -> [1, 3]
  5 -> [5]
  6 -> []
  9 -> [1, 3, 5] ([9] un geçerli bir cevap olmadığını unutmayın)
 15 -> [3, 5, 7]
104 -> [23, 25, 27, 29] ([51, 53] 'ın geçerli bir cevap olmadığını unutmayın)

puanlama

Bu , yani her dilde en kısa cevap kazanır.


2
Herhangi bir çözüm yoksa programım sonsuza kadar çalışabilir mi?
Dennis,

Çok ilgili . Bu sayılarda bazı çiftlerin temsil edilememesi gerçeği, bunu bir dupe olmaktan kurtarabilir.
ETHproductions

6
15, [-1, 1, 3, 5, 7] veremiyor mu? Sadece pozitif değerlere izin verilirse, bunu söylemelisiniz.
xnor

2
@ ЕвгенийНовиков atladınız 17
kalsowerus

1
kalsowerus evet. "Ardışık" kelimesini yanlış anlıyorum
Евгений Новиков

Yanıtlar:


11

Haskell, 67 65 63 62 58 bayt

Julian Wolf sayesinde 4 byte kurtarıldı

f x=[[2*n+1,2*n+3..2*m]|n<-[0..x],m<-[n..x],m^2-n^2==x]!!0

Çevrimiçi deneyin!

İki numaralı kareler o fark olarak ifade edilebilir olmadığını kontrol edin: m^2-n^2. Sonra ardışık tek sayı listesi oluşturabilirsiniz: [2n+1,2n+3...2m-1]. Minimum nseçili olduğundan, en uzun listenin çıktısını alın.


7
Aşağı oy veren: Özellikle yeni bir kullanıcı aşağı oy kullanırken, sebebinizi belirten bir yorum eklemek hem dostça hem de daha yapıcı olacaktır.
Jonathan Allan

1
Bir şeyi özlemediğim sürece, xher ikisine de nm
Julian Wolf

Sadece, bildiğiniz gibi, siz de cevabınızı düzelttikten sonra oylama Topluluk tarafından otomatik olarak yayınlandı. Bunun bir hata olduğunu düşünüyorum . (CC @JonathanAllan)
Dennis,

Ahh, onlardan biriydi.
Jonathan Allan,

9

Python 2 , 66 62 bayt

f=lambda n,k=0,*r:n-sum(r)and f(n,k+1,*range(k%n|1,k/n,2))or r

Bir çözüm yoksa , RuntimeError ile çıkar (maksimum yineleme derinliği aşıldı).

Çevrimiçi deneyin!


1
Giriş değerleri yeterince yüksekse, ancak bir çözüm varsa, bu RuntimeError'a neden olur mu?
Okx

Özyineleme sınırı yeterince yüksek değilse ve / veya yığın yeterince büyük değilse, evet. Bununla birlikte, fiziksel sınırlamaları göz ardı etmek yaygındır (örneğin, bir C cevabının sadece 32-bit ints için çalışması gerekir) ve OP açıkça bir çözüm yoksa sonsuza dek koşmanın kabul edilebilir olduğunu söyledi.
Dennis,

9

Jöle ,  11  10 bayt

-1 Dennis bayt sayesinde (örtük aralığı yapı kullanmak - yerine Rm2Ẇile ẆḤ’)

ẆḤ’S_¥Ðḟ⁸Ṫ

Summands mümkünse veya bir listesini dönen bir monadic bağlantı 0değilse.

Çevrimiçi deneyin!

Nasıl?

ẆḤ’S_¥Ðḟ⁸Ṫ - Link: number, n
Ẇ          - all sublists (implicit range of input) note: ordered by increasing length
           -                i.e. [[1], [2], [3], ..., [1,2], [2,3], ..., [1,2,3], ...]]
 Ḥ         - double              [[2], [4], [6], ..., [2,4], [4,6], ..., [2,4,6], ...]]
  ’        - decrement           [[1], [3], [5], ..., [1,3], [3,5], ..., [1,2,5], ...]]
        ⁸  - link's left argument, n
      Ðḟ   - filter out items for which the following yields a truthy value:
     ¥     -   last two links as a dyad:
   S       -     sum
    _      -     subtract the right from the left = sum - n
         Ṫ - tail (last and hence longest such run)

1
ẆḤ’bir bayt kaydeder.
Dennis,

8

JavaScript (ES7), 87 86 85 81 bayt

Virgülle ayrılmış bir tam sayı listesi veya 0çözüm yoksa döndürür .

n=>(g=(s,k,x=n+s)=>(x**.5|0)**2-x?k>n?0:g(s+k,k+2):(n-=k)?k+','+g(-n,k+2):k)(0,1)

Nasıl?

İlk önce en küçük kusursuz kareyi ararız ki x = n + s bir başka mükemmel kare olur.

Eğer s var, n fark x - s ardışık tek sayı 2 dizilerinin fark olarak yazılabilir 2 tam kareleri, bir. Ardından sonuç listesini oluştururuz.

Örnek:

İçin , n = 104 :

Biz bulmak s = 11² = 121 olan tatmin X = n + s = 225 = 15²

Sonra:

15² = 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 17 + 19 + 21 + 23 + 25 + 27 + 29
11² = 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21
104 = 15² - 11² = 23 + 25 + 27 + 29


3
Bekle, bana n^2her zaman ilk ntek sayıların toplamına eşit olduğunu mu söylüyorsun ? Huh, ilginç
Skidsdev

2
@Mayube Gerçekten !
Arnauld,


7

05AB1E , 9 8 bayt

Emigna sayesinde -1 bayt

ÅÉŒʒOQ}н

Açıklama:

ÅÉ           Generate a list of odd numbers up to, and including, the input
  Π         Substrings
   ʒ         Only keep values
    O          where the sum
     Q         equals the input
       }     End
             For 9, the result would look like this:
             [[1, 3, 5], [9]]
        н    Get the first value

Geçersiz girişte, hiçbir şey çıkarmaz.

Çevrimiçi deneyin!


ʒOQ}DO¹QÏBir bayt yerine kaydeder.
Emigna

@JonathanAllan Docs "düzensiz" diyor bu yüzden kafası karışmış olabilirdi ...
Outgolfer Erik

1
@ JonathanAllan Küçük hata. Sabit.
Okx

6

Haskell , 61 60 bayt

1 byte tıraş için @maple_shaft sayesinde

f n=[k|r<-[1,3..],s<-[r,r+2..n],k<-[[r,r+2..s]],sum k==n]!!0

Çevrimiçi deneyin!

En uzun koşunun her zaman en düşük sayı ile başlayan koşma olacağı gerçeğini kullanır.

Ben kaba zorlama yerine aritmetik ile bir şeyler yapmak istedim k, ama fromIntegeronu öldürüyor gibi görünüyor.


Sen değiştirerek kendinize bir bayt kaydedebilirsiniz [1,3..n]için[1,3..]
maple_shaft

1
Bir yardımcı işlev ile 7 bayt kaydedebilirsiniz r?n=[r,r+2..n]. Çevrimiçi deneyin!
Ørjan Johansen

4

Python , 67 bayt

f=lambda n,R=[1]:n-sum(R)and f(n,[R+[R[-1]+2],R[1:]][sum(R)>n])or R

Çevrimiçi deneyin!

Ben kopyalanan önceki ardışık toplamı meydan gelen cevabımı ve değiştirilemez +1için +2. Golf kodunun bu kadar modüler olacağını kim bilebilirdi?

Tuhaf bir şekilde basit bir strateji: Rİstenilen toplamı olan aralığı arayın .

  • Toplam çok küçükse, üstündeki sonraki sayı 2'yi ekleyerek aralığın 2 sağ uç noktasını yukarı kaydırın.
  • Toplam çok büyükse, en küçük öğeyi kaldırarak sol uç noktayı yukarı kaydırın
  • Toplam doğru ise, çıktı R.

Aralığın sadece alt ucu arttığından, kısa aralıklardan önce daha uzun aralıklar bulunur. Olası bir aralık bulunamazsa, IndexError ile sonlanır.


4

JavaScript (ES6), 65 64 bayt

f=(a,i=1)=>a>i?(c=f(a-i,i+=2))[0]==i?[i-2,...c]:f(a,i):a<i?0:[i]

Bir çözüm varsa bir dizi, çözüm yoksa 0 döndürür.

Bu, soruna son derece verimsiz ama golfçü bir çözüm.

Özyinelemeli yığını işe yaramasa bile a-ive kullanarak ilk çözümü arar i=1. Bu çözüm ile başlamıyorsa i+2, o zaman yinelemeli kullanarak ilk çözüm aramak ave i+2.

Ungolfed

f=(a,i=1)=>
  a > i ? 
    (c = f(a - i, i += 2))[0] == i ? 
      [i-2, ...c] : 
      f(a, i) :
  a < i ? 
    0 :
    [i]

Test durumları:

Bunun ne kadar verimsiz olduğuna dair bir fikir için, çözüm f(104)69,535 özyinelemeli çağrıları gerektirir. Yığın hiçbir zaman 51 seviyeden fazla değildir, bu nedenle yığın taşması ile ilgili bir sorun yoktur.

Çözüm , 99 seviyeli bir yığınla f(200)8.6 milyon özyinelemeli çağrıları gerektiriyor . (Onun çözümü [11,13,15,17,19,21,23,25,27,29].)

İşte çalışan programın görsel bir gösterimi:


3

Python 2.7, 109 108 97 bayt

11 bayt aşağı, Outgolfer Erik sayesinde.

Bu benim ilk golf kodum!

def f(N):
 for n in range(N):
    x=(n*n+N)**.5-n
    if x%1==0:return[2*(k+n)+1for k in range(int(x))]

Nasıl çalışır

Ben bilinen kimliği kullandım 1 + 3 + 5 + ... + (2n - 1) = n²

Davasını al 15

15 = 3 + 5 + 7 = (1 + 2) + (3 + 2) + (5 + 2) = (1 + 3 + 5) + 3×2 = 3² + 3×2

Genel olarak, orada eğer x terimleri başlayarak 2n + 1gibi

(2n + 1) + (2n + 3) + (2n + 5) ... (2n + (2x-1))


Eşittir 2nx + x²

Eğer Ngiriş tamsayıdır, sorun maksimum bulma azaltır xşekilde

x² + 2nx - N = 0

Çözümü ile ikinci dereceden bir denklem

x = sqrt(n² + N) - n

En uzun dizi en büyük olandır x. Program dolaşır ngelen 0etmek Nve onu bulmak zaman xbir tam sayıdır, bir listesini oluşturur (2n + 1) + (2n + 3) + (2n + 5) ... (2n + (2x-1))ve döner o.



@EriktheOutgolfer, Teşekkürler, sekmeleri kullanmayı unuttum (=
dark32

3

Python 3, 190 81 Bayt

def c(q,l,i):
    if sum(l)0:
        l.append(i)
        return c(q,l,i+2)
    elif sum(l)>q:
        l.pop(0)
        return c(q,l,i)
    else:
        print(l)
c(q,[1],1)

c=lambda q,l=[1]:c(q,l+[l[-1]+2])if(sum(l)<q)*l else c(q,l[1:])if sum(l)>q else l

@Ovs ve @ musicman523 sayesinde


4
Sadece girinti kaldırarak bunu 122 bayta indirebilirsin . Eğer kodunuzu daha da kısaltmak istiyorsanız , Python'daki golf oynamaya bir göz atın .
ovs

3
Bu Python 3'te yayınlanmıyor, çünkü çağrıda printparantez yok
musicman523

2
Özyinelemeli aramada l.append(i)sadece kullanarak kaldırabilirsiniz l+[i]. Özyinelemeli aramada l.pop(0)kullanarak kaldırabilirsiniz l[1:]. Bunun cyerine, anahtar kelime argümanlarını kullanarak aramayı en altta kaldırabilirsiniz . >02. satırda kaldırabilirsiniz . Sonunda, lambda ifadesi olarak sizi 92 bayta indiren üçlü formu kullanarak ifadelerinizi ifve elseifadelerinizi ifadeler halinde değiştirebilirsiniz . Çevrimiçi deneyin!
musicman523

1
@ Musicman523 önerilerine dayanarak koşulları hala kısaltabilir ve itoplam 81 bayta kadar düşebiliriz .
ovs

1 byte tasarruf sum(l)>q elseetmek q<sum(l)elseiçin değişebileceğini düşünüyorum .
Zacharý

2

QBIC , 47 bayt

{_Cg=q┘q=q+2~g>:|_Xp\?g,[q,a,2|?b,┘g=g+b~g=a|_X

Bu, tek sayıları bir taneden toplamına kadar saymaya çalışır n. Geçerse n, döngüyü sıfırlayın, 1'den 3'e yükseltin ve tekrar deneyin. Çıkın, 0 basıyor, döngünün başında numaramız varsa > n.

açıklama

{       Do infinitely
_C      Clear the screen (we basically print every run of odd numbers, but clear out everything that doesn't sum up to n)
g=q     Set g to the first num of this cycle (q starts as 1 in QBIC)    
┘       (Syntatcic linebreak)
q=q+2   Raise q to the next odd number, this sets up both the next outer loop as well as a coming FOR loop
~g>:|   If we start out with a number > n (read as 'a' from the cmd line)
_Xp     THEN quit, printing 0 (the value of the number var 'p')
\       ELSE
[q,a,2| FOR b = q, b <= n, b+=2
?b,┘    PRINT b followed by a tab
g=g+b   Add 'b' to running total 'g'
~g=a|   and if that lands us on 'n'
_X      QUIT (printing nothing: everything is already printed)

1

R , 90 bayt

f=function(x,y=1)'if'(length(w<-which(cumsum(r<-y:x*2-1)==x)),r[1:w],'if'(y>x,0,f(x,y+1)))

Çevrimiçi deneyin!

Tek bir sayı sırasına dönüştürülen y: x kümülatif toplamını test eden bir özyinelemeli işlev kullanır. y, her tekrarlamada x'i geçinceye kadar artırılır. Hedefe toplanan ilk dizi geri döndürülür.


1

Python 2 , 89 bayt

lambda n,r=range:[v for v in[r(1,n+1,2)[i:j]for i in r(n)for j in r(n+1)]if sum(v)==n][0]

Olumsuz bir tamsayı alarak adlandırılmamış bir işlev nve eğer varsa ve IndexErroraksi takdirde yükselterek sonucu döndürerek .

Çevrimiçi deneyin!

İle ilgili tüm tek numaralarının bir listesini oluşturur r(1,n+1,2)olan range(start=1, stop=n+1, step=2); bundan dilimleme tarafından tüm ilgili alt dilimleri (artı bazı boş olanlar) oluşturur ikapsayıcı jile özel [i:j]genelinde ide ) 0 [n kullanarak r(n)ve jiçinde 0 [n] kullanarak r(n+1)(boş olanlar i>=jveya i) sınırların dışında; toplamı doğru olanlar için filtreler if sum(v)==n; ilk (ve dolayısıyla en uzun) bu dilim kullanılarak döner [0].




1

PHP , 73 bayt

hiçbir çözüm sonsuz bir döngü değildir

for($e=-1;$s-$i=$argn;)$s+=$s<$i?$n[]=$e+=2:-array_shift($n);print_r($n);

Çevrimiçi deneyin!

PHP , 83 bayt

çözüm için hiçbir şey yazdırmaz

her giriş mod 4 == 2 çözümü yok

for($e=-1;($i=$argn)%4-2&&$s-$i;)$s+=$s<$i?$n[]=$e+=2:-array_shift($n);print_r($n);

Çevrimiçi deneyin!


çözülemeyen girişini tespit etmek için başarısız
Titus

@Titus fixed ...
Jörg Hülsermann


0

Python 3 , 93 bayt

lambda n,r=range:[[*r(s,e+1,2)]for s in r(1,n+1,2)for e in r(s,n+1,2)if(s+e)*(2+e-s)==4*n][0]

Çevrimiçi deneyin!

Yaptığım tek özel şey, (s+e)*(2+e-s)==4*nbunun eşdeğer olduğunu sum(range(s,e+1,2))==nve eskilerin ifadeye r=rangedaha yakın yerleştirilebildikleri halde aynı boyutta olmasına rağmen if.


0

Python 3 , 185 bayt

def f(s):
  d={k:v for k,v in{a:(1-a+((a-1)**2+4*s)**(.5))/2 for a in range(1,s,2)}.items()if int(v)==v};m=max(d.keys(), key=(lambda k: d[k]));return list(range(int(m),int(m+2*d[m]),2))

Çevrimiçi deneyin!


Bunun nasıl yürüdüğünü, basit kaba kuvvet aramadan biraz daha zarif bir çözüm bulmaya çalıştım. Bir aritmetik dizinin toplamı için formülü yeniden düzenledim (1-a+((a-1)**2+4*s)**(.5))/2ve kodda görünen ifadeyi elde etmek için ikinci dereceden formülü uyguladım . İfadenin hesapladığı, saritmetik dizilim için istenen bir toplam ve birinci terim olan dizinin auzunluğudur. Bu uzunluklar bir sözlükte ilk terimlerin değerleri olarak anahtar olarak saklanır.

Ardından, tüm tamsayı olmayan değerler, geçersiz dizileri temsil ettiği için sözlükten kaldırılır. Oradan, en büyük değer ile tanımlanır max(d.keys(), key=(lambda k: d[k]))ve bu konumdaki ve bu uzunluktaki tek sayıların sırası ile yapılır list(range(int(m),int(m+2*d[m]),2)).


Bir şey görürseniz, golf oynamak için yardım arıyorum. Önemsiz olmayan bir algoritmayla ne kadar iyi yapabileceğimi görmek ilgimi çekmişti; Cevabım, en iyi Python çözümü ile neredeyse iki kat daha uzun.


Bu işe yarar mı? repl.it/JTt7 (177 bytes)
Zacharý

0

Mathematica, 56 bayt

Last@Cases[Subsequences@Table[n,{n,1,#,2}],x_/;Tr@x==#]&

Functionilk argümanla #. Table[n,{n,1,#,2}]eşit veya daha küçük pozitif tek sayılar listesini hesaplar #. Subsequencesuzunluğu artan sırasına göre bu listenin tüm alt dizilerini döndürür. Daha sonra Caseshangi eşleşmeyi x_/;Tr@x==#, yani xtoplamlarının Tr@xgirişe eşit olacak şekilde dizilişini alıyoruz #. Daha sonra Lastböyle bir dizi alırız.


0

JavaScript (ES6), 72 bayt

n=>(g=s=>s?s>0?g(s-(u+=2)):g(s+l,l+=2):u-l?l+' '+g(s,l+=2):u)(n-1,l=u=1)

Boşlukla ayrılmış bir tek sayı dizesi döndürür veya geçersiz girişe atar. (Uygun olduğunda boş) bir dizi döndüren 84 bayt sürümü:

n=>n%4-2?(g=s=>s?s>0?g(s-(u+=2)):g(s+l,l+=2):u-l?[l,...g(s,l+=2)]:[u])(n-1,l=u=1):[]

Açıklama: Gevşek için Cabbie407 en awk çözümü @ dayanan Ardıl Tamsayılar Tutarlarla ben özyineleme kullanarak bazı bayt tasarruf edebildi hariç.


0

PHP, 78 bayt

for($b=-1;$s-$argn;)for($n=[$s=$x=$b+=2];$s<$argn;)$s+=$n[]=$x+=2;print_r($n);

çözüm yoksa sonsuz döngü. insert ?$b>$argn+2?$n=[]:1:0sonra $s-$argnyerine boş diziyi yazdırmak için.

Çevrimiçi olarak çalıştırın -nRveya deneyin .


0

C # (.NET Çekirdeği) , 129 bayt

(i)=>{int s,j,b=1,e=3;for(;;){var o="";s=0;for(j=b;j<e;j+=2){s+=j;o+=j+" ";}if(s==i)return o;s=s<i?e+=2:b+=2;if(b==e)return"";}};

Boşluklarla ayrılmış bir dizgede sayılar çıkar (başka bir karakter sadece değiştirmeyi gerektirir " "). Çözüm içermeyen giriş boş bir dize döndürür (ancak sonsuza dek hatasız çalıştırılması, hiçbir çözüm olmadığını belirtmek için geçerli bir yol olsa da, kaldırılarak 17 bayt kaydedilebilirif(b==e)return""; ).

Algoritma:

  1. [1] ile başla
  2. Toplam, hedefe eşitse, listeyi döndür
  3. Toplam, hedeften azsa, bir sonraki tek sayıyı ekleyin.
  4. Toplam, hedeften büyükse, ilk öğeyi kaldır
  5. Liste boşsa, geri gönderin
  6. 2’den tekrarla

Sen yazabilir (i)=>olaraki=>
aloisdg eski haline Monica diyor

0

C ++, 157 -> 147 Bayt


DJMcMayhem sayesinde -10 Bayt

cevap yoksa 0 döndürür, aksi takdirde 1

En son yazdığı satır cevaptır.

int f(int n){for(int i=1;;i+=2){int v=0;for(int k=i;;k+=2){v+=k;std::cout<<k<<" ";if(v==n)return 1;if(v>n)break;}if(i>n)return 0;std::cout<<"\n";}}

ungolfed:

int f(int n)
{
    for (int i = 1;; i += 2)
    {
        int v = 0;
        for (int k = i;; k += 2)
        {
            v += k;
            std::cout << k << " ";
            if (v == n)
                return 1;
            if (v > n)
                break;

        }
        if (i > n)
            return 0;
        std::cout << "\n";
    }
}

bu benim ilk kod golf ^^


Bir int işlevi yaptıysanız ve 0 veya 1 döndürdüyse bazı baytları kaydedebilirsiniz. Ayrıca, int v=0;yerine yerine int v;....v=0;yapabilirdiniz std::cout<<k<<"\n";ve
çıktınızı Newline'ı


0

Kotlin, 152 bayt

fun f(a:Double){var n=Math.sqrt(a).toInt()+1;var x=0;while(n-->0){if(((a/n)-n)%2==0.0){x=((a/n)-n).toInt()+1;while(n-->0){println(x.toString());x+=2}}}}

Çevrimiçi deneyin (4-5 saniye bekleyin, derleyici yavaştır)

Ungolfed

fun f(a: Double){
    var n=Math.sqrt(a).toInt()+1;
    var x=0;

    while(n-->0){
        if(((a/n)-n)%2==0.0){
            x=((a/n)-n).toInt()+1;

            while(n-->0){
                println(x.toString());
                x+=2;
            }

        }
    }
}

0

Excel VBA, 139 Bayt

SubnBeklenen tür tamsayının girişini alan ve ardışık tek sayıların hücreye en uzun dizisini bildiren yordam[A1]

Sub a(n)
For i=1To n Step 2
s=0
For j=i To n Step 2
s=s+j
If s=n Then:For k=i To j-1 Step 2:r=r &k &"+":Next:[A1]=r &j:End
Next j,i
End Sub
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.