Es una tarea anual, está bien

22

Dado un número 1≤n≤365, muestra el enésimo día del año en formato "Día-mes número". Por ejemplo, dado 1, debe generar "1 de enero", sin "de".

Se utilizará el calendario gregoriano y el programa no debe tener en cuenta los años bisiestos, por lo que su programa nunca debería salir "29 de febrero" en ninguna circunstancia. Se puede utilizar cualquier método, siempre que siga el formato "Día-mes-mes" mencionado anteriormente. Su programa también debe generar ordinales correctamente, lo que significa que siempre debe generar 1º, 2º, 3º, 1, 2 o 3, respectivamente, deben ser los números de día para cualquier entrada. Se permiten espacios iniciales u otras sangrías.

Este es el código de golf, por lo que gana la solución más corta por personajes.

Casos de prueba:

1 gives 1st January
2 gives 2nd January
3 gives 3rd January
365 gives 31st December
60 gives 1st March
11 gives 11th January
Andrés
fuente
44
Además, ¿necesita forzar un mensaje de error en números> 365? ¿Puede el programa asumir que es una entrada no válida y no necesitará manejar eso?
Rɪᴋᴇʀ
55
Como no todos son hablantes nativos de inglés, es posible que desee agregar ese día los números 11, 12 y 13 obtienen "th", los números que terminan en "1" obtienen "st", "2" obtienen "nd", "3" obtener "rd", y todos los demás obtener "th".
Adám
99
Whoa, no aceptes respuestas tan rápido. Especialmente no respuestas incorrectas !
Adám
66
Usted debe agregar al menos 11(11 º de enero) y 21(21 st enero) a los casos de prueba.
Arnauld
1
Y mientras edita casos de prueba, tal vez especifique cuál es exactamente el formato de su caso de prueba. Un par de personas que respondieron pensaron que 123=era parte de la producción requerida. O simplemente edite sus casos de prueba para leer algo como: 365da31st December
Adám

Respuestas:

9

PHP ,38 40 30 28 bytes

<?=date("jS F",86399*$argn);

Pruébalo en línea!

Ejecutar con php -nFentrada es de STDIN. Ejemplo (script anterior nombrado y.php):

$ echo 1|php -nF y.php
1st January
$ echo 2| php -nF y.php
2nd January
$ echo 3| php -nF y.php
3rd January
$ echo 11|php -nF y.php
11th January
$ echo 21|php -nF y.php
21st January
$ echo 60|php -nF y.php
1st March
$ echo 365|php -nF y.php
31st December

Explicación

Construya una marca de tiempo de época para el día deseado en 1970 (convenientemente no un año bisiesto) multiplicando el day number * number of seconds per day(86400). Sin embargo, esto produciría un día más, por lo tanto, multiplique por number of seconds in a day - 1(86399) que para el rango de números de entrada (1≤n≤365) dará como resultado la marca de tiempo del final de cada día correcto. Luego, solo use el formato de fecha incorporado de PHP para la salida.

640 KB
fuente
¿Por qué es -nnecesario?
Ven
@Ven podría no serlo en todos los casos, pero solo deshabilita cualquier configuración en php.ini local que pueda crear un comportamiento inconsistente.
640 KB
6

Jalea ,  79 78  77 bytes

-1 arreglando un error :) (no debería pre-transponer para encontrar el índice, debería post-revertir, pero luego podemos seguir la cola en lugar de la cabeza)
-1 usando la reflexión ( ⁽©ṅB+30_2¦2-> ⁽0ṗb4+28m0)

⁽0ṗb4+28m0SRṁRƲœiµṪȮ%30%20«4ị“nḄƲf⁷»s3¤Ṗ,ị“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»Ḳ¤$K

Un programa completo que imprime el resultado.

Pruébalo en línea!

¿Cómo?

actualizará esto más tarde ...

⁽©ṅB+30_2¦2SRṁRƲZœiµḢȮ%30%20«4ị“nḄƲf⁷»s3¤Ṗ,ị“...»Ḳ¤$K - Main Link: integer, n
⁽©ṅB+30_2¦2SRṁRƲZœi - f(n) to get list of integers, [day, month]
⁽©ṅ                 - compressed literal 2741
   B                - to a list of binary digits -> [ 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1]
    +30             - add thirty                    [31,30,31,30,31,30,31,31,30,31,30,31]
         ¦          - sparse application...
        2           - ...to indices: [2]
       _  2         - ...action: subtract two       [31,28,31,30,31,30,31,31,30,31,30,31]
               Ʋ    - last four links as a monad - i.e. f(x):
           S        -   sum x                       365
            R       -   range                       [1..365]
              R     -   range x (vectorises)        [[1..31],[1..28],...]
             ṁ      -   mould like                  [[1..31],[32..59],...]
                Z   - transpose                     [[1,32,...],[2,33,...],...]
                 œi - 1st multi-dimensional index of n  -> [day, month]

µḢȮ%30%20«4ị“nḄƲf⁷»s3¤Ṗ,ị“...»Ḳ¤$K - given [day, month] format and print
µ                                  - start a new monadic chain - i.e. f(x=[day, month])
 Ḣ                                 - head -- get the day leaving x as [month])
  Ȯ                                - print it (with no newline) and yield it
   %30                             - modulo by thirty
      %20                          - modulo by twenty
         «4                        - minimum of that and four
                     ¤             - nilad followed by link(s) as a nilad:
            “nḄƲf⁷»                -   dictionary words "standard"+" the" = "standard the"
                   s3              -   split into threes = ["sta","nda","rd ","the"]
           ị                       - index into
                      Ṗ            - remove rightmost character
                               ¤   - nilad followed by link(s) as a nilad:
                         “...»     -   dictionary words "January"+" February"+...
                              Ḳ    -   split at spaces = ["January","February",...]
                        ị          - index into (vectorises across [month])
                       ,           - pair                  e.g. ["th", ["February"]]
                                K  - join with spaces           ["th ", "February"]
                                   - print (implicitly smashes)   th February
Jonathan Allan
fuente
44
El truco "estándar" es asombroso.
Ven
Estoy de acuerdo con @Ven , ¡gran truco! También guardó un byte en mi respuesta 05AB1E en comparación con la cadena comprimida "thstndrd"dividida en partes de tamaño 2 ( .•oθ2(w•2ô), así que gracias. :)
Kevin Cruijssen
1
Este tiene que ser uno de los programas Jelly más largos que he visto.
JAD
6

C # (compilador interactivo de Visual C #) , 115 113 109 98 bytes

g=>$"{f=(g=p.AddDays(g-1)).Day}{"tsnr"[f=f%30%20<4?f%10:0]}{"htdd"[f]} {g:MMMM}";DateTime p;int f;

Gracias a @someone por guardar 9 bytes

Pruébalo en línea!

Encarnación de la ignorancia
fuente
1
@KevinCruijssen Obtuve los módulos fuera de servicio, debería arreglarse ahora.
Encarnación de la ignorancia
.code.tio(2,22): error CS0165: Use of unassigned local variable 'p'Parece que la estructura no funciona.
JAD
var g=new DateTime().AddDays(n-1)funciona
JAD
@JAD error de mi parte, corregido
Encarnación de la ignorancia
110 bytes, creo
mi pronombre es monicareinstalar el
5

Python 3.8 (prelanzamiento) , 112 bytes

lambda x:str(d:=(t:=gmtime(x*86399)).tm_mday)+'tsnrhtdd'[d%5*(d%30%20<4)::4]+strftime(' %B',t)
from time import*

Pruébalo en línea!

Por extraño que parezca, no tengo que poner entre paréntesis d:=(t:=gmtime(~-x*86400), probablemente porque el intérprete solo verifica si hay ()caracteres alrededor de la expresión de asignación y no porque la expresión en sí está entre paréntesis.

-2 gracias a gwaugh .
-5 gracias a xnor .

Erik el Outgolfer
fuente
5

Perl 6 , 166 161 bytes

{~(.day~(<th st nd rd>[.day%30%20]||'th'),<January February March April May June July August September October November December>[.month-1])}o*+Date.new(1,1,1)-1

Pruébalo en línea!

Codifica todos los nombres de los meses, lo que ocupa la mayor parte del espacio. Hombre, Perl 6 realmente necesita un formateador de fecha adecuado.

Jo King
fuente
4

Hack, 115 59 39 bytes

$x==>date("jS F",mktime(0,0,0,1,$x));

Como @gwaugh llegó a la misma solución que la mía mientras jugaba al golf, en su lugar publico esto en Hack :).

Ven
fuente
Wow, las grandes mentes piensan igual. :) +1 a usted señor!
640 KB
@gwaugh jaja, no sabía que podía tener un programa de alto nivel. También editaré el mío para que sea de nivel superior, y encontraré la manera de obtener un mejor puntaje ;-)
Ven
1
@gwaugh Hizo el mío Hack en su lugar.
Ven
1
Probablemente desee especificar un parámetro de año no bisiesto para su mktime()llamada; de lo contrario, devolverá la salida incorrecta si se ejecuta en un año bisiesto. (tuvo que hacer a mi respuesta).
640 KB
4

Javascript (ES6),  117  113 bytes

Guardado 4 bytes gracias a @tsh

d=>(n=(d=new Date(1,0,d)).getDate())+([,'st','nd','rd'][n%30%20]||'th')+' '+d.toLocaleString('en',{month:'long'})

Pruébalo en línea!

Comentado

d =>                     // d = input day
  ( n =                  //
    ( d =                // convert d to
      new Date(1, 0, d)  //   a Date object for the non leap year 1901
    ).getDate()          // save the corresponding day of month into n
  ) + (                  //
    [, 'st', 'nd', 'rd'] // ordinal suffixes
    [n % 30 % 20]        // map { 1, 2, 3, 21, 22, 23, 31 } to { 'st', 'nd', 'rd' }
    || 'th'              // or use 'th' for everything else
  ) + ' ' +              // append a space
  d.toLocaleString(      // convert d to ...
    'en',                // ... the English ...
    { month: 'long' }    // ... month name
  )                      //

Sin fecha incorporada, 188 bytes

f=(d,m=0)=>d>(k=31-(1115212>>m*2&3))?f(d-k,m+1):d+([,'st','nd','rd'][d%30%20]||'th')+' '+`JanuaryFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecember`.match(/.[a-z]*/g)[m]

Pruébalo en línea!

Arnauld
fuente
Falla los días 11, 12 y 13 de cada mes
Datos
1
@ExpiredData Gracias por informar esto. Corregido ahora.
Arnauld
Ignora mi comentario, cometí un error ID10T.
Asgallant
No estoy seguro de cómo nodejs maneja las etiquetas de idioma, pero parece que usar 0funcionaría como usar "en". Y cambiar a toLocaleStringahorraría 4 bytes. 110 bytes
tsh
@tsh Parece que toLocaleStringestá usando la configuración predeterminada del sistema cuando se pasa una cadena no reconocida o un valor numérico. Entonces, puede ser cualquier cosa. Este parámetro es básicamente ineficaz en una instancia TIO, porque de todos modos solo se instalan configuraciones regionales en inglés .
Arnauld
4

Smalltalk, 126 bytes

d:=Date year:1day:n.k:=m:=d dayOfMonth.10<k&(k<14)and:[k:=0].o:={#st.#nd.#rd}at:k\\10ifAbsent:#th.m asString,o,' ',d monthName
Leandro Caniglia
fuente
1
No conozco Smalltalk, pero ¿es esto correcto 11th,12th,13th? Si leí correctamente, divide el número entero por 10, pero eso significaría que resultaría 11st,12nd,13rd, a menos que algo más en el código solucione esto mientras no lo sepa.
Kevin Cruijssen
@KevinCruijssen Tienes razón. Gracias por llamar mi atención sobre esto. Necesitaré gastar más bytes para arreglar esto.
Leandro Caniglia
1
@KevinCruijssen, Listo. Gracias de nuevo.
Leandro Caniglia
3

C # (compilador interactivo de Visual C #) , 141 139 133 124 122 bytes

a=>{var d=s.AddDays(a-1);int x=d.Day,m=x%30%20;return x+"thstndrd".Substring(m<4?m*2:0,2)+d.ToString(" MMMM");};DateTime s

Gracias a Arnauld por el método más rápido de eliminar 11,12,13º ahorro de 4 bytes

Pruébalo en línea!

Datos caducados
fuente
Con C # 8, esto se puede reducir a: a=>{var d=s.AddDays(a-1);int x=d.Day,m=x%30%20;return x+"thstndrd"[(m<4?m*2:0)..2]+$" {d:MMMM}";};DateTime s Sin embargo, el compilador interactivo no parece admitir el cambio de su nivel de lenguaje para "vista previa" en este momento.
Arcanox
116 bytes
Encarnación de la ignorancia
Estoy bastante seguro de que tiene que agregar un punto y coma después deDataTime s
Encarnación de la ignorancia
3

MySQL, 47 45 42 bytes

SELECT DATE_FORMAT(MAKEDATE(1,n),"%D %M")

1901 se puede reemplazar por cualquier año que haya sido / no sea bisiesto.

Editar: ahorró dos bytes eliminando espacios y otros tres bytes cambiando el año a 1, gracias a @Embodyment of Ignorance .

NicolasB
fuente
¿Puedes eliminar los espacios entre 1901, ny la cadena?
Encarnación de la ignorancia
@EmbodimentofIgnorance sí puedo, gracias!
NicolasB
Además, ¿por qué no reemplazar 1901 con un año como 1? 1 no es un año bisiesto, y es 3 bytes más corto
Encarnación de la ignorancia
@EmbodimentofIgnorance hecho y hecho :-)
NicolasB
3

05AB1E , 81 79 78 76 75 74 73 71 70 69 bytes

•ΘÏF•ºS₂+.¥-D0›©ÏθDT‰ć≠*4šß„—ÊØ3ôsè¨ð”……‚應…ä†ï€¿…Ë…ê†Ä…æ…Ì…Í”#®OèJ

-9 bytes gracias a @Grimy .
-1 byte gracias al standard thetruco de @ JonathanAllan para th,st,nd,rd, que utilizó en su respuesta de Jelly .

Pruébelo en línea o verifique todos los casos de prueba posibles .

Explicación:

•ΘÏF        # Push compressed integer 5254545
     º       # Mirror it vertically: 52545455454525
      S      # Converted to a list of digits: [5,2,5,4,5,4,5,5,4,5,4,5,2,5]
       ₂+    # And 26 to each: [31,28,31,30,31,30,31,31,30,31,30,31,28,31]
             # (the additional trailing 28,31 won't cause any issues)
           # Undelta this list (with automatic leading 0):
             #  [0,31,59,90,120,151,181,212,243,273,304,334,365,393,424]
  -          # Subtract each from the (implicit) input-integer
   D0       # Duplicate the list, and check for each if it's positive (> 0)
      ©      # Store the resulting list in the register (without popping)
       Ï     # Only leave the values at those truthy indices
        θ    # And get the last value from the list, which is our day
D            # Duplicate this day
 T          # Take the divmod-10 of this day: [day//10, day%10]
   ć         # Extract the head; pop and push the remainder-list and head: [day%10], day//10
            # Check whether the day//10 is NOT 1 (0 if day//10 == 1; 1 otherwise)
     *       # Multiply that by the [day%10] value
      4š     # Prepend a 4 to this list
        ß    # Pop and push the minimum of the two (so the result is one of [0,1,2,3,4],
             # where the values are mapped like this: 1..3→1..3; 4..9→4; 10..19→0; 20..23→0..3; 24..29→4; 30,31→0,1)
 thŠØ       # Push dictionary string "th standards"
      3ô     # Split it into parts of size 3: ["th ","sta","nda","rds"]
        sè   # Swap and index the integer into this list (4 wraps around to index 0)
          ¨  # And remove the trailing character from this string
ð            # Push a space " "
”……‚應…ä†ï€¿…Ë…ê†Ä…æ…Ì…Í”
             # Push dictionary string "December January February March April May June July August September October November"
 #           # Split on spaces
  ®          # Push the list of truthy/falsey values from the register again
   O         # Get the amount of truthy values by taking the sum
    è        # Use that to index into the string-list of months (12 wraps around to index 0)
J            # Join everything on the stack together to a single string
             # (and output the result implicitly)

Vea este consejo 05AB1E mío para entender por qué:

  • (sección ¿Cómo usar el diccionario? ) ”……‚應…ä†ï€¿…Ë…ê†Ä…æ…Ì…Í”es"December January February March April May June July August September October November"
  • (sección ¿Cómo usar el diccionario? ) …thŠØes"th standards"
  • (sección ¿Cómo comprimir enteros grandes? ) •ΘÏF•es5254545
Kevin Cruijssen
fuente
1
-2 bytes mediante el uso de 5 +28 para la compresión: TIO
Grimmy
1
Usar S es una buena idea, -1 byte nuevamente: TIO
Grimmy
1
@Grimy Gracias por el byte -1 •EË7Óæ•S₂+, pero tu golf -3 no funciona desafortunadamente. La indexación se ajusta automáticamente en 05AB1E, por lo 5st,6nd,7rd,25st,26nd,27rd,29stque estará mal. PD: si hubiera funcionado, podría haber sido por un -1 adicional. :)
Kevin Cruijssen
1
-1 de nuevo (usando "th estándares" en lugar de "estándar, el" elimina la necesidad de Á).
Grimmy
1
-1 ( •C.ñÒā•a •ΘÏF•º, los dígitos adicionales no importan)
Grimmy
2

bash, 82 80 bytes

-2 bytes gracias a @ ASCII-only

a=(th st nd rd);set `printf "%(%e %B)T" $[$1*86399]`;echo $1${a[$1%30%20]-th} $2

TIO

bash + fecha GNU, 77 bytes

a=(th st nd rd);set `date -d@$[$1*86399] +%e\ %B`;echo $1${a[$1%30%20]-th} $2
Nahuel Fouilleul
fuente
80?
Solo ASCII
@ Solo ASCII, sí restando 100s por cada día, 100 * 365 = 36500s, que es menos de un día (86400), también funciona con 86399 (resta 1s por día)
Nahuel Fouilleul
: / todavía parece muy largo pero aún no he encontrado una mejor manera
solo ASCII
2

Shell + coreutils, 112 90 bytes

date -d0-12-31\ $1day +%-dth\ %B|sed 's/1th/1st/;s/2th/2nd/;s/3th/3rd/;s/\(1.\).. /\1th /'

Pruébalo en línea! El enlace incluye casos de prueba. Editar: Guardado 22 bytes gracias a @NahuelFouilleul. Explicación:

date -d0-12-31\ $1day

Calcule el número de días después del primer día anterior a un año no bisiesto. (Lamentablemente, no puede hacer cálculos de fechas relativas @-1).

+%-dth\ %B|sed

Salida del día del mes (sin cero a la izquierda) th, y el nombre completo del mes.

's/1th/1st/;s/2th/2nd/;s/3th/3rd/;

Arreglar 1st, 2nd, 3rd, 21st, 22nd, 23rdy 31st.

s/\(1.\).. /\1th /'

Restaurar 11tha 13th.

Neil
fuente
vi esta respuesta después de la mía, podría salvar 18bytes utilizando un comando sed, también sen el daysse puede quitar, y 19en1969
Nahuel FOUILLEUL
@NahuelFouilleul Ese último usa un Bash-ism, por lo que debe publicarse como una respuesta por separado, ¡pero gracias por los otros consejos!
Neil
2

Jalea , 115 114 101 97 bytes

%30%20¹0<?4Ḥ+ؽị“thstndrd”ṭ
“5<Ḟ’b4+28ÄŻ_@µ>0T,>0$ƇZṪµ1ịị“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»Ḳ¤,2ịÇƊṚK

Pruébalo en línea!

Largo para los estándares de Jelly, pero hecho desde los primeros principios.

Gracias a @JonathanAllan por guardar 13 bytes a través de una mejor comprensión de la compresión de cadenas.

Nick Kennedy
fuente
“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»Ḳ¤ahorraría 13 (Compress.dictionary busca un espacio líder y tiene un manejo especial para ello).
Jonathan Allan
2

Hojas de Google, 118 103 86 bytes

=day(A1+1)&mid("stndrdth",min(7,1+2*mod(mod(day(A1+1)-1,30),20)),2)&text(A1+1," mmmm")

No puedo editar mi comentario , así que aquí hay una versión funcional del código de Google Sheets.

Pruébalo en línea!

Zylviij
fuente
1

Rojo , 124 bytes

func[n][d: 1-1-1 + n - 1[rejoin[d/4 either 5 > t: d/4 % 30 % 20[pick[th st nd rd]t + 1]['th]]pick system/locale/months d/3]]

Pruébalo en línea!

Agrega n: 1 días a 1-1-1 (1 de enero de 2001) para formar una fecha, que utiliza el método de Arnauld para indexar en sufijos de mes. Lástima que el rojo esté indexado en 1, esto requiere ajustes adicionales. Lo bueno es que Red sabe los nombres de los meses :)

Galen Ivanov
fuente
1

APL (NARS), 235 caracteres, 470 bytes

{k←↑⍸0<w←+\v←(1-⍵),(12⍴28)+13561787⊤⍨12⍴4⋄k<2:¯1⋄d←1+v[k]-w[k]⋄(⍕d),({d∊11..13:'th'⋄1=10∣d:'st'⋄2=10∣d:'nd'⋄3=10∣d:'rd'⋄'th'}),' ',(k-1)⊃(m≠' ')⊂m←'January February March April May June July August September October November December'}

13561787 es el número que en la base 4 se puede sumar (12⍴28) para obtener la duración de cada mes ... prueba:

  f←{k←↑⍸0<w←+\v←(1-⍵),(12⍴28)+13561787⊤⍨12⍴4⋄k<2:¯1⋄d←1+v[k]-w[k]⋄(⍕d),({d∊11..13:'th'⋄1=10∣d:'st'⋄2=10∣d:'nd'⋄3=10∣d:'rd'⋄'th'}),' ',(k-1)⊃(m≠' ')⊂m←'January February March April May June July August September October November December'}     
  ⊃f¨1 2 3 365 60 11
1st January  
2nd January  
3rd January  
31st December
1st March    
11th January 
RosLuP
fuente
0

C (gcc) , 174155 bytes

i;char a[99],*b="thstndrd";f(long x){x--;x*=86400;strftime(a,98,"%d   %B\0",gmtime(&x));i=*a==49?0:a[1]-48;a[2]=b[i=i>3?0:i*2];a[3]=b[++i];x=*a==48?a+1:a;}

Pruébalo en línea!

GPS
fuente
-2

Python 3 , 95 bytes

Fecha y hora: P

from datetime import *;f=lambda s:(datetime(2019,1,1)+timedelta(days=s-1)).strftime("%d of %B")

Pruébalo en línea!

Querosenoico
fuente
2
Esto no produce los sufijos ordinales y tiene ceros a la izquierda en el número del día. El oftambién es innecesario
Jo King