ผลรวมของจำนวนเต็มต่อเนื่อง


27

ก่อนที่ทุกคนพูดว่าอะไรที่คล้ายกันและคล้ายกัน แต่นี่ไม่ใช่การล่อลวง


จำนวนเต็มบวกบางตัวสามารถเขียนเป็นผลรวมของจำนวนเต็มบวกอย่างน้อยสองตัวติดต่อกัน ตัวอย่างเช่น9=2+3+4=4+5. เขียนฟังก์ชั่นที่ใช้เป็นจำนวนเต็มบวกเป็น input และภาพพิมพ์ที่เป็นผลผลิตของตนที่ยาวที่สุดลำดับการเพิ่มขึ้นของจำนวนเต็มบวกติดต่อกันว่าผลรวมไป (รูปแบบใด ๆ ที่เป็นที่ยอมรับได้แม้ว่า -5 ไบต์ถ้าการส่งออกเป็นลำดับที่เพิ่มขึ้นแยกจากกันโดย+ที่แสดงข้างต้น หากไม่มีลำดับดังกล่าวหมายเลขนั้นควรถูกพิมพ์

นี่คือรหัสกอล์ฟ ใช้กฎมาตรฐาน รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


ตัวอย่าง (โปรดทราบว่าการจัดรูปแบบแตกต่างกันไป)

Input:   9
Output:  2,3,4

Input:   8
Output:  8

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

2
ตัวเลขที่ส่งออกจะต้องอยู่ในลำดับที่เฉพาะเจาะจง (เช่นเพิ่มขึ้น)?
xnor

2
ทำตัวเลขต้องเป็น> 0: 6 = 0 + 1 + 2 + 3 หรือ 6 = 1 + 2 + 3
ดาเมียน

5
ในฐานะที่เป็นบันทึกด้านข้างหากมีความท้าทายที่เกี่ยวข้องอย่างใกล้ชิดการพูดว่า "นี่ไม่ใช่ผู้ล่อลวง" จะทำให้เชื่อใจผู้คนเล็กน้อยว่าหากพวกเขาคิดว่ามันเป็นผู้ล่อลวง มันจะมีประโยชน์มากขึ้นถ้าคุณอธิบายว่าทำไมคุณถึงคิดว่ามันไม่ใช่
Martin Ender

1
@ Damien "positive" ตามปกติหมายถึง> 0 หากมีการรวม 0 มันจะถูกเรียกว่า "ไม่ใช่ลบ"
Martin Ender

3
cc @Vixen ^ (เช่นกันหากอนุญาตให้ใช้จำนวนลบได้ทางออกที่ดีที่สุดจะอยู่ในช่วงตั้งแต่-n+1ถึงn)
Martin Ender

คำตอบ:


11

Python ขนาด 67 ไบต์

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

กลยุทธ์ที่ตรงไปตรงมาอย่างผิดปกติ: ค้นหาช่วงเวลา R ด้วยผลรวมที่ถูกต้อง

  • หากผลรวมมีขนาดเล็กเกินไปให้เลื่อนจุดปลายด้านขวาของช่วงเวลาขึ้นหนึ่งจุดด้วยการต่อท้ายจำนวนสูงสุดถัดไป
  • หากผลรวมมีขนาดใหญ่เกินไปให้เลื่อนจุดปลายด้านซ้ายขึ้นโดยการลบองค์ประกอบที่เล็กที่สุด
  • ถ้าผลรวมถูกต้องเอาต์พุต R

เนื่องจากจุดสิ้นสุดด้านล่างของช่วงเวลาเพิ่มขึ้นเท่านั้นจึงพบช่วงเวลาที่ยาวนานกว่าก่อนช่วงเวลาที่สั้น


มีประสิทธิภาพที่ผิดปกติเช่นกัน กองการเรียกซ้ำในที่สุดก็ล้นเช่น n = 8192
primo

7

Pyth, 12 10 ไบต์

j\+hfqsTQ}M^SQ2

รหัสมีความยาว15 ไบต์และมีคุณสมบัติเหมาะสมสำหรับ-5 ไบต์โบนัสลองใช้ออนไลน์ในPyth คอมไพเลอร์

