Sử dụng công thức của xkcd để ước tính dân số thế giới


42

Trong xkcd 1047 , Randall Munroe danh sách "hơi sai" xấp xỉ của các loại với số lượng và số với độ chính xác và độ phức tạp khác nhau, chẳng hạn như số lượng lít trong một gallon là rất gần với 3 + π / 4 . Ở giữa truyện tranh, anh đưa ra một đoạn: một cách để ước tính dân số thế giới (và Hoa Kỳ) dựa trên một năm nhất định.

Công thức dân số thế giới và Hoa Kỳ, được mô tả dưới đây
(Cắt từ xkcd: Xấp xỉ của Randall Munroe)

Nhiệm vụ của bạn là viết một chương trình thực hiện các công thức này để xấp xỉ thế giới hiện tại và dân số Hoa Kỳ, được nhân rộng như sau.

Dân số thế giới

  1. Lấy hai chữ số cuối của năm hiện tại.
  2. Trừ đi số năm nhuận (bao gồm cả năm hiện tại) kể từ cơn bão Katrina (2005). Đối với các mục đích này, bất kỳ năm nào chia hết cho 4 được coi là một năm nhuận.
  3. Thêm một dấu thập phân giữa hai số (giống như chia cho 10).
  4. Thêm 6. Điều này mang lại kết quả trong hàng tỷ người.

Dân số Hoa Kỳ

  1. Lấy hai chữ số cuối của năm hiện tại.
  2. Trừ 10.
  3. Nhân với 3.
  4. Thêm 10.
  5. Thêm 3 vào đầu (đối với thử thách này, một số số sẽ âm, vì vậy hãy thêm 300 thay vào đó). Bằng cách nào đó tôi đã không nhận thấy rằng chỉ ghép nối sẽ không hoạt động vì chương trình tôi đã sử dụng để tạo kết quả chỉ cần thêm 300.
  6. Điều này mang lại kết quả trong hàng triệu người.

Chi tiết

Công thức này "nên duy trì hiện tại trong một hoặc hai thập kỷ", nhưng bạn phải có khả năng xử lý về mặt lý thuyết bất kỳ năm 2000 20002020. Đối với một số trường hợp, những năm nhuận kể từ Katrina sẽ có giá trị âm hoặc bằng không.

Bạn có thể tự do đơn giản hóa công thức theo bất kỳ cách nào, miễn là tất cả các kết quả đầu ra khớp với các công thức dưới đây.

Đối với năm, sử dụng năm theo đồng hồ của máy tính. Nó phải hoạt động vào năm tới và bất kỳ năm nào khác trong thế kỷ này, vì vậy bạn không thể đơn giản là mã cứng 2015. Để thuận tiện, bạn có thể muốn bao gồm một cách để chỉ định năm là một biến hoặc đầu vào để kiểm tra các năm khác.

Đầu ra phải là dân số thế giới xấp xỉ (tính bằng tỷ người), theo sau là một số dấu phân cách (ví dụ: dấu cách hoặc dấu phẩy), tiếp theo là dân số Hoa Kỳ (tính bằng triệu người). Bạn cũng có thể viết một hàm trả về hoặc in một chuỗi hoặc một mảng các số hoặc chuỗi.

Đây là mã golf, vì vậy mã ngắn nhất trong byte thắng. Tiebreaker là bài sớm nhất.

Các trường hợp thử nghiệm

Đây là danh sách tất cả các năm có thể, tiếp theo là hai đầu ra.

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
Bạn có phải làm tròn số?
Màu xanh

5
@muddyfish Tôi không chắc là tôi hiểu. Nếu bạn làm theo các hướng dẫn trong truyện tranh một cách chính xác, về mặt kỹ thuật sẽ không có sự phân chia nào xảy ra, nhưng dân số thế giới nên được làm tròn đến phần mười gần nhất.
NinjaBearMonkey

2
Tôi có một chút bối rối bởi người dân Hoa Kỳ. Nếu bạn đang nối một 3, không nên 2040cho dân số 3100? 40 - 10 = 30, 30 * 3 = 90, 90 + 10 = 100, Mà sẽ cung cấp"3" + "100" = 3100
cole

