fundo
Alguns feriados têm datas fixas e fáceis de lembrar, como 31 de outubro, 25 de dezembro, etc. Alguns, no entanto, querem ser problemáticos. Eles são especificados como "primeira segunda-feira de setembro" ou "quarta quinta-feira de novembro". Como vou saber quando é isso?
Tudo o que sei é que o Dia de Ação de Graças está se aproximando rapidamente, por isso preciso de um programa para me ajudar a descobrir quando é que está. Algumas pessoas até dizem que é amanhã , então seu programa precisa ser o mais curto possível para garantir que eu possa digitá-lo novamente a tempo.
O desafio
Crie um programa ou função que, com um ano de até quatro dígitos (por exemplo, 2015 ou 1984), produza ou retorne a data do Dia de Ação de Graças dos Estados Unidos naquele ano. O Dia de Ação de Graças é definido como a quarta quinta-feira de novembro, de acordo com a página da Wikipedia . (Dica: essa página também inclui algumas informações interessantes sobre o padrão de data.)
Entrada : um número decimal com no máximo quatro dígitos representando um ano na Era Comum (CE). Exemplos: 987, 1984, 2101
Saída : a data, incluindo mês e dia, em que o Dia de Ação de Graças cai, ou cairia se existisse naquele ano. Isso pode estar em qualquer formato razoável; use seu melhor julgamento. Use o calendário gregoriano em todos os casos, mesmo que não estivesse em uso no momento.
(Nota: lide com os anos bissextos corretamente!)
Casos de teste
Entrada 1:
2015
Saída 1:
Nov 26
Entrada 2:
1917
Saída 2:
Nov 22
Pontuação
As submissões serão pontuadas em bytes . Eu recomendo este site para acompanhar sua contagem de bytes, embora você possa usar qualquer contador que desejar.
Bônus
-25% a sua pontuação, se você lidar com datas de AEC como números negativos (por exemplo, -480 seria o ano da batalha das Termópilas).
Entrada negativa do caso de teste:
-480
Saída correspondente:
Nov 25
Isso é código-golfe , então a pontuação mais baixa ganha!
Edit: Estou marcando o envio do TI-BASIC de Thomas Kwa como aceito. Não deixe isso desencorajar você a enviar novas entradas!
Classificação
Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.
Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:
# Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes
Se você quiser incluir vários números em seu cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou deseja listar as penalidades de sinalizador de intérprete separadamente), verifique se a pontuação real é o último número no cabeçalho:
# Perl, 43 + 2 (-p flag) = 45 bytes
Você também pode transformar o nome do idioma em um link que será exibido no snippet da tabela de classificação:
# [><>](http://esolangs.org/wiki/Fish), 121 bytes
var QUESTION_ID=64785,OVERRIDE_USER=45162;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?([\d.]+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
Respostas:
TI-BASIC, 15 bytes * 0,75 = 11,25
Testado na minha calculadora TI-84 +
O Dia de Ação de Graças é 29 de novembro, menos o dia da semana de 1º de setembro, onde 1 é domingo e 7 é sábado. Isso gera no formato
MMDD
.Casos de teste:
2015
->1126
,1917
->1122
,-480
->1125
foram verificados. O TI-BASIC parece usar o calendário gregoriano para todas as datas.O TI-BASIC não suporta anos negativos, mas isso recebe o bônus porque adicionamos 10000 à entrada. Como o calendário gregoriano tem um período de 400 anos, isso não muda o dia da semana.
fonte
dayofWK(
eAns
com 2 e 1 bytes cada.PHP,
6548424136 (+2 para-F
) = 38 bytesRecebe entrada como o primeiro argumento da linha de comando. É executado com avisos que são aceitáveis pelas nossas regras. Impressões
NovDD
, ondeDD
é o dia de Ação de Graças.Nenhum link on-line porque o ideone não suporta argumentos de linha de comando e eu não conheço um intérprete on-line que suporte.
Agradeço a Alexander O'Mara por me ensinar um novo truque e por uma redução significativa
fonte
"4thuXI"
. Você pode até deixar o espaço entre o ano"4thuXI2015"
.-F
, a entrada pode ser reduzida para"4thuXI$argn"
.Md
não precisa de aspas, comE_NOTICE
pessoas com deficiência.Mathematica,
5938 bytesfonte
WolframAlpha["Thanksgiving " <> #] &
onde a data é inserida como uma sequência.JavaScript (ES6),
424031 bytes - 25% = 23,25Como a data "pode estar em qualquer formato razoável", esta função é utilizada
DD.MM
. Eu escrevi uma resposta TeaScript com uma técnica diferente, mas essa fórmula foi mais curta.Explicação
Como os meses são baseados em zero,
new Date(a,10)
retorna umDate
objeto que representa 1 de novembro do ano especificado.Como
getDay()
retorna um número que representa o dia da semana0..6
, queremos mapear a partir dedepois adicione 22. Acontece que
(11 - new Date(a,10).getDay()) % 7
isso funcionará. Como apontou @Thomas Kwa , é o mesmo28-new Date(a,8).getDay()
que ocorre 28 menos o dia da semana de 1º de setembro.fonte
Japt ,
4337363529 bytes - 25% = 21,75Japt é uma versão abreviada do Ja vaScri pt .
Hahaha, encontrei um truque muito barato: o intérprete ignora quaisquer colchetes dentro de strings (usados para inserir código) enquanto os descompacta, para que possamos compactar todo o código-fonte para salvar um byte>: D
Os dois
?
s devem ser os unprintables Unicode U + 0098 e U + 0085, respectivamente. Experimente online!Após a descompressão, o código avalia isso:
Qual avalia para:
O que fornece a saída adequada.
Utiliza a técnica do intrepidcoder , produzindo em formato
dd.mm
. Apoia adequadamente anos negativos. Sugestões são bem-vindas!Edit: A partir de 2 de dezembro, agora você pode usar este código de 11 bytes (com pontuação de 8,25 pontos ):
(Eu gostaria de ter implementado isso mais cedo!)
fonte
Vitsy , 44 bytes
Eu estou calculando com pura matemática !
Golfe:
Ungolfed (moveu a chamada de método para a primeira linha para torná-la legível):
Provavelmente existe um algoritmo melhor para isso (e isso provavelmente é terrivelmente complicado), mas para aqueles que se perguntam, meu algoritmo vem daqui .
Experimente online!
Recebo pontos de bônus por calculá-lo e ter exatamente 42 bytes?Sonhos arruinados.Obrigado a @ Hosch250 por apontar que estava fazendo errado. : D Fixo.
fonte
Python, 38 * 0,75 = 28,5 bytes
Isso funciona com anos negativos da maneira especificada na pergunta, embora tenha chegado ao meu conhecimento que não há ano 0 no calendário gregoriano, portanto esse comportamento é um pouco suspeito.
fonte
f=
."Nov "+`...`
-40%7==2
mas-40%-7==-5
JavaScript (ES6), 43,5
A contagem real de bytes é 58. O bônus de -25% se aplica => 58 * 0,75 = 43,5
De maneira bem direta
e boba, sem nenhuma solução ou cálculo complicado.De-golfe (ES5) + demo:
Observe que esse ano 0-100 produz 1900-2000 ano. No entanto, parece que 0-100 anos dão a mesma data que 1900-2000, a julgar pelas outras respostas.
Substituindo
a+18
por22
, porque é chamado apenas em "else" e "else" ocorre apenas se a não for maior nem menor que 4, ou seja, exatamente 4.Substituindo
a<4?26-a:a>4?a+21:22
pora<=4?26-a:a+21
fonte
a<4?x:a>4?y:a+18
equivalentea<4?x:a>4?y:22
?TeaScript,
353324 bytes - 25% = 18Esse é o mesmo método da minha resposta JavaScript , que usa a fórmula inteligente de Thomas Kwa .
Versão alternativa com explicação
fonte
Jython,
141155 bytesUsa as classes Java Calendar e Scanner com sintaxe Python.
Editar: pequenos problemas de sintaxe, adicionados 14 bytes.
Veja também minha versão do Brainfuck .
fonte
Python,
838178 bytesfonte
import datetime as d
e, em seguida, você poderá usard
sempre que usardatetime
em seu programa.import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
from datetime import*
é ainda um pouco mais curto, pois você não precisarád.
mais dissoExcel,
36715453 - 25% = 39,75 bytesSupõe que o ano seja mantido na célula A1, no formato Data. Retorna o número inteiro do dia de novembro em que o Dia de Ação de Graças é realizado.
Isso explica apenas os anos bissextos normais. Não explica o fato de que os anos 2100, 2200, 2300 não são bissextos.
Isso foi projetado apenas para trabalhar a partir de 1621 - ou seja, desde que o Dia de Ação de Graças começou a ser realizado. (Embora certamente funcione até 0 dC).
Pretty-impresso:
Gah! Em vez de calcular com base no dia 1º de janeiro, e depois fazer muitos cálculos do ano bissexto para lidar com o dia 29 de fevereiro, eu deveria ter baseado os cálculos no dia 1º de novembro. Agora, isso agora lida corretamente com os anos 2100, 2200 e 2300 , mas torna a implementação dependente do formato de data padrão da instalação do Excel. Esta versão foi projetada para dd / mm / aaaa:
E agora que eu fiz o pfaffing para obter um cálculo conciso no Smalltalk, o backporting para o Excel resulta em:
(com o ano ainda em A1, mas como um número inteiro). Isso funciona até para os anos 2100, 2200 e 2300, para todas as datas a partir de 7700BC / E, usando o truque de repetição de datas de Thomas Kwa.
fonte
PowerShell,
676484725845 BytesTomamos nosso número inteiro de entrada como
$a
e imediatamenteNov
produzimos uma nova linha. Em seguida, pegamos$a
e anexamos com zeros e 1º de setembro com00$a/9/1
antes de gerar um novodate
e determinar oDayOfWeek
que é isso. Se 1º de setembro for no domingo (.DayOfWeek
igual a0
), o Dia de Ação de Graças será no dia 28. Se 1º de setembro for uma segunda-feira (.DayOfWeek
igual a1
), o Dia de Ação de Graças será no dia 27. E assim por diante. Assim, subtraímos esse dia da semana28
para produzir nossa resposta.O prefixo com zeros duplos é responsável por anos de um e dois dígitos, sem interromper a análise por anos de três ou quatro dígitos. Não funciona para números negativos, pois o .NET
datetime
não suporta anos menos que0
.Agradecemos a TessellatingHeckler e Toby Speight pela assistência.
fonte
"{0:D3}/Nov/$_" -f $a
é mais curto que"$($a.ToString("000"))/Nov/$_"
e produz o mesmo resultado, e acho que você poderia usar em11
vez deNov
Nov
era um remanescente de quando eu estava tentando fazer com que ele reconhecesse os anos de dois dígitos corretamente, então trocarei isso também. Obrigado!date "11/1/$a"
resultadosThursday, November 1, 2007 12:00:00 AM
. Isso ocorre porque não estamos editando a propriedade Calendar.TwoDigitYearMax ; portanto, quando ele é analisado , estamos presos a um preenchimento com zero duplo para contornar isso.Golfscript, 25 * 0,75 = 18,75 bytes
Isso usa a fórmula de Sakamoto para o dia da semana. Como há pessoas fazendo isso, a saída está na forma de
dd-mm
. Meu envio anterior pode ser encontrado abaixo:fonte
TSQL,
478296 bytesApenas por diversão. Normalmente, você teria uma tabela dimensional de data para tornar isso simples,
select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'
mas na ausência disso ...Ungolfed:
fonte
(28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7
) Sim, ler outras respostas tende a ajudar bastante.Pitão,
3028 * 75% = 21 bytesTenho 100% de certeza de que isso poderia ser reduzido, mas, ei, é o meu primeiro programa Pyth! \ o /
Suíte de teste
Mostra a data em
dd.mm
formato.Por favor, sugira maneiras de jogar isso se puder! Eu gostaria de aprender mais sobre Pyth.
fonte
Excel,
6448.Ano na A1
= DATA (A1,11, ESCOLHA (SEMANA (DATA (A1,11,1)), 26,25,24,23,22,28,27))fonte
13
bytesTEXT
de=TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")
- a saída é um número inteiro sem formatação.Befunge, 41 bytes
Execute esse intérprete .
Explicação: Um ano comum é 365 = 1 mod 7 dias, de modo que o ano mais todos os 4 th ano, menos a cada 100 th (
d
ano em ASCII), além de cada 400 th anos é responsável por quaisquer dias salto (incluindo o presente ano). O resultado:::4"d"*/\"d"/-\4/++
pode ser pensado como 05 março th , o primeiro dia depois de fevereiro a cair no mesmo dia como o primeiro dia do ano em anos comuns. Depois que calibrar o padrão com5+7%-
subtraindo um número de dias da semana a partir do 28 º (a47*
armazenados anteriormente) de novembro. Então imprima.Atualmente, uma versão corrigida para os anos BC é mais longa do que o bônus previsto, com 59 a 25% = 44,25 bytes:
fonte
Matlab, 78 bytes
fonte
Ruby,
605857 * 0,75 = 42,75 bytes58 bytes
60 bytes
Ungolfed:
Uso:
fonte
VBA, 124 bytes * 75% = 93 bytes
Não sei se os espaços contam, é algo entre 102 e 124, fique à vontade para editar.
Se números inteiros são uma saída válida, fico feliz em remover a
Format
peça.fonte
PHP 5.3 ou superior, 59 bytes
Isso usa a função incorporada do PHP
strtotime
para analisar a data.Isso espera que o valor seja passado sobre o parâmetro GET
Y
OU sobrephp-cli Y=<year>
.Ele tenta encontrar a próxima quinta-feira após 19 de novembro.
Até agora, com os testes que fiz, funciona bem.
Esteja ciente de que os anos de 2 dígitos podem ser interpretados de maneira diferente.
Eu uso
gmdate
para evitar problemas de fuso horário, mas funciona igualmente bem usandodate
(pelo menos onde eu moro).fonte
T-SQL
215 bytes248 * 0,75 = 186 bytesUngolfed
que com este andaime de teste
produz conforme desejado
fonte
Pike ,
87 91 107 7776 bytes - 25% = 57deixando o antigo para comparação porque acho mais inteligente em termos de tirar proveito do módulo Calendário, mas o acima é bem mais curto.
fonte
string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}
, conto isso como 107 bytes.Smalltalk - Squeak and Pharo ,
6957544935343332 - 25% = 24 bytes"
Novnn":69B49B (-25% = 36,75B)11nn (anInt):
575432B (-25% = 24B)Versões prévias
Saída 11nn
Novnn output
saída nn
NOTA: Isso é fornecido como um programa - especificamente uma expressão do Espaço de Trabalho - e não como um método.
Ele assume que a entrada é um dado (de acordo com o fraseado "dado um ano de até quatro dígitos".
Incluir a declaração e a doação da entrada adicionaria outros 11 caracteres:
|y|y:=2015.(12-(Date y:y m:11 d:1)w)\\7+1122
Obrigado ao eMBee, por mostrar como remover mais um caractere - o espaço em branco imediatamente antes do 'w'.
Na verdade, isso me inspirou a tentar remover o espaço em branco antes de 'd:':
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
que funcionou!
fonte
Coreutils GNU, 35 bytes
Basta pesquisar na semana 22 e 28 de novembro uma quinta-feira. Execute-o em um código de idioma C ou POSIX, pois dependo que quinta-feira seja a única abreviação de dia para conter um 'h'.
Aqui está uma resposta mais inteligente, embora um byte mais longo:
Recuperamos o número do dia da semana de uma data em uma semana razoavelmente arbitrária entre março e setembro (portanto, dia e mês têm um dígito cada e não somos afetados por um possível dia bissexto). Escolhemos o dia para que seja domingo (
%w==0
) quando o Dia de Ação de Graças é no dia 28. Podemos então subtrair esse valor de 28 para obter a quinta-feira apropriada.fonte
TSQL,
5352 bytesViolino
Calculando segunda-feira antes ou 2 de setembro e adicionando 59 dias
(melhor do que calcular segunda-feira antes ou no dia 4 de outubro e adicionar 31 dias porque outubro é o 10º mês, economizando 1 byte)
fonte
Perl, 92 bytes
EDIT: Formato de saída fixo, bug corrigido, por exemplo, resultado de 2012, usado no formato "for" mais curto. Graças ao msh210.
fonte
use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29
. Mas ambos os scripts sofrem das mesmas falhas: (1) eles não imprimem uma representação do mês conforme necessário; (2) eles têm uma saída errada para, por exemplo 2012.