Fondo
Algunos días festivos tienen fechas fijas y fáciles de recordar, como el 31 de octubre, el 25 de diciembre, etc. Sin embargo, algunos quieren ser problemáticos. Se especifican como "el primer lunes de septiembre" o "el cuarto jueves de noviembre". ¿Cómo se supone que debo saber cuándo es eso?
Todo lo que sé es que el Día de Acción de Gracias se acerca rápidamente, por lo que necesito un programa que me ayude a descubrir cuándo es. Algunas personas incluso dicen que es mañana , por lo que su programa debe ser lo más breve posible para asegurarse de que pueda volver a escribirlo a tiempo.
El reto
Cree un programa o función que, dado un año de hasta cuatro dígitos (por ejemplo, 2015 o 1984), muestre o devuelva la fecha del Día de Acción de Gracias de los Estados Unidos en ese año. El Día de Acción de Gracias se define como el cuarto jueves de noviembre según la página de Wikipedia . (Sugerencia: esa página también incluye información interesante sobre el patrón de fecha).
Entrada : un número decimal con un máximo de cuatro dígitos que representa un año en la Era Común (CE). Ejemplos: 987, 1984, 2101
Resultado : la fecha, incluido el mes y el día, en que cae el Día de Acción de Gracias, o caería si existiera, en ese año. Esto puede estar en cualquier formato razonable; usa tu mejor juicio. Use el calendario gregoriano en todos los casos, incluso si no estaba en uso en ese momento.
(Nota: ¡Asegúrate de manejar los años bisiestos correctamente!)
Casos de prueba
Entrada 1:
2015
Salida 1:
Nov 26
Entrada 2:
1917
Salida 2:
Nov 22
Tanteo
Las presentaciones se puntuarán en bytes . Recomiendo este sitio web para realizar un seguimiento de su recuento de bytes, aunque puede usar cualquier contador que desee.
Bonos
-25% a su puntaje si maneja las fechas BCE como números negativos (por ejemplo, -480 sería el año de la batalla de las Termópilas).
Entrada de caso de prueba negativa:
-480
Salida correspondiente:
Nov 25
Este es el código de golf , por lo que gana el puntaje más bajo.
Editar: Estoy marcando la presentación TI-BASIC de Thomas Kwa como aceptada. ¡No dejes que esto te desanime de enviar nuevas entradas!
Tablas de clasificación
Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.
Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:
# Language Name, N bytes
¿Dónde N
está el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes
Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:
# Perl, 43 + 2 (-p flag) = 45 bytes
También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento de la tabla de clasificación:
# [><>](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>
Respuestas:
TI-BASIC, 15 bytes * 0.75 = 11.25
Probado en mi calculadora TI-84 +
El Día de Acción de Gracias es el 29 de noviembre, menos el día de la semana del 1 de septiembre, donde 1 es domingo y 7 es sábado. Esto sale en el formato
MMDD
.Se han verificado los casos de prueba:
2015
->1126
,1917
->1122
,-480
->1125
. TI-BASIC parece usar el calendario gregoriano para todas las fechas.TI-BASIC no admite años negativos, pero esto obtiene la bonificación porque agregamos 10000 a la entrada. Debido a que el calendario gregoriano tiene un período de 400 años, esto no cambia el día de la semana.
fuente
dayofWK(
yAns
que son de 2 y 1 bytes cada uno.PHP,
6548424136 (+2 para-F
) = 38 bytesToma la entrada como el primer argumento de línea de comando. Funciona con advertencias, que son aceptables según nuestras reglas. Impresiones
NovDD
, dondeDD
es el día de Acción de Gracias.No hay enlace en línea porque ideone no admite argumentos de línea de comando y no conozco un intérprete en línea que lo haga.
Gracias a Alexander O'Mara por enseñarme un nuevo truco, y primo por una reducción significativa.
fuente
"4thuXI"
. Incluso puedes dejar el espacio entre el año"4thuXI2015"
.-F
, la entrada podría acortarse a"4thuXI$argn"
.Md
no necesita comillas, conE_NOTICE
deshabilitado.Mathematica,
5938 bytesfuente
WolframAlpha["Thanksgiving " <> #] &
donde se ingresa la fecha como una cadena.JavaScript (ES6),
424031 bytes - 25% = 23.25Dado que la fecha "puede estar en cualquier formato razonable", utiliza esta función
DD.MM
. Escribí una respuesta de TeaScript con una técnica diferente, pero esta fórmula fue más corta.Explicación
Como los meses están basados en cero,
new Date(a,10)
devuelve unDate
objeto que representa el 1 de noviembre del año especificado.Dado que
getDay()
devuelve un número que representa el día de la semana desde el0..6
que queremos asignarluego agregue 22. Resulta que
(11 - new Date(a,10).getDay()) % 7
hará el truco. Como señaló @Thomas Kwa , esto es lo mismo28-new Date(a,8).getDay()
que 28 menos el día de la semana del 1 de septiembre.fuente
Japt ,
4337363529 bytes - 25% = 21.75Japt es una versión abreviada de Ja vaScri pt .
Jajaja, encontré un truco realmente engañoso: el intérprete ignora los corchetes dentro de las cadenas (utilizados para insertar código) mientras los descomprime, para que podamos comprimir todo el código fuente para guardar un byte>: D
Los dos
?
s deben ser los Unicode no imprimibles U + 0098 y U + 0085, respectivamente. Pruébalo en línea!Después de la descompresión, el código evalúa esto:
Lo que evalúa a:
Lo que da la salida adecuada.
Utiliza la técnica de intrepidcoder , que sale en formato
dd.mm
. Apoya adecuadamente los años negativos. Sugerencias bienvenidas!Editar: a partir del 2 de diciembre, ahora puede usar este código de 11 bytes (con una puntuación de 8.25 puntos ):
(¡Ojalá hubiera implementado esto antes!)
fuente
Vitsy , 44 bytes
Estoy calculando con pura matemática !
Golfizado:
Ungolfed (movió la llamada al método a la primera línea para que sea legible):
Probablemente haya un mejor algoritmo para esto (y esto probablemente sea un campo de golf horrible), pero para aquellos que se preguntan, mi algoritmo proviene de aquí .
Pruébalo en línea!
¿Recibo puntos de bonificación por calcularlo y tener exactamente 42 bytes?Sueños arruinados.Gracias a @ Hosch250 por señalar que lo estaba haciendo mal. : D Fijo.
fuente
Python, 38 * 0.75 = 28.5 bytes
Esto funciona con años negativos de la manera especificada en la pregunta, aunque me ha llamado la atención que no hay año 0 en el calendario gregoriano, por lo que este comportamiento es un poco sospechoso.
fuente
f=
."Nov "+`...`
-40%7==2
pero-40%-7==-5
JavaScript (ES6), 43.5
El recuento de bytes real es 58. Se aplica la bonificación de -25% => 58 * 0.75 = 43.5
De una manera bastante directa
y tontacomo podría ser, sin ninguna solución o cálculo complicado.De-golf (ES5) + demo:
Tenga en cuenta que entrar en el año 0-100 produce 1900-2000 año. Sin embargo, parece que 0-100 años dan la misma fecha que 1900-2000, a juzgar por las otras respuestas.
Reemplazar
a+18
con22
, porque se llama solo en "else", y "else" ocurre solo si a no es mayor ni menor que 4, es decir, exactamente 4.Reemplazar
a<4?26-a:a>4?a+21:22
cona<=4?26-a:a+21
fuente
a<4?x:a>4?y:a+18
equivalente aa<4?x:a>4?y:22
?TeaScript,
353324 bytes - 25% = 18Este es el mismo método que mi respuesta de JavaScript , que utiliza la fórmula inteligente de Thomas Kwa .
Versión alternativa con explicación
fuente
Jython,
141155 BytesUtiliza las clases Java Calendar y Scanner con la sintaxis de Python.
Editar: problemas menores de sintaxis, se agregaron 14 bytes.
Ver también mi versión Brainfuck .
fuente
Pitón,
838178 bytesfuente
import datetime as d
y luego puede usard
cada vez que usedatetime
en su programa.import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
from datetime import*
es incluso un poco más corto, ya que no necesitarád.
másExcel,
36715453 - 25% = 39,75 bytesAsume que el año se lleva a cabo en la celda A1, en formato de fecha. Devuelve el número entero del día de noviembre en el que se celebra el Día de Acción de Gracias.
Esto solo representa los años bisiestos normales. No tiene en cuenta el hecho de que los años 2100, 2200, 2300 no son años bisiestos.
Esto solo está diseñado para funcionar desde 1621 en adelante, es decir, desde que comenzó el Día de Acción de Gracias. (Aunque ciertamente funcionará hasta 0 AD).
Bonito estampado:
Gah! En lugar de calcular según el 1 de enero, luego hacer muchos cálculos de año bisiesto para hacer frente al 29 de febrero, debería haber basado los cálculos el 1 de noviembre. Nb Esto ahora trata correctamente con los años 2100, 2200 y 2300 , pero hace que la implementación dependa del formato de fecha predeterminado de su instalación de Excel. Esta versión está diseñada para dd / mm / aaaa:
Y ahora que he hecho el pfaffing para obtener un cálculo conciso en Smalltalk, el respaldo a Excel da como resultado:
(con el año todavía en A1, pero como un número entero). Esto funciona incluso para los años 2100, 2200 y 2300, para todas las fechas desde 7700BC / E en adelante, utilizando el truco de repetición de fechas de Thomas Kwa.
fuente
PowerShell,
676484725845 BytesTomamos nuestro entero de entrada como
$a
, e inmediatamente salimosNov
y una nueva línea. Luego lo tomamos$a
y lo anteponemos con ceros y el 1 de septiembre con00$a/9/1
antes de generar un nuevodate
y determinar quéDayOfWeek
es eso. Si el 1 de septiembre es un domingo (.DayOfWeek
igual a0
), el Día de Acción de Gracias es el 28. Si el 1 de septiembre es un lunes (.DayOfWeek
igual a1
), el Día de Acción de Gracias es el 27. Y así. Por lo tanto, restamos ese día de la semana de28
para obtener nuestra respuesta.Preceder con ceros dobles representa años de uno y dos dígitos sin interrumpir el análisis por años de tres o cuatro dígitos. No funciona para números negativos, ya que .NET
datetime
no admite años menos0
.Gracias a TessellatingHeckler y Toby Speight por su ayuda en esto.
fuente
"{0:D3}/Nov/$_" -f $a
es más corto"$($a.ToString("000"))/Nov/$_"
y produce el mismo resultado, y creo que podría usarlo en11
lugar deNov
Nov
era un remanente de cuando intentaba que reconociera correctamente los años de dos dígitos, así que también lo cambiaré. ¡Gracias!date "11/1/$a"
resultadosThursday, November 1, 2007 12:00:00 AM
. Esto se debe a que no estamos editando la propiedad Calendar.TwoDigitYearMax , por lo que cuando se analiza , nos quedamos con doble relleno de cero para evitar eso.Golfscript, 25 * 0.75 = 18.75 bytes
Utiliza la fórmula de Sakamoto para el día de la semana. Como hay personas haciendo esto, el resultado es en forma de
dd-mm
. Mi envío anterior se puede encontrar a continuación:fuente
TSQL,
478296 bytesSolo por diversión. Por lo general, tendrías una tabla de dimensiones de fecha para hacer esto simple
select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'
pero en ausencia de eso ...Sin golf:
fuente
(28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7
) Sí, leer otras respuestas tiende a ayudar mucho.Pyth,
3028 * 75% = 21 bytesEstoy 100% seguro de que esto podría hacerse más corto, pero bueno, ¡es mi primer programa Pyth! \ o /
Banco de pruebas
Emite la fecha en
dd.mm
formato.¡ Sugiera formas de jugar golf si puede! Me gustaría aprender más sobre Pyth.
fuente
Sobresalir,
6448Año en A1
= FECHA (A1,11, ELIGE (DÍA DE LA SEMANA (FECHA (A1,11,1)), 26,25,24,23,22,28,27)fuente
13
bytesTEXT
desde=TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")
: la salida es un número entero sin formato.Befunge, 41 Bytes
Ejecutar en este intérprete .
Explicación: Un año común es 365 = 1 mod 7 días, por lo que el año más cada 4 º año, menos cada 100 º (
d
año en ascii), además de cada 400 th años representa cualquier día bisiestos (incluyendo el presente año). El resultado:::4"d"*/\"d"/-\4/++
puede entonces considerarse como el 5 de marzo , el primer día después de febrero para caer el mismo día que el primer día del año en años comunes. Después de que se calibra con el patrón de5+7%-
restar un número de días de la semana desde el 28 º (el47*
almacenado antes) de noviembre. Luego imprime.Una versión que corrige los años de BC es actualmente más larga que la bonificación, en 59-25% = 44.25 bytes:
fuente
Matlab, 78 bytes
fuente
Ruby,
605857 * 0.75 = 42.75 bytes58 bytes
60 bytes
Sin golf:
Uso:
fuente
VBA, 124 bytes * 75% = 93 bytes
No estoy seguro de si los espacios cuentan, es entre 102 y 124, no dude en editar.
Si los enteros son una salida válida, estoy más que feliz de eliminar la
Format
parte.fuente
PHP 5.3+, 59 bytes
Esto utiliza la función integrada de PHP
strtotime
para analizar la fecha.Esto espera que el valor se pase sobre el parámetro GET
Y
O sobrephp-cli Y=<year>
.Intenta encontrar el próximo jueves después del 19 de noviembre.
Hasta ahora, con las pruebas que hice, funciona bien.
Tenga en cuenta que los años de 2 dígitos pueden interpretarse de manera diferente.
Lo uso
gmdate
para evitar problemas de zona horaria, pero funciona igual de biendate
(al menos, donde vivo).fuente
T-SQL
215 bytes248 * 0.75 = 186 bytesSin golf
que con este andamio de prueba
rinde según lo deseado
fuente
Pike ,
87 91 107 7776 bytes - 25% = 57dejando el viejo para comparar porque me parece más inteligente en términos de aprovechar el módulo Calendario, pero lo anterior es mucho más corto.
fuente
string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}
, lo cuento como 107 bytes.Smalltalk - Squeak and Pharo ,
6957544935343332 - 25% = 24 bytes"Nov nn":
69B49B (-25% = 36.75B)11nn (anInt):
575432B (-25% = 24B)Versión anterior
Salida 11nn
Nov nn salida
nn salida
nb Esto se proporciona como un programa, específicamente una expresión de Workspace, en lugar de como un método.
Asume que la entrada es un dato (según la frase "dado un año de hasta cuatro dígitos".
Incluyendo la declaración y entrega de la entrada agregaría otros 11 caracteres:
|y|y:=2015.(12-(Date y:y m:11 d:1)w)\\7+1122
Gracias a eMBee, por mostrar cómo eliminar aún un carácter más: el espacio en blanco inmediatamente antes de la 'w'.
En realidad, eso me inspiró a intentar eliminar el espacio en blanco antes de 'd:': ¡
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
Lo que funcionó!
fuente
GNU coreutils, 35 bytes
Simplemente busca en la semana del 22 al 28 de noviembre un jueves. Ejecútelo en una configuración regional C o POSIX, ya que dependo de que el jueves sea la única abreviatura de día que contenga una 'h'.
Aquí hay una respuesta más inteligente, aunque un byte más largo:
Recuperamos el número de día de la semana de una fecha en una semana bastante arbitraria entre marzo y septiembre (de modo que día y mes son un dígito cada uno y no nos afecta un posible día bisiesto). Escogemos el día para que sea domingo (
%w==0
) cuando el Día de Acción de Gracias sea el 28. Entonces podemos restar ese valor de 28 para obtener el jueves apropiado.fuente
TSQL,
5352 bytesViolín
Calculando el lunes antes o el 2 de septiembre y sumando 59 días
(mejor que calcular el lunes antes o el 4 de octubre y agregar 31 días porque octubre es el décimo mes, ahorrando así 1 byte)
fuente
Perl, 92 bytes
EDITAR: Se corrigió el formato de salida, se corrigió el error, por ejemplo, el resultado de 2012, se utilizó el formato "para" más corto. Gracias a msh210.
fuente
use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29
. Pero ambos guiones adolecen de los mismos defectos: (1) no imprimen una representación del mes como se requiere; (2) tienen una salida incorrecta para, por ejemplo, 2012.