Ardışık Tam Sayıların Toplamı


27

Herhangi biri bir şey söylemeden önce, benzer ve benzer . Ama bu bir dupe değil.


Bazı pozitif tam sayılar, en az iki ardışık pozitif tamsayının toplamı olarak yazılabilir. Örneğin, 9=2+3+4=4+5. Girdili olarak pozitif bir tamsayı alan ve çıktısı olarak basan bir fonksiyon yazınız; çıktının yukarıda gösterildiği gibi artan artan sıra olması durumunda -5 bayt olmasına rağmen, çıktısını artıran ardışık pozitif tamsayıların en uzun dizisi +Eğer böyle bir sıra yoksa, numara kendisinin basılmalıdır.

Bu kod golfü. Standart kurallar geçerlidir. Bayt cinsinden en kısa kod kazanır.


Örnekler (biçimlendirmenin değiştiğine dikkat edin)

Input:   9
Output:  2,3,4

Input:   8
Output:  8

Input:   25
Output:  [3,4,5,6,7]

2
Çıktılan sayıların belirli bir sırada mı olması gerekiyor (artan gibi)?
XNOR

2
0> sayılar olmak zorunda mı: 6 = 0 + 1 + 2 + 3 ya da 6 = 1 + 2 + 3
Damien

5
Not olarak, yakından ilgili zorluklar varsa, "bu bir dupe değil" demek, insanları bir dupe olduğunu düşünürlerse ikna etmek için çok az şey yapacaktır. Neden olmadığını düşündüğünüzü açıklarsanız daha yararlı olur.
Martin Ender

1
@Damien "pozitif" normalde> 0 anlamına gelir. 0 dahil edildiyse "negatif olmayan" olarak adlandırılır.
Martin Ender

3
cc @Vixen ^ (negatif sayılara izin verilirse, en uygun çözüm her zaman ile arasındaki aralık -n+1olur n)
Martin Ender

Yanıtlar:


11

Python, 67 bayt

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

Tuhaf derecede basit bir strateji: R aralığını doğru toplamla arayın.

  • Toplam çok küçükse, bir sonraki en yüksek sayıyı ekleyerek aralığın sağ uç noktasını bir 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, R çıktısını alın.

Aralığın sadece alt ucu arttığından, kısa aralıklardan önce daha uzun aralıklar bulunur.


Garip derecede verimli. Özyineleme yığını sonunda taşar, örneğin n = 8192.
primo

7

Pyth, 12 10 bayt

j\+hfqsTQ}M^SQ2

Kod 15 bayt uzunluğunda ve -5 bayt bonusu için uygun. Pyth Compiler'da çevrimiçi olarak deneyin .

2 baytlık golf oynamak için @Jakube'e teşekkürler!

Nasıl çalışır

j\+hfqsTQ}M^SQ2    (implicit) Store evaluated input in Q.

            S      Compute [1, ..., Q].
           ^  2    Get all pairs of elements of [1, ..., Q].
         }M        Reduce each pair by inclusive range. Maps [a, b] to [a, ..., b].
    f              Filter; for each pair T:
      sT             Add the integers in T.
     q  Q            Check if the sum equals Q.
                   Keep the pair if it does.
   h               Retrieve the first match.
                   Since the ranges [a, ..., b] are sorted by the value of a,
                   the first will be the longest, in ascending order.
j\+                Join, using '+' as separator.

1
Pyth alanında aydınlanmayanlarımız için, lütfen bir açıklama ekler misiniz? :)
ETHproductions

Cevabımı düzenledim.
Dennis,

Müthiş, teşekkürler! Tekniğini beğendim.
ETHProductions

1
Giriş 1000: 30 dakika ve sayım ...
primo

3

Mathematica, 73 68 65 56 43 bayt

