Primer miércoles


22

Primer miércoles

Su tarea es contar la cantidad de miércoles que cae en un primer día del mes en un año en particular. Por ejemplo, 7-13-16es un primer miércoles. Por coherencia, utilice el calendario gregoriano para todas las fechas.

Entrada

La entrada a su programa / función será un año (por ejemplo 2016) y es flexible. El año será un número entero entre 1912 y 2233 inclusive.

Salida

La salida también es flexible y debe ser el número de miércoles principales (por ejemplo 18).

Tanteo

Este es el código más corto en bytes gana!

Casos de prueba

entrada -> salida
--------------------
1912 -> 19
1914 -> 16
1984 -> 17
1996 -> 19
2063 -> 19
2150 -> 16
2199 - > 18
2233 -> 18

Respuestas:


7

MATL , 38 36 34 bytes

FT+"@llI$YO]q&:t8XO!s9\~)9#1$ZOZps

Pruébalo en línea! O verifique todos los casos de prueba (toma unos segundos).

Explicación

FT+     % Input year implicitly. Add [0 1] element-wise. Gives array with input year
        % and next year
"       % For each of those two years
  @     %   Push year
  ll    %   Push 1 twice. This indicates January 1.
  I$YO  %   Convert year, month, day to serial date number
]       % End for each. We now have the serial date number for January 1 of the input
        % year and that of the following year
q       % Subtract 1 to the latter, to yield December 31 of the input year
&:      % Inclusive range between those two numbers. This gives an array of serial date
        % numbers for the whole input year
t       % Push another copy of that array
8XO     % Convert to date string with format 8. This gives weekday as "Mon", "Tue" etc.
        % The result is a 3-column 2D char array, where each row is a day
!s      % Transpose, sum of each column. 'Wed' gives 288 (sum of ASCII codes)
9\~     % 288 gives 0 modulo 9, and is the only weekday to do so. So we compute modulo 9
        % and negate. This gives true for Wednesdays, false for the rest
)       % Apply as logical index into the array of serial date numbers
9#1$ZO  % Array of month numbers corresponding to those serial date numbers
Zp      % Array that contains true for prime numbers, false for the rest
s       % Sum of array. Display implicitly

Estoy convencido de que MATL no puede ser vencido en desafíos basados ​​en fechas. Deberíamos crear DATL, que está aún más optimizado para manejar desafíos basados ​​en fechas.
Suever

@Suever Jaja, buen nombre
Luis Mendo

20

Python 2, 95 93 68 67 bytes

lambda y:0x10ea2c8dbb06c5619/5**((y+((y-22)/99-y/2002)*16)%28)%5+16

¡Gracias a @Josay por jugar golf en 1 byte!

Pruébalo en Ideone .


3
Puede guardar 1 carácter con en 0x10ea2c8dbb06c5619lugar de 19501370182350951961.
SylvainD

Entiendo la idea de, big_constant//5**long_expressionpero ¿cómo diablos vienes con esa constante y esa expresión? Es una locura: D
Sherlock9

2
La constante es una tabla de búsqueda simple que usa dígitos de base 5, pero se convierte a base 10, de modo que los dígitos se extraen numéricamente en lugar de usar un índice de cadena. La expresión me parece un calendario perpetuo. (El problema sería demasiado fácil si se limitara a años desde 1901 hasta 2099, ya que las respuestas se repiten cada 28 años dentro de ese intervalo, por lo que sería solo un caso de tomar el año mod 28 y buscarlo en la tabla. )
Neil

13

Brain-Flak , 6588 , 2310 , 2308 , 2290 bytes

Primero lo primero, no escribí casi el 100% de este programa, lo que probablemente se evidencia por el enorme tamaño del programa. La mayor parte de este código fue escrito por mi propio algoritmo de golf Brain-Flak . Junto con un script de python adicional que escribí para indicarlo en la dirección correcta.

Pruébalo en línea!

({}<(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()()())){}{}){})[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])()())[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])())()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())>[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}]){({}[()]<{}>)}{}({}<{{}}>)

Si bien este programa es bastante largo para el golf de código, realmente es bastante corto para Brain-Flak. Actualmente, el récord mundial para la división de enteros supera los 1000 bytes.

Explicación

El algoritmo es bastante simple. Debido a que hay un número limitado de años disponibles (321), simplemente empuja las respuestas en orden inverso debajo de la entrada y utiliza un algoritmo de búsqueda para encontrar la respuesta correcta. Si bien la codificación rígida de todas las 321 posibilidades puede parecer bastante ineficiente con una tarea tan compleja como esta y un lenguaje tan esotérico como el ataque cerebral, puede ser la mejor solución. (Planeo averiguarlo la próxima semana).

