Cuantos dias en un mes

25

Dada una representación textual (nombre completo que no distingue entre mayúsculas y minúsculas o abreviatura de 3 caracteres) de un mes, devuelve el número de días del mes.

Por ejemplo, december, DEC, y dectodos deben volver 31.

Febrero puede tener 28 o 29 días.

Suponga que la entrada es un mes en una de las formas correctas.

qw3n
fuente
19
Probablemente debería enumerar todas las variaciones de los nombres de los meses que deberíamos poder aceptar.
Giuseppe
1
Para cualquiera que pueda usarlo, las sumas ordinales ASCII de los primeros 3 caracteres reducidos son únicas.
Totalmente humano
19
Eso fue demasiado, demasiado pronto para aceptar una solución.
Shaggy
55
Creo que esto sería mejor si la entrada fuera solo el mes en un formato fijo, ya que el formato ahora básicamente requiere convertir a un caso fijo y solo mirar las primeras 3 letras.
xnor
44
Tal como está parece que quiere respuestas para manejar todas las formas enumeradas - "Por ejemplo, december, DEC, y decdebe todo retorno 31" - ¿Es esa la intención?
Jonathan Allan

Respuestas:

4

Pyke , 9 bytes

l4C9@~%R@

Pruébalo aquí!

l4        -   input.title()
    @     -  v.index(^)
  C9      -   ['PADDING', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
        @ - v[^]
     ~%R  -  ['Padding', 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

O 15 bytes si se requieren todos los formatos de entrada

l43<C9 3L<@~%R@

Pruébalo aquí!

l43<            -   input.title()[:3]
          @     -  v.index(^)
    C9 3L<      -   ['PAD', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
              @ - v[^]
           ~%R  -  ['Padding', 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
Azul
fuente
66
Esto devuelve 31 para FEB.
Laikoni
2
Creo @ punto de Laikoni es válido (también devuelve 31 para Apr, Jun, Sep, y Nov), pero también creo que se necesita una pequeña aclaración en el PO (véase mi pregunta ).
Jonathan Allan
@JonathanAllan Bueno, el OP ha aceptado esta respuesta, ¿entonces supongo que es válida?
Erik the Outgolfer
44
@EriktheOutgolfer No saltaría a esa conclusión personalmente.
Jonathan Allan
Tenía la impresión de que solo necesitaba trabajar para una forma de entradas
azul
33

JavaScript (ES6),  48 47 44 43  42 bytes

m=>31^'311'[parseInt(m[1]+m[2],34)*3%49%8]

Manifestación

¿Cómo?

Estas operaciones conducen a una tabla de búsqueda de 8 entradas, que no sería muy interesante si los valores se distribuyeran aleatoriamente. Pero cualquier resultado mayor que 2 se asigna a 31 días. Por lo tanto, solo las primeras 3 entradas deben almacenarse explícitamente.

Month | [1:2] | Base 34 -> dec. | * 3  | % 49 | % 8 | Days
------+-------+-----------------+------+------+-----+-----
  JAN |    AN |             363 | 1089 |   11 |   3 |  31
  FEB |    EB |             487 | 1461 |   40 |   0 |  28
  MAR |    AR |             367 | 1101 |   23 |   7 |  31
  APR |    PR |             877 | 2631 |   34 |   2 |  30
  MAY |    AY |              10 |   30 |   30 |   6 |  31
  JUN |    UN |            1043 | 3129 |   42 |   2 |  30
  JUL |    UL |            1041 | 3123 |   36 |   4 |  31
  AUG |    UG |            1036 | 3108 |   21 |   5 |  31
  SEP |    EP |             501 | 1503 |   33 |   1 |  30
  OCT |    CT |             437 | 1311 |   37 |   5 |  31
  NOV |    OV |             847 | 2541 |   42 |   2 |  30
  DEC |    EC |             488 | 1464 |   43 |   3 |  31
Arnauld
fuente
14
honestamente, ¿cómo diablos sigues haciendo estas increíbles presentaciones extrañas con cosas locas de matemáticas D: ¿tienes un programa para encontrarlas o eres demasiado bueno para el resto de nosotros
HyperNeutrino
1
@HyperNeutrino Lo primero que intento es siempre encontrar una conversión de base, seguida de una multiplicación opcional seguida de una o varias operaciones de módulo. Este fue encontrado rápidamente de esa manera. Pero leí mal el desafío y primero pensé que .substr(0,3)no era necesario. Entonces, pensándolo bien, este puede no ser el mejor enfoque.
Arnauld
substr? slice!
Neil
Mi enfoque trivial es solo <s> 2 </s> 3 bytes más, por lo que puede que ya no sea óptimo debido a eso, pero sigue siendo muy impresionante :)
HyperNeutrino
1
La edición de alguien eliminó esa parte, pero una de las razones por las que originalmente no lo permití es que quería ver respuestas como esta. Me encanta el uso de la base 34 para evitar el tema de la capitalización y los diferentes formatos.
qw3n
15

Javascript (ES6), 36 33 bytes

-3 bytes gracias a @JustinMariner y @Neil

m=>31-new Date(m+31).getDate()%31

Lo siento @Arnauld, abusar de la rareza de JavaScript es más corto que tus sofisticadas conversiones de base.

Cómo funciona

Por alguna razón, JavaScript permite ingresar fechas fuera del mes especificado. El código cuenta cuántos días fuera del mes es la fecha para determinar cuántos días hay en el mes. Ejemplos:
"FEB31"Thu Mar 02 200031 - 2 % 3129
"October31"Tue Oct 31 200031 - 31 % 3131

Casos de prueba

Herman L
fuente
MS Excel también hace esto. El 0 de enero siempre es el último día de diciembre, entonces = DÍA ("00/01/2017") dará como resultado 31
DavChana
Parece que Javascript solo permite cadenas de fecha donde el día es hasta 31. Si intenta ingresar "feb 32", se traduce a 2032-02-01, y si intenta forzarlo con "0-feb-32" (o una cadena similar), solo dice "Fecha inválida". Por extraño que parezca, si establece el día en 0 ("feb 0"), se traduce en 2000-02-01 en lugar de 2000-01-31.
TehPers
Es posible que pueda guardar un byte soltando el espacio anterior 31. Parece funcionar en Chrome como new Date("feb31")por ejemplo.
Justin Mariner
De hecho, probablemente podría usar +31guardar tres bytes en general. Sin embargo, nada de esto funciona en Firefox.
Neil
7

Bash , 21 bytes

cal $1|xargs|tail -c3

Pruébalo en línea!

Toma la entrada como argumento de línea de comando y las salidas con una nueva línea final. El recuento de días para febrero depende del año actual

Requiere la versión util-linux 2.29 de cal, que es la que está disponible en TIO . También depende de la configuración regional, por lo que LC_TIME debe cambiarse en sistemas que no están en inglés (gracias @Dennis por su aclaración).

La idea de pasar xargsa calla salida del recorte es de esta respuesta SO .

Justin Mariner
fuente
2
Esto no es solo bash. Generalmente es sh, pero es probable que casi todas las implementaciones de shell admitan búsquedas de ruta y tuberías, en un sistema con cal, tail y xargs.
kojiro
5

Protón , 50 bytes

k=>31-((e=k.lower()[1to3])in"eprunov")-3*(e=="eb")

Pruébalo en línea!

-14 bytes gracias a Jonathan Frech

Treinta días tiene septiembre, abril, junio y noviembre. Todo lo demás tenía mantequilla de maní. Todos excepto mi abuela; ella tenía un pequeño triciclo rojo, pero lo robé. muahahahahaha

(He estado esperando contar esa broma (fuente: mi profesor de matemáticas) durante siglos en este sitio: D: D: D)

Hiperneutrino
fuente
@Riker oh, vaya, eso no estaba allí cuando comencé a escribir esto: /
HyperNeutrino
1
Hay una nueva regla que debe verificar para un mes no válido y devolver 0. Espero que se elimine
Level River St
1
No
importa
Creo que puede usar una sola cadena en 'sepaprjunnov'lugar de una lista de cadenas.
Jonathan Frech
@JonathanFrech tal vez; Lo intentaré, gracias
HyperNeutrino
4

C # (.NET Core) , 52 + 13 = 65 38 + 24 = 62 bytes

m=>D.DaysInMonth(1,D.Parse(1+m).Month)

Pruébalo en línea!

+24 para using D=System.DateTime;

Expresiones de gratitud

-3 bytes gracias a Grzegorz Puławski.

Ayb4btu
fuente
¿Esto funciona sin using System;? ¿O puedes excluir eso del conteo de bytes?
Matty
@ Matty Ese es un buen punto; ahora agregado.
Ayb4btu
Consejo tardío, pero -3 bytes: using D=System.DateTime;y m=>D.DaysInMonth(1,D.Parse(1+m).Month)como aquí: tio.run/##jc5BSwMxEAXgs/…
Grzegorz Puławski
3

Python 3 , 60 bytes

x=input().lower()[1:3];print(31-(x in"eprunov")-3*(x=="eb"))

Pruébalo en línea!

Portar mi solución de protones

-10 bytes gracias a totalmente humano

Hiperneutrino
fuente
Mejor que la mía je
Thomas Ward
1
um
totalmente humano
: P incorporados son a veces demasiado largos: P
HyperNeutrino
@totallyhuman oh rly wow. +1 gracias: P
HyperNeutrino
2
umm
totalmente humano
2

Python 3 - 93 86 84 82 bytes

Variantes de respuesta (que muestran la progresión del tiempo y bytes para cada una, con enlaces TIO):

Respuesta original (93 bytes)

-7 bytes gracias a Jonathan Frech. (86 bytes)

-2 bytes más gracias a mis propias pruebas adicionales de los monthrangeresultados, con el segundo valor siempre siendo el valor más alto. (84 bytes) 1

-2 más al usarlo import calendar as cy hacer referencia a él con c.monthrange. (82 bytes, revisión actual )


lambda x:c.monthrange(1,time.strptime(x[:3],'%b')[1])[1];import time,calendar as c

Obviamente, no es tan bueno como la respuesta de HyperNeutrino, que no utiliza elementos integrados, pero todavía funciona.


Notas al pie

1 : Casos de prueba a través de TIO.run que muestra la prueba de cómo estoy manejando esos monthrangevalores, para un número variable de casos de prueba mensuales.

Thomas Ward
fuente
86 bytes .
Jonathan Frech
@ JonathanFrech Gracias. Además, revisé a la baja al haber probado más sobre cómo funciona el rango de meses, y también al usarlo import ...,calendar as cpara no tener que escribir 'calendario' dos veces.
Thomas Ward
2

Perl 5 , 47 + 1 ( -p) = 48 bytes

$_=substr$_,1,2;$_=31-("eprunov"=~/$_/i)-3*/b/i

Pruébalo en línea!

Xcali
fuente
-6 bytes: en ($_)=/.(..)/;lugar de $_=substr$_,1,2;y ()alrededor "eprunov"=~/$_/ise pueden eliminar.
Nahuel Fouilleul
2

Haskell , 65 63 62 bytes

f.map((`mod`32).fromEnum)
f(_:b:c:_)|c<3=28|c>13,b>3=30
f _=31

Pruébalo en línea!

Enfoque de coincidencia de patrones. La primera línea es manejar la insensibilidad a mayúsculas y minúsculas. Luego volvemos28 si la tercera letra es más pequeña que C (número 3), 30si la segunda letra es más grande que C y la tercera más grande que M, o de lo 31contrario.

Editar: -1 byte gracias a Leo


Alternativa ( 65 64 bytes)

f s|let i#n=n<mod(fromEnum$s!!i)32=sum$29:[2|2#2]++[-1|2#13,1#3]

Pruébalo en línea!

Laikoni
fuente
1
¡Uno inteligente! Puede guardar un byte marcando en c<3lugar de a==6(febrero es el primer mes si los ordena por su tercera carta, seguido de diciembre)
Leo
2

APL (Dyalog) , 32 bytes *

Función de prefijo tácito. Asume ⎕IO( I ndex O rigin) 0, que es por defecto en muchos sistemas.

31 28 30⊃⍨∘⊃'.p|un|no|f'S 11

Pruébalo en línea!

⍠1 caso insensible

1 devolver la longitud de la

⎕S PCRE S earch para

'.p|un|no|f' any-char, "p" o "un" o "no" o "f"

⊃⍨∘⊃ y use el primer elemento de eso (0 si no hay) para elegir

31 28 30 esta lista

Así:

  • Ap r, S ep , J un y No v seleccionarán el número en el índice 2, es decir, 30

  • F eb seleccionará el número en el índice 1, es decir, 28

  • cualquier otra cosa seleccionará el número en el índice 0, es decir, 31


* Usando Classic y contando como ⎕OPT.

Dyalog APL
fuente
2

Plantilla Mediawiki, 19 bytes

{{#time:t|{{{1}}}}}
tsh
fuente
1

MATL , 22 bytes

14L22Y2c3:Z)Z{kj3:)km)

Pruébalo en línea!

Explicación

14L    % Push numeric array of month lengths: [31 28 ... 31]
22Y2   % Push cell array of strings with month names: {'January', ..., 'December'}
c      % Convert to 2D char array, right-padding with spaces
3:Z)   % Keep first 3 columns
Z{     % Split into cell array of strings, one each row
k      % Convert to lower case
j      % Input string
3:)    % Keep first 3 characcters
k      % Convert to lower case
m      % Ismember: gives a logical index with one match
)      % Use that as index into array of month lengths. Implicit display
Luis Mendo
fuente
1

Wolfram Language (Mathematica) , 46 30 bytes

#~NextDate~"Month"~DayCount~#&

Pruébalo en línea!

Dará cualquiera 28o29 para febrero, dependiendo de si el año actual es bisiesto.

Cómo funciona

Todos los comandos de fecha en Mathematica interpretarán entrada tal April, APR, ApRiL, y así sucesivamente como el primer día del mes correspondiente en el año en curso. (Como beneficio adicional, las entradas como "February 2016"o {2016,2}también funcionan como se esperaba).

#~NextDate~"Month"da el primer día del mes después de eso, y DayCountda el número de días entre sus dos argumentos. El número de días entre el 1 de abril y el 1 de mayo es 30, el número de días en abril.

Misha Lavrov
fuente
1

Retina , 32 31 28 bytes

i`f
28
i`p|v|un
30
\D

^$
31

Pruébalo en línea! Editar: Guardado 1 byte gracias a @RobertBenson. Guardado 3 bytes gracias a @ovs.

Neil
fuente
Creo que podría guardar un byte usando 'f' en lugar de 'eb'
Robert Benson
28 bytes
ovs
1

q / kdb +, 36 bytes

Solución:

28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#

Ejemplos:

q)28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#"January"
31
q)28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#"FEB"
28
q)28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#"jun"
30

Explicación:

Hay un millón de formas de pelar un gato. Creo que es un poco diferente a los demás. Tome las letras segunda y tercera de la entrada, en minúsculas, luego búsquelas en la cadena"ebeprunov" . Si están en la ubicación 0, entonces es febrero, si están en una ubicación> 0 son 30 días, si no están en la cadena, son 31 días.

28 30 31@2^1&first"ebeprunov"ss lower 1_3# / ungolfed solution
                                        3# / take first 3 items from list, January => Jan
                                      1_   / drop the first item from the list, Jan => an
                                lower      / lower-case, an => an
                  "ebeprunov"ss            / string-search in "ebeprunov", an => ,0N (enlisted null)
             first                         / take the first, ,0N => 0N
           1&                              / take max (&) with 1, 0N => 0N
         2^                                / fill nulls with 2, 0N => 2
        @                                  / index into
28 30 31                                   / list 28,30,31
callejero
fuente
1

Excel VBA, 47 43 Bytes

Función de ventana inmediata anónima VBE que toma datos, como nombre de mes, abreviatura o número, del rango [A1] y emite la duración de ese mes en el año 2001 a la función de ventana inmediata de VBE.

?31-Day(DateValue("1 "&[A1]&" 1")+30)Mod 31

Versión antigua

d=DateValue(["1 "&A1&" 1"]):?DateAdd("m",1,d)-d
Taylor Scott
fuente
1

PHP, 38 33 + 1 32 + 1 bytes

Guardado 5 bytes gracias a Titus

<?=date(t,strtotime("$argn 1"));

Corre como tubería con -nF

Pruébalo en línea!

Jo
fuente
1
Oye, no creo que lo necesites .' 1', ¡parece funcionar en TIO sin él!
Dom Hastings
1
28 + 1 bytes: <?=date(t,strtotime($argn));(ejecutar como tubería con -nF)
Titus
3
@DomHastings, así que, antes de publicar, había probado para ver si funcionaría sin el .' 1', pero no estaba funcionando. Después de ver tu comentario, traté de averiguar qué había hecho mal. Debido a que lo estaba ejecutando el día 31 del mes, estaba tomando el día 31 (actual) para cualquier mes que ingresé, lo que lo pondría más allá del mes actual. El 31 de febrero se convierte en el 3 de marzo, por lo que el código devuelve 31 (el número de días en marzo). Debido a esto, cada mes regresaba 31. Por lo tanto, funciona sin el .' 1'día <= 28 del mes.
Jo.
Ahhh, ¡me olvido de cómo PHP completa los espacios en blanco! ¡Gracias por la explicación!
Dom Hastings
@Titus Gracias. Soy un novato en el golf! No sé por qué no me di cuenta de la 't'-> t. Además, tuve que hacer un montón de búsquedas para descubrir cómo "correr como una tubería -nF", pero lo resolví (creo). :)
Jo.
0

Java (OpenJDK 8) , 126 bytes

s->{for(java.time.Month m:java.time.Month.values())if(m.name().startsWith(s.toUpperCase()))System.out.print(m.length(false));}

Pruébalo en línea!

Roberto Graham
fuente
1
Creo que puede acortar falsea una expresión booleana como 1<0guardar un par de bytes.
Justin Mariner
0

QBIC , 49 35 bytes

?31-(instr(@aprjunsepnov feb`,;)%3)

Significativamente más corto con algunos trucos.

Explicación

?                          PRINT
31-(                       31 minus
  instr(                   the position of
                      ,;   our input string
    @aprjunsepnov feb`  )  in the string cntaining all non-31 months                                
    %3)                    modulo 3 (this yields a 1 for each month except feb=2)
Steenbergh
fuente
0

Ruby , 45 bytes

->m{((Date.parse(m)>>1)-1).day}
require'date'

Pruébalo en línea!

Ruby's Date.parseacepta un nombre de mes solo. Lo que normalmente sería un desplazamiento a la derecha ( >>) en realidad se agrega al mes del Dateobjeto. La resta afecta el día del mes, que se remontará al último día del mes anterior.

Justin Mariner
fuente