ขอบคุณ @Jakube สำหรับการตีกอล์ฟ 2 ไบต์!

มันทำงานอย่างไร

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 คุณช่วยอธิบายเพิ่มเติมหน่อยได้ไหม? :)
ETHproductions

ฉันแก้ไขคำตอบของฉันแล้ว
Dennis

เยี่ยมมากขอบคุณ! ฉันชอบเทคนิคของคุณ
ETHproductions

1
ป้อน 1,000: 30 นาทีและนับ ...
primo

3

Mathematica, 73 68 65 56 43 ไบต์

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

1
+1 ฉันสิ้นสุดด้วยโซลูชันที่คล้ายกันเมื่อคืน แต่อินเทอร์เน็ตของฉันลง นอกจากนี้คุณสามารถสร้างTuplesนิพจน์มัดได้
LegionMammal978


2

MATLAB, 87 79 ไบต์

ฉันรู้ว่ามีคำตอบ MATLAB อยู่แล้ว แต่คำตอบนี้แตกต่างอย่างมากในแนวทาง

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)

ยังสามารถใช้งานได้ในระดับแปดเสียง คุณสามารถลองออนไลน์ได้ที่นี่ ฉันได้เพิ่มรหัสไปยังconsecutiveSum.mในพื้นที่ทำงานที่เชื่อมโยงดังนั้นเพียงป้อนconsecutiveSumที่พร้อมท์คำสั่งแล้วป้อนค่า (เช่น 25)

ฉันยังคงทำงานเกี่ยวกับการลดลง (อาจจะปรับสมการที่ใช้บิต) แต่โดยทั่วไปจะพบว่าค่าที่มากที่สุดnที่mเป็นจำนวนเต็มแล้วแสดงคนแรกที่ตัวเลขเริ่มต้นด้วยmn

เหตุใดจึงใช้งานได้ โดยพื้นฐานแล้วมีสมการทางคณิตศาสตร์ที่ควบคุมจำนวนทั้งหมดเหล่านั้น หากคุณพิจารณาว่าพวกเขาอยู่ติดกันและเริ่มจากจุดหนึ่งคุณสามารถพูดได้ว่า:

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

ขณะนี้จากนี้มันจะกลายเป็นที่ชัดเจนว่าลำดับเป็นเพียงครั้งแรกที่pตัวเลขสามเหลี่ยม (รวม 0'th) ที่เพิ่มจำนวนมากp+1 nตอนนี้ถ้าเราปล่อยm=p+1เราสามารถพูดได้:

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

นี่เป็นวิธีแก้ปัญหาได้ค่อนข้างจริง ฉันยังคงมองหารหัสที่สั้นที่สุดในการทำฉันมีความคิดที่จะลองและลดรหัสข้างต้น


สำหรับอินพุต 25 เอาต์พุตจะเป็น:

3     4     5     6     7

2
สำหรับประเด็นที่เกี่ยวกับตัวเลขสามเหลี่ยมความท้าทายนี้ก็คือการพยายามหาตัวเลขสามเหลี่ยมที่มีความแตกต่างในเชิงบวกของอินพุตเช่นว่าดัชนีของตัวเลขสามเหลี่ยมในลำดับ1,3,6,10,...นั้นจะถูกขยายให้ใหญ่สุด
Arcturus

1

Python 2, 94 ไบต์

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

อินพุตถูกนำมาจาก stdin โซลูชันนี้เหมาะสำหรับอินพุตที่มีขนาดใหญ่มาก

สิ่งนี้วนซ้ำตามความยาวของโซลูชันที่เป็นไปได้r , มีr ≤√ (2n)และตรวจสอบวิธีแก้ไขอย่างชัดเจน ในการสั่งซื้อสำหรับการแก้ปัญหาที่มีอยู่ถ้าRเป็นเลขคี่, n R modต้องเป็นศูนย์และถ้าRคือแม้n R modต้องR / 2


ตัวอย่างการใช้งาน

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

ฉันเลือกตัวอย่างด้วยเจตนาที่ค่อนข้างเล็ก


1

อ็อกเทฟ 89 ไบต์

นี่คือสิ่งที่ดีที่สุดที่ฉันสามารถทำได้ในอ็อกเทฟ อัลกอริทึมเหมือนกับ xnor's

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 จะเป็น 95 ไบต์:

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 วิ่งในประมาณ 0.1 วินาทีสำหรับการป้อนข้อมูล2000000และ 1 1000002วินาทีสำหรับการป้อนข้อมูล


1

awk, 51 ไบต์

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

รหัสคือ 56 ไบต์ลบ 5 ไบต์สำหรับรูปแบบผลลัพธ์ ฉันต้องใช้ 4 ไบต์พิเศษเพื่อสร้างรูปแบบนั้นดังนั้นฉันบันทึกจริง 1 ไบต์ ไชโย! ;)