Dado que la mayoría de los 321 números son aproximadamente 18 en promedio y difieren muy poco de un año a otro en lugar de presionar todos los números individualmente, presiono el primer año (2233) normalmente y luego simplemente duplico y cambio el valor un poco para cada año después. De esta manera, en lugar de pagar para empujar ~ 18 por los 321 años, solo pago por empujar ~ 2 por cada año.

Una vez que todas las respuestas han sido enviadas, resta 1912 de la entrada ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}])(Esto puede ser subóptimo, reescribí el optimizador para omitir ciertos valores que creía que no serían óptimos porque los números de codificación rígida son un proceso súper exponencial y su ejecución hasta su finalización puede tener Tomado unos días).

A continuación, resta uno del primer elemento y aparece el segundo elemento hasta que el resultado llega a cero, {({}[()]<{}>)}.

Aparece el cero {}y todos los elementos debajo del elemento superior ({}<{{}}>).


¿Cuál es el enfoque general de los números de golf?
Neil

La idea simple es que si tienes un número con factores n y m, presionas n m-1 veces y luego haces estallar m-1 veces. La inserción inicial se evalúa como n y cada pop se evalúa como una n adicional, lo que hace que (1 + m-1) (n) sea lo mismo que mn. Esto se hace de forma recursiva porque para empujar n también tenemos que jugar golf n. Dado que este método no funciona bien para algunos números primos en particular, también miramos a nuestro alrededor para ver si hay un número más eficiente cerca y, de ser así, expresamos esto como la suma de ese número y la diferencia.
Wheat Wizard

Ya veo ... ¿entonces dados dos números ny mcuáles tienen longitudes ky l, supongo n+mque tendrían longitud k+l? ¿Qué hay de n*m?
Neil

n*msería k+4m-4o l+4n-4. Esto se debe a que la multiplicación está codificada. Primero presionamos los n m-1tiempos. Para hacer esto, necesitamos ksímbolos para expresar ny 2m-2símbolos para expresar los impulsos (cada impulso es 2 símbolos). Luego hacemos estallar m-1tiempos, lo que nos cuesta un adicional 2m-2(los estallidos cuestan 2 símbolos también). Esto suma a k+4m-4. También podemos multiplicar m*n(propiedad conmutativa) para obtener l+4n-4. El resultado será el más corto de los dos.
Wheat Wizard

1
Bueno, si eso es cierto, entonces +1cuesta 2, *2cuesta 4, *3cuesta 8, *4cuesta 12, que es más caro que *2*2, por lo que no vale la pena (de los números por debajo de 1000 solo encontré 10 que no usaron *2: 1, 2, 3 , 4, 5, 9, 15, 27, 45, 135). Para 1912, lo mejor que pude hacer fue ((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2con una longitud de 52.
Neil

7

Bash + utilidades comunes, 39

ncal $1|grep W|factor|egrep -c ': \S+$'

Toma el año de entrada como un parámetro de línea de comando. Por lo general, envía mensajes como este a STDERR: creo que esto es legal según esta meta respuesta :

factor: We is not a valid positive integer

Si desea suprimir explícitamente la salida STDERR, puede hacerlo para obtener una puntuación de 43 :

ncal $1|grep W|factor 2>-|egrep -c ': \S+$'

Tenga en cuenta que esto supone una configuración regional en inglés o C / POSIX. No funciona tan bien en gd_GB.utf8, donde todos los nombres de los días se abrevian Di.
Toby Speight

6

Octava, 86 bytes

Esto no es rápido, de ninguna manera. Pero ese no es realmente el objetivo de un código de golf, ¿verdad?

function r=p(y)r=0;for(i=698346:7:815953)d=datevec(i);r+=d(1)==y*isprime(d(3));end;end

Octave puede rastrear las fechas por "número de fecha": número de días transcurridos donde el 1 de enero, 0 es el día 1. Según esta medida, el 3 de enero de 1912 (el primer miércoles de nuestro conjunto) es el día 698,346. Comience allí e repita cada 7 días (todos los miércoles) hasta el final de 2233, y agregue 1 si el año es el año objetivo Y el mes-día es primo.


5

Python 2.7, 166 , 165 , 150 bytes

from datetime import*
y=input()
d,c=date(y,1,1),0
while d.year==y:n=d.day;c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n));d+=timedelta(1)
print c

Ciertamente hay margen de mejora aquí. Soy bastante nuevo en el golf en Python. Esto usa eldatetime módulo. Recorre todos los días del año agregando uno a un acumulador si cumple con el criterio. Luego imprime el resultado. La mayor parte del trabajo pesado está en el módulo, por lo que el código puede ser bastante delgado.

