ผลรวมของจำนวนเต็มทั้งหมดตั้งแต่ 1 ถึง n


63

ฉันประหลาดใจอย่างแท้จริงว่าสิ่งนี้ยังไม่เสร็จ หากคุณสามารถค้นหากระทู้ที่มีอยู่โดยทั้งหมดทำเครื่องหมายสิ่งนี้ว่าซ้ำหรือแจ้งให้เราทราบ

อินพุต

ข้อมูลของคุณอยู่ในรูปแบบของจำนวนเต็มบวกใด ๆ ที่มากกว่าหรือเท่ากับ 1

เอาท์พุต

คุณต้องส่งออกผลรวมของจำนวนเต็มทั้งหมดระหว่างและรวมถึง 1 และการป้อนตัวเลข

ตัวอย่าง

 In: 5
     1+2+3+4+5 = 15
Out: 15

OEIS A000217 - หมายเลขสามเหลี่ยม: a (n) = binomial (n + 1,2) = n (n + 1) / 2 = 0 + 1 + 2 + ... + n

ลีดเดอร์บอร์ด

เรียกใช้ข้อมูลโค้ดด้านล่างเพื่อดูกระดานแต้มนำสำหรับคำตอบของคำถามนี้ (ขอบคุณ programmer5000 และ steenbergh สำหรับการแนะนำสิ่งนี้และ Martin Ender สำหรับการสร้าง)



@FryAmTheEggman ขออภัย - มีสมองผายลมเล็กน้อย ฉันเห็นสิ่งที่คุณหมายถึง
GarethPW

2
@Aaron คุณได้ ninja'd โดยแกลบซึ่งเพิ่งโพสต์ด้วยวิธีที่ 1 ไบต์
Skidsdev

7
ฉันแนะนำตัวอย่างสแต็ก
programmer5000

1
ที่เกี่ยวข้อง: minecraftforum.net/forums/off-topic/ …
Jerry Jeremiah

คำตอบ:


46

Pyth , 2 ไบต์

sS

ลองออนไลน์! อินพุตโดยนัย Sคือช่วงที่มีการจัดทำดัชนี 1 และsเป็นผลรวม


102
ในที่สุดรหัส Pyth (บน) ดูเหมือนงู
มนุษย์โดยรวม

2
นี่เป็นความท้าทายที่สมบูรณ์แบบสำหรับ Pyth ...
Mr. Xcoder

ฉันจะตอบคำถามนี้ แต่ฉันเดาไม่ได้
Stan Strum

32

เปลือกหอย 1 ไบต์

Σ

ลองออนไลน์!

Builtin! Σในแกลบมักจะถูกนำมาใช้เพื่อให้ได้ผลรวมขององค์ประกอบทั้งหมดของรายการ n*(n+1)/2แต่เมื่อนำไปใช้เป็นจำนวนมากก็จะส่งกลับว่า


1
สิ่งนี้เกิดขึ้นเพราะจำนวนนั้นถูกส่งไปยังช่วงและรวมแล้วหรือนี่คือฮาร์ดโค้ดจริงหรือ
FryAmTheEggman

4
@FryAmTheEggman นี่คือฮาร์ดโค้ดและคล้ายกับพฤติกรรมของบิวด์อินอีกตัวหนึ่งซึ่งสามารถคำนวณผลคูณขององค์ประกอบทั้งหมดของรายการหรือแฟคทอเรียลของหมายเลขเดียว
Leo

4
Σเป็นอักขระ Unicode สองไบต์บนเครื่องของฉัน ฉันเดาว่าคุณใช้รหัสหน้า 1253? msdn.microsoft.com/en-us/library/cc195055.aspx
gmatht


21

Piet , 161 bytes / 16 codels

คุณสามารถแปลด้วยนี้ล่าม Piet หรืออัพโหลดภาพบนนี้เว็บไซต์และทำงานที่นั่น ไม่แน่ใจเกี่ยวกับจำนวนไบต์ถ้าฉันสามารถเข้ารหัสได้แตกต่างกันเพื่อลดขนาด

ปรับขนาดภาพอิมเมจต้นฉบับขึ้น:

rapapaing ภาพ

คำอธิบาย

highlightedข้อความแสดงกองปัจจุบัน (เพิ่มขึ้นจากซ้ายไปขวา) สมมติว่าผู้ใช้ป้อนคือ5:

การเปลี่ยนแปลงครั้งที่ 1 ใส่ตัวเลขและกดลงบนสแต็ก

5

การเปลี่ยนแปลงครั้งที่ 2 ทำซ้ำหมายเลขนี้บนสแต็ก

5 5

ช่วงการเปลี่ยนภาพที่ 3 กด 1 (ขนาดของพื้นที่สีแดงเข้ม) ลงบนสแต็ก

5 5 1

การเปลี่ยนครั้งที่ 4 เพิ่มตัวเลขสองอันดับแรก

5 6

การเปลี่ยนแปลงครั้งที่ 5 ทวีคูณตัวเลขสองอันดับแรก

30

การเปลี่ยนแปลงครั้งที่ 6 พื้นที่สีดำทำให้แน่ใจว่าเคอร์เซอร์เลื่อนไปทางขวาไปยัง codel สีเขียวอ่อน ช่วงการเปลี่ยนภาพนั้นจะผลัก 2 (ขนาดของสีเขียวเข้ม) ไปยังสแต็ก

30 2

ช่วงการเปลี่ยนภาพที่ 7 หารตัวเลขที่สองบนสแต็กด้วยตัวเลขแรก

15

การเปลี่ยนแปลงครั้งที่ 8 ป๊อปและเอาท์พุทหมายเลขสูงสุด (ตีความว่าเป็นตัวเลข)

[empty]

กับดักสุดท้าย ด้วยการแทรกพื้นที่สีขาวการเปลี่ยนแปลงคือ a nopสีดำจะวางกับเคอร์เซอร์ของเรา นี่เป็นการสิ้นสุดการทำงานของโปรแกรม

ไฟล์ต้นฉบับ (เล็กเกินไปสำหรับที่นี่): รูปภาพต้นฉบับดั้งเดิม


เราเปลี่ยนจากข้อความที่เข้าใจได้ (เช่น C) เป็นข้อความที่ไม่สามารถเข้าใจได้ (เช่น Jelly) เป็นรูปภาพ ... จะทำอะไรต่อไป : P
frarugi87

+1 ฉันไม่เคยเห็นคำตอบ Piet จริง ๆ มาก่อน
MilkyWay90

21

Brain-Flakขนาด 16 ไบต์

({({}[()])()}{})

ลองออนไลน์!

นี่เป็นหนึ่งในสองสามสิ่งที่ทำให้สมองสะบัดดีจริงๆ

เนื่องจากนี่เป็นหนึ่งในสิ่งที่ง่ายที่สุดที่คุณสามารถทำได้ในสมองและมีการมองเห็นได้มากมายต่อไปนี้เป็นคำอธิบายโดยละเอียด :

# Push the sum of all of this code. In brain-flak, every snippet also returns a
# value, and all values inside the same brackets are summed
(
    # Loop and accumulate. Initially, this snippet return 0, but each time the
    # loop runs, the value of the code inside the loop is added to the result.
    {
        # Push (and also return)...
        (
            # The value on top of the stack
            {}

            # Plus the negative of...
            [
                # 1
                ()
            ]

        # The previous code pushes n-1 on to the stack and returns the value n-1
        )

        # 1
        # This code has no side effect, it just returns the value 1 each loop.
        # This effectively adds 1 to the accumulator
        ()

    # The loop will end once the value on top of the stack is 0
    }

    # Pop the zero off, which will also add 0 to the current value
    {}

# After the sum is pushed, the entire stack (which only contains the sum)
# will be implicitly printed.
)


18

Mathematica ขนาด 9 ไบต์

#(#+1)/2&

Mathematica ขนาด 10 ไบต์