Cases[Range~Array~{#,#},i_/;Tr@i==#,{2},1]&

1
+1 Dün gece benzer bir çözüm buldum ama internetim bozuldu. Ayrıca Tuplesbir ek ifadesi de yapabilirsiniz .
LegionMammal978,

3

Haskell, 49 48 bayt

f n=[[a..b]|a<-[1..n],b<-[a..n],sum[a..b]==n]!!0

1
1 bayt kaydetmek için: [...]!!0yerine kullanın head[...].
nimi

2

MATLAB, 87 79 bayt

Zaten bir MATLAB cevabı olduğunu biliyorum, ancak bu yaklaşımda önemli ölçüde farklı.

x=input('');m=1:x;n=.5-m/2+x./m;l=max(find(~mod(n(n>0),1)));disp(m(1:l)+n(l)-1)

Bu aynı zamanda Octave'da da çalışır . Şunları yapabilirsiniz buraya çevrimiçi deneyin . Kodu zaten consecutiveSum.mbağlantılı çalışma alanına ekledim , bu yüzden sadece consecutiveSumkomut istemine girin, ardından değeri girin (örneğin 25).

Hala azaltmaya çalışıyorum (belki biraz kullanılan denklemi ayarlamak için), fakat temelde bir tamsayı nolan en büyük değeri bulur m, sonra mbaşlayan ilk sayıları görüntüler n.

Peki bu neden çalışıyor? Temel olarak, tüm bu sayıları düzenleyen matematiksel bir denklem var. Hepsinin ardışık olduğunu düşünüyorsanız ve bir noktadan başlarsanız, temel olarak şöyle diyebilirsiniz:

n+(n+1)+(n+2)+(n+3)+...+(n+p)=x

Şimdi, bundan açıkça görüldüğü gibi, sekansın temelde sadece ilk püçgenin sayıları (0'lar dahil), p+1çok sayıda eklenmiştir n. Şimdi izin m=p+1verirsek şöyle diyebiliriz:

m*(n+(m-1)/2)==x

Bu aslında oldukça çözülebilir. Hala bunu yapmanın en kısa kod yolunu arıyorum, yukarıdaki kodu azaltmak ve denemek için bazı fikirlerim var.


25 giriş için çıkış şöyle olacaktır:

3     4     5     6     7

2
Üçgenin sayıları ile ilgili noktaya gelince, bu zorluk temelde dizideki üçgen sayıların indekslerini 1,3,6,10,...maksimize edecek şekilde girdiyle pozitif bir fark yaratan üçgen sayıları bulmaya çalışıyor .
Arcturus,

1

Python 2, 94 bayt

n=input()
r=int((2*n)**.5)
while r:
 if~r%2*r/2==n%r:print range(n/r-~-r/2,n/r-~r/2);r=1
 r-=1

Girdi stdin'den alınmıştır. Bu çözüm çok büyük girdiler için uygundur.

Bu bir olası çözüm uzunlukları boyunca dolaşır r , sahip olan R ≤ √ (2n) açık bir solüsyon için ve kontrol eder. Bir çözümün var olması için, r'nin tek olması durumunda , n mod r sıfır olmalı ve r eşitse , n mod r / 2 olmalıdır .


Örnek Kullanım

$ echo 8192 | python sum-con-int.py
[8192]

$ echo 1000002 | python sum-con-int.py
[83328, 83329, 83330, 83331, 83332, 83333, 83334, 83335, 83336, 83337, 83338, 83339]

$ echo 1000000006 | python sum-con-int.py
[250000000, 250000001, 250000002, 250000003]

Ben kasıtlı olarak nispeten küçük çıktılara sahip örnekleri seçtim.


1

Octave, 89 Bayt

Octave'da yapabileceğimin en iyisi bu. Algoritma, xnor'ınkiyle aynıdır.

x=input('');k=i=1;while x;s=sum(k:i);if s<x;i++;elseif s>x;k++;else;x=0;end;end;disp(k:1)

MATLAB'de bu 95 bayt olacaktır:

x=input('');k=1;i=1;while x;s=sum(k:i);if s<x;i=i+1;elseif s>x;k=k+1;else x=0;end;end;disp(k:i)

MATLAB'da bu giriş için yaklaşık 0,1 saniye ve giriş için 20000001 saniyedir 1000002.


1

awk, 51 bayt

{while($0!=s+=s<$0?++j:-++i);while(++i-j)r=r i"+"}$0=r j

Kod, çıktı formatı için eksi 5 bayt olan 56 bayttır. Bu formatı üretmek için 4 ekstra byte kullanmak zorunda kaldım, bu yüzden aslında 1 byte kaydettim. Yaşasın! ;)

Aslında 1'den başlayarak toplam girdiden daha büyük olana kadar toplamı zorlaştırıyor. Ardından, sayı girişten daha küçük olana kadar 1'den başlayan sayıları çıkarma işlemine başlar. Bir sonuç bulana kadar başlangıç ​​ve bitiş numaralarını bu şekilde değiştirmeye devam eder ve ardından yazdırır.

Kullanım örneği

echo 303 | awk '{while($0!=s+=s<$0?++j:-++i);while(++i-j)r=r i"+"}$0=r j'

Örneğin çıktısı

48 + 49 + 50 + 51 + 52 + 53

Bunu bir giriş için denedim 1e12ve 464562+...+1488562hemen ( ) hemen doğru sonuç verdi . Elbette baskı yaparken biraz zaman aldı ...


Awk yaklaşımını seviyorum. Ciltlemelerde öncelik sırasını çözmekte güçlük çekiyorum. Biraz daha belirgin hale getirmek için daha fazla parantez eklenmiş bir sürüm ekler misiniz? :)
Wildcard

1
Bu yardımcı olur umarım: {while($0!=s)s+=(s<$0) ? (++j) : -(++i); while(++i<j)r=r i"+"}$0=r j Ben her zaman zincir başlangıcından çıkarıldı en son tamsayı, j her zaman zincir sonuna eklenen son tamsayıdır
Cabbie407

0

Japt , 33 bayt

Bu, Dennis'in Pyth tekniğini kullanır , ancak daha uzun olmasına rağmen ...

1oU à2 £W=Xg o1+Xg1¹x ¥U©W} rª ªU