Un byte guardado gracias a Morgan Thrapp y 15 bytes guardados por Pietu1998 .


1
Puede guardar un byte cambiando n%x==0a n%x<1.
Morgan Thrapp

2
El -1no es necesario ya que rangeel índice final es exclusivo. Además, puede convertir el filtera un generador. [0for x in range(2,n)if n%x<1]
PurkkaKoodari

Podrías usar any(...)o en all(...)lugar de not filter(...).
kennytm

1
Combinando comparaciones encadenadas y allpuede ahorrar un montón. c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
PurkkaKoodari

3

J, 44 bytes

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)

Acabo de descubrir que J tiene incorporados para la manipulación de citas.

Uso

Se utilizan comandos adicionales para formatear múltiples entradas / salidas.

   f =: +/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)
   (,.f"0) 1912 1914 1984 1996 2063 2150 2199 2233
1912 19
1914 16
1984 17
1996 19
2063 19
2150 16
2199 18
2233 18

Explicación

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)  Input: year
                                       i.12   The range [0, ..., 11]
                              >:              Increment each to get the months [1, ..., 12]
                                    p:        Get the first 12 primes [2, ..., 37]
                                ,"0/          Make a table between each month and prime
                           ,/                 Join the rows
                       ,.&                    Prepend the year to each
                                              The date format is YYYY MM DD
            3=weekday                         Check if each date occurs on Wednesday
    valdate*                                  and is a valid date
+/@                                           Count the number of true values and return

1

PowerShell v3 +, 99 95 bytes

Enfoque de fuerza bruta

param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count

Toma datos $y, recorre desde 1hasta 12, almacena el mes temporalmente en $m, luego recorre cada primo desde 2hasta 31. Para cada uno de ellos, construimos uno Get-Datede ese día en particular, luego seleccionamos solo aquellos con DayOfWeek -equal a 3(es decir, miércoles). Encapsula que todo en un parens para formular una matriz, y toma el .Countmismo.


Alternativamente, enfoque matemático -

PowerShell v3 +, 105 bytes

param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)

Termina siendo solo un pelo más largo que el enfoque de la fuerza bruta, pero lo estoy incluyendo aquí, ya que puede ser beneficioso para otros.

Nuevamente toma entrada $ycomo el año. Esta vez estamos realizando operaciones estrictamente matemáticas basadas en el primer día del año. Primero calculamos qué día de la semana es ese y lo almacenamos $apara su uso posterior. Eso se indexa en la primera matriz, lo que nos da el número que generalmente es correcto. Tenemos que agregar a eso un segundo índice basado en si es un año bisiesto potencial, si es domingo, martes, miércoles o jueves, y en función de qué año es.

Esto se basa en la siguiente observación. La primera columna es qué día de la semana es el 1 de enero, la segunda es la salida habitual. A menos que el año sea uno de los números intermedios, entonces es el número en pares. La columna final describe cómo funciona la indexación% 5.

Jan-1 -> #  ... Except if $y=       (then it's this number) | $y % 5 =
Sun   -> 16 ... 1928 1956 1984 etc. (17)                    |    3
Mon   -> 19
Tue   -> 18 ... 1924 1952 1980 etc. (20)                    |    4
Wed   -> 20 ... 1936 1964 1992 etc. (17)                    |    1
Thur  -> 16 ... 1920 1948 1976 etc. (17)                    |    0
Fri   -> 18
Sat   -> 19

Nota: Ambos asumen que en-uses la configuración actual de PowerShell para la información de cultura / fecha. Es posible que el formato de fecha y el DayOfWeeknúmero deban ajustarse en consecuencia para otras variantes de cultivo.


1

Ruby, 83 + 15 ( -rdate -rprimebanderas) = ​​98 bytes

Pruébalo en línea! (Los módulos importados están en línea porque idk si puedo usar banderas en repl.it)

->y{k=0;Prime.each(31){|d|k+=(1..12).count{|m|Date.new(y,m,d).wday==3 rescue p}};k}

1

JavaScript ES6, 187 182 181 179 bytes

179 Intercambiado en un ciclo for por el ciclo while

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);for(;a()<=y;c())N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

181 Compactado el ternario

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());c()}return N}

182 combinado los dos bucles

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=a()==y?-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b()):0;c()}return N}

187

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<y)c();for(;a()==y;c())N+=-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

No creo que esto cuente, ya que has dado el primer miércoles inicial para el año específico, en este ejemplo. El desafío del OP dice que necesita el año como el único parámetro ... Gran esfuerzo hasta ahora ...
WallyWest

"La entrada a su programa / función será un año", pero lo que está señalando no es eso. Utilizo el primer miércoles de 1912 como semilla porque es o es cada dos miércoles en el período de tiempo establecido por el OP, pero podría usar fácilmente cualquier miércoles arbitrario de 1911 o antes para sembrarlo también. La entrada a mi función aún es un año, y la función aún calcula el número de miércoles principales en cualquier año dado en el marco de tiempo sugerido por el OP, por lo que no estoy seguro de cómo esto no se ajusta al desafío.
Pandacoder

Ah, disculpas ... Al principio no me di cuenta de que estás usando eso como un componente de siembra ... Gran idea ... Especialmente considerando que tu solución supera a la mía por unos 30 ...;)
WallyWest

1
Gracias. Me inspiré en la implementación Brain-Flak de Eamon Olive, que en realidad tiene todas las respuestas preprogramadas, según su explicación.
Pandacoder

1

Lote, 248 bytes.

@set/ad=0,l=1,n=20
@for /l %%i in (1913,1,%1)do @set/ad=(d+l+1)%%7,l=!(%%i%%4)-!(%%i%%100)+!(%%i%%400)
@goto %l%%d%
:03
:06
@set/an-=1
:12
:13
:16
@set/an-=1
:01
:04
:14
@set/an-=1
:00
:05
:10
:15
@set/an-=1
:02
:11
@echo %n%

Explicación: des el día de la semana, con el 0lunes, que es convenientemente el 1 de enero de 1912. les un indicador de si el año es bisiesto, 1para 1912. Luego pasamos de 1913 al año de entrada, actualizando el día de semana y recalculando la bandera del año bisiesto a medida que avanzamos. Finalmente, utilizamos la bandera del año bisiesto y el día de la semana para indexar en lo que efectivamente es una gran declaración de cambio para determinar n, el número de miércoles principales. Sin nembargo, establecer 20 y disminuirlo con caída es más barato que usar la lógica de control de flujo, pero el resultado es que si el 1 de enero de un año no bisiesto es jueves o domingo, entonces hay 16 miércoles principales y así sucesivamente para los otros casos .


1

JavaScript ES6 206 203 199 197 195 183 182 179

No es el más corto, pero lo mejor que puedo hacer por ahora ... bienvenidas sugerencias de golf ...

p=n=>--d-1?n%d&&p(n):1;v=Date;D=(x,y)=>new v(x.setDate(x.getDate()-y));W=a=>eval('for(Z=0,z=D(w=new v(a,11,31),(w.getDay()+4)%7);z>new v(a,0,1);)Z+=~~p(d=z.getDate()),z=D(z,7);Z')

Cambios:

  1. alterar el componente ternario de: 3>=x?3-x:10-xa 6-(x+10)%7, guardar: 3 cambios en las ubicaciones de declaración;
  2. fusionado x=w.getDay();z=D(w,6-(x+10)%7)con z=D(w,6-(w.getDay()+10)%7), ahorro: 4
  3. pasó Z=0de la fordeclaración de bucle a fecha y se introdujo z=D(w,6-(x+10)%7)en el forbucle para ordenar, guardando: 2
  4. w=new Date(a,Z=0,1)declaración desplazada en forbucle, fusionándose con la wdeclaración existente , guardando: 2
  5. reescribiendo la función de búsqueda principal en una función de prueba principal, guardando: 12
  6. cambiando +!!a ~~para reducir y todavía convertir p(d=1)de NaNa0 , permitiendo que la función Prime Test siga funcionando, ahorrando: 1
  7. Se eliminaron todas las funciones adicionales de la función de llamada principal W, se redefinió el forbucle: retrocediendo desde el 31 de diciembre, escribiendo el Dateobjeto como una variable separada, luego reescribió el forbucle en la evalllamada; ahorro 3.

@PandaCoder, ¡te estoy alcanzando, amigo!


1

R, 149 147 bytes

y=function(x){s=strftime;b=ISOdate
a=seq(b(x,1,1),t=b(x,12,31),b='d')
length(a[s(a,'%u')==3&trimws(s(a,'%e'))%in%c(2,3,5,7,11,13,17,19,23,29,31)])}

Pruébalo en Ideone .


0

Groovy, 126

Groovy no tiene validación de números primos, también tuvo que construir eso.

{n->p={x->x<3||(2..Math.sqrt(x)).every{x%it}};(new Date("1/1/$n")..new Date("12/31/$n")).collect{it[7]==4&&p(it[5])?it:0}-[0]}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.