กระดานผู้นำ - รวบรวม JIT (ด้านล่างดีกว่า)
- es1024 - 81.2 คะแนน (รวมถึงคอมไพเลอร์ที่ใช้งานได้!)
- Kieth Randall - 116 คะแนน
- Ell - 121 คะแนน
กระดานผู้นำ - ตีความ (ด้านล่างดีกว่า)
- Martin Büttner - 706654 คะแนน (ประมาณ 2 ชั่วโมง)
- criptych - 30379 คะแนน (97 วินาที)
ภารกิจของคุณคุณควรเลือกที่จะยอมรับมันคือการเขียน bytecode interpreter / VM ที่เล็กที่สุดที่เป็นไปได้ VM / interpreter ใช้สถาปัตยกรรม CISC ขนาดเล็ก (การดำเนินการอาจแตกต่างกันในขนาด) ด้วยภาษาที่ระบุด้านล่าง เมื่อเสร็จสิ้นคุณจะต้องพิมพ์ค่าของ CPU 3 ตัวเพื่อลงทะเบียนเพื่อพิสูจน์ว่ามีการพิมพ์เอาต์พุตที่ถูกต้อง (3,126,900,366)
ผู้รวบรวม
หากคุณต้องการทำการทดสอบของคุณเองคอมไพเลอร์จะโพสต์ด้านล่าง อย่าลังเลที่จะโพสต์การทดสอบของคุณด้วยคำตอบของคุณ
ข้อมูลจำเพาะ "VM"
VM มีการลงทะเบียนหนึ่งตัวที่ไม่ได้ลงนาม 3 32 บิต: R0, R1, R2 พวกเขาจะแสดงในรูปแบบเลขฐานสิบหกเป็น 0x00, 0x01 และ 0x02
การดำเนินการต่อไปนี้ต้องได้รับการสนับสนุน:
รูปแบบคือ [ชื่อ] [... ตัวถูกดำเนินการ ... ], [รหัสเลขฐานสิบหก] [... ตัวถูกดำเนินการซ้ำ ... ]
- โหลด [ลงทะเบียน] [ค่า 4 ไบต์], 0x00 [ลงทะเบียน] [ค่า 4 ไบต์]
- ผลัก [ลงทะเบียน], 0x02 [ลงทะเบียน]
- POP [ลงทะเบียน], 0x03 [ลงทะเบียน]
- เพิ่ม [ลงทะเบียน 1 ไบต์] [ลงทะเบียน 1 ไบต์], 0x04 [ลงทะเบียน] [ลงทะเบียน]
- SUB [ลงทะเบียน 1 ไบต์] [ลงทะเบียน 1 ไบต์], 0x05 [ลงทะเบียน] [ลงทะเบียน]
- MUL [ลงทะเบียน 1 ไบต์] [ลงทะเบียน 1 ไบต์], 0x06 [ลงทะเบียน] [ลงทะเบียน]
- DIV [register, 1 byte] [register, 1 byte], 0x07 [register] [register]
- JMP [รหัสบรรทัด 4 ไบต์], 0x08 [หมายเลขบรรทัดรหัส 4 ไบต์]
- CMP [register, 1 byte] [register, 1 byte], 0x09 [register] [register]
- BRANCHLT [รหัสบรรทัด 4 ไบต์], 0x0a [หมายเลขบรรทัดรหัส 4 ไบต์]
หมายเหตุบางส่วน:
- การดำเนินการทางคณิตศาสตร์ข้างต้นเพิ่มค่าของการลงทะเบียน 2 ตัวพร้อมกันโดยวางผลลัพธ์ในการลงทะเบียนครั้งแรก
- CMP ตัวดำเนินการเปรียบเทียบควรเปรียบเทียบค่าของ 2 รีจิสเตอร์และเก็บเอาท์พุทในแฟลกภายในบางตัว
- หาก BRANCH ถูกเรียกใช้ก่อน CMP เว้นแต่ว่า BRANCHEQ จะถูกเรียกใช้ "VM" ไม่ควรแยกสาขา
- ผลักดัน / ป๊อปผลักดันหรือป๊อปตัวเลขจากสแต็คอย่างแปลกใจ
- ตัวดำเนินการกระโดดและสาขาข้ามไปที่การดำเนินการเฉพาะ (บรรทัดของรหัส) ไม่ใช่ที่อยู่ไบนารี
- การดำเนินการสาขาไม่ทำการเปรียบเทียบ ค่อนข้างพวกเขาจะเอาท์พุทจากการเปรียบเทียบล่าสุดเพื่อดำเนินการ
- ตัวดำเนินการสาขาและตัวกระโดดใช้ระบบการจัดทำดัชนีหมายเลขบรรทัดตามศูนย์ (เช่น JMP 0 กระโดดไปที่บรรทัดแรก)
- การดำเนินการทั้งหมดจะต้องดำเนินการกับตัวเลขที่ไม่ได้ลงนามซึ่งล้นเป็นศูนย์และไม่ส่งข้อยกเว้นในการล้นจำนวนเต็ม
- ไม่อนุญาตให้หารด้วยศูนย์และไม่อนุญาตให้กำหนดพฤติกรรมของโปรแกรม คุณสามารถ (ตัวอย่าง) ...
- ขัดข้องของโปรแกรม
- สิ้นสุดการดำเนินการของ VM และกลับสู่สถานะปัจจุบัน
- แสดงข้อความ "ERR: Division by 0"
- การสิ้นสุดของโปรแกรมถูกกำหนดเป็นเมื่อตัวชี้คำสั่งถึงจุดสิ้นสุดของโปรแกรม (สามารถสันนิษฐานว่าไม่ใช่โปรแกรมว่าง)
เอาท์พุทเอาท์พุ ทจะต้องตรงนี้ (รวมบรรทัดใหม่)
R0 3126900366
R1 0
R2 10000
คะแนน
สะสมคำนวณจากสูตรต่อไปนี้:Number Of Characters * (Seconds Needed To Run / 2)
เพื่อหลีกเลี่ยงความแตกต่างของฮาร์ดแวร์ที่ทำให้เกิดเวลาที่ต่างกันการทดสอบแต่ละครั้งจะถูกเรียกใช้บนคอมพิวเตอร์ของฉัน (i5-4210u, 8GB ram) ในเซิร์ฟเวอร์ ubuntu หรือ Windows 8 ดังนั้นอย่าพยายามใช้ runtime บ้าๆที่คอมไพล์ใน Dual G5 เท่านั้น Mac Pro ที่มี RAM ฟรี 762.66 mb
หากคุณใช้ runtime / ภาษาเฉพาะกรุณาโพสต์ลิงค์
- สำหรับผู้ที่สนใจฉันได้โพสต์รหัสทดสอบ (เขียนเป็นภาษา C #) ที่นี่: http://pastebin.com/WYCG5Uqu
โปรแกรมทดสอบ
แนวคิดมาจากที่นี่ดังนั้นเราจะใช้โปรแกรมที่มีการแก้ไขบ้าง
ผลลัพธ์ที่ถูกต้องสำหรับโปรแกรมคือ: 3,126,900,366
ใน C:
int s, i, j;
for (s = 0, i = 0; i < 10000; i++) {
for (j = 0; j < 10000; j++)
s += (i * j) / 3;
}
ในรหัส: [R0 เป็นตัวแทนของ s, R1 ของ j, R2 ของ i]
LOAD R0 0
LOAD R2 0 <--outer loop value
LOAD R1 0 <--inner loop value
--Begin inner loop--
PUSH R1 <--push inner loop value to the stack
MUL R1 R2 <--(i*j)
PUSH R2
LOAD R2 3
DIV R1 R2 <-- / 3
POP R2
ADD R0 R1 <-- s+=
POP R1
PUSH R2
LOAD R2 1
ADD R1 R2 <--j++
POP R2
PUSH R2
LOAD R2 10000
CMP R1 R2 <-- j < 10000
POP R2
BRANCHLT 3 <--Go back to beginning inner loop
--Drop To outer loop--
LOAD R1 1
ADD R2 R1 <--i++
LOAD R1 10000
CMP R2 R1 <-- i < 10000
LOAD R1 0 <--Reset inner loop
BRANCHLT 2
ในไบนารี / ฐานสิบหก:
0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x02 0x00 0x00 0x00 0x00
0x00 0x01 0x00 0x00 0x00 0x00
0x02 0x01
0x06 0x01 0x02
0x02 0x02
0x00 0x02 0x00 0x00 0x00 0x03
0x07 0x01 0x02
0x03 0x02
0x04 0x00 0x01
0x03 0x01
0x02 0x02
0x00 0x02 0x00 0x00 0x00 0x01
0x04 0x01 0x02
0x03 0x02
0x02 0x02
0x00 0x02 0x00 0x00 0x27 0x10
0x09 0x01 0x02
0x03 0x02
0x0a 0x00 0x00 0x00 0x03
0x00 0x01 0x00 0x00 0x00 0x01
0x04 0x02 0x01
0x00 0x01 0x00 0x00 0x27 0x10
0x09 0x02 0x01
0x00 0x01 0x00 0x00 0x00 0x00
0x0a 0x00 0x00 0x00 0x02
คะแนนโบนัส (เอฟเฟ็กต์ถูกนำไปใช้คูณ) เช่นถ้าคุณมีคุณสมบัติครบทั้งสามจะเป็น ((ตัวละคร * 0.50) * 0.75) * 0.90
- ลดลง 50% หากล่ามนั้นเป็นคอมไพเลอร์ JIT
- ลดลง 25% หากใช้การเพิ่มประสิทธิภาพแบบวนซ้ำใด ๆ / การเพิ่มประสิทธิภาพที่มีความหมาย
- ลดลง 10% หากคุณขยาย VM ด้วย
- BRANCHEQ [รหัสบรรทัด 4 ไบต์] (สาขาถ้าเท่ากัน - opcode 0x0b)
- BRANCHGT [รหัสบรรทัด 4 ไบต์] (สาขาถ้ามากกว่า - opcode 0x0c)
- BRANCHNE [รหัสบรรทัด 4 ไบต์] (สาขาถ้าไม่เท่ากัน - opcode 0x0d)
- ดาวน์โหลด [ลงทะเบียน 1] [ลงทะเบียน 2] (ย้ายค่าลงทะเบียน 2 เพื่อลงทะเบียน 1 - opcode 0x01)
ไม่ได้รับอนุญาต
- การคอมไพล์เคสการทดสอบล่วงหน้าในโปรแกรมเป็นสิ่งต้องห้าม คุณต้องยอมรับ bytecode จาก STDIN หรือจากไฟล์ (ไม่สำคัญว่าจะต้องทำอะไร)
- การส่งคืนเอาต์พุตโดยไม่ต้องรันโปรแกรม
- วิธีอื่นที่คุณสามารถคิดได้ว่าจะโกงข้อกำหนดของ VM
CMP
ตรวจสอบน้อยกว่าหรือเท่าเทียมกัน? และเกิดอะไรขึ้นกับผลลัพธ์ของมัน
MUL
และDIV
ยังไม่ระบุโดยละเอียด พวกเขาควรจะลงนามหรือไม่ได้ลงนาม? เกิดอะไรขึ้นกับการคูณล้น?