Çevrimiçi deneyin! Uyarı: Daha büyük girişler için (<= 20) işlemin bitmesi biraz zaman alır ve tarayıcınızın bitmesine kadar donar.

Ungolfed ve açıklama

1oU à2 £    W=Xg o1+Xg1¹ x ¥ U© W} rª  ª U
1oU à2 mXYZ{W=Xg o1+Xg1) x ==U&&W} r|| ||U

          // Implicit: U = input integer
1oU à2    // Generate a range from 1 to U, and take all combinations of length 2.
mXYZ{     // Map each item X in this range to:
W=Xg o    //  Set variable W to the range of integers starting at the first item in X,
1+Xg1)    //  and ending at 1 + the second item in X.
x ==U&&W  //  If the sum of this range equals U, return W; otherwise, return false.
r||       // Reduce the result with the || operator, returning the first non-false value.
||U       // If this is still false, there are no consecutive ranges that sum to U,
          // so resort to U itself.
          // Implicit: output last expression

Bonus kazanma versiyonu: (38 bayt - 5 = 33)

1oU à2 £W=Xg o1+Xg1¹x ¥U©W} rª ªU² q'+

0

Julia, 92 bayt

x->(t=filter(i->all(j->j==1,diff(sort(i))),partitions(x));collect(t)[indmax(map(length,t))])

Bu bir tamsayıyı kabul eden ve bir dizi döndüren adsız bir işlevdir. Aramak için bir isim verin, örneğin f=x->....

Ungolfed:

function f(x::Integer)
    # Get all arrays of integers that sum to x
    p = partitions(x)

    # Filter these down to only consecutive runs by checking whether
    # all differences are 1
    t = filter(i -> all(j -> j == 1, diff(sort(i))), p)

    # Find the index of the longest element of t
    i = indmax(map(length, t))

    return collect(t)[i]
end

0

Ruby, 94 bayt

->n{([*1..n].permutation(2).map{|i,j|[*i..j]if(i..j).reduce(:+)==n}-[p]).max_by{|k|k.size}||n}

Ungolfed:

-> n {
  ([*1..n].permutation(2).map { |i,j|   # Finds all the possible sets of size 2
     [*i..j] if(i..j).reduce(:+) == n   # Adds a set to an array if sum of the set is n.
   }-[p]                                # Removes nil from the array
  ).max_by { |k|                        # Finds the longest sequence
    k.size
  } || n                                # Returns n if no sequence found.
}

Kullanımı:

->n{([*1..n].permutation(2).map{|i,j|[*i..j]if(i..j).reduce(:+)==n}-[p]).max_by{|k|k.size}||n}[25]
=> [3, 4, 5, 6, 7]

0

Cidden, 53 - 5 = 48 bayt

