Quando é o Dia de Ação de Graças?

38

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 é , 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 Nestá 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

bkul
fonte
25
Para quem está se perguntando quando o Dia de Ação de Graças estará chegando este ano: O Dia de Ação de Graças será amanhã.
TheNumberOne
6
Mas eu tive ação de graças no dia 10 de outubro? Lamento dizer que sua pergunta está atrasada.
JimmyJazzx
5
@Downgoat Use o contador de bytes que desejar. Esse é apenas o que eu uso pessoalmente e recomendaria.
bkul
22
"Alguns feriados têm datas fixas e fáceis de lembrar, como 31 de outubro e 25 de dezembro". Esses exemplos são fáceis de lembrar porque são realmente no mesmo dia: 31 de outubro == decimal 25. ;-)
Adrian McCarthy
7
Para uma resposta que ofereça o bônus, deve haver um ano 0 entre -1 e 1 ou não?
feersum

Respostas:

40

TI-BASIC, 15 bytes * 0,75 = 11,25

Testado na minha calculadora TI-84 +

1129-dayOfWk(Ans+ᴇ4,9,1

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-> 1125foram 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.

lirtosiast
fonte
5
Caralho. xD Eu nunca pensei que isso teria funcionado assim, +1.
Addison Crump
Boa ideia para adicionar 10000. Legal.
agtoever
Eu conto 23 letras. Como isso pode ser de 15 bytes?
Stephan Schinkel
1
@StephanSchinkel O TI-BASIC usa tokens armazenados na memória das calculadoras. Acredito que todos os caracteres aqui tenham 1 byte, exceto os tokens dayofWK(e Anscom 2 e 1 bytes cada.
FryAmTheEggman
Você testou em uma calculadora? Uau.
23

PHP, 65 48 42 41 36 (+2 para -F) = 38 bytes

<?date(Md,strtotime("4thuXI$argn"));

Recebe entrada como o primeiro argumento da linha de comando. É executado com avisos que são aceitáveis ​​pelas nossas regras. Impressões NovDD, onde DDé 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

Mego
fonte
2
Isso é mais engraçado que o Mathematica.
lirtosiast
2
@Tryth ainda mais curto: "4thuXI". Você pode até deixar o espaço entre o ano "4thuXI2015".
Alexander O'Mara
1
Usando a opção de linha de comando -F, a entrada pode ser reduzida para "4thuXI$argn".
Primo
3
Espere, isso realmente funciona? Isso é ... isso é ... eu nem ...
ETHproductions
1
Funciona para mim . Enquanto estou nisso, Mdnão precisa de aspas, com E_NOTICEpessoas com deficiência.
primo
18

Mathematica, 59 38 bytes

DayRange[{#,11},{#,12},Thursday][[4]]&
LegionMammal978
fonte
+1 inteligente. Também é WolframAlpha["Thanksgiving " <> #] &onde a data é inserida como uma sequência.
DavidC
WolframAlpha retorna no dia de Ação de Graças dos EUA a partir de 1863 (quando Lincoln declarou que seria na ÚLTIMA quinta-feira de novembro) em diante. Os EUA observam o Dia de Ação de Graças desde 1789.
DavidC
@DavidCarraher No entanto, os estados do OP que o programa tem de trabalhar para , pelo menos, 0 - 9999 CE
LegionMammal978
17

JavaScript (ES6), 42 40 31 bytes - 25% = 23,25

a=>28.11-new Date(a,8).getDay()

Como 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 um Dateobjeto que representa 1 de novembro do ano especificado.

Como getDay()retorna um número que representa o dia da semana 0..6, queremos mapear a partir de

Su Mo Tu We Th Fr Sa 
0  1  2  3  4  5  6  
to to to to to to to
4  3  2  1  0  6  5  

depois adicione 22. Acontece que (11 - new Date(a,10).getDay()) % 7isso funcionará. Como apontou @Thomas Kwa , é o mesmo 28-new Date(a,8).getDay()que ocorre 28 menos o dia da semana de 1º de setembro.

intrepidcoder
fonte
Solução agradável, eu amo o quão curto é e que ainda é mais compreensível do que a maioria das entradas.
Marko Grešak 28/11
16

Japt , 43 37 36 35 29 bytes - 25% = 21,75

Japt é uma versão abreviada do Ja vaScri pt .

`{28.11-?w D?e(U,8).getDay()}

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:

"{28.11-new Date(U,8).getDay()}"

Qual avalia para:

""+(28.11-new Date(U,8).getDay())+""

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 ):

28.11-ÐU8 e

(Eu gostaria de ter implementado isso mais cedo!)

ETHproductions
fonte
Muito bem feito.
bkul
Agora isso é mais do que o JavaScript básico. Thomas Kwa tem uma fórmula muito mais curta .
Intrepidcoder
@intrepidcoder Obrigado, corrigido.
ETHproductions
12

Vitsy , 44 bytes

Eu estou calculando com pura matemática !

Golfe:

Ve2 * V2-V41m + Vaa * Dv1m-Vv4 * 1m + 7M-baa * / + N
/ D1M-

Ungolfed (moveu a chamada de método para a primeira linha para torná-la legível):

Ve2 * V2-V4 / D1M- + Vaa * Dv / D1M - Vv4 * / D1M- + 7M-baa * / + N

V Salve a entrada como uma variável final.
 e2 * Pressione 28 para a pilha.
    V Empurre a entrada para a pilha.
     2- Subtraia dois.
       V4 / D1M - Obter piso (entrada / 4).
              + Adicione ao total.
               Vaa * Dv / D1M - obtenha piso (entrada / 100) e economize 100 como uma temperatura
                                    variável no processo.
                          - Subtraia do total.
                           Vv4 * / D1M - Obter piso (entrada / 400).
                                    + Adicione ao total.
                                     Módulo 7M por sete.
                                       - Subtraia o resultado de 28.
                                        baa * / + Adicionar .11
                                              N Saída como número.

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.

Addison Crump
fonte
2
Não. Mas você recebe um +1 de mim;)
Conor O'Brien
Ele diz que a acção de graças em 2016 é novembro 28. É realmente novembro 24.
Hosch250
@ Hosch250 Você está certo - corrigido agora.
Addison Crump
10

Python, 38 * 0,75 = 28,5 bytes

lambda x:28.11-(x-2+x/4-x/100+x/400)%7

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.

Luke
fonte
1
Você pode largar f=.
feersum
1
Como isso funciona para datas negativas? O módulo em Python se aplica a negativos? : O
Addison Crump
Deve ser mais curto para usar representantes de cadeia de caracteres,"Nov "+`...`
xnor
O módulo Python do @VoteToClose fornece uma resposta com o mesmo sinal que o segundo argumento. Assim, -40%7==2mas-40%-7==-5
quintopia 26/11/2015
@ Quintopia Espere, espere, eu sou um idiota. OK. Isso faz sentido.
Addison Crump
10

JavaScript (ES6), 43,5

A contagem real de bytes é 58. O bônus de -25% se aplica => 58 * 0,75 = 43,5

s=>new Date(s,10,(a=new Date(s,10).getDay())<5?26-a:a+21)

De maneira bem direta e boba , sem nenhuma solução ou cálculo complicado.

De-golfe (ES5) + demo:

function t(s) {
    a = new Date(s, 10).getDay();
    alert(new Date(s,10,a<=4?26-a:a+21))
}

t(prompt())

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+18por 22, 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:22pora<=4?26-a:a+21

nicael
fonte
2
Perdoe-me se eu estiver errado, mas não é a<4?x:a>4?y:a+18equivalente a<4?x:a>4?y:22?
ETHproductions
Aliás, ele me indica o ano errado para qualquer entrada de 0 a 99. Porém, não tenho certeza se isso importa.
ETHproductions
@Eth LOL é claro que você está certo, não acho que é sempre 4 + 18: D
nicael
@ Et hm, 0 a 99 é realmente errado, deixe a minha tentativa de consertar isso.
Nicael
@Eth Parece que 0-100 deu a mesma data que 1900-2000, a julgar pelas outras respostas.
Nicael
8

TeaScript, 35 33 24 bytes - 25% = 18

28.11-new D(x,8).getDay¡

Esse é o mesmo método da minha resposta JavaScript , que usa a fórmula inteligente de Thomas Kwa .

Versão alternativa com explicação

r(22,28)F(#/h/t(new D(x,10,l)))+'-11'

r(22,28)    // Range from 22 to 28
        F(    // filter, keeps elements for which the function returns true. 
          #    // Expands to function(l,i,a,b)
           /h/    // RegExp literal, Thursday is the only day with an 'h'.
              t(    // test, true if date string contains an 'h'.
                new D(x,10,l) // Create date object
                             ))+'-11' // Append '-11' for the month.
intrepidcoder
fonte
É 35 caracteres, mas 36 bytes devido a ¡:)
nicael
@nicael Não é por este site , não é;)
ETHproductions
Hm, conseguindo 36 com mothereff.in/… .
Nicael
O @Downgoat geralmente usa esse formato , no qual todos os caracteres até U + 00FF são de 1 byte.
ETHproductions
5

Jython, 141 155 bytes

Usa as classes Java Calendar e Scanner com sintaxe Python.

import java.util.Scanner as s;import java.util.Calendar as c
d=c.getInstance();k=s(System.in);d.set(c.YEAR,k.nextInt());d.set(c.DAY_OF_WEEK,c.THURSDAY)

Editar: pequenos problemas de sintaxe, adicionados 14 bytes.

Veja também minha versão do Brainfuck .

Comunidade
fonte
5

Python, 83 81 78 bytes

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 bytes: adicionou um nome para importar (obrigado @ Κριτικσι Λίθος)
  • -1 bytes: alterado para * import ** (obrigado @FryAmTheEggman)
  • -2 bytes: alterado para repr para converter o dia (obrigado @willem)
Cajado
fonte
1
Apenas uma sugestão para reduzir a contagem de bytes: use import datetime as de, em seguida, você poderá usar dsempre que usar datetimeem seu programa.
Kritixi Lithos
2
Você também pode tentar pandas. import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
Willem
@ ΚριτικσιΛίθος mas então datetime.datetime seria apenas d.datetime, não seria?
TanMath
2
from datetime import*é ainda um pouco mais curto, pois você não precisará d.mais disso
FryAmTheEggman 25/11/2015
5

Excel, 367 154 53 - 25% = 39,75 bytes

Supõ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).

=IF(MOD(YEAR(A1),4)=0,IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

Pretty-impresso:

=IF(MOD(YEAR(A1),4)=0,
    IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),
    IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

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:

 =IF(WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy"))))<6,  
     1127-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))),
     1134-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))))

E agora que eu fiz o pfaffing para obter um cálculo conciso no Smalltalk, o backporting para o Excel resulta em:

=DATE(A1,11,MOD(12-WEEKDAY(DATE(9600+A1,11,1)),7)+22)

(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.

Euan M
fonte
1
Quando eu tento isso com datas anteriores a 1900, ele não funciona na minha cópia do Excel.
Angelo Fuchs
A versão longa não funciona tão bem.
Angelo Fuchs
Para datas antigas, use a pasta de trabalho de datas anteriores a 1900 do Usuário do Excel. < exceluser.com/downloads/examples/post_900_123/index.html >
Euan M
Perguntas sobre se isso funciona de lado, acho que você não pode produzir apenas a data de novembro; você precisa de um "Nov" ou "11" de alguma forma.
lirtosiast
@Thomas Kwa A entrada da data é o ano, no formato da data. O cálculo calcula o dia da semana em que o dia 1º de novembro cai e calcula a data da quarta quinta-feira de novembro.
Euan M
4

PowerShell, 67 64 84 72 58 45 Bytes

param($a)'Nov';28-(date "00$a/9/1").DayOfWeek

Tomamos nosso número inteiro de entrada como $ae imediatamente Novproduzimos uma nova linha. Em seguida, pegamos $ae anexamos com zeros e 1º de setembro com 00$a/9/1antes de gerar um novo datee determinar o DayOfWeekque é isso. Se 1º de setembro for no domingo ( .DayOfWeekigual a 0), o Dia de Ação de Graças será no dia 28. Se 1º de setembro for uma segunda-feira ( .DayOfWeekigual a 1), o Dia de Ação de Graças será no dia 27. E assim por diante. Assim, subtraímos esse dia da semana 28para 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 datetimenão suporta anos menos que 0.

Agradecemos a TessellatingHeckler e Toby Speight pela assistência.

AdmBorkBork
fonte
"{0:D3}/Nov/$_" -f $aé mais curto que "$($a.ToString("000"))/Nov/$_"e produz o mesmo resultado, e acho que você poderia usar em 11vez deNov
n0rd 25/11/2015
@ n0rd Ah, excelente! Sim - Novera 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!
AdmBorkBork 27/11
@TessellatingHeckler Essa abordagem funciona, mas você precisa acrescentar dois zeros para contabilizar os anos de um dígito; caso contrário, você está de volta ao 20XX em que encontrei. Obrigado pela assistência - atualizei a resposta.
AdmBorkBork
1
@TessellatingHeckler No meu sistema, pelo menos, inserindo anos de um dígito nos date "11/1/$a"resultados Thursday, 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.
AdmBorkBork
Certo, certo. Preenchimento duplo é.
TessellatingHeckler
3

Golfscript, 25 * 0,75 = 18,75 bytes

~.4/.25/.4/2---+7%28\--11

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:

~.4/.25/.4/2---+7%"Nov "28@-
xsot
fonte
3

TSQL, 478 296 bytes

Apenas 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 ...

create function a(@y varchar(4))returns date as begin declare @d date,@i int=0 set @d=convert(date,@y+'-11-01')declare @t table(d date,c int identity)while @i<28 begin if datepart(weekday,@d)=5 insert @t(d) select @d select @d=dateadd(d,1,@d),@i+=1 end select @d=d from @t where c=4 return @d end

Ungolfed:

if exists(select * from sys.objects where name='a' and [type]='FN') drop function a
go

create function a(@y varchar(4))returns date
-- select dbo.a('2015')
as
begin
    declare @d date,@i int=0;

    set @d=convert(date,@y+'-11-01'); -- cannot golf out dashes for dates <year 1000

    declare @t table(d date,c int identity)

    while @i<28 
    begin -- populate "November" array
        if datepart(weekday,@d)=5 insert @t(d) select @d -- assumes @@datefirst = 7
        select @d=dateadd(d,1,@d),@i+=1
    end;

    select @d=d from @t where c=4 

    return @d

end
Peter Vandivier
fonte
Este é realmente o caminho mais curto?
lirtosiast
Suponho que talvez eu não esteja familiarizado com as regras do código golf, mas a resposta cria um objeto DB que aceita entrada e retorna saída para corresponder ao OP. Há algum encurtamento óbvio que poderia ocorrer se a entrada pudesse ser aceita no código embutido, mas esse foi o meu pensamento para o tipo de objeto de função. Tenho certeza de que poderia ser ainda mais jogado em ambos os casos. @ThomasKwa, você tem sugestões?
Peter Vandivier
Bem, parece-me que você poderia usar a fórmula de matemática pura que esta resposta menciona e não se preocupar com todas essas coisas de objeto de data.
lirtosiast
não estritamente uma solução de matemática pura, mas a leitura dessa resposta definitivamente me deu algumas idéias para obter 200 caracteres. Obrigado!!
Peter Vandivier
(Eu quis dizer (28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7) Sim, ler outras respostas tende a ajudar bastante.
lirtosiast
3

Pitão, 30 28 * 75% = 21 bytes

Tenho 100% de certeza de que isso poderia ser reduzido, mas, ei, é o meu primeiro programa Pyth! \ o /

-28.11%+-+-Q2/Q4/Q100/Q400 7

Suíte de teste

Mostra a data em dd.mmformato.

Por favor, sugira maneiras de jogar isso se puder! Eu gostaria de aprender mais sobre Pyth.

ETHproductions
fonte
2

Excel, 64 48.

Ano na A1

= DATA (A1,11, ESCOLHA (SEMANA (DATA (A1,11,1)), 26,25,24,23,22,28,27))

=DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22)
SeanC
fonte
Como o Excel é baseado em localização, eu gostaria de testar isso. Por favor, explique o que as funções fazem, para que eu possa selecionar a correta no meu idioma.
Angelo Fuchs
1
Além disso, este não funciona para datas anteriores a 1900 (pelo menos na minha cópia do Excel)
Angelo Fuchs
Além disso, você salvou os 13bytes TEXTde =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.
user3819867
@ user3819867, é assim que o Excel armazena suas datas. a formatação é deixada ao usuário #
SeanC
@AngeloFuchs, DATE retorna um valor de data, usando ano, mês, dia como parâmetros. MOD retorna a parte restante de uma divisão (módulo). WEEKDAY retorna o dia da semana de uma data (1 = domingo, 2 = segunda-feira etc.).
SeanC 27/11/2015
2

Befunge, 41 bytes

47*&:::4"d"*/\"d"/-\4/++5+7%-" voN",,,,.@

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 ( dano 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 com 5+7%-subtraindo um número de dias da semana a partir do 28 º (a 47*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:

47*&v
!`0:<+*"(F"_v#
" voN",,,,.@>:::4"d"*/\"d"/-\4/++5+7%-
Linus
fonte
2

Matlab, 78 bytes

x=find(all(bsxfun(@eq,datestr(datenum(input(''),11,1:30),'ddd'),'Thu')'));x(4)
Luis Mendo
fonte
2

Ruby, 60 58 57 * 0,75 = 42,75 bytes

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

58 bytes

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

60 bytes

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11,1).wday]+21}"}

Ungolfed:

-> y {
  puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"
}

Uso:

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

=> Nov 26
Vasu Adari
fonte
0

VBA, 124 bytes * 75% = 93 bytes

Function e(y)
For i = 1 To 7
x = DateSerial(y, 11, 21) + i
If Weekday(x) = 5 Then e = Format(x, "mmm dd")
Next
End Function

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 Formatpeça.

user3819867
fonte
Espaços contam; se eles são desnecessários para o programa, você pode removê-los.
lirtosiast
0

PHP 5.3 ou superior, 59 bytes

Isso usa a função incorporada do PHP strtotime para analisar a data.

<?=gmdate('M d',strtotime("Next Thursday $_GET[Y]-11-19"));

Isso espera que o valor seja passado sobre o parâmetro GET Y OU sobre php-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 gmdatepara evitar problemas de fuso horário, mas funciona igualmente bem usando date(pelo menos onde eu moro).

Ismael Miguel
fonte
1
Uma resposta não é um local apropriado para discutir a validade de um método de entrada. Criei essa opção na meta post de E / S padrão (para que a comunidade possa votar nela) e movi sua conversa para o chat . (CC @Mego)
Dennis
0

T-SQL 215 bytes 248 * 0,75 = 186 bytes

create function t(@y int)returns table return select x=convert(char(6),x,107)from(select x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)from(select d=21+n from(values(0),(1),(2),(3),(4),(5),(6))b(n))c)t where datepart(weekday,x)=5

Ungolfed

set nocount on;
if object_id('dbo.t') is not null drop function dbo.t
go

create function t(@y int)returns table return
    select x=convert(char(6),x,107)
    from (
        select
        x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)
        from (
            select d=21+n 
            from (values (0),(1),(2),(3),(4),(5),(6))b(n)
        )c
    )t
    where datepart(weekday,x)=5
go

que com este andaime de teste

select 
  [ 2015 = Nov. 26]=(select x from dbo.t( 2015))
 ,[ 1917 = Nov. 22]=(select x from dbo.t( 1917))
 ,[ 1752 = Nov. 23]=(select x from dbo.t( 1752))
 ,[ 1582 = Nov. 25]=(select x from dbo.t( 1582))
 ,[ 1400 = Nov. 27]=(select x from dbo.t( 1400))
 ,[ -480 = Nov. 25]=(select x from dbo.t( -480))
 ,[-5480 = Nov. 28]=(select x from dbo.t(-5480))
;
go

produz conforme desejado

2015 = Nov. 26  1917 = Nov. 22  1752 = Nov. 23  1582 = Nov. 25  1400 = Nov. 27  -480 = Nov. 25 -5480 = Nov. 28
--------------- --------------- --------------- --------------- --------------- --------------- ---------------
Nov 26          Nov 22          Nov 23          Nov 25          Nov 27          Nov 25          Nov 28
Pieter Geerkens
fonte
0

Pike , 87 91 107 77 76 bytes - 25% = 57

string t(int y){return"Nov "+((11-Calendar.Day(y,11,1)->week_day())%7+22);}

deixando 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.

string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}
eMBee
fonte
Isso não parece receber informações.
Peter Taylor
Sim, fiquei confuso com isso, algumas soluções têm uma definição de função e outras apenas usam uma variável que não está definida em nenhum lugar, então não tenho certeza do que devo usar para o bytecount.
Embee
Eu acho que as respostas que você vê como " uma variável que não está definida em nenhum lugar " estão realmente usando uma sintaxe de declaração de função muito curta. Há uma ou duas respostas que usam esolangs que têm tratamento especial para stdin e, portanto, favorecem a criação de programas completos. Não conheço Pike, mas se você pode remover os espaços em branco e abreviar o nome da função para obter 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.
Peter Taylor
Eu pensei que tinha visto alguns que não eram declarações de função, mas eles parecem ter sido corrigidos, apenas o exemplo smalltalk não se encaixa. se isso é válido i poderia raspar outros 17 bytes de um presente ...
Embee
A versão Smalltalk é escrita como um programa - especificamente uma expressão da área de trabalho. Foi-nos dito que recebemos uma entrada, em vez de solicitar uma entrada.
precisa
0

Smalltalk - Squeak and Pharo , 69 57 54 49 35 34 33 32 - 25% = 24 bytes

" Novnn ": 69B 49B (-25% = 36,75B)
11nn (anInt): 57 54 32B (-25% = 24B)

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn
 Methods Date>>y:m:d: and >>w created as duplicates 
 of year:month:day and weekdayIndex"
(12-(Date y:y m:11d:1)w)\\7+1122

Versões prévias

Saída 11nn

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn"
(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

"Year supplied as an integer value, y  
 Result provided as an integer value, d, prefixed by 11"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

Novnn output

"Year supplied as an integer value, y  Result provided as a string, 'Nov nn'"
'Nov ', (12-(Date year:y month:11 day:1) weekdayIndex\\7+22) asString

saída nn

"Year supplied as an integer value, y  Result provided as an integer value, d"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+22

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!

Euan M
fonte
De acordo com o esclarecimento do OP , a versão do número do dia não é válida.
Mego
Eu concordo - mas, como existem algumas versões apenas de número de dias na lista, eu o coloco aqui para uma comparação de maçãs para maçãs #
Euan M
0

Coreutils GNU, 35 bytes

seq -f$1-11-2%g 2 8|date -f-|grep h

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:

echo Nov $((28-`date -d$1-5-5 +%w`))

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.

Toby Speight
fonte
2
Isso funciona, a menos que Sean Connery o execute.
bkul
0

TSQL, 53 52 bytes

DECLARE @ CHAR(4)=2000

PRINT DATEADD(d,59,DATEDIFF(d,1,DATEADD(m,9,@))/7*7)

Violino

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)

t-clausen.dk
fonte
-1

Perl, 92 bytes

use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print "Nov $_":0for 22..28

EDIT: Formato de saída fixo, bug corrigido, por exemplo, resultado de 2012, usado no formato "for" mais curto. Graças ao msh210.

Steve
fonte
Esta é mais curto e faz a mesma coisa: 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.
msh210