อันที่จริงแล้วการทำงานอย่างหนักของการสรุปเริ่มจาก 1 จนกระทั่งผลรวมนั้นใหญ่กว่าอินพุต จากนั้นมันจะเริ่มแทนที่ตัวเลขเริ่มต้นจาก 1 จนกระทั่งตัวเลขมีขนาดเล็กกว่าอินพุต มันจะเปลี่ยนหมายเลขเริ่มต้นและสิ้นสุดด้วยวิธีนี้จนกว่าจะพบผลลัพธ์ซึ่งจะพิมพ์ออกมา

ตัวอย่างการใช้งาน

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

ตัวอย่างผลลัพธ์

48 + 49 + 50 + 51 + 52 + 53

ฉันได้ลองทำสิ่งนี้เพื่อรับข้อมูล1e12แล้วและให้ผลลัพธ์ที่ถูกต้อง ( 464562+...+1488562) เกือบจะในทันที แม้ว่ามันจะใช้เวลาสักพักในการพิมพ์แน่นอน ...


รักวิธีการ Awk ฉันมีปัญหาในการทำงานตามลำดับความสำคัญในการผูก คุณจะช่วยกรุณารวมรุ่นที่มีวงเล็บเพิ่มเข้ามาเพื่อให้ชัดเจนมากขึ้น? :)
สัญลักษณ์แทน

1
หวังว่านี่จะช่วยได้: {while($0!=s)s+=(s<$0) ? (++j) : -(++i); while(++i<j)r=r i"+"}$0=r j ฉันเป็นจำนวนเต็มที่สุดท้ายที่ลบออกจากจุดเริ่มต้นของโซ่เสมอjเป็นจำนวนเต็มสุดท้ายที่เพิ่มที่ท้ายของโซ่เสมอ
เสมอ

0

Japt , 33 ไบต์

วิธีนี้ใช้เทคนิค Pyth ของเดนนิสถึงแม้ว่ามันจะนานกว่าก็ตาม ...

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

ลองออนไลน์! คำเตือน:สำหรับอินพุตที่มีขนาดใหญ่กว่า (<= 20) จะใช้เวลาสักครู่จึงจะเสร็จสิ้นและหยุดเบราว์เซอร์ของคุณจนกว่าจะเสร็จ

Ungolfed และคำอธิบาย

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

รุ่นที่รับโบนัส: (38 ไบต์ - 5 = 33)

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

0

Julia, 92 ไบต์

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

นี่คือฟังก์ชั่นที่ไม่ระบุชื่อที่ยอมรับจำนวนเต็มและส่งกลับอาร์เรย์ 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 ไบต์

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

การใช้งาน:

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

อย่างจริงจัง 53 - 5 = 48 ไบต์

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

ฐานสิบหก

2c3b3b3bbc603b75406ec728443b29606e2858586b60697540754
0783be4be3d5b5d29496960bb60a4bd4d604d3bb0704058272b6a

ลองออนไลน์!

มันเป็นวิธีการที่ดุร้ายคล้ายกับเดนนิสพีท

ทุกอย่างจนถึงkเพียงแค่อ่านอินพุตnลงทะเบียน 1 จากนั้นสร้างรายการ[[1],[2,2],[3,3,3],[4,4,4,4],...]ขึ้นn n 's

