Используйте формулу xkcd, чтобы приблизить население мира

42

В xkcd 1047 Рэндалл Манро перечисляет «слегка неправильные» аппроксимации различных величин и чисел с различной точностью и сложностью, например, что количество литров в галлоне очень близко к 3 + π4 . В середине комикса он дает антракт: способ оценки мирового населения (и Соединенных Штатов) на основе данного года.

Формула населения мира и США, описанная ниже
(Вырезано из xkcd: приближения Рэндалла Манро)

Ваша задача состоит в том, чтобы написать программу, которая реализует эти формулы для аппроксимации текущего мира и населения США, реплицируясь следующим образом.

Мировое население

  1. Возьмите последние две цифры текущего года.
  2. Вычтите число високосных лет (включая текущий год) после урагана Катрина (2005 г.). Для этих целей любой год, кратный 4, считается високосным.
  3. Добавьте десятичную точку между двумя числами (так же, как деление на 10).
  4. Добавить 6. Это дает результат в миллиардах людей.

Население США

  1. Возьмите последние две цифры текущего года.
  2. Вычтите 10.
  3. Умножьте на 3.
  4. Добавить 10
  5. Добавьте 3 к началу (для этого задания некоторые числа будут отрицательными, поэтому вместо них добавьте 300). Почему-то я не заметил, что просто конкатенация не сработает, потому что программа, которую я использовал для генерации результатов, только добавила 300.
  6. Это дает результат в миллионах людей.

Детали

Эта формула «должна оставаться актуальной в течение десяти или двух лет», но теоретически вы должны быть в состоянии справиться с любым 2000–2039 годом включительно. В некоторых случаях високосные годы после Катрины будут иметь отрицательное или нулевое значение.

Вы можете упростить формулу любым способом, если все выходные данные соответствуют приведенным ниже.

Для года используйте год по часам компьютера. Он должен работать в следующем году и в любой другой год этого столетия, поэтому вы не можете просто жестко кодировать 2015. Для удобства вы можете включить способ указания года в качестве переменной или ввода для проверки других лет.

Выходными данными должны быть приблизительные данные о численности населения мира (в миллиардах человек), после которых следует некоторый разделитель (например, пробел или запятая), за которым следует население США (в миллионах человек). Вы также можете написать функцию, которая возвращает или печатает строку или массив чисел или строк.

Это код гольф, поэтому выигрывает самый короткий код в байтах. 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
NinjaBearMonkey
источник
1
Вы должны округлить числа?
Синий,
5
@muddyfish Я не уверен, что понимаю. Если вы точно следуете инструкциям в комиксе, технически разделение не происходит, но численность населения мира должна быть округлена до десятых.
NinjaBearMonkey
2
Я немного смущен населением Соединенных Штатов. Если вы объединяете 3, разве не следует 2040давать населению 3100? 40 - 10 = 30, 30 * 3 = 90, 90 + 10 = 100, Который дал бы"3" + "100" = 3100
Cole
2
@Cole Хорошая мысль, я сделаю так, чтобы вам приходилось поддерживать только годы до 2039 года. Что касается жесткого кодирования года, я не хочу разрешать жесткое кодирование, потому что это почти всегда будет короче даже для языков, которые поддерживают даты.
NinjaBearMonkey
8
@NinjaBearMonkey Я предлагаю, чтобы вы изменили описание «добавление 3, конкатенация мышления» на буквальное «добавить 300», чтобы охватить все крайние случаи, которые возникают, когда предыдущий результат не является хорошим двузначным положительным числом. (Например, 2000 год дает 280в результате, -20+300=280а не 3 . -20= "3-20")
PhiNotPi

Ответы:

22

Pyth, 21 20 байт

-1 байт Денисом

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

Они имеют одинаковое количество байтов, но только для ASCII:

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

Я не знаю Пита, так что все еще возможно возможно игра в гольф. Используя тот же алгоритм:

TI-BASIC, 23 байта

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

getDateвозвращает список из трех чисел с плавающей точкой {YYYY,MM,DD}в некотором порядке, в зависимости от настройки формата даты (TI-84 не имеют истинного типа данных int); max(будет год. Умножение и вычитание изнутри max(спасает близкого человека.

lirtosiast
источник
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

Предложения приветствуются!

ETHproductions
источник
10

Pyth, 30 байт

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

Моя первая программа Pyth!

Спасибо @Jakube за некоторые подсказки (я бы никогда не подумал об этом!)

синий
источник
3
Не читал вопрос, но вот несколько оптимизаций, которые я сразу увидел. Напишите все в одной строке. Выберите другой порядок чисел и переменных ( +*3Z280вместо, +*Z3 280например). C\dвместо 100(экономит место). Используйте Jвместо Z(сохраняет =). Вставьте задание. Ссылка
Якуб
10

Python 2, 80 байт

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

Теперь раунды!

синий
источник
Вы должны округлить, как объяснил OP минуту назад. ;-)
mynxomaτ
3
год% 100 совпадает с годом% 40.
lirtosiast
6

CJam, 28 байтов

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

Попробуйте онлайн

Чтобы попробовать годы, отличные от текущего, замените et0=в начале буквальное значение года.

Рето Коради
источник
2
Поскольку 2000 делится на 40, а вам нужно только 2000-2039, вы можете использовать, 40%чтобы сохранить один байт.
Андреа Биондо
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'). Или скопируйте другой ответ Python: 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:-).

mınxomaτ
источник
4

PowerShell, 53 45 байт

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

Использует трюк с округлением, аналогичный ответу Python 2 от muddyfish, для упрощения расчета численности населения в мире, поскольку PowerShell неявно Round()s при [double]преобразовании из a в [int], а не в усечение.

Для вывода мы предполагаем, что «после некоторого разделителя (например, пробел или запятая)» также может означать «перевод строки», поэтому мы выполняем один результат, а затем второй. PowerShell неявно записывает результаты, поэтому нам не нужно явно вызывать какие-либо команды печати.

AdmBorkBork
источник
3

Mathematica, 50 байтов

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

Обратите внимание, что это зависит от наличия двигателя Wolfram Engine с версией 10+ (выпущена в 2014 году) из-за зависимости от DateObjects.

R, 64 байта

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

Прямой порт кода Mathematica, думаю, у меня было более короткое решение, но зависящее от пакетов, тогда как это работает с базой R.

Мартин Джон Хэдли
источник
1
(1/10)-> .1?
lirtosiast
1
Я думаю, вам также не нужны круглые скобки .1.
lirtosiast
3

Java, 180 177 166 152 143 байта

Спасибо Томасу за помощь новичку :)

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 }

edc65
источник
2

Рубин, 57 байт

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

К сожалению, Time.now.yearдействительно стоит некоторых персонажей.

PotatoOmeletteSandwich
источник
2

Desmos , 140 байт

Я считаю, что новая строка является сигналом для нового уравнения. Папки по ссылке предназначены только для организации.

Гольф , 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 байт

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

Глава, 77 байт

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

Перевод моего Java-ответа.

спагетто
источник
1

PHP, 45 байт

Код:

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

Поскольку y(аргумент date()) является неопределенной константой, PHP вызывает уведомление (которое может быть отключено) и преобразует его в строку (как нам нужно); эта вежливость PHP позволяет сэкономить 2 байта.

Чтобы подавить уведомление, программа должна быть запущена с использованием error_reporting=0директивы runtime, например:

$ 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
axiac
источник
1

APL, 25 23 29 байт

{(10÷⍨⌊⍵÷4),⍵+33}⊃¯5753+3×⎕TS

TryAPL

Да, это 29 байтов .

Shujal
источник
Сохраните два символа: (÷ ∘40, + ∘33) ¯5753 + 3 × ⊃⎕TS
Адам