2
@Cole Điểm hay, tôi sẽ làm điều đó để bạn chỉ phải hỗ trợ từ năm 2039. Về mã hóa trong năm, tôi không muốn cho phép mã hóa cứng vì điều đó hầu như sẽ luôn ngắn hơn ngay cả các ngôn ngữ hỗ trợ ngày.
NinjaBearMonkey

8
@NinjaBearMonkey Tôi khuyên bạn nên thay đổi mô tả "thêm 3, suy nghĩ ghép" thành "thêm 300" theo nghĩa đen để bao gồm tất cả các trường hợp cạnh xảy ra khi kết quả trước đó không phải là số dương 2 chữ số đẹp. (Ví dụ: năm 2000 280là kết quả của -20+300=280và không 3 . -20= "3-20")
PhiNotPi

Câu trả lời:


22

Bình thường, 21 20 byte

-1 byte bởi Dennis

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

Chúng có cùng số byte nhưng chỉ có ASCII:

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

Tôi không biết Pyth, nên vẫn thể chơi được. Sử dụng cùng một thuật toán:

TI-BASIC, 23 byte

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

getDatetrả về danh sách ba số float {YYYY,MM,DD}theo một số thứ tự tùy thuộc vào cài đặt định dạng ngày (TI-84 không có kiểu dữ liệu int thực sự); những max(sẽ là năm. Nhân và trừ bên trong max(tiết kiệm một paren gần.


1
Tôi nghĩ rằng đây là lần đầu tiên tôi thấy câu trả lời TI-BASIC ở đây ....
The_Basset_Hound

7
@The_Basset_Hound TI-BASIC là ngôn ngữ phổ biến thứ 28 tại đây với 140 câu trả lời; nó cũng giành được một câu hỏi lớnmột vài câu hỏi nhỏ hơn .
lirtosiast

16

Javascript (ES6), 55 54 48 byte

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

Hoạt động trong Firefox 33; về mặt lý thuyết hỗ trợ tất cả các năm từ 2000 đến 2099. Nếu các chương trình đổ kết quả vào bàn điều khiển không được phép, hãy sử dụng hàm 51 byte này:

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

Chương trình đầy đủ, 55 byte:

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

Nhận được một năm khá tốn kém, nhưng sau khi sử dụng getYear()thay thế getFullYear(), tất cả các số trong phương trình trở nên nhỏ hơn, tiết kiệm rất nhiều byte. EDIT: Nhờ một thủ thuật eeevil, tôi đã bỏ qua newgetYear()hoàn toàn. >: D

Gợi ý chào mừng!


10

Bình thường, 30 byte

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

Chương trình Pyth đầu tiên của tôi!

Cảm ơn @Jakube vì một số gợi ý (tôi sẽ không bao giờ nghĩ về những điều đó!)


3
Chưa đọc câu hỏi, nhưng đây là một vài tối ưu hóa tôi thấy ngay lập tức. Viết mọi thứ trên một dòng. Chọn một thứ tự khác nhau của số và biến ( +*3Z280thay vì +*Z3 280ví dụ). C\dthay vì 100(tiết kiệm không gian). Sử dụng Jthay vì Z(lưu =). Nội tuyến bài tập. Liên kết
Jakube

10

Python 2, 80 byte

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

Bây giờ tròn!


Bạn phải làm tròn, như OP đã làm rõ một phút trước. ;-)
mınxomaτ

3
năm% 100 giống như năm% 40.
lirtosiast

6

CJam, 28 byte

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

Dùng thử trực tuyến

Để thử các năm khác với năm hiện tại, hãy thay thế et0=từ đầu bằng giá trị theo nghĩa đen của năm.


2
Vì 2000 chia hết cho 40 và bạn chỉ cần 2000-2039, bạn có thể sử dụng 40%để lưu một byte.
Andrea Biondo

5

Python 3, 134 byte

Hoạt động tốt nhưng có vẻ hơi dài

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)

Để rút ngắn điều này, sử dụng from time import*, y=strftime('%Y'). Hoặc sao chép câu trả lời của con trăn khác: P
FlipTack

5

Tự động - 60 58 56 byte

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

Việc làm tròn ăn byte (không còn nữa). Bây giờ tôi đã điều chỉnh cả hai công thức. Một số kết quả đầu ra mẫu:

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

Tất cả đều có vẻ chính xác.

Mẹo: Thứ tự thực hiện lưu byte trên dấu ngoặc đơn. Ví dụ (a-4)/4 = a/4-1:-).


4

PowerShell, 53 45 byte

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

Sử dụng một mẹo làm tròn tương tự như câu trả lời Python 2 của muddyfish để đơn giản hóa việc tính toán dân số thế giới, vì PowerShell hoàn toàn Round()s khi bạn chuyển từ a [double]sang một [int], thay vì cắt ngắn.

Đối với đầu ra, chúng tôi giả sử rằng "theo sau bởi một số dấu phân cách (ví dụ: dấu cách hoặc dấu phẩy)" cũng có thể có nghĩa là "dòng mới", vì vậy chúng tôi thực hiện một kết quả và sau đó là kết quả thứ hai. PowerShell hoàn toàn viết ra kết quả, vì vậy chúng tôi không cần gọi rõ ràng bất kỳ lệnh in nào.


3

Toán học, 50 byte

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

Lưu ý rằng điều này phụ thuộc vào việc có Wolfram Engine với Phiên bản số 10+ (phát hành 2014) do phụ thuộc vào DateObjects.

R, 64 byte

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

Cổng trực tiếp của mã Mathicala, nghĩ rằng tôi có một giải pháp ngắn hơn nhưng phụ thuộc vào các gói trong khi điều này hoạt động với cơ sở R.


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

1
Tôi nghĩ bạn cũng không cần dấu ngoặc đơn xung quanh .1.
lirtosiast

3

Java, 180 177 166 152 143 byte

Cảm ơn Thomas đã giúp đỡ một noob :)

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);}}

Phiên bản bị đánh cắp:

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);
  }
}

Yêu cầu Java 8.


import java.time.*? 3.0-> 3.? Bạn cũng không cần phải in năm với đầu ra.
lirtosiast

Ồ, tôi đã không nhận ra rằng bạn không cần năm được in ra ...: P
một spaghetto

3

JavaScript (ES6) 52

Một hàm trả về đầu ra dưới dạng một mảng.

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

Chỉ nhằm mục đích thử nghiệm, hàm chấp nhận đầu vào bằng với năm hiện tại - 1900 (ví dụ 105 cho năm 2015)

Đó là trong dòng câu trả lời của ETHproductions (toán học là toán học) nhưng tránh được mánh khóe xấu xa, nó dễ mang theo hơn ở các địa phương khác nhau. Và như một chức năng, nó ngắn hơn 1 byte.

Đoạn kiểm tra:

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 byte

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

Thật không may, Time.now.yearthực sự chi phí một số nhân vật.


2

Desmos , 140 byte

Tôi đang đếm một dòng mới là tín hiệu cho một phương trình mới. Các thư mục trên liên kết chỉ dành cho tổ chức.

Đã chơi gôn , 140 byte

Nhấp vào add sliderkhi được nhắc.

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 byte

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|

2

Glava, 77 byte

i|f=java.time.LocalDate.now().getYear();F("%.1f %d\n",(3.*f-5755)/40,3*f-5720

Một bản dịch câu trả lời Java của tôi.


1

PHP, 45 byte

Mật mã:

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

y(đối số của date()) là hằng số không xác định, PHP kích hoạt một thông báo (có thể bị tắt tiếng) và chuyển đổi nó thành một chuỗi (khi chúng ta cần); phép lịch sự PHP này cho phép tiết kiệm 2 byte.

Để chặn thông báo, chương trình cần được chạy bằng error_reporting=0chỉ thị thời gian chạy, như sau:

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

Để thử nghiệm

Bằng cách thay thế lệnh gọi date(y)bằng $argv[1](đối số dòng lệnh đầu tiên), độ dài chương trình tăng thêm 1 byte nhưng nó có thể lấy năm từ dòng lệnh.

Đối số dự kiến ​​là năm trừ 2000; nó cũng hoạt động cho các giá trị âm (năm trước năm 2000) hoặc giá trị lớn hơn 40 (sau năm 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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.