,;;;╝`;u@n╟(D;)`n(XXk`iu@u@x;Σ╛=[])Ii`╗`ñ╜M`M;░p@X'+j

Hex Dump

2c3b3b3bbc603b75406ec728443b29606e2858586b60697540754
0783be4be3d5b5d29496960bb60a4bd4d604d3bb0704058272b6a

Çevrimiçi Deneyin!

Dennis'in Pyth'una benzeyen kaba kuvvet yaklaşımı.

kSadece her şey sadece nregister 1 içine girişi okur ve daha sonra 's' ye [[1],[2,2],[3,3,3],[4,4,4,4],...]kadar olan listeyi oluşturur n n.

Bir sonraki bit , kayıt 0'da depolanan, bir çifti alan, her iki öğeyi de arttıran, onları bir aralığa dönüştüren, aralığın toplamını bulan ve bu toplamın kayıt 1'deki değer olup olmadığını kontrol eden bir işlevdir. karşılık gelen aralığı döndürür ve değilse, boş bir liste döndürür.

En son ortaya çıkma aşamasına kadar olan bölüm Myukarıda açıklanan listelerin fantezi listesi üzerinde bir işlevi haritalandırır enumerate, her bir listede yer alır ve ardından saklanan işlevi bunun üzerinde eşler . Tamamlandığında, her biri boş ya da toplanacak bir dizi listeye sahibiz n.

;░boş listeleri siler. p@Xkalan ilk listeyi alır ( 0@Eayrıca işe yarar). '+jkoyar +o ödül için bir dizeye listesini dönüştürür olarak her sayısı arasında.


0

ES6, 72 bayt

n=>{for(l=u=1;n;)n>0?n-=u++:n+=l++;return[...Array(u).keys()].slice(l);}

@ Cabbie407'nin awk çözümünün doğrudan limanı, ancak biçimlendirme bonusu olmadan, buradaki bir ceza.


0

Python 3, 239 236 215 203 bayt

Bu biraz hantal. Daha sonra golf oynamak zorunda kalacağım.

def x(n):
 r=[n]
 for i in range(2,n):
  t=[]
  if i%2*(n%i<1):t=[j+n//i-i//2for j in range(i)]
  elif i%2<1and n%i==i//2:t=[j+n//i-i//2+1for j in range(i)]
  if t[:1]>[0]*(sum(t)==n):r+=t,
 return r[-1]

kEğer kontrol çünkü t[0]boş üzerinde t, Python size kaba gürültü yapar. Yine, bu golf ihtiyacı var. Teşekkürler t[:1], artık kaba sesler yok! Sadece başka bir diziye karşı kontrol etmeniz gerekir.


0

Jöle , 8 bayt (yarışmaz)

ẆS⁼¥Ðf⁸Ṫ

Çevrimiçi deneyin!

Doğru anlarsam, bu (11-5 = 6) baytlık bir sürüm olabilir:

ẆS⁼¥Ðf⁸Ṫj”+

İlginin uğruna, vectorizing eşdeğerleri için vectorizing eşdeğerlerini değiştirerek, sol argümanını birinci argümanla veya kimliğe değiştirerek ve denk olmayan ve sınama için eşdeğerlerini değiştirerek 12 benzer çözüm vardır. hem vektör hem de vektör olmayanlar için filtreleme. : O
HyperNeutrino

Diyelim ki en mantıklı olanı, ancak hız optimizasyonunu yayınladım.
Outgolfer Erik

0

05AB1E , 11 - 5 = 6 bayt (rekabet etmeyen)

Tabii bu bonusu alarak :)

LŒʒOQ}é¤'+ý

Çevrimiçi deneyin!

LŒʒOQ}é¤'+ý  Argument: n
LŒ           Sublists of range 1 to n
  ʒOQ}       Filter by total sum equals n
      é¤     Get longest element
        '+ý  Join on '+'

0

PHP, 70 bayt

while(fmod($q=sqrt(2*$argn+(++$p-.5)**2)-.5,1));print_r(range($p,$q));

Pipe ile çalıştırın -nRveya çevrimiçi deneyin .

artışlarla pbunun için bir tamsayı çözeltisi bulana kadar argument==(p+q)*(q-p+1)/2,
daha sonra gelen bir dizi basar piçin q.


0

Excel VBA, 119 - 5 = 114 Bayt

SubnBeklenen tip tamsayıların girişini alan ve hücreye toplayan ardışık sayıların en uzun dizisini veren rutin[A1]

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