บิตถัดไปขึ้นไป เป็นฟังก์ชันที่เก็บไว้ใน register 0 ที่จับคู่เพิ่มทั้งสององค์ประกอบแปลงเป็นช่วงค้นหาผลรวมของช่วงและตรวจสอบว่าผลรวมนั้นเป็นค่าใน register 1 หรือไม่ถ้าเป็น มันจะส่งกลับช่วงที่สอดคล้องกันและถ้าไม่มันก็จะส่งกลับรายการที่ว่างเปล่า

ส่วนจนถึงการเกิดขึ้นครั้งสุดท้ายของMแผนที่ฟังก์ชั่นมากกว่ารายการแฟนซีของรายการที่อธิบายไว้ข้างต้นทำenumerateในแต่ละรายการจากนั้นทำแผนที่ฟังก์ชั่นที่เก็บไว้เหนือมัน เมื่อเสร็จแล้วเราจะมีรายการของแต่ละรายการที่ว่างหรือช่วงที่ผลรวมnเมื่อได้มีการทำเรามีรายชื่อของรายการแต่ละแห่งซึ่งเป็นที่ว่างเปล่าหรือช่วงที่จำนวนเงินที่จะ

;░ลบรายการที่ว่างเปล่า p@Xใช้รายการแรกที่ยังคงอยู่ ( 0@Eจะใช้งานได้) '+jใส่+ระหว่างแต่ละหมายเลขในขณะที่มันแปลงรายการเป็นสตริงสำหรับโบนัส


0

ES6, 72 ไบต์

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

ตรงพอร์ตของโซลูชั่น awk ของ @ Cabbie407 แต่ไม่มีโบนัสการจัดรูปแบบเนื่องจากเป็นบทลงโทษที่นี่


0

Python 3, 239 236 215 203 ไบต์

นี่เป็นเรื่องยุ่งยากเล็กน้อย ฉันจะตีกอล์ฟให้ทีหลัง

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]

kเป็นเพราะถ้าคุณตรวจสอบt[0]ในที่ว่างเปล่าt, Python ทำให้เสียงที่หยาบคายคุณ นี่เป็นความต้องการของการเล่นกอล์ฟอีกครั้ง ขอบคุณที่t[:1]ไม่มีเสียงหยาบคายอีกต่อไป! คุณเพียงแค่ต้องตรวจสอบกับอาร์เรย์อื่น


0

เยลลี่ , 8 ไบต์ (ไม่แข่งขัน)

ẆS⁼¥Ðf⁸Ṫ

ลองออนไลน์!

ถ้าฉันเข้าใจถูกต้องอาจเป็นรุ่น (11-5 = 6) --byte:

ẆS⁼¥Ðf⁸Ṫj”+

เพื่อประโยชน์ของมี 12 โซลูชั่นที่คล้ายกัน (รวมถึงนี้) โดยการแลกเปลี่ยนที่ไม่ใช่เวกเตอร์เท่ากับสำหรับ vectorizing เท่ากับการเปลี่ยนอาร์กิวเมนต์ซ้ายเป็นอาร์กิวเมนต์แรกหรือเพื่อตัวตนและการแลกเปลี่ยนเท่ากับกับไม่เท่ากับและตัวกรองใน กรองออกสำหรับทั้ง vectorizing และ non-vectorizing : O
HyperNeutrino

สมมติว่าฉันโพสต์สิ่งที่เหมาะสมที่สุด แต่ด้วยการเพิ่มประสิทธิภาพความเร็ว
Erik the Outgolfer


0

PHP, 70 ไบต์

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

เรียกใช้เป็นไพพ์ด้วย-nRหรือลองออนไลน์ลองออนไลน์

เพิ่มขึ้นpจนกว่าจะพบวิธีการแก้ปัญหาสำหรับจำนวนเต็มargument==(p+q)*(q-p+1)/2,
แล้วพิมพ์ช่วงจากไปpq


0

Excel VBA, 119 - 5 = 114 ไบต์

Subรูทีนที่รับอินพุตnจำนวนเต็มชนิดที่คาดหวังและเอาต์พุตลำดับที่ยาวที่สุดของตัวเลขที่ต่อเนื่องกันซึ่งรวมเข้ากับเซลล์[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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.