Cuando es Acción de Gracias?

38

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

bkul
fuente
25
Para cualquiera que se pregunte cuándo llegará el Día de Acción de Gracias este año: el Día de Acción de Gracias será mañana.
TheNumberOne
66
¿Pero tuve acción de gracias el 10 de octubre? Lamento decir que tu pregunta llega tarde.
JimmyJazzx
55
@Downgoat Use el contador de bytes que desee. Ese es solo el que uso personalmente y lo recomendaría.
bkul
22
"Algunos días festivos tienen fechas fijas y fáciles de recordar, como el 31 de octubre y el 25 de diciembre" Esos ejemplos son fáciles de recordar porque realmente son el mismo día: octal 31 == decimal 25. ;-)
Adrian McCarthy
77
Para una respuesta que hace la bonificación, ¿debería haber un año 0 entre -1 y 1 o no?
feersum

Respuestas:

40

TI-BASIC, 15 bytes * 0.75 = 11.25

Probado en mi calculadora TI-84 +

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

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.

lirtosiast
fuente
55
Santo cielo. xD Nunca hubiera pensado que esto hubiera funcionado así, +1.
Addison Crump
Buena idea agregar 10000. Agradable.
2015
Cuento 23 cartas. ¿Cómo puede ser esto 15 bytes?
Stephan Schinkel
1
@StephanSchinkel TI-BASIC usa tokens que están almacenados en la memoria de la calculadora, creo que todos los caracteres aquí son de 1 byte, excepto los tokens dayofWK(y Ansque son de 2 y 1 bytes cada uno.
FryAmTheEggman
¿Lo probaste en una calculadora? Guau.
23

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

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

Toma la entrada como el primer argumento de línea de comando. Funciona con advertencias, que son aceptables según nuestras reglas. Impresiones NovDD, donde DDes 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.

Mego
fuente
2
Esto es más divertido que Mathematica.
lirtosiast
2
@Tryth aún más corto: "4thuXI". Incluso puedes dejar el espacio entre el año "4thuXI2015".
Alexander O'Mara
1
Usando la opción de línea de comando -F, la entrada podría acortarse a "4thuXI$argn".
primo
3
Espera, ¿esto realmente funciona? Eso es ... eso es solo ... Ni siquiera ...
ETHproductions
1
Que funciona para mí . Mientras estoy en eso, Mdno necesita comillas, con E_NOTICEdeshabilitado.
primo
18

Mathematica, 59 38 bytes

DayRange[{#,11},{#,12},Thursday][[4]]&
LegionMammal978
fuente
+1 inteligente. También es WolframAlpha["Thanksgiving " <> #] &donde se ingresa la fecha como una cadena.
DavidC
WolframAlpha regresa las fechas del Día de Acción de Gracias de Estados Unidos desde 1863 (cuando Lincoln declaró que era el último jueves de noviembre) en adelante. Estados Unidos ha observado el Día de Acción de Gracias desde 1789.
DavidC
@DavidCarraher Sin embargo, el OP establece que el programa tiene que funcionar por lo menos 0 - 9999 CE
LegionMammal978
17

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

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

Dado 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 un Dateobjeto 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 el 0..6que queremos asignar

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  

luego agregue 22. Resulta que (11 - new Date(a,10).getDay()) % 7hará el truco. Como señaló @Thomas Kwa , esto es lo mismo 28-new Date(a,8).getDay()que 28 menos el día de la semana del 1 de septiembre.

codificador intrépido
fuente
Buena solución, me encanta lo corto que es y que aún es más comprensible que la mayoría de las entradas.
Marko Grešak
16

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

Japt es una versión abreviada de Ja vaScri pt .

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

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:

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

Lo que evalúa a:

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

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

28.11-ÐU8 e

(¡Ojalá hubiera implementado esto antes!)

ETHproducciones
fuente
Muy bien hecho.
bkul
Esto ahora es más largo que JavaScript vainilla. Thomas Kwa tiene una fórmula mucho más corta .
intrepidcoder
@intrepidcoder Gracias, arreglado.
ETHproductions
12

Vitsy , 44 bytes

Estoy calculando con pura matemática !

Golfizado:

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

Ungolfed (movió la llamada al método a la primera línea para que sea legible):

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

V Guarde la entrada como una variable final.
 e2 * Empuja 28 a la pila.
    V Empuje la entrada a la pila.
     2- Resta dos.
       V4 / D1M- Obtener piso (entrada / 4).
              + Agrégalo al total.
               Vaa * Dv / D1M: obtenga el piso (entrada / 100) y guarde 100 como temperatura
                                    variable en el proceso.
                          - Restarlo del total.
                           Vv4 * / D1M- Obtener piso (entrada / 400).
                                    + Agrégalo al total.
                                     7M Módulo por siete.
                                       - Restar el resultado de 28.
                                        baa * / + Agregar .11
                                              N Salida como número.

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.

Addison Crump
fuente
2
No. pero obtienes un +1 de mí;)
Conor O'Brien el
Dice que el Día de Acción de Gracias en 2016 es el 28 de noviembre. Realmente es el 24 de noviembre.
Hosch250
@ Hosch250 Tienes razón, arreglado ahora.
Addison Crump
10

Python, 38 * 0.75 = 28.5 bytes

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

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.

Luke
fuente
1
Puedes caer f=.
feersum
1
¿Cómo funciona esto para fechas negativas? ¿El módulo en Python se aplica a los negativos? : O
Addison Crump
Debería ser más corto usar repeticiones de cuerda,"Nov "+`...`
xnor
@VoteToClose El módulo Python da una respuesta con el mismo signo que el segundo argumento. Así, -40%7==2pero-40%-7==-5
quintopia
@quintopia Espera, espera, soy un idiota. Bueno. Eso tiene sentido.
Addison Crump
10

JavaScript (ES6), 43.5

El recuento de bytes real es 58. Se aplica la bonificación de -25% => 58 * 0.75 = 43.5

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

De una manera bastante directa y tonta como podría ser, sin ninguna solución o cálculo complicado.

De-golf (ES5) + demo:

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

t(prompt())

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

nicael
fuente
2
Disculpe si me equivoco, pero no es a<4?x:a>4?y:a+18equivalente a a<4?x:a>4?y:22?
ETHproductions
Por cierto, me dice el año equivocado para cualquier entrada de 0 a 99. Sin embargo, no estoy seguro si esto importa.
ETHproductions
@Eth LOL, por supuesto, tienes razón, no pensé que eso siempre sea 4 + 18: D
nicael
@Eth hm, 0 a 99 está realmente mal, deja que intente arreglar eso.
nicael
@Eth Parece que 0-100 da la misma fecha que 1900-2000, a juzgar por las otras respuestas.
nicael
8

TeaScript, 35 33 24 bytes - 25% = 18

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

Este 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

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.
codificador intrépido
fuente
Son 35 caracteres, pero 36 bytes debido a ¡:)
nicael
@nicael No por este sitio , no lo es;)
ETHproductions
Hm, obteniendo 36 con mothereff.in/… .
nicael
@Downgoat generalmente usa este formato , en el que todos los caracteres hasta U + 00FF son de 1 byte.
ETHproductions
5

Jython, 141 155 Bytes

Utiliza las clases Java Calendar y Scanner con la sintaxis de 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: problemas menores de sintaxis, se agregaron 14 bytes.

Ver también mi versión Brainfuck .

Comunidad
fuente
5

Pitón, 83 81 78 bytes

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 bytes: agregó un nombre para importar (gracias @ Κριτικσι Λίθος)
  • -1 bytes: cambiado a * import ** (gracias @FryAmTheEggman)
  • -2 bytes: cambiado a repr para convertir el día (gracias @willem)
Barra
fuente
1
Solo una sugerencia para reducir el recuento de bytes: use import datetime as dy luego puede usar dcada vez que use datetimeen su programa.
Kritixi Lithos
2
También puedes probar pandas. import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
Willem
@ ΚριτικσιΛίθος pero entonces datetime.datetime solo sería d.datetime, ¿no?
TanMath
2
from datetime import*es incluso un poco más corto, ya que no necesitará d.más
FryAmTheEggman
5

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

Asume 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).

=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"))))))

Bonito estampado:

=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! 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:

 =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")))))

Y ahora que he hecho el pfaffing para obtener un cálculo conciso en Smalltalk, el respaldo a Excel da como resultado:

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

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

Euan M
fuente
1
Cuando intento esto con fechas anteriores a 1900, no funciona en mi copia de Excel.
Angelo Fuchs
La versión larga no funciona tan bien.
Angelo Fuchs
Para fechas anteriores, use el libro de trabajo de fechas de usuario anteriores a 1900 de Excel. < exceluser.com/downloads/examples/post_900_123/index.html >
Euan M
Preguntas sobre si esto funciona a un lado, no creo que se le permita emitir solo la fecha en noviembre; necesita un "Nov" u "11" de alguna forma.
lirtosiast el
@Thomas Kwa La entrada de fecha es el año, en formato de fecha. El cálculo luego se calcula el día de la semana en que cae el 1 de noviembre, luego se calcula la fecha del cuarto jueves de noviembre.
Euan M
4

PowerShell, 67 64 84 72 58 45 Bytes

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

Tomamos nuestro entero de entrada como $a, e inmediatamente salimos Novy una nueva línea. Luego lo tomamos $ay lo anteponemos con ceros y el 1 de septiembre con 00$a/9/1antes de generar un nuevo datey determinar qué DayOfWeekes eso. Si el 1 de septiembre es un domingo ( .DayOfWeekigual a 0), el Día de Acción de Gracias es el 28. Si el 1 de septiembre es un lunes ( .DayOfWeekigual a 1), 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 datetimeno admite años menos 0.

Gracias a TessellatingHeckler y Toby Speight por su ayuda en esto.

AdmBorkBork
fuente
"{0:D3}/Nov/$_" -f $aes más corto "$($a.ToString("000"))/Nov/$_"y produce el mismo resultado, y creo que podría usarlo en 11lugar deNov
n0rd
@ n0rd Ah, excelente! Sí, Novera un remanente de cuando intentaba que reconociera correctamente los años de dos dígitos, así que también lo cambiaré. ¡Gracias!
AdmBorkBork
@TessellatingHeckler Ese enfoque funciona, pero debe anteponer dos ceros para tener en cuenta los años de un dígito, de lo contrario, volverá al 20XX con el que me encontré. Gracias por la ayuda. Actualicé la respuesta.
AdmBorkBork
1
@TessellatingHeckler En mi sistema, al menos, ingresar años de un solo dígito en date "11/1/$a"resultados Thursday, 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.
AdmBorkBork
Bien bien. Doble acolchado lo es.
TessellatingHeckler
3

Golfscript, 25 * 0.75 = 18.75 bytes

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

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:

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

TSQL, 478 296 bytes

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

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

Sin golf:

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
fuente
¿Es este realmente el camino más corto?
lirtosiast
Supongo que no estoy familiarizado con las reglas del código golf, pero la respuesta crea un objeto DB que acepta la entrada y devuelve la salida para que coincida con el OP. Hay un acortamiento obvio que podría ocurrir si la entrada se puede aceptar en el código en línea, pero este fue mi pensamiento para el tipo de objeto de función. Estoy seguro de que podría jugar más en cualquier caso. @ThomasKwa, ¿tienes sugerencias?
Peter Vandivier
Bueno, me parece que podría usar la fórmula matemática pura que menciona esta respuesta y no molestarse con todo ese objeto de fecha.
lirtosiast
no es estrictamente una solución matemática pura, pero leer esa respuesta definitivamente me dio algunas ideas para jugar 200 caracteres. ¡¡Gracias!!
Peter Vandivier
(Quise decir (28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7) Sí, leer otras respuestas tiende a ayudar mucho.
lirtosiast el
3

Pyth, 30 28 * 75% = 21 bytes

Estoy 100% seguro de que esto podría hacerse más corto, pero bueno, ¡es mi primer programa Pyth! \ o /

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

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.

ETHproducciones
fuente
2

Sobresalir, 64 48

Año en A1

= FECHA (A1,11, ELIGE (DÍA DE LA SEMANA (FECHA (A1,11,1)), 26,25,24,23,22,28,27)

=DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22)
SeanC
fuente
Como Excel se basa en la localización y me gustaría probar esto. Explique qué hacen las funciones para que pueda seleccionar la adecuada en mi idioma.
Angelo Fuchs
1
Además, esto no funciona para fechas anteriores a 1900 (al menos en mi copia de Excel)
Angelo Fuchs
Además, guardó 13bytes TEXTdesde =TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm"): la salida es un número entero sin formato.
user3819867
@ user3819867, así es como Excel almacena sus fechas. el formato se deja al usuario
SeanC
@AngeloFuchs, DATE devuelve un valor de fecha, usando año, mes, día como parámetros. MOD devuelve la parte restante de una división (módulo). WEEKDAY devuelve el día de la semana de una fecha (1 = domingo, 2 = lunes, etc.).
SeanC
2

Befunge, 41 Bytes

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

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 º ( dañ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 de 5+7%-restar un número de días de la semana desde el 28 º (el 47*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:

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

Matlab, 78 bytes

x=find(all(bsxfun(@eq,datestr(datenum(input(''),11,1:30),'ddd'),'Thu')'));x(4)
Luis Mendo
fuente
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}"}

Sin golf:

-> 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
fuente
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

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

usuario3819867
fuente
Los espacios cuentan; sin embargo, si son innecesarios para el programa, puede eliminarlos.
lirtosiast
0

PHP 5.3+, 59 bytes

Esto utiliza la función integrada de PHP strtotimepara analizar la fecha.

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

Esto espera que el valor se pase sobre el parámetro GET Y O sobre php-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 gmdatepara evitar problemas de zona horaria, pero funciona igual de bien date(al menos, donde vivo).

Ismael Miguel
fuente
1
Una respuesta no es un lugar apropiado para discutir la validez de un método de entrada. Creé esta opción en la meta publicación de E / S predeterminada (para que la comunidad pueda votarla) y trasladé su conversación al 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

Sin golf

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 con este andamio de prueba

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

rinde según lo deseado

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

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

string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}
eMBee
fuente
Esto no parece tomar entrada.
Peter Taylor
sí, me confundí con eso, algunas soluciones tienen una definición de función y algunas solo usan una variable que no está definida en ningún lado, por lo que no estoy seguro de lo que se supone que debo usar para el bytecount.
eMBee
Creo que las respuestas que ves como " una variable que no está definida en ninguna parte " en realidad están usando una sintaxis de declaración de función muy corta. Hay una o dos respuestas que usan esolangs que tienen un tratamiento especial para stdin y, por lo tanto, prefieren escribir programas completos. No conozco Pike, pero si puede eliminar espacios en blanco y abreviar el nombre de la función para obtenerlo 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.
Peter Taylor
Pensé que había visto algunas que no eran declaraciones de funciones, pero parecen haber sido arregladas, solo el ejemplo de Smalltalk no encaja. si eso es válido, podría reducir otros 17 bytes de este ...
eMBee
La versión Smalltalk está escrita como un programa, específicamente una expresión de Workspace. Nos dijeron que recibimos una entrada, en lugar de solicitarla.
Euan M
0

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

"Nov nn": 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

Versión anterior

Salida 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

Nov nn salida

"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

nn salida

"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

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ó!

Euan M
fuente
Según la aclaración del OP , la versión del número de día no es válida.
Mego
Estoy de acuerdo, pero dado que hay bastantes versiones de solo días en la lista, lo puse allí para una comparación de manzanas con manzanas
Euan M
0

GNU coreutils, 35 bytes

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

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:

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

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.

Toby Speight
fuente
2
Esto funciona a menos que Sean Connery lo ejecute.
bkul
0

TSQL, 53 52 bytes

DECLARE @ CHAR(4)=2000

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

Violí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)

t-clausen.dk
fuente
-1

Perl, 92 bytes

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

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.

Steve
fuente
Esto es más corta y hace lo mismo: 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.
msh210