ใช้สูตรของ xkcd เพื่อประมาณประชากรโลก


42

ในxkcd 1047รายการ Randall Munroe "เล็กน้อยผิด" การประมาณปริมาณสารพันและตัวเลขที่มีความแม่นยำและความซับซ้อนที่แตกต่างกันเช่นว่าจำนวนลิตรในแกลลอนที่อยู่ใกล้กับ 3 + π / 4 ในช่วงกลางของการ์ตูนเขาให้หยุดพักชั่วคราว: วิธีการประมาณประชากรโลก (และสหรัฐอเมริกา) ตามปีที่กำหนด

สูตรประชากรโลกและสหรัฐอเมริกาตามที่อธิบายไว้ด้านล่าง
(ครอบตัดจากxkcd: การประมาณโดย Randall Munroe)

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

ประชากรโลก

  1. ใช้ตัวเลขสองหลักสุดท้ายของปีปัจจุบัน
  2. ลบจำนวนปีอธิกสุรทิน (รวมถึงปีปัจจุบัน) นับตั้งแต่เฮอร์ริเคนแคทรีนา (2548) สำหรับวัตถุประสงค์เหล่านี้หารด้วย 4 ปีใดถือว่าเป็นปีอธิกสุรทิน
  3. เพิ่มจุดทศนิยมระหว่างตัวเลขสองตัว (เช่นเดียวกับหารด้วย 10)
  4. เพิ่ม 6 สิ่งนี้ให้ผลลัพธ์เป็นพันล้านคน

ประชากรสหรัฐ

  1. ใช้ตัวเลขสองหลักสุดท้ายของปีปัจจุบัน
  2. ลบ 10
  3. คูณด้วย 3
  4. เพิ่ม 10
  5. เพิ่ม 3 เข้ากับจุดเริ่มต้น (สำหรับความท้าทายนี้บางหมายเลขจะเป็นค่าลบดังนั้นเพิ่ม 300 แทน) ยังไงก็เถอะฉันไม่ได้สังเกตเห็นว่าเพียงแค่การต่อกันจะไม่ทำงานเพราะโปรแกรมที่ฉันใช้เพื่อสร้างผลลัพธ์ที่เพิ่งเพิ่ม 300
  6. สิ่งนี้ให้ผลในคนหลายล้านคน

รายละเอียด

สูตรนี้ "ควรอยู่ในปัจจุบันเป็นเวลาสิบหรือสองปี" แต่คุณจะต้องสามารถจัดการกับเหตุผลใดก็ตามในปี พ.ศ. 2543-2582 รวม สำหรับบางกรณีปีอธิกสุรทินตั้งแต่ Katrina จะมีค่าเป็นลบหรือศูนย์

คุณสามารถลดความซับซ้อนของสูตรได้ทุกวิธีตราบใดที่ผลลัพธ์ทั้งหมดตรงกับสูตรด้านล่าง

สำหรับปีให้ใช้ปีตามนาฬิกาของคอมพิวเตอร์ มันจะต้องใช้งานได้ในปีหน้าและปีอื่น ๆ ในศตวรรษนี้ดังนั้นคุณจึงไม่สามารถ hardcode 2015 ได้เพื่อความสะดวกคุณอาจต้องการรวมวิธีการระบุปีเป็นตัวแปรหรืออินพุตเพื่อทดสอบปีอื่น ๆ

ผลลัพธ์ควรเป็นประชากรโลกโดยประมาณ (เป็นพันล้านคน) ตามด้วยตัวคั่นบางตัว (เช่น space หรือเครื่องหมายจุลภาค) ตามด้วยประชากรสหรัฐฯ (ในล้านคน) นอกจากนี้คุณยังสามารถเขียนฟังก์ชั่นที่ส่งคืนหรือพิมพ์สตริงหรืออาร์เรย์ของตัวเลขหรือสตริง

นี่คือรหัสกอล์ฟดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ Tiebreaker เป็นโพสต์แรกสุด

กรณีทดสอบ

นี่คือรายการของปีที่เป็นไปได้ทั้งหมดตามด้วยผลลัพธ์สองรายการ