(#^2+#)/2&

Mathematica ขนาด 11 ไบต์

Tr@Range@#&

Mathematica ขนาด 12 ไบต์

i~Sum~{i,#}&

Mathematica ขนาด 14 ไบต์

(โดย @ user71546)

1/2/Beta[#,2]&

Mathematica ขนาด 15 ไบต์

Tr[#&~Array~#]&

Mathematica ขนาด 16 ไบต์

Binomial[#+1,2]&

Mathematica ขนาด 17 ไบต์

(โดย @ ไม่ต้นไม้)

⌊(2#+1)^2/8⌋&

Mathematica ขนาด 18 ไบต์

PolygonalNumber@#&

Mathematica, 19 ไบต์

#+#2&~Fold~Range@#&

Mathematica ขนาด 20 ไบต์

(โดย @ ไม่ต้นไม้)

f@0=0;f@i_:=i+f[i-1]

4
ดูเหมือนจะเป็นเรื่องน่าละอายที่จะข้าม 13, 14 และ 17 ...
ไม่ใช่ต้นไม้

3
ดูเหมือนจะเป็นความท้าทายครั้งต่อไป .... หรืออย่างน้อยก็ช่วยฉันทำรายการให้เสร็จ
J42161217

2
ผมก็ยังไม่ได้มีอะไรที่ 13 หรือ 14 ไบต์ (นอกเหนือจากเพียงแค่ยกเลิกการเล่นกอล์ฟตอบสั้นของคุณ) แต่ที่นี่เป็นอีก 26 มีขนาดใหญ่ไบต์นับ
ไม่ใช่ต้นไม้

1
@MarkS ใน 10.4 ใช้งานได้ดี
J42161217

1
@Notatree สำหรับรายการของคุณนี่คือผู้สมัครที่ 35: Array[Boole[#2>=#]& ,{#,#}]~Total~2&
Mark S.


11

x86_64 ภาษาเครื่อง (Linux), 9 8 ไบต์

0:   8d 47 01                lea    0x1(%rdi),%eax
3:   f7 ef                   imul   %edi
5:   d1 e8                   shr    %eax
7:   c3                      retq 

เพื่อลองออนไลน์! รวบรวมและเรียกใช้โปรแกรม C ต่อไปนี้

#include<stdio.h>
const char f[]="\x8d\x47\x01\xf7\xef\xd1\xe8\xc3";
int main(){
  for( int i = 1; i<=10; i++ ) {
    printf( "%d %d\n", i, ((int(*)())f)(i) );
  }
}

ขอขอบคุณที่@CodyGrayและ@ Peterสำหรับ -1


1
คุณควรใช้shrแทนsarเพื่อรักษาผลงานของคุณเป็นไม่ได้ลงนาม (ไม่มีการเปลี่ยนแปลงขนาดรหัส) (เห็นโดย @CodyGray และชี้ให้เห็นใน7 ไบต์add+ loopคำตอบของเขา )
Peter Cordes

1
สิ่งนี้ดูดีที่สุดสำหรับประสิทธิภาพในการใช้งานสูตรปิดรูปแบบ แต่คุณสามารถบันทึกไบต์โดยใช้รูปแบบหนึ่งตัวถูกดำเนินการของmul %ediหรือimul %edi(แต่ละ 2B) แทนรูปแบบสองตัวถูกดำเนินการ 3B มันอุดตัน EDX ด้วยผลการแข่งขันสูง แต่ก็ไม่เป็นไร Multi-operand imulได้รับการแนะนำในภายหลังกว่ารูปแบบหนึ่งตัวถูกดำเนินการและมี opcode ขนาด 2 ไบต์พร้อมด้วย0FEscape byte ตัวเลือกใดตัวเลือกหนึ่งในสามตัวนั้นจะให้ผลลัพธ์ที่เหมือนกันเสมอeaxมันเป็นเพียงครึ่งที่สูงซึ่งขึ้นอยู่กับการเซ็นชื่อกับผู้ที่ไม่ได้ลงชื่อ
Peter Cordes




10

คู่ , 22 19 ไบต์

เนื่องจากการดำเนินการทางคณิตศาสตร์น่าเบื่อ ...

@(n)nnz(triu(e(n)))

ลองออนไลน์!

คำอธิบาย

รับnนี้จะสร้างเมทริกซ์n× nกับรายการทั้งหมดเท่ากับจำนวนe ; ทำรายการด้านล่างศูนย์แนวทแยง และส่งออกจำนวนของค่าที่ไม่ใช่ศูนย์


อันนี้จริงแล้วสั้นกว่ารุ่นที่เป็นตัวเลขหรือไม่?
แยกผลไม้

@ Challenger5 ไม่ แต่รุ่นตัวเลขน่าเบื่อ:@(n)sum(1:n)
Luis Mendo


8

เยลลี่ 2 ไบต์

RS

ลองออนไลน์!

คำอธิบาย

RS

    implicit input
 S  sum of the...
R   inclusive range [1..input]
    implicit output

เกาส์ผลรวม 3 ไบต์

‘×H

คำอธิบาย

‘×H

     implicit input
  H  half of the quantity of...
‘    input + 1...
 ×   times input
     implicit output

สิ่งนี้สามารถใช้งานได้ใน Anyfix: P (ไม่ใช่ TIO)
HyperNeutrino

8

APL, 3 ไบต์

+/⍳

ลองออนไลน์!

+/- ผลรวม (ลด+) - ช่วง


ขึ้นอยู่กับการจัดทำดัชนี หากการจัดทำดัชนีถูกตั้งค่าเป็น 0 คุณจะต้องเพิ่ม 2 ไบต์1+
เวอร์เนอร์

2
@ การจัดทำดัชนีของ Werner เป็นค่าเริ่มต้น1ดังนั้นฉันจึงไม่ได้ระบุ ธรรมดาที่นี่เพื่อระบุเฉพาะเมื่อใช้⎕IO←0(และมันไม่ได้รวมอยู่ในจำนวนไบต์)
ยูเรียล

8

Haskellขนาด 13 ไบต์

นี่คือสั้นที่สุด (ฉันคิดว่า):

f n=sum[1..n]

ลองออนไลน์!

ตรง, 17 13 ไบต์

f n=n*(n+1)/2

ขอบคุณ @WheatWizard สำหรับ-4ไบต์!

ลองออนไลน์!

Pointfree โดยตรง 15 ไบต์

(*)=<<(/2).(+1)

ขอบคุณ @nimi สำหรับความคิด!

ลองออนไลน์!

Pointfree ผ่านsum16 ไบต์

sum.enumFromTo 1

ลองออนไลน์!

วนซ้ำ22 18 ไบต์

f 0=0;f n=n+f(n-1)

ขอบคุณ @maple_shaft สำหรับความคิด & @Laikoni สำหรับการเล่นกอล์ฟ!

ลองออนไลน์!

มาตรฐานfold, 19 ไบต์

f n=foldr(+)0[1..n]

ลองออนไลน์!


7

Starry , 27 22 ไบต์

บันทึก 5 ไบต์ด้วย@miles !

, + +  **       +   *.

ลองออนไลน์!

คำอธิบาย

,             Read number (n) from STDIN and push it to the stack
 +            Duplicate top of the stack
 +            Duplicate top of the stack
  *           Pop two numbers and push their product (n*n)
*             Pop two numbers and push their sum (n+n*n)
       +      Push 2
   *          Pop two numbers and push their division ((n+n*n)/2)
.             Pop a number and print it to STDOUT

22 ไบต์
ระยะทาง

@miles ขอบคุณ! ความคิดที่ดีมาก!
Luis Mendo

7

05AB1E , 2 ไบต์

LO

ลองออนไลน์!

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

     #input enters stack implicitly
L    #pop a, push list [1 .. a]
 O   #sum of the list
     #implicit output 

ผลรวมเกาส์, 4 ไบต์

>¹*;

ลองออนไลน์!

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

>       #input + 1
 ¹*     #get original input & multiply
   ;    #divide by two 

3
ÝOhelloยังทำงานและวิธีการ
Magic Octopus Urn

1
L0 และดู ..
dylnan

7

Java (OpenJDK 8) , 10 ไบต์

a->a++*a/2

ลองออนไลน์!

ใช้เวลาสักครู่เพื่อเล่นกอล์ฟจากn->n*(n+1)/2เพราะฉันช้า

แต่นี่ไม่ใช่คำตอบ Java จริง มันไม่แน่นอนเพียงพอ

import java.util.stream.*;
a->IntStream.range(1,a+1).sum()

ไม่เลว แต่เราทำได้ดีกว่า

import java.util.stream.*;
(Integer a)->Stream.iterate(1,(Integer b)->Math.incrementExact(b)).limit(a).reduce(0,Integer::sum)

ฉันรักชวา


1
หากคุณต้องการให้มันละเอียดยิ่งขึ้นทำไมต้องใช้แลมบ์ดา!? : P
TheLethalCoder

2
ฉันกำลังเล็งลูกแกะรายละเอียดฉันสามารถเขียนโปรแกรมเต็มรูปแบบได้ถ้าฉันต้องการพูดจาไพเราะเป็นพิเศษ: P
Xanderhall

1
มีการโพสต์วิธีแก้ปัญหาแบบเดียวกันนี้เรียบร้อยแล้ว
Winter

2
ฉันต้องพลาด แต่ในกรณีใด ๆ ฉันมักจะไม่ดูเนื้อหาของคำตอบอื่น ๆ ฉันชอบที่จะเขียนกอล์ฟของตัวเอง
Xanderhall

7

ตรวจสอบ 5 ไบต์

:)*$p

ตรวจสอบว่าไม่ใช่ภาษากอล์ฟ แต่มันก็เต้น CJam!

ลองออนไลน์!

คำอธิบาย:

หมายเลขอินพุตถูกวางไว้บนสแต็ก ซ้ำมันเพื่อให้: n, nมันจะเพิ่มขึ้นแล้วกับการให้) คูณทั้งสองเข้าด้วยกันแล้วหารผลลัพธ์ด้วย 2 พิมพ์ผลลัพธ์และโปรแกรมสิ้นสุดลงn, n+1*$p



6

แท็กซี่ 687 ไบต์

Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:s 1 l 1 r.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 1 l 2 r.[a]Pickup a passenger going to Addition Alley.Pickup a passenger going to The Underground.Go to Zoom Zoom:n.Go to Addition Alley:w 1 l 1 r.Pickup a passenger going to Addition Alley.Go to The Underground:n 1 r 1 r.Switch to plan "z" if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:n 3 l 2 l.Switch to plan "a".[z]Go to Addition Alley:n 3 l 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:n 1 r 1 r.Pickup a passenger going to Post Office.Go to Post Office:n 1 l 1 r.

ลองออนไลน์!

เลิกเล่นกอล์ฟด้วยความคิดเห็น:

[ n = STDIN ]
Go to Post Office: west 1st left 1st right 1st left.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: south 1st left 1st right.
Pickup a passenger going to Cyclone.
Go to Cyclone: north 1st left 1st left 2nd right.

[ for (i=n;i>1;i--) { T+=i } ]
[a]
Pickup a passenger going to Addition Alley.
Pickup a passenger going to The Underground.
Go to Zoom Zoom: north.
Go to Addition Alley: west 1st left 1st right.
Pickup a passenger going to Addition Alley.
Go to The Underground: north 1st right 1st right.
Switch to plan "z" if no one is waiting.
Pickup a passenger going to Cyclone.
Go to Cyclone: north 3rd left 2nd left.
Switch to plan "a".

[ print(T) ]
[z]
Go to Addition Alley: north 3rd left 1st left.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: north 1st right 1st right.
Pickup a passenger going to Post Office.
Go to Post Office: north 1st left 1st right.

ไบต์น้อยกว่า 22.6% ในการวนซ้ำมากกว่าที่จะใช้ x*(x+1)/2



5

Brainfuck, 24 ไบต์

I / O ถูกจัดการเป็นไบต์

,[[->+>+<<]>[-<+>]<-]>>.

อธิบาย

,[[->+>+<<]>[-<+>]<-]>>.
,                           # Read a byte from STDIN
 [                  ]       # Main loop, counting down all values from n to 1
  [->+>+<<]                 # Copy the i value to *i+1 and *i+2
           >[-<+>]          # Move *i+1 back to i
                  <-        # Move back to i, lower it by one. Because *i+2 is never reset, each iteration adds the value of i to it.
                     >>.    # Output the value of *i+2

2
มันค่อนข้างเจ๋งที่ Brainfuck สามารถเอาชนะภาษาระดับสูงในการท้าทายนี้ได้
GarethPW

เป็นเรื่องถูกต้องหรือไม่ที่ฉันจะเพิ่มคำตอบใน Lenguage (เพื่อความสนุก) โดยใช้รหัสของคุณ? @ATaco
V. Courtois

ฉันไม่คิดอย่างนั้นเพราะมันจะเป็นรหัสเดียวกันเพียงแค่เข้ารหัสต่างกัน @ V.Courtois
ATaco

@ATaco Ahh คุณพูดถูก
V. Courtois


4

เรติน่า 13 ไบต์

.+
$*
1
$`1
1

ลองออนไลน์! คำอธิบาย: สเตจแรกและสเตจสุดท้ายเป็นเพียงการแปลงทศนิยมแบบนัวเนีย เวทีกลางแทนที่แต่ละ1ที่มีจำนวนของ1s ไปทางซ้ายบวกอีกมัน1สำหรับ1ตัวเองจึงนับจาก1การnสรุปค่าโดยปริยาย


4

> <> , 7 + 3 = 10 ไบต์

คำนวณn (n + 1) / 2
เพิ่ม 3 ไบต์สำหรับแฟล็ก -v

:1+2,*n

ลองออนไลน์!

หรือถ้าใส่สามารถนำมาเป็นรหัสตัวอักษร:

> <> , 9 ไบต์

i:1+2,*n;

ลองออนไลน์!


2
การใช้วิธีการทางคณิตศาสตร์อื่น ๆ ( (n^2+n)/2) ก็มีขนาด 7 ไบต์:::*+2,n
steenbergh


4

PHP, 19 ไบต์

<?=$argn*-~$argn/2;
<?=$argn/2*++$argn;
<?=$argn*++$argn/2; # this one fails

ใช้ builtins, 29 ไบต์:

<?=array_sum(range(1,$argn));

วน 31 ไบต์:

while($argn)$s+=$argn--;echo$s;

ฉันเดาด้วยเช่นกัน:for(;$argn;$s+=$argn--);echo$s;
Progrock

4

Cubix , 12 10 ไบต์

*,)2I://O@

รุ่นเริ่มต้น

....I:)*2,O@

ลองออนไลน์!

คำอธิบาย

โค้ดจะขยายออกเป็นลูกบาศก์

    * ,
    ) 2
I : / / O @ . .
. . . . . . . .
    . .
    . .

ตัวชี้คำสั่ง (IP) เริ่มต้นที่I, เคลื่อนไปทางทิศตะวันออก มันยังคงเคลื่อนที่ไปทางตะวันออกจนกว่าจะเจอ/กระจกซึ่งสะท้อนทิศเหนือ เมื่อ IP ไปถึงด้านบนของรหัสมันจะวนไป.ที่บรรทัดสุดท้ายในบรรทัดที่สามเคลื่อนไปทางใต้ จากนั้นมันจะพันตัวสุดท้าย.ในบรรทัดสุดท้ายเคลื่อนไปทางเหนือ จากนั้นมันก็มาถึง/กระจกอีกครั้งซึ่งสะท้อนให้เห็นมันอยู่ทางตะวันออกเฉพาะตอนถัดไปที่/จะสะท้อนทิศเหนืออีกครั้ง เวลานี้ IP จะตัดคำสุดท้าย.ในบรรทัดที่สามจากนั้นเป็น.บรรทัดสุดท้ายในบรรทัดสุดท้าย

คำแนะนำจะดำเนินการตามลำดับต่อไปนี้

I:)*2,O@ # Explanation
I        # Take input as an integer and push it to the stack
 :       # Duplicate the input
  )      # Increment one of the inputs
   *     # Multiply the input by input+1
    2    # Push 2 to the stack
     ,   # Integer devide the multiplication result by 2
      O  # Output the result
       @ # End program

4

x86-64 รหัสเครื่อง 7 ไบต์

31 C0
01 C8
E2 FC
C3  

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

มันถูกเขียนไปยังMicrosoft x64 การเรียกการประชุมซึ่งส่งผ่านพารามิเตอร์ในการECXลงทะเบียน ค่าส่งคืนจะถูกปล่อยไว้EAXเช่นเดียวกับการประชุมแบบเรียก x86 / x86-64 ทั้งหมด

คำย่อของชุดประกอบ Ungolfed:

       xor  eax, eax    ; zero out EAX
Next:  add  eax, ecx    ; add ECX to EAX
       loop Next        ; decrement ECX by 1, and loop as long as ECX != 0
       ret              ; return, with result in EAX

ลองออนไลน์!
(การเรียกฟังก์ชัน C นั้นมีหมายเหตุประกอบกับแอตทริบิวต์ที่ทำให้ GCC เรียกใช้โดยใช้หลักการเรียก Microsoft ที่รหัสแอสเซมบลีของฉันใช้ถ้า TIO ให้ MSVC สิ่งนี้ไม่จำเป็น)


ตามมาตรฐานที่ผิดปกติของรหัสกอล์ฟคุณจะเห็นว่าวิธีการวนซ้ำแบบนี้เหมาะสำหรับวิธีที่ใช้สูตรทางคณิตศาสตร์ที่มีสติมากขึ้น ( n(n+1) / 2) แม้ว่ามันจะมีประสิทธิภาพน้อยลงอย่างเห็นได้ชัดในแง่ของความเร็วในการวิ่ง

ด้วยการใช้ทฤษฎีจำนวนการติดตั้งของแมวป่ายังสามารถเอาชนะได้ทีละไบต์ คำแนะนำแต่ละคำเหล่านี้จำเป็น แต่มีการเข้ารหัสที่สั้นกว่าเล็กน้อยสำหรับการIMULใช้EAX โดยปริยายว่าเป็นตัวถูกดำเนินการปลายทาง (จริง ๆ แล้วมันใช้EDX:EAXแต่เราสามารถละเว้นผลลัพธ์ 32 บิตด้านบน) นี่เป็นเพียง 2 ไบต์ที่จะเข้ารหัสลดลงจาก 3

LEAใช้เวลาสามไบต์เช่นกัน แต่จริงๆแล้วไม่มีวิธีแก้ไขเพราะเราจำเป็นต้องเพิ่มขึ้นในขณะที่รักษาค่าเดิมไว้ ถ้าเราทำ a MOVเพื่อทำสำเนาINCเราก็จะอยู่ที่ 4 ไบต์ (ใน x86-32 ซึ่งINCมีเพียง 1 ไบต์เราจะอยู่ที่ 3 ไบต์เหมือนLEAกัน)

การเปลี่ยนแปลงครั้งสุดท้ายจำเป็นต้องแบ่งผลลัพธ์ออกเป็นครึ่งและแน่นอนว่ามีขนาดกะทัดรัด (และมีประสิทธิภาพมากขึ้น) กว่าการคูณ อย่างไรก็ตามรหัสควรใช้shrแทนsarเพราะมันสมมติว่าค่าอินพุตnเป็นจำนวนเต็มไม่ได้ลงนาม (ข้อสันนิษฐานนั้นถูกต้องตามกฎของหลักสูตร แต่ถ้าคุณรู้ว่าการป้อนข้อมูลนั้นไม่ได้ลงนามคุณไม่ควรทำการเปลี่ยนแปลงทางคณิตศาสตร์ที่ลงนามแล้วเนื่องจากบิตบนที่ถูกตั้งค่าที่ไม่ได้ลงนามขนาดใหญ่จะทำให้เกิดผลลัพธ์ จะไม่ถูกต้อง)

8D 41 01                lea    eax, [rcx+1]
F7 E9                   imul   ecx
D1 E8                   shr    eax, 1
C3                      ret

ตอนนี้เหลือเพียง8 ไบต์เท่านั้น(ต้องขอบคุณ Peter Cordes) ถึงกระนั้น 8> 7


1
อันที่จริงหนึ่งตัวถูกดำเนินการimul ecxหรือmul ecxจะทำงานและบันทึกไบต์ในการใช้งานแบบฟอร์มปิด ฉันไม่ได้เห็นมันทันที ฉันกำลังจะแสดงความคิดเห็นว่ามันเป็นสิ่งที่ดีที่สุดสำหรับทั้งประสิทธิภาพและขนาดรหัสก่อนที่จะตระหนักว่าeaxตัวถูกดำเนินการโดยนัยนั้นใช้ได้
Peter Cordes

ฉันสงสัยว่าถ้าadd+ loopจะสั้นกว่าimulขณะที่ดูคำตอบอื่น มีประโยชน์ว่าจะมีวิธีการเรียกมาตรฐานที่ผ่านการโต้แย้งครั้งแรกในecx
Peter Cordes

1
ว้าวฉันไม่อยากจะเชื่อเลยว่าฉันพลาดฟอร์มตัวเดียว! ตอนนี้ฉันควรรู้จริง ๆ แล้วว่าอย่าพูดในสิ่งที่เหมือน "ไม่สามารถเอาชนะ" ฉันจะเรียนเมื่อไหร่! ขอบคุณ @Peter
Cody Gray
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.