Death By Shock Probe: นั่นเป็นลูกเต๋าจำนวนมาก


20

ในคอมมิคDarths & Droids , Pete ผู้เล่น R2-D2 ในแคมเปญสวมบทบาทสวมบทบาทที่การ์ตูนมีพื้นฐานมาจากการอ้างสิทธิ์ครั้งเดียว (คำเตือน: สปอยเลอร์ที่มีศักยภาพในการ์ตูนที่เชื่อมโยง) ซึ่งกับ Orb แห่ง Phanastacoria โพรบช็อตตอนนี้เขาสามารถกำจัด 1048576d4มหันต์ของความเสียหาย (จีเอ็มไม่ได้ยืนยันหรือปฏิเสธสิ่งนี้) เนื่องจากมันควรจะมีเหตุผลที่ชัดเจนว่าแทบจะไม่มีใครมีความอดทนที่จะม้วนลูกเต๋าหลาย ๆ อันให้เขียนโปรแกรมคอมพิวเตอร์เพื่อทำเพื่อเขา รูปแบบ. รายการจะถูกจัดอันดับตามขนาดของโปรแกรม (โปรแกรมที่สั้นที่สุดตามจำนวนไบต์ชนะ) ทั้งโดยรวมและต่อภาษาโดยมีความสัมพันธ์แบบแบ่งเวลา คำตอบอาจเป็นได้ทั้งโปรแกรมเต็มรูปแบบหรือฟังก์ชั่นการกำหนด

คะแนนต่อภาษา

Pyth

Maltysen - 8 ไบต์ *

Jakube - 10 ไบต์

APL

Alex A - 10 ไบต์

CJam

เครื่องมือเพิ่มประสิทธิภาพ - 11 ไบต์

J

--ıʇǝɥʇuʎs - 12 ไบต์ **

Clip10

Ypnypn - 12 ไบต์ **

K

JohnE - 13 ไบต์

Ti-84 พื้นฐาน

SuperJedi224 - 17 ไบต์ *

R

MickyT - 23 ไบต์

Octave / MATLAB

Oebele - 24 ไบต์

PARI / GP

Charles - 25 ไบต์ **

วุลแฟรม / มาติกา

LegionMammal978 - 27 ไบต์

Perl

Nutki - 29 ไบต์

AsciiThenAnsii - 34 ไบต์

ทับทิม

Haegin - 32 ไบต์ **

ConfusedMr_C - 51 ไบต์ **

พลเรือจัตวาพื้นฐาน

มาร์ค - 37 ไบต์ **

PHP

Ismael Miguel - 38 ไบต์

VBA

Sean Cheshire - 40 ไบต์ **

PowerShell

Nacht - 41 ไบต์ **

จาวาสคริ

Ralph Marshall - 41 ไบต์

edc65 - 54 ไบต์ (ต้องการฟังก์ชั่น ES6 ที่ไม่มีในเบราว์เซอร์ทั้งหมด)

Lua

cryptych - 51 ไบต์

ชวา

RobAu - 52 ไบต์ **

Geobits - 65 ไบต์

Functino - 57 ไบต์

หลาม

CarpetPython - 58 ไบต์

Postgre / SQL

Andrew - 59 ไบต์ **

รวดเร็ว

Skrundz - 69 ไบต์

GoatInTheMachine - 81 ไบต์

Haskell

Zeta - 73 ไบต์ **

ActionScript

Brian - 75 ไบต์ **

> <>

ConfusedMr_C - 76 ไบต์

ไป

Kristoffer Sall-Storgaard - 78 ไบต์

ค#

แบรนดอน - 91 ไบต์ **

Andrew - 105 ไบต์

Ewan - 148 ไบต์

เกา

SuperJedi224 - 102 ไบต์

C ++

Michelfrancis Bustillos - 154 ไบต์

polyglots

Ismael Miguel (Javascript / ActionScript2) - 67 ไบต์


โดยรวม 10 อันดับแรก

Maltysen
อเล็กซ์
Jakube
เพิ่มประสิทธิภาพ
ɐɔıʇǝɥʇuʎs / Ypnypn (ความไม่แน่นอนของคำสั่งซื้อ)
Johne
SuperJedi224
MickyT
Oebele

คำเตือน - รายการที่มีเครื่องหมาย * เป็น VERY SLOW

ทำเครื่องหมายเป็นโปรแกรม ** ฉันยังไม่สามารถทดสอบได้อย่างถูกต้อง


เดี๋ยวก่อนฉันต้องให้ผลรวมของการทอยลูกเต๋าหรือแค่กลิ้งทั้งหมดในรายการหรือไม่?
Maltysen