Year   World  U.S.
2000    6.1   280
2001    6.2   283
2002    6.3   286
2003    6.4   289
2004    6.4   292
2005    6.5   295
2006    6.6   298
2007    6.7   301
2008    6.7   304
2009    6.8   307
2010    6.9   310
2011    7     313
2012    7     316
2013    7.1   319
2014    7.2   322
2015    7.3   325
2016    7.3   328
2017    7.4   331
2018    7.5   334
2019    7.6   337
2020    7.6   340
2021    7.7   343
2022    7.8   346
2023    7.9   349
2024    7.9   352
2025    8     355
2026    8.1   358
2027    8.2   361
2028    8.2   364
2029    8.3   367
2030    8.4   370
2031    8.5   373
2032    8.5   376
2033    8.6   379
2034    8.7   382
2035    8.8   385
2036    8.8   388
2037    8.9   391
2038    9     394
2039    9.1   397

1
คุณต้องปัดเศษตัวเลขหรือไม่
บลู

5
@muddyfish ฉันไม่แน่ใจว่าฉันเข้าใจ หากคุณทำตามคำแนะนำในหนังสือการ์ตูนแน่นอนว่าไม่มีการแบ่งทางเทคนิค แต่ประชากรโลกควรจะถูกปัดเศษเป็นสิบส่วนที่ใกล้ที่สุด
NinjaBearMonkey

2
ฉันสับสนเล็กน้อยโดยประชากรสหรัฐอเมริกาหนึ่ง หากคุณกำลังต่อกันคุณไม่3ควร2040ให้ประชากรเป็น3100? 40 - 10 = 30, 30 * 3 = 90, 90 + 10 = 100ซึ่งจะให้"3" + "100" = 3100
โคล

2
@ จุดที่ดีฉันจะทำให้มันดังนั้นคุณจะต้องให้การสนับสนุนปีที่ผ่าน 2039 เกี่ยวกับการเข้ารหัส hardcoding ปีฉันไม่ต้องการให้ hardcoding เพราะมันจะสั้นกว่าเสมอแม้แต่ภาษาที่รองรับวันที่
NinjaBearMonkey

8
@NinjaBearMonkey ฉันขอแนะนำให้คุณเปลี่ยนคำอธิบายของ "การเพิ่ม 3 คิดการต่อข้อมูล" เป็นตัวอักษร "เพิ่ม 300" เพื่อครอบคลุมกรณีขอบทั้งหมดที่เกิดขึ้นเมื่อผลลัพธ์ก่อนหน้านี้ไม่ใช่ตัวเลขบวก 2 หลักที่ดี (ตัวอย่างเช่นปี 2000 แสดง280เป็นผลมาจาก-20+300=280และไม่ใช่3 . -20= "3-20")
PhiNotPi

คำตอบ:


22

Pyth, 21 20 ไบต์

-1 ไบต์โดย Dennis

c/J-*3.d3C\ᙹ4T+33J

สิ่งเหล่านี้มีจำนวนไบต์เท่ากัน แต่เป็นแบบ ASCII เท่านั้น:

c/J%*3.d3 523 4T+33J
c/-J%*3.d3*44T33 4TJ

ฉันไม่รู้Pyth ดังนั้นจึงอาจเป็นไปได้ที่จะเล่นกอล์ฟ ใช้อัลกอริทึมเดียวกัน:

TI-BASIC ขนาด 23 ไบต์

max(3getDate-5753
{.1int(Ans/4),Ans+33

getDateส่งกลับรายการของสาม float {YYYY,MM,DD}ในบางคำสั่งขึ้นอยู่กับการตั้งค่ารูปแบบวันที่ (TI-84s ไม่มีประเภทข้อมูล int จริง) max(จะเป็นปี การคูณและการลบภายในmax(จะช่วยลดระยะใกล้


1
ฉันคิดว่านี่เป็นครั้งแรกที่ฉันเห็นคำตอบ TI-BASIC ที่นี่ ....
The_Basset_Hound

7
@The_Basset_Hound TI-BASIC เป็นภาษาที่พบบ่อยที่สุดที่ 28ที่ 140 คำตอบ; ก็ยังได้รับรางวัลหนึ่งที่สำคัญและไม่กี่ขนาดเล็กคำถาม
lirtosiast

16

Javascript (ES6), 55 54 48 ไบต์

-~((n=Date().substr(13,2)*3+280)/4-9.1)/10+' '+n

ทำงานได้ใน Firefox 33; ในทางทฤษฎีสนับสนุนทุกปีตั้งแต่ปี 2000 ถึงปี 2099 ถ้าโปรแกรมที่ถ่ายโอนข้อมูลผลลัพธ์ไปยังคอนโซลไม่ได้รับอนุญาตให้ใช้ฟังก์ชัน 51- ไบต์นี้:

(n=Date().substr(13,2)*3+280)=>-~(n/4-9.1)/10+' '+n

โปรแกรมเต็มรูปแบบ 55 ไบต์:

n=Date().substr(13,2)*3+280,alert(-~(n/4-9.1)/10+' '+n)

การเดินทางปีมีราคาแพงมาก แต่หลังจากใช้เลิกใช้getYear()แทนgetFullYear()ทั้งหมดของตัวเลขในสมการกลายเป็นขนาดเล็กประหยัดมากไบต์ แก้ไข:ขอบคุณเคล็ดลับ eeevil ฉันข้ามnewและgetYear()ทั้งหมด >: D

ยินดีต้อนรับข้อเสนอแนะ!


10

Pyth, 30 ไบต์

.R+*.075J%.d3C\d6.105 1+*3J280

โปรแกรม Pyth แรกของฉัน!

ขอบคุณ @Jakube สำหรับคำแนะนำบางอย่าง (ฉันไม่เคยคิดเลย!)


3
ยังไม่ได้อ่านคำถาม แต่นี่คือการปรับปรุงบางอย่างที่ฉันเห็นในทันที เขียนทุกอย่างในบรรทัดเดียว เลือกการเรียงลำดับตัวเลขและตัวแปรอื่น ( +*3Z280แทนที่จะ+*Z3 280เป็นตัวอย่าง) C\dแทน100(บันทึกที่ว่าง) ใช้JแทนZ(บันทึก=) แบบอินไลน์งานที่มอบหมาย Link
Jakube

10

Python 2, 80 ไบต์

from datetime import*
y=date.today().year%40
print int(61.55+.75*y)/10.,y*3+280

ตอนนี้รอบ!


คุณต้องปัดเศษเนื่องจาก OP ชี้แจงเมื่อนาทีที่แล้ว ;-)
mınxomaτ

3
ปี% 100 เหมือนกับปี% 40
lirtosiast

6

CJam, 28 ไบต์

et0=100%__4/(-Ad/6+S@3*280+

ลองออนไลน์

หากต้องการลองปีที่ไม่ใช่แบบปัจจุบันให้แทนที่et0=ด้วยการเริ่มต้นด้วยค่าตัวอักษรของปี


2
ตั้งแต่ 2000 หารด้วย 40 และคุณต้องการเพียง 2000-2039 คุณสามารถใช้40%เพื่อบันทึกหนึ่งไบต์
Andrea Biondo

5

Python 3, 134 ไบต์

ใช้งานได้ดี แต่ดูเหมือนจะยาวไปหน่อย

from datetime import*
y=str(date.today().year)
z=int(y[2:])
m=str(60+(z-int((int(y)-2005)/4)))
print("%s.%s"%(m[0],m[1]),310+(z-10)*3)

เพื่อลดระยะนี้การใช้งาน,from time import* y=strftime('%Y')หรือคัดลอกคำตอบหลามอื่น ๆ : P
FlipTack

5

AutoIt - 60 58 56 ไบต์

$_=@YEAR-2e3
ClipPut(($_-Int($_/4-1))/10+6&' 3'&3*$_-20)

การปัดเศษจะกินจำนวนไบต์ (ไม่ใช่อีกต่อไป) ตอนนี้ฉันได้ปรับสูตรทั้งสองสูตรแล้ว ตัวอย่างผลลัพธ์บางส่วน:

7.3 325 // 2015
7.3 328
7.4 331
7.5 334 // 2018
8.4 370 // 2030

พวกเขาทั้งหมดดูเหมือนจะถูกต้อง

คำแนะนำ: ลำดับของการดำเนินการบันทึกไบต์บนวงเล็บ ตัวอย่างเช่น(a-4)/4 = a/4-1:-)


4

PowerShell, 53 45 ไบต์

$n=date -f yy;.1*[int](61.45+.75*$n);280+3*$n

ใช้เคล็ดลับการปัดเศษที่คล้ายกันเช่นเดียวกับคำตอบ Python 2ของ muddyfish เพื่อทำให้การคำนวณประชากรโลกง่ายขึ้นเนื่องจาก PowerShell มีนัยโดยนัยRound()เมื่อคุณส่งจาก a [double]ถึงa [int]แทนที่จะตัดทอน

สำหรับผลลัพธ์เราสมมติว่า"ตามด้วยตัวคั่นบางตัว (เช่น space หรือเครื่องหมายจุลภาค)"อาจหมายถึง "การขึ้นบรรทัดใหม่" ดังนั้นเราจึงเรียกใช้ผลลัพธ์หนึ่งผลลัพธ์จากนั้นผลลัพธ์ที่สอง PowerShell เขียนผลลัพธ์โดยปริยายดังนั้นเราจึงไม่จำเป็นต้องเรียกคำสั่งการพิมพ์ใด ๆ อย่างชัดเจน


3

Mathematica, 50 ไบต์

n=Today["YearShort"];{.1*(61+n-Floor[n/4]),280+3n}

โปรดทราบว่านี้จะขึ้นอยู่กับการมีเครื่องยนต์วุลแฟรมที่มีจำนวนเวอร์ชั่น 10+ (ปล่อยตัว 2014) DateObjectsเนื่องจากการพึ่งพา

R, 64 ไบต์

n=as.numeric(format(Sys.time(),"%y"))
c(.1*(61+n-n%/%4),280+3*n)

พอร์ตโดยตรงของรหัส Mathematica คิดว่าฉันมีวิธีแก้ปัญหาที่สั้นกว่า แต่ขึ้นอยู่กับแพ็คเกจในขณะที่มันใช้กับ base R ได้


1
(1/10)-> .1?
lirtosiast

1
.1ฉันคิดว่าคุณยังไม่จำเป็นต้องวงเล็บรอบ
lirtosiast

3

Java, 180 177 166 152 143 ไบต์

ขอบคุณ Thomas ที่ช่วย noob out :)

class D{public static void main(String[]a){int f=java.time.LocalDate.now().getYear();System.out.printf("%.1f %d\n",(3.*f-5755)/40,3*f-5720);}}

เวอร์ชันที่ไม่ถูกปรับแต่ง:

class D {
  public static void main(String[]a) {
    int f = java.time.LocalDate.now().getYear();
    System.out.printf("%.1f %d\n",(3.*f-5755)/40,3*f-5720);
  }
}

ต้องใช้ Java 8


import java.time.*? 3.0-> 3.? คุณไม่จำเป็นต้องพิมพ์ปีด้วยผลลัพธ์
lirtosiast

โอ้ฉันไม่ทราบว่าคุณไม่ต้องการปีที่พิมพ์ออกมา ... : P
สปาเก็ตตี้

3

JavaScript (ES6) 52

ฟังก์ชั่นกลับผลลัพธ์เป็นอาร์เรย์

(y=(new Date).getYear())=>[(y+~(y/4)-13)/10,y*3-20]

เพียงเพื่อวัตถุประสงค์ในการทดสอบฟังก์ชั่นยอมรับอินพุตเท่ากับปีปัจจุบัน - 1900 (เช่น 105 สำหรับปี 2015)

ที่อยู่ในแนวของคำตอบของ ETHproductions (คณิตศาสตร์คือคณิตศาสตร์) แต่การเอาเล่ห์เหลี่ยมอุบายชั่วร้ายมันพกพาได้มากกว่าในสถานที่ต่าง ๆ และฟังก์ชั่นมันสั้นลง 1 ไบต์

ตัวอย่างข้อมูลทดสอบ:

f=(y=(new Date).getYear())=>[(y+~(y/4)-13)/10,y*3-20]

o=[];
for(a=2000;a<2050;a++)o.push(`<td>${a}</td><td>${f(a-1900)}</td>`);
document.write(`<table><tr>${o.join`</tr><tr>`}</tr></table>`)
td { text-align:right; font-family:monospace }


2

Ruby, 57 ไบต์

y=Time.now.year%40;puts "#{6+(y-(y-5)/4)*0.1} #{3*y+280}"

น่าเสียดายที่Time.now.yearค่าใช้จ่ายตัวละครบางอย่างจริงๆ


2

Desmos , 140 ไบต์

ฉันนับบรรทัดใหม่เป็นสัญญาณสำหรับสมการใหม่ โฟลเดอร์บนลิงก์มีไว้สำหรับองค์กรเท่านั้น

Golfedขนาด 140 ไบต์

คลิกใช่add sliderเมื่อได้รับแจ้ง

a=6+.1b-.1c
d=280+3b
c=\sum_{n=2005}^q\left\{0=\operatorname{mod}\left(n,4\right),0\right\}
b=100\left|\operatorname{floor}\left(.01q\right)-.01q\right|

Ungolfed , 261 Bytes

p_{world}=6+\frac{l_{astdig}-l_{eap}}{10}
p_{us}=310+3\left(l_{astdig}-10\right)
y_{ear}=2039
l_{eap}=\sum _{n=2005}^{y_{ear}}\left\{0=\operatorname{mod}\left(n,4\right),0\right\}
l_{astdig}=100\left|\operatorname{floor}\left(\frac{y_{ear}}{100}\right)-\frac{y_{ear}}{100}\right|


1

PHP, 45 ไบต์

รหัส:

echo(int)(($x=3*date(y)+247)/4)*.1," ",$x+33;

เพราะy(อาร์กิวเมนต์ของdate()) เป็นค่าคงที่ที่ไม่ได้กำหนด PHP เรียกการแจ้งเตือน (ที่สามารถปิดเสียง) และแปลงเป็นสตริง (ตามที่เราต้องการ); PHP นี้ช่วยให้ประหยัดได้ 2 ไบต์

เพื่อที่จะระงับการแจ้งเตือนโปรแกรมจำเป็นต้องรันโดยใช้error_reporting=0คำสั่งรันไทม์เช่นนี้:

$ php -d error_reporting=0 -r 'echo(int)(($x=3*date(y)+247)/4)*.1," ",$x+33;'
7.3 325

สำหรับการทดสอบ

โดยการเปลี่ยนการเรียกร้องให้date(y)มี$argv[1](อาร์กิวเมนต์บรรทัดคำสั่งแรก) การเพิ่มขึ้นของระยะเวลาของหลักสูตร 1 ไบต์ แต่ก็จะได้รับปีจากบรรทัดคำสั่ง

อาร์กิวเมนต์ที่คาดหวังคือปีลบ 2000; มันยังใช้งานได้สำหรับค่าลบ (ปีก่อนปี 2000) หรือค่าที่มากกว่า 40 (หลังจากปี 2040)

$ php -r 'echo(int)(($x=3*$argv[1]+247)/4)*.1," ",$x+33;' 00
6.1 280

$ php -r 'echo(int)(($x=3*$argv[1]+247)/4)*.1," ",$x+33;' 01
6.2 283

$ php -r 'echo(int)(($x=3*$argv[1]+247)/4)*.1," ",$x+33;' 02
6.3 286

$ php -r 'echo(int)(($x=3*$argv[1]+247)/4)*.1," ",$x+33;' 03
6.4 289

$ php -r 'echo(int)(($x=3*$argv[1]+247)/4)*.1," ",$x+33;' 04
6.4 292

$ php -r 'echo(int)(($x=3*$argv[1]+247)/4)*.1," ",$x+33;' 15
7.3 325

$ php -r 'echo(int)(($x=3*$argv[1]+247)/4)*.1," ",$x+33;' 39
9.1 397

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