Use a fórmula do xkcd para aproximar a população mundial


42

No xkcd 1047 , Randall Munroe lista aproximações "levemente erradas" de quantidades e números variados com precisão e complexidade variadas, tais como que o número de litros em um galão é muito próximo de 3 + π4 . No meio dos quadrinhos, ele dá um intervalo: uma maneira de estimar a população mundial (e dos Estados Unidos) com base em um determinado ano.

Fórmula da população mundial e americana, descrita abaixo
(Cortado de xkcd: Aproximações de Randall Munroe)

Sua tarefa é escrever um programa que implemente essas fórmulas para aproximar o mundo atual e as populações dos EUA, replicadas da seguinte maneira.

População mundial

  1. Pegue os dois últimos dígitos do ano atual.
  2. Subtraia o número de anos bissextos (incluindo o ano atual) desde o furacão Katrina (2005). Para esses fins, qualquer ano divisível por 4 é considerado um ano bissexto.
  3. Adicione um ponto decimal entre os dois números (o mesmo que dividir por 10).
  4. Adicionar 6. Isso dá o resultado em bilhões de pessoas.

População dos EUA

  1. Pegue os dois últimos dígitos do ano atual.
  2. Subtraia 10.
  3. Multiplique por 3.
  4. Adicione 10.
  5. Adicione 3 ao início (para esse desafio, alguns números serão negativos; portanto, adicione 300). De alguma forma, eu não percebi que apenas concatenar não funcionaria porque o programa que eu usei para gerar os resultados acabou de adicionar 300.
  6. Isso dá o resultado em milhões de pessoas.

Detalhes

Essa fórmula "deve permanecer atual por uma década ou duas", mas você deve ser capaz de lidar teoricamente com qualquer ano 2000-2039, inclusive. Em alguns casos, os anos bissextos desde o Katrina terão um valor negativo ou zero.

Você é livre para simplificar a fórmula de qualquer forma, desde que todas as saídas correspondam às que estão abaixo.

Para o ano, use o ano de acordo com o relógio do computador. Ele deve funcionar no próximo ano e em qualquer outro ano deste século, para que você não possa simplesmente codificar em 2015. Por conveniência, convém incluir uma maneira de especificar o ano como uma variável ou entrada para testar outros anos.

O resultado deve ser a população mundial aproximada (em bilhões de pessoas), seguida por algum delimitador (por exemplo, espaço ou vírgula), seguido pela população dos EUA (em milhões de pessoas). Você também pode escrever uma função que retorne ou imprima uma string ou uma matriz de números ou strings.

Este é o código golf, pelo que o código mais curto em bytes vence. O desempate é o primeiro post.

Casos de teste

Esta é uma lista de todos os anos possíveis, seguidos pelas duas saídas.

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
Você precisa arredondar os números?
azul

5
@muddyfish Não sei se entendi. Se você seguir exatamente as instruções dos quadrinhos, tecnicamente não há nenhuma divisão, mas a população mundial deve ser arredondada para o décimo mais próximo.
NinjaBearMonkey

2
Estou um pouco confuso com a população dos Estados Unidos. Se você está concatenando um 3, não deve 2040fornecer uma população de 3100? 40 - 10 = 30, 30 * 3 = 90, 90 + 10 = 100, O que daria"3" + "100" = 3100
cole

2
@Cole Bom ponto, farei com que você só precise dar suporte aos anos até 2039. Sobre a codificação do ano, não quero permitir a codificação, porque isso quase sempre será mais curto, mesmo nos idiomas que suportam datas.
NinjaBearMonkey 12/09

8
@NinjaBearMonkey Sugiro que você altere a descrição de "adicionando 3, concatenação pensando" para um literal "adicione 300" para cobrir todos os casos extremos que ocorrem quando o resultado anterior não é um número positivo de dois dígitos. (Por exemplo, 2000 dá 280como resultado de -20+300=280e não 3 . -20= "3-20")
PhiNotPi

Respostas:


22

Pitão, 21 20 bytes

-1 byte por Dennis

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

Eles têm a mesma contagem de bytes, mas são apenas ASCII:

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

Eu não conheço Pyth, então ainda provavelmente provavelmente jogável. Usando o mesmo algoritmo:

TI-BASIC, 23 bytes

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

getDateretorna uma lista de três carros alegóricos {YYYY,MM,DD}em alguma ordem, dependendo da configuração do formato da data (as TI-84 não têm um tipo de dados int verdadeiro); o max(será o ano. Multiplicar e subtrair dentro do max(salva um ponto final.


1
Eu acho que esta é a primeira vez que eu vi uma resposta TI-BASIC aqui ....
The_Basset_Hound

7
@The_Basset_Hound O TI-BASIC é o 28º idioma mais comum aqui, com 140 respostas; ele também ganhou um grande e um alguns pequenos questões .
precisa saber é o seguinte

16

Javascript (ES6), 55 54 48 bytes

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

Funciona no Firefox 33; teoricamente, suporta todos os anos de 2000 a 2099. Se programas que despejam o resultado no console não forem permitidos, use esta função de 51 bytes:

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

Programa completo, 55 bytes:

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

Obter o ano foi bastante caro, mas depois de usar o obsoleto em getYear()vez de getFullYear(), todos os números na equação ficaram menores, economizando muitos bytes. Edição: Graças a um truque eeevil, eu pulei newe getYear()completamente. >: D

Sugestões são bem-vindas!


10

Pitão, 30 bytes

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

Meu primeiro programa Pyth!

Obrigado @Jakube por algumas dicas (eu nunca teria pensado nisso!)


3
Ainda não li a pergunta, mas aqui estão algumas otimizações que vi imediatamente. Escreva tudo em uma linha. Escolha uma ordem diferente de números e variáveis ​​(em +*3Z280vez de, +*Z3 280por exemplo). C\dem vez de 100(economiza espaços). Use em Jvez de Z(salva o =). Inline a tarefa. Link
Jakube 12/09/2015

10

Python 2, 80 bytes

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

Agora rodadas!


Você tem que arredondar, como o OP esclareceu um minuto atrás. ;-)
mınxomaτ

3
ano% 100 é o mesmo que ano% 40.
lirtosiast

6

CJam, 28 bytes

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

Experimente online

Para tentar anos diferentes do atual, substitua o et0=no início pelo valor literal do ano.


2
Como 2000 é divisível por 40 e você só precisa de 2000-2039, você pode usar 40%para salvar um byte.
Andrea Biondo

5

Python 3, 134 bytes

Funciona bem, mas parece um pouco longo

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)

Para encurtar isso, use from time import*, y=strftime('%Y'). Ou copie a outra resposta python: P
FlipTack

5

AutoIt - 60 58 56 bytes

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

O arredondamento come bytes (não mais). Agora ajustei as duas fórmulas. Algumas saídas de amostra:

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

Todos eles parecem ser precisos.

Uma dica: a ordem de execução salva bytes entre parênteses. Por exemplo: (a-4)/4 = a/4-1:-).


4

PowerShell, 53 45 bytes

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

Usa um truque de arredondamento semelhante ao da resposta de Python 2 do muddyfish para simplificar o cálculo da população mundial, pois o PowerShell implicitamente Round()s quando você transmite de a [double]para um [int], em vez de truncar.

Para a saída, assumimos que "seguido por algum delimitador (por exemplo, espaço ou vírgula)" também pode significar "nova linha"; portanto, executamos um resultado e depois o segundo. O PowerShell escreve implicitamente os resultados, portanto, não precisamos chamar explicitamente nenhum comando de impressão.


3

Mathematica, 50 bytes

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

Observe que isso depende de ter um Wolfram Engine com o número da versão 10+ (lançado em 2014) devido à dependência DateObjects.

R, 64 bytes

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

Porta direta do código do Mathematica, acho que tive uma solução mais curta, mas dependente dos pacotes, enquanto isso funciona com a base R.



1
Eu acho que você também não precisa de parênteses ao redor do .1.
lirtosiast

3

Java, 180 177 166 152 143 bytes

Obrigado Thomas por ajudar um noob a sair :)

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

Versão não destruída:

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

Requer Java 8.


import java.time.*? 3.0-> 3.? Você também não precisa imprimir o ano com a saída.
lirtosiast

Oh, eu não sabia que você não precisa do ano impresso ...: P
uma Spaghetto

3

JavaScript (ES6) 52

Uma função retornando a saída como uma matriz.

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

Apenas para fins de teste, a função aceita uma entrada igual ao ano atual - 1900 (por exemplo, 105 para 2015)

Isso está na linha da resposta da ETHproductions (a matemática é a matemática), mas avodando o truque do mal , é mais portátil em locais diferentes. E, como função, é 1 byte menor.

Snippet de teste:

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 bytes

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

Infelizmente, Time.now.yearrealmente custa alguns personagens.


2

Desmos , 140 bytes

Estou contando uma nova linha para ser um sinal para uma nova equação. Pastas no link são apenas para organização.

Golfe , 140 Bytes

Clique add sliderquando solicitado.

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|

2

Glava, 77 bytes

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

Uma tradução da minha resposta Java.


1

PHP, 45 bytes

O código:

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

Como y(o argumento de date()) é uma constante indefinida, o PHP aciona um aviso (que pode ser silenciado) e o converte em uma string (conforme necessário); essa cortesia do PHP permite economizar 2 bytes.

Para suprimir o aviso, o programa precisa ser executado usando a error_reporting=0diretiva de tempo de execução, assim:

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

Para teste

Substituindo a chamada por date(y)with $argv[1](o primeiro argumento da linha de comando), o comprimento do programa aumenta em 1 byte, mas ele pode obter o ano a partir da linha de comando.

O argumento esperado é o ano menos 2000; também funciona para valores negativos (anos antes de 2000) ou valores maiores que 40 (após o ano 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

1

APL, 25 23 29 bytes

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

TryAPL

Sim, são 29 bytes .


Salve dois caracteres: (∘ ∘40, + ∘33) ¯5753 + 3 × ⊃⎕TS
Adám
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.