5
คำถามของคุณอาจถูกวิพากษ์วิจารณ์ว่าไม่ชัดเจนหรือกว้างเกินไป มันจะมีประโยชน์มากหากคุณอธิบายไว้ในเงื่อนไขที่เฉพาะเจาะจงว่าจะให้คะแนนโปรแกรมอย่างไรและโปรแกรมวิธีใดที่ควรมีให้ นอกจากนี้สัญกรณ์ของ1048576d4อาจไม่ชัดเจนสำหรับผู้ใช้บางคน มันจะมีประโยชน์ในการให้รายละเอียดเกี่ยวกับสิ่งที่ควรคำนวณและแนวทางใด ๆ ที่ต้องปฏิบัติตามอย่างแม่นยำ
BrainSteel

2
ปัญหานี้สามารถทำได้เร็วเกินไปที่จะลองเป็นช่วงเวลาที่ดี
isaacg

12
คุณสามารถลองทำลีดเดอร์กระดานข้อมูลแบบสแต็กเพื่อหลีกเลี่ยงการเก็บรายการการส่งด้วยตนเองให้ทันสมัยอยู่เสมอ
Alex A.

1
ฉันรักชื่อนี้อย่างแน่นอน
ASCIIThenANSI

คำตอบ:


10

Pyth - 9 8 ไบต์

ใช้วิธีง่าย ๆ ที่ชัดเจนของการรวมของ randint ใช้เวลาสักครู่เพื่อรับรู้1048576คือ2^20ตอนนี้ผมรู้สึกโง่จริงๆ ขอขอบคุณที่ @Jakube 2^20 = 4^10สำหรับการบันทึกฉันไบต์โดยชี้ให้เห็น

smhO4^4T

รันไทม์เป็นที่น่ากลัวก็ยังไม่เสร็จสิ้นในคอมพิวเตอร์ของฉันจึงมีจุดทำงานแบบออนไลน์เพื่อให้ที่นี่ไม่เป็น2^10ที่หนึ่ง: ลองออนไลน์ได้ที่นี่

s        Summation
 m       Map
  h      Incr (accounts for 0-indexed randint)
   O4    Randint 4
  ^4T    Four raised to ten

4
8 ไบต์เป็นไปได้ 2^20 = 4^10
Jakube

@Jakube ขอบคุณสำหรับเคล็ดลับ :)
Maltysen

สิ่งนี้จะเสร็จสิ้นทันทีสำหรับฉัน
Carcigenicate

@Carcigenicate คุณกำลังพูดถึงลิงก์ที่ฉันให้หรือไม่ 1024d4นั่นคือการปรับเปลี่ยนอย่างใดอย่างหนึ่งเท่านั้นเงินก้อน
Maltysen

@Maltysen อ๊ะขออภัย ใช่นั่นแหล่ะ
Carcigenicate

9

Perl - 48 44 37 39 34 ไบต์

$-+=rand(4)+1for(1..2**20);print$-

พิมพ์ผลรวมโดยไม่ขึ้นบรรทัดใหม่
บันทึก 4 ไบต์ด้วยการแทนที่2**20(ขอบคุณ Maltysen) และลบเครื่องหมายคำพูดรอบ ๆ การพิมพ์
บันทึกอีก 7 ไบต์ด้วยการจัดเรียงโค้ดใหม่ (ขอบคุณ Thaylon!)
เสีย 2 ไบต์เนื่องจากรหัสเก่าของฉันสร้างขึ้น 0-4 (ควรเป็น 1-4)
บันทึกอีก 5 ไบต์ด้วย Caek และ nutki

โค้ดที่เขียนผิดอย่างถูกต้อง:

my $s = 0
$s += int( rand(4) + 1 ) for (1 .. 2**20);
print "$s";

มันยากนิดหน่อยที่จะใช้ตัวจับเวลา แต่ในที่สุดฉันก็ทำให้มันทำงานได้
SuperJedi224

2
เนื่องจากเราไม่สนใจคำเตือน ... $ s + = int rand (5) สำหรับ (1..2 ** 20); พิมพ์ $ s
Thaylon

3
int(rand(5))ส่งคืนช่วง 0 ถึง 4 ในขณะที่ d4 ควรเป็น 1 ถึง 4
nutki

@ nutki ตกลงขอบคุณ ฉันได้แก้ไขมันแล้วในตอนนี้
ASCIIThenANSI

$s+=int rand(4)+1for(1..2**20);print$sการลบวงเล็บสำหรับ int ก็ใช้งานได้สำหรับฉันเช่นกัน
Caek

7

APL, 11 10 ไบต์

+/?4⍴⍨2*20

นี่จะใช้ผลรวมของอาร์เรย์ของ 2 20 = 1048576 จำนวนเต็มแบบสุ่มระหว่าง 1 และ 4

+/           ⍝ Reduce by summing a
  ?          ⍝ random integer
   4⍴⍨       ⍝ array with values between 1 and 4
      2*20   ⍝ of length 2^20

คุณสามารถ เปรียบเทียบสิ่งนี้กับ TryAPLโดยการพิมพ์เวลาก่อนและหลัง ใช้เวลาประมาณ 0.02 วินาที

บันทึกเป็นไบต์ด้วย marinus และ FUZxxl!


หนึ่งและ 5 ??? D4 สามารถให้ 1, 2, 3 หรือ 4 คุณไม่สามารถรับ 5
Loren Pechtel

@ LorenPechtel: ขอโทษฉันไม่ดี ขอบคุณสำหรับการชี้ให้เห็นว่า ตอนนี้ได้รับการแก้ไขแล้ว ฉันมีสมองที่เหนื่อยล้า
Alex A.

บันทึกไบต์:+/?4⍴⍨2*20
marinus

การปรับปรุง+/?4⍴⍨2*20เล็กน้อย: ใช้แทน
FUZxxl

1
โดยไม่ได้ตั้งใจคำตอบนี้ไม่ได้เล่นกอล์ฟ แต่อย่างใด: มันจะถูกเขียนในลักษณะเดียวกันในการผลิตรหัส APL
FUZxxl

7

Ti-84 พื้นฐาน 17 ไบต์

Total footprint - ขนาดของส่วนหัวของโปรแกรม = 17 ไบต์

เวลาทำงาน: ไม่รู้จักประมาณ 5-6 ชั่วโมงขึ้นอยู่กับประสิทธิภาพของม้วนน้อย (โดยทั่วไปไม่ดีมาก)

Σ (randInt (1,4), A, 1,2 ^ 20

1
+1 ที่ทำให้มันทำงานบน TI-84 ฉันเดาว่าคงไม่มีปัญหาเวลานี่คือเครื่องคิดเลขอายุ 30-40 ปีแล้ว
ASCIIThenANSI

ฉันคิดว่ามีฟังก์ชั่นสำหรับการสุ่มตัวอย่างการแจกแจงแบบปกติมากกว่าแบบเครื่องแบบหรือไม่? ควรจะเร็วกว่ามาก
Ben Voigt

@BenVoigt: เนื่องจากมีวัตถุประสงค์เพื่อจำลองการทอยลูกเต๋าการแจกแจงแบบปกติจึงไม่เหมาะสม มันจะต้องเป็นชุด
Alex A.

2
@AlexA: Central Limit Theorem ให้ผลรวมของลูกเต๋าที่เหมือนกันหลายตัวซึ่งแยกไม่ออกจากการแจกแจงแบบปกติ ดังนั้นมันขึ้นอยู่กับว่าพวกเราช่างเกี่ยวกับ "การเลียนแบบการกลิ้ง"
Ben Voigt

1
@MIWright ฉันคิดว่ามันเป็นเพียงการสื่อสาร อย่างน้อยหนึ่งที่ฉันได้ใช้แบตเตอรี่ AAA
Arturo Torres Sánchez

7

R, 32 24 23 21 ไบต์

แก้ไข: Got กำจัดของใช้ส่วนจำนวนเต็มas.integer %/%เร่งความเร็วขึ้นเล็กน้อย

ขอบคุณ Alex A สำหรับเคล็ดลับตัวอย่าง ... และ Giuseppe สำหรับการลบ r=

sum(sample(4,2^20,T))

ทดสอบกับ

i = s = 0
repeat {
i = i + 1
print(sum(sample(4,2^20,r=T)))
s = s + system.time(sum(sample(4,2^20,r=T)))[3]
if (i == 10) break
}
print (s/10)

เอาท์พุท

[1] 2621936
[1] 2620047
[1] 2621004
[1] 2621783
[1] 2621149
[1] 2619777
[1] 2620428
[1] 2621840
[1] 2621458
[1] 2620680
elapsed 
   0.029 

สำหรับความเร็วบริสุทธิ์การทำสิ่งต่อไปนี้ให้เสร็จสมบูรณ์ในหน่วยไมโครวินาที อย่างไรก็ตามฉันไม่แน่ใจว่าฉันได้แก้ไขตรรกะของฉันแล้ว ผลลัพธ์ปรากฏสอดคล้องกับวิธีการสุ่ม ความอัปยศมันยาวอีกต่อไป

sum(rmultinom(1,2^20,rep(1,4))*1:4)

นี่คือเวลาที่ฉันทำบนเครื่องของฉัน

system.time(for(i in 1:1000000)sum(rmultinom(1,2^20,rep(1,4))*1:4))
                   user                  system                 elapsed 
7.330000000000040927262 0.000000000000000000000 7.370000000000345607987 

คุณสามารถบันทึกไบต์คู่โดยใช้sample()ในสถานที่ของคือrunif() sum(sample(4,2^20,r=T))
Alex A.

เพิ่งทำการเปรียบเทียบในคอมพิวเตอร์ของฉันและsample()ก็เร็วขึ้นด้วย!
Alex A.

@AlexA ขอขอบคุณจะทดสอบและเปลี่ยนแปลงเมื่อฉันเข้าใกล้คอมพิวเตอร์
MickyT

ไม่ต้องสนใจสิ่งนี้หรือสิ่งอื่นใด แต่คุณไม่ต้องการr=Tเพียงแค่Tปรับเปลี่ยนได้
จูเซปเป้

1
@Giuseppe ขอบคุณ .. นี่มันเก่าจริง ๆ
MickyT

6

Python 2, 58 ไบต์

เราได้รับ 1048576 ตัวอักษรแบบสุ่มจากระบบปฏิบัติการใช้เวลา 2 บิตของแต่ละตัวและเพิ่มขึ้น การใช้osไลบรารีดูเหมือนจะบันทึกอักขระสองสามตัวโดยใช้randomห้องสมุด

import os
print sum(1+ord(c)%4 for c in os.urandom(1<<20))

ใช้เวลาประมาณ 0.2 วินาทีในพีซีของฉัน


6

CJam, 12 11 ไบต์

YK#_{4mr+}*

นี่มันช่างตรงไปตรงมา:

YK                  e# Y is 2, K is 20
  #                 e# 2 to the power 20
   _                e# Copy this 2 to the power 20. The first one acts as a base value
    {    }*         e# Run this code block 2 to the power 20 times
     4mr            e# Get a random int from 0 to 3. 0 to 3 works because we already have
                    e# 2 to the power 20 as base value for summation.
        +           e# Add it to the current sum (initially 2 to the power 20)

แต่ความงามของมันก็คือมันเร็วเกินไป! บนเครื่องของฉัน (และใช้คอมไพเลอร์ Java ) ใช้เวลาเฉลี่ย 70 มิลลิวินาที

รุ่นออนไลน์ใช้เวลาประมาณ 1.7 วินาทีในเครื่องของฉัน

อัปเดต : บันทึก 1 ไบต์ด้วย DocMax


เวอร์ชั่นออนไลน์ใช้เวลาประมาณ 6 วินาทีจากคอมพิวเตอร์ที่นี่ แต่นั่นอาจเป็นเพียงเครือข่ายและ / หรือ macbooks ที่โรงเรียนยืนยันว่าใช้งาน ฉันจะลองอีกครั้งเมื่อกลับถึงบ้าน
SuperJedi224

@ SuperJedi224 เวอร์ชันออนไลน์ทั้งหมดอยู่ในจาวาสคริปต์ไม่ทำการโทรบนเครือข่าย คุณสามารถดาวน์โหลดเวอร์ชัน Java และรันโดยใช้คำแนะนำบนเว็บไซต์
เครื่องมือเพิ่มประสิทธิภาพ

3
ถ้าฉันไม่ได้ทำอะไรบางอย่าง (ซึ่งเป็นเรื่องธรรมดาเกินไปกับ CJam และฉัน) แทนที่จะทำการเพาะด้วย 0 และเพิ่ม 1 สำหรับการวิ่ง 2 ^ 20 ให้เมล็ดด้วย 2 ^ 20 เพื่อบันทึก 1 ไบต์:YK#_{4mr+}*
DocMax

@DocMax คุณพูดถูก ขอบคุณ!
เครื่องมือเพิ่มประสิทธิภาพ

+1; ฉันจะโพสต์คำตอบที่แน่นอนนี้ (ยกเว้น4A#แทนที่จะเป็นYK#) แต่คุณเอาชนะฉันได้ :)
Ilmari Karonen

6

JavaScript (ES6), 54 ไบต์

เวลาเฉลี่ย <100 msec เรียกใช้ตัวอย่างเพื่อทดสอบ (ใน Firefox)

// This is the answer
f=t=>(i=>{for(t=i;i--;)t+=Math.random()*4|0})(1<<20)|t

// This is the test
test();

function test(){
  var time = ~new Date;
  var tot = f();
  time -= ~new Date;
  
  Out.innerHTML = "Tot: " + tot + " in msec: " + time + "\n" + Out.innerHTML;
}
<button onclick="test()">Repeat test</button><br>
<pre id=Out></pre>

คำอธิบาย

ไม่มีแพคเกจสถิติในตัวใน Javascript วิธีที่สั้นที่สุดในการรับผลรวมของตัวเลขสุ่ม 1 ล้านคือการโทรสุ่ม () เป็นล้านครั้ง ดังนั้นง่ายๆ

f=()=>{
   var t = 0, r, i
   for (i=1<<20; i--; ) 
   {
      r = Math.random()*4 // random number between 0 and 3.9999999
      r = r + 1 // range 1 ... 4.999999
      r = r | 0 // truncate to int, so range 1 ... 4
      t = t+r
   }
   return t
}

ทีนี้การเพิ่ม 1 สำหรับล้านครั้งก็เหมือนกับการเพิ่ม 1 ล้านหรือดีกว่าเริ่มรวมกับ 1 ล้านแล้วเพิ่มส่วนที่เหลือ:

f=()=>{
   var t, r, i
   for (t = i = 1<<20; i--; ) 
   {
      r = Math.random()*4 // random number between 0 and 3.9999999
      r = r | 0 // truncate to int, so range 0 ... 3
      t = t+r
   }
   return t
}

จากนั้นกอล์ฟวางตัวแปร temp r และวางการประกาศตัวแปรท้องถิ่น เป็นพารามิเตอร์ที่เป็นหนึ่งเป็นสิ่งจำเป็นที่จะลดลงประกาศของt เป็นสากล (สิ่งเลวร้าย)fi

f=t=>{
   for(t=i=1<<20;i--;) 
      t+=Math.random()*4|0
   return t
}

จากนั้นหาวิธีหลีกเลี่ยง 'การกลับมา' โดยใช้ฟังก์ชั่นภายในแบบไม่ระบุชื่อ ในฐานะที่เป็นผลข้างเคียงเราได้รับพารามิเตอร์อื่นดังนั้นจึงไม่ได้ใช้รูปทรงกลม

f=t=>(
  (i=>{ // start inner function body
     for(t=i;i--;)t=t+Math.random()*4|0 // assign t without returning it
   })(1<<20) // value assigned to parameter i
  | t // the inner function returns 'undefined', binary ored with t gives t again
) // and these open/close bracket can be removed too

ใช้งานไม่ได้กับโครเมี่ยม กำลังจะทดสอบใน FF
SuperJedi224

แน่นอน. Chrome คือ ES5
edc65

1
มันมีการรองรับ ES6 บางส่วน (ส่วนใหญ่จะมีให้โดยการเปิดใช้งานจาวาสคริปต์ทดลองจาก chrome: \\ ธง) แต่ยังไม่รองรับฟังก์ชั่นลูกศร
SuperJedi224

5

Perl, 29

สร้างตารางที่มีความยาวที่ต้องการ

print~~map{0..rand 4}1..2**20

ฉันได้รับข้อผิดพลาดทางไวยากรณ์ของอันนี้
SuperJedi224

สิ่งนี้ต้องการ Perl รุ่นใหม่ที่เพียงพอ (ตัวดำเนินการ smartmatch ถูกนำมาใช้ใน 5.10.1 และฉันคิดว่ามันไม่ได้มีให้เป็นค่าเริ่มต้นจนกระทั่งภายหลัง)
ทำเครื่องหมาย

~~ไม่ใช่ smartmatch เพียงการผกผันสองครั้งเพื่อบังคับบริบทสเกลาร์ ตัวละครตัวหนึ่งจะใช้เวลานานกว่าprint$x=map...นั้น บางทีในรุ่นที่ใหม่กว่านั้นมันเตือนเพราะความคลุมเครือกับ smartmatch แต่ดูเหมือนว่าจะทำงานโดยไม่มีคำเตือนในระบบของฉันและในที่นี่: ideone.com/LAIWzq
nutki

ใช่มันทำงานบน IDEone ฉันจะมอบให้คุณ
SuperJedi224

5

J (12 ไบต์, ประมาณ 9.8 มิลลิวินาที)

+/>:?4$~2^20

ฉันสงสัยว่านี่เป็นหน่วยความจำแบนด์วิดท์ที่มี จำกัด ส่วนใหญ่: ฉันไม่สามารถแม้แต่จะทำให้มันเป็นแกนหลักเดียว ...

คุณสามารถทดสอบสิ่งนี้ด้วยรหัสต่อไปนี้:

   timeit =: 13 : '(1000 * >./ ($/x) 6!:2"0 1 y)'
   4 20 timeit '+/>:?4$~2^20'
9.90059

สิ่งนี้รันในกลุ่ม 4 กลุ่มจาก 20 เส้นทางและส่งคืนจำนวนมิลลิวินาทีของเวลาความเสียหายในกลุ่มที่เร็วที่สุด ล่ามสามารถพบได้ที่นี่


4

Pyth, 10 ไบต์

u+GhO4^4TZ

นี่มีไบต์มากกว่าโซลูชัน Pyth ของ @ Maltysen เล็กน้อย แต่มันใช้งานได้ใน 8.5 วินาทีบนแล็ปท็อปของฉันในขณะที่โซลูชันของ @ Maltysen ไม่สามารถแก้ปัญหาได้ในเวลา 20 นาที

แต่ก็ยังช้าไปหน่อยสำหรับคอมไพเลอร์ออนไลน์

คำอธิบาย

u     ^4TZ   start with G = 0, for H in 0, ... 4^10-1:
                G = 
 +GhO4              G + (rand_int(4) + 1)
             result is printed implicitly 

จะทดสอบช่วงบ่ายนี้
SuperJedi224

4

Java, 65

เนื่องจากเรามีคะแนนตามภาษาทำไมไม่โยน Java ลงในส่วนผสม? ที่นี่มีกอล์ฟไม่มากนักแค่วนซ้ำง่าย ๆ แต่ฉันสามารถบีบความพยายามครั้งแรกของฉันออกเป็นสอง:

int f(){int i=1<<20,s=i;while(i-->0)s+=Math.random()*4;return s;}

จะทดสอบช่วงบ่ายนี้
SuperJedi224

ไม่มีปัญหา. ใช้เวลาประมาณ 80ms กับพีซี (ช้า) นี้ แต่ฉันไม่รู้ว่าคุณกำลังใช้อะไรอยู่
Geobits

ฉันไม่เชื่อว่าโปรแกรมของคุณเป็นรุ่นที่ถูกต้อง มันสามารถและทำในการทดสอบของฉันเพิ่ม 0 ในบางม้วน ตามที่ฉันเข้าใจแล้ว d4 ส่วนใหญ่จะเป็น 1,2,3,4 (ไม่เป็นไปได้ 0)

4
@ user39526 s(ยอดรวมทั้งหมด) เริ่มต้นที่1<<20(จำนวนม้วน) นี่เทียบเท่ากับการเพิ่มหนึ่งม้วนในแต่ละม้วน เมื่อเครื่องมือสุ่มโยน 0 มันจะกลิ้ง 1 และอื่น ๆ
Geobits

คุณควรอัพเกรดเป็น Java 8! codegolf.stackexchange.com/a/52919/7021
RobAu

4

Matlab, 24

ส่งครั้งแรก!

sum(randi([1,4],1,2^20))

ฉันหวังว่าจะใช้ประโยชน์จาก randi ([1,4], 1024) ซึ่งให้เมทริกซ์ขององค์ประกอบ 1048576 แต่จากนั้นฉันต้องการผลรวมสองเท่าซึ่งใช้อักขระมากกว่านี้

เกี่ยวกับความเร็วในการวิ่งที่กล่าวถึงในคำถาม timeitบอกฉันว่ารันไทม์ประมาณ 0.031 วินาที ดังนั้นทันใดนั้นเอง


ฉันได้รับ 0.04 ถึง 0.05 วินาทีผ่านทางออนไลน์ระดับแปดเสียง
SuperJedi224


4

C #: 105 ไบต์

using System.Linq;class C{int D(){var a=new System.Random();return new int[1<<20].Sum(i=>a.Next(1,5));}}

ดีฉันชอบสิ่งนี้แม้ว่ามันจะผิดสองครั้ง มันคือ 1 << 20 ไม่ใช่ 2 << 20 และพารามิเตอร์ตัวที่สองของ Random.Next The *exclusive* upper bound of the rangeก็ควรจะเป็น 5
edc65

@ edc65 ขอบคุณที่ติดตามข้อผิดพลาดเหล่านั้น ฉันได้อัพเดตคำตอบแล้ว
Andrew

1
คุณสามารถประหยัด 9 ตัวอักษรโดยการกำจัดaและการย้ายภายในของnew System.Random() Sumแน่นอนว่ามันจะสร้างใหม่Randomทุกครั้ง แต่ใครจะสนใจตราบใดที่มันให้ผลลัพธ์
LegionMammal978

@ LegionMammal978 หากคุณสร้างการสุ่มใหม่อีกครั้งและอีกครั้งผลลัพธ์ส่วนใหญ่จะไม่สุ่ม
edc65

@ edc65 นั่นคือเหตุผลที่ฉันไม่ได้ไปเส้นทางนั้น ฉันไม่ได้มีโอกาสทดสอบว่าจะเกิดอะไรขึ้นถ้าฉันทำตามคำแนะนำ
แอนดรู

4

PHP, 38 37 ไบต์

สิ่งนี้ใช้ความคิดที่ง่ายมาก: รวมพวกมันทั้งหมด!

นอกจากนี้ผมได้สังเกตเห็นว่า1048576เป็นในไบนารีเทียบเท่ากับ100000000000000000001<<20

นี่คือรหัส:

while($i++<1<<20)$v+=rand(1,4);echo$v

ทดสอบในเบราว์เซอร์ของคุณ (ด้วยการเปลี่ยนแปลงVERY LITTLE ):

$i=$v=0;while($i++<1<<20)$v+=rand(1,4);printf($v);

การเปลี่ยนแปลงทั้งหมดในรหัสได้อธิบายไว้ในความคิดเห็น


คุณสามารถลบ;หลังecho$v
Martijn

@Martijn ฉันทิ้งไว้ที่นั่นเพราะ PHP ส่วนใหญ่บ่นเกี่ยวกับเรื่องนี้ แต่ฉันได้ลบมันทันที มันทำงานบนsandbox.onlinephpfunctions.comและนั่นก็เพียงพอแล้ว
Ismael Miguel


3

C, 57 ไบต์

main(a,b){for(b=a=1<<20;a--;b+=rand()%4);printf("%d",b);}

รหัสนี้ใช้งานได้ ... ครั้งเดียว หากคุณจำเป็นต้องหมุนลูกเต๋าเหล่านั้นอีกครั้งคุณจะต้องใส่srand(time(0))เข้าไปที่นั่นเพิ่มขึ้น 14 ไบต์


ทำไมคุณจะต้องเพิ่มsrand(time(0))? (ขออภัยฉันไม่ได้ใช้ C. )
ASCIIThenANSI

@ ASCIIThenANSI การใช้งานหลายอย่างของrandเมล็ดของ C ให้เป็นค่าเดียวกันทุกครั้งที่รัน srandเพาะเมล็ด RNG และtime(0)รับเวลาปัจจุบันเป็นวินาทีตั้งแต่ปี 1970
Functino

หากคุณเริ่มต้นa=b=1<<20แล้วคุณสามารถข้าม1+สิ่งนี้จะช่วยประหยัด 4 ไบต์
nutki

นอกจากนี้intก่อนหน้าmainนี้ไม่จำเป็นต้องใช้
nutki

แนะนำให้ทุกคนทำt=0แล้วt=t (...) +1สำหรับ 1048576 ครั้ง: คิดอีกครั้ง! (ดูคำตอบของฉันในที่สุด)
edc65

3

PostgreSQL ขนาด 59 ไบต์

select sum(ceil(random()*4)) from generate_series(1,1<<20);

ฉันจะยอมรับกับปัญหาเล็กน้อยที่random()ในทางทฤษฎีแล้วสามารถสร้างศูนย์ได้อย่างแน่นอนซึ่งในกรณีนี้การหมุนตายจะเป็นศูนย์


คุณไม่จำเป็นต้อง;ยกเลิกการค้นหาเนื่องจากเป็นคำถามเดียวเท่านั้น
MickyT

3

Ruby, 32 ไบต์

(1..2**20).inject{|x|x-~rand(4)}

ในรูปแบบที่อ่านได้มากขึ้น:

(1..2**20).inject(0) do |x|
  x + rand(4) + 1
end

มันสร้างช่วงจาก 1 ถึง 1048576 แล้ววนซ้ำบล็อกนั้นหลาย ๆ ครั้ง ทุกครั้งที่มีการดำเนินการบล็อกค่าจากการทำซ้ำก่อนหน้านี้จะถูกส่งผ่านเป็นx(เริ่มต้น 0, เริ่มต้นสำหรับinject) การวนซ้ำแต่ละครั้งจะคำนวณตัวเลขสุ่มระหว่าง 0 ถึง 3 (รวม) เพิ่มหนึ่งค่าดังนั้นจึงจำลองการหมุน d4 และเพิ่มเข้ากับยอดรวม

บนเครื่องของฉันมันค่อนข้างเร็วในการรัน ( 0.25 real, 0.22 user, 0.02 sys)

หากคุณติดตั้ง Ruby คุณสามารถเปิดใช้งานด้วยruby -e 'p (1..2**20).inject{|x|x+rand(4)+1}'(pจำเป็นต้องเห็นผลลัพธ์เมื่อทำงานในลักษณะนี้ให้ละเว้นหากคุณไม่สนใจหรือเรียกใช้ภายใน IRB ซึ่งพิมพ์ผลลัพธ์ไปที่หน้าจอ สำหรับคุณ). ฉันได้ทำการทดสอบกับ Ruby 2.1.6 แล้ว

ขอขอบคุณที่ histocrat สำหรับบิต twiddling สับที่มาแทนที่ด้วยx + rand(4) + 1x-~rand(4)


1
คุณอธิบายได้ไหมว่ามันทำงานอย่างไร
ASCIIThenANSI

ล่ามออนไลน์รายแรกที่ฉันพบว่าจริง ๆ แล้วต้องการโหลดการอ้างสิทธิ์ว่าไม่มีวิธีการ rand () ฉันจะพยายามหาอันอื่น
SuperJedi224

โอเคฉันเจออันที่ใช้ได้แล้ว
SuperJedi224

Bit twiddling สับ: เทียบเท่ากับx-~rand(4) x+rand(4)+1
ฮิสโทแกต

นอกจากนี้คุณยังสามารถแทนที่ด้วย2**20 4e10
ฮิสโทแกต

3

PARI/GP, 25 bytes

จริงๆไม่จำเป็นต้องเล่นกอล์ฟที่นี่ - นี่เป็นวิธีการคำนวณที่ตรงไปตรงมาใน GP มันทำงานใน 90 มิลลิวินาทีบนเครื่องของฉัน การชักรอก+1จะช่วยประหยัดประมาณ 20 มิลลิวินาที

sum(i=1,2^20,random(4)+1)

เพียงเพื่อความสนุกสนานถ้าใครได้รับการเพิ่มประสิทธิภาพสำหรับผลการดำเนินงานใน PARI,

inline long sum32d4(void) {
  long n = rand64();
  // Note: __builtin_popcountll could replace hamming_word if using gcc
  return hamming_word(n) + hamming_word(n & 0xAAAAAAAAAAAAAAAALL);
}

long sum1048576d4(void) {
  long total = 0;
  int i;
  for(i=0; i<32768; i++) total += sum32d4();
  return total;
}

มีจำนวนการดำเนินการโดยรวมที่น้อยมาก - ถ้าxorgensต้องการ ~ 27 รอบต่อคำที่ 64 บิต (ใครสามารถตรวจสอบได้?) ดังนั้นโปรเซสเซอร์ที่มี POPCNT ควรใช้เวลาประมาณ 0.5 รอบ / บิตหรือไม่กี่ร้อยไมโครวินาทีในขั้นสุดท้าย จำนวน.

This should have close-to-optimal worst-case performance among methods using random numbers of similar or higher quality. It should be possible to greatly increase average speed by combining cases -- maybe a million rolls at a time -- and selecting with (essentially) arithmetic coding.


3

Javascript, 55 53 50 47 41 bytes

for(a=i=1<<20;i--;)a+=(Math.random()*4)|0

I didn't realize that non-random numbers were a known irritant, so I figure that I ought to post a real solution. Meant no disrespect.

Commentary: as noted by others above you can skip the +1 to each roll by starting off with the number of rolls in your answer, and by not having to write a=0,i=1<<20 you save two bytes, and another 2 because you don't add +1 to each roll. The parseInt function does the same thing as Math.floor but is 2 characters shorter.


Note that this answer is completely different from the one originally commented on by SuperJedi224 and @Andrew
Ralph Marshall

You can remove both brackets and the last semicolon (and only the last one) to cut down a few further characters. Also, the current version is only 50 characters, not 52.
SuperJedi224

SuperJedi - thanks for the suggestions. I thought I'd tried it without the brackets only to run into problems, but perhaps I had a different problem. In any case, I think this is about as good as it's going to get.
Ralph Marshall

a+=parseInt(Math.random()*4) may be shortened to a+=1+Math.random()*4&7. The 1+ is only if you care if it rolls 0 or not.
Ismael Miguel

You can golf it down to this: for(a=i=1<<20;i--;)a+=(Math.random()*4)|0, that's only 41 bytes
SuperJedi224




2

Commodore Basic, 37 bytes

1F┌I=1TO2↑20:C=C+INT(R/(1)*4+1):N─:?C

PETSCII substitutions: = SHIFT+E, / = SHIFT+N, = SHIFT+O

Estimated runtime based on runs with lower dice counts: 4.25 hours.

It's tempting to try to golf off two bytes by making C an integer, getting implicit rounding of the random numbers. However, the range on integers in Commodore Basic is -32678 to 32767 -- not enough, when the median answer is 2621440.



2

Ruby, 51 47 chars

x=[];(2**20).times{x<<rand(4)+1};p x.inject(:+)

I looked at all of the answers before I did this, and the sum(2**20 times {randInt(4)}) strategy really stuck out, so I used that.

><>, 76 chars

012a*&>2*&1v
|.!33&^?&:-<
3.v < >-:v >
   vxv1v^<;3
  1234    n+
  >>>> >?!^^

I'm not sure if this one works, because my browser crashed when I tried to test it, but here's the online interpreter.


I'll give you a +1 for the ><> answer.
SuperJedi224

2

Swift, 64 bytes

Nothing clever, golfing in Swift is hard...

func r()->Int{var x=0;for _ in 0..<(2<<19) {x+=Int(arc4random()%4)+1;};return x;}

Version 2 (too late)

var x=0;for _ in 0..<(2<<19){x+=Int(arc4random()%4)+1;};print(x)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.