È un compito annuale, va bene


22

Dato un numero 1≤n≤365, visualizza l'ennesimo giorno dell'anno nel formato "Giorno-numero-mese". Ad esempio, dato 1, dovresti visualizzare "1 gennaio", senza "di".

Verrà utilizzato il calendario gregoriano e il programma non dovrebbe tenere conto degli anni bisestili, quindi il programma non dovrebbe mai produrre "29 febbraio" in nessuna circostanza. È possibile utilizzare qualsiasi metodo, purché segua il formato "Giorno-numero mese" menzionato in precedenza. Il tuo programma dovrebbe anche generare correttamente gli ordinali, il che significa che dovrebbe sempre emettere 1 °, 2 °, 3 °, dovrebbero rispettivamente 1, 2 o 3 i numeri del giorno per qualsiasi input. Sono consentiti spazi iniziali o altri rientri.

Questo è il golf del codice, quindi vince la soluzione più breve per i personaggi.

Casi test:

1 gives 1st January
2 gives 2nd January
3 gives 3rd January
365 gives 31st December
60 gives 1st March
11 gives 11th January

4
Inoltre, devi forzare un messaggio di errore su numeri> 365? Il programma può solo supporre che l'input non sia valido e non sarà necessario gestirlo?
Rɪᴋᴇʀ

5
Poiché non tutti sono di madrelingua inglese, potresti voler aggiungere quel giorno i numeri 11, 12 e 13 get "th", i numeri che terminano con "1" get "st", "2" get "nd", "3" get "rd" e tutti gli altri ottengono "th".
Adám

9
Whoa, non accettare risposte così in fretta. Soprattutto risposte non sbagliate !
Adám

6
Si dovrebbe aggiungere almeno 11(11 ° gennaio) e 21(21 st gennaio) per i casi di test.
Arnauld,

1
E mentre stai modificando i casi di test, forse specifica quale sia esattamente il formato del tuo caso di test. Un paio di risponditori hanno pensato che 123=fosse parte dell'output richiesto. O semplicemente modifica i tuoi casi di test per leggere qualcosa di simile: 36531st December
Adám

Risposte:


9

PHP ,38 40 30 28 byte

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

Provalo online!

Esegui con php -nFinput viene da STDIN. Esempio (sopra lo script chiamato 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

Spiegazione

Costruisci un timestamp di epoca per il giorno desiderato nel 1970 (convenientemente non un anno bisestile) moltiplicando day number * number of seconds per day(86400). Tuttavia, ciò produrrebbe un giorno in più, quindi moltiplicare invece per number of seconds in a day - 1(86399) che per l'intervallo dei numeri di input (1≤n≤365) risulterà con il timestamp della fine di ciascun giorno corretto. Quindi basta usare la formattazione della data integrata di PHP per l'output.


perché è -nnecessario?
Ven

@Ven potrebbe non essere in tutti i casi, ma disabilita semplicemente qualsiasi impostazione in php.ini locale che potrebbe creare comportamenti incoerenti.
640 KB

6

Gelatina ,  79 78  77 byte

-1 correzione di un bug :) (non dovrebbe pre-trasporre per trovare l'indice, dovrebbe essere post-reverse, ma poi possiamo fare la coda piuttosto che dirigerci)
-1 usando la riflessione ( ⁽©ṅ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 programma completo che stampa il risultato

Provalo online!

Come?

lo aggiornerò più tardi ...

⁽©ṅ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

4
Il trucco "standard the" è sorprendente.
Ven

Sono d'accordo con @Ven , grande trucco! Ha anche salvato un byte nella mia risposta 05AB1E rispetto alla stringa compressa "thstndrd"divisa in parti di dimensione 2 ( .•oθ2(w•2ô), quindi grazie. :)
Kevin Cruijssen il

1
Questo deve essere uno dei programmi Jelly più lunghi che abbia mai visto.
JAD

6

C # (compilatore interattivo Visual C #) , 115 113 109 98 98 byte

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;

Grazie a @someone per aver salvato 9 byte

Provalo online!


1
@KevinCruijssen Ho rimosso i moduli, dovrebbe essere risolto ora.
Incarnazione dell'ignoranza il

.code.tio(2,22): error CS0165: Use of unassigned local variable 'p'Sembra che la cosa struct non funzioni.
JAD

var g=new DateTime().AddDays(n-1)funziona però
JAD

@JAD errore da parte mia, risolto
Incarnazione dell'ignoranza il


5

Python 3.8 (pre-release) , 112 byte

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

Provalo online!

Stranamente, non devo essere tra parentesi d:=(t:=gmtime(~-x*86400), probabilmente perché l'interprete controlla solo se ci sono ()caratteri attorno all'espressione di assegnazione e non che l'espressione stessa sia tra parentesi.

-2 grazie a Gwaugh .
-5 grazie a xnor .


5

Perl 6 , 166 161 byte

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

Provalo online!

Hardcodes tutti i nomi dei mesi, che occupa gran parte dello spazio. Amico, Perl 6 ha davvero bisogno di un vero programma di formattazione della data.


4

Hack, 115 59 39 byte

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

Dato che @gwaugh è arrivato alla stessa soluzione della mia mentre giocavo a golf, sto pubblicando questo in Hack :).


Wow, le grandi menti pensano allo stesso modo. :) +1 a te signore!
640 KB

@gwaugh haha, non sapevo che avrei potuto avere solo un programma di alto livello. Modificherò il mio per renderlo anche ai massimi livelli e troverò un modo per ottenere un miglior punteggio e ;-)
Ven

1
@gwaugh Ha invece creato il mio Hack.
Ven

1
Probabilmente vorrai specificare un parametro per l'anno non bisestile alla tua mktime()chiamata, altrimenti restituirà un output errato se eseguito in un anno bisestile. (dovuto fare alla mia risposta).
640 KB

4

JavaScript (ES6),  117  113 byte

Salvato 4 byte grazie a @tsh

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

Provalo online!

Commentate

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

Senza data incorporata, 188 byte

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]

Provalo online!


Errore dell'11, 12, 13 di ogni mese
Dati scaduti il

1
@ExpiredData Grazie per aver segnalato questo. Riparato ora.
Arnauld,

Ignora il mio commento, ho fatto un errore ID10T.
asgallant

Non sono sicuro del modo in cui nodejs gestisca i tag di lingua, ma sembra che l'utilizzo 0funzionerebbe come se fosse "en". E cambiando in toLocaleStringsi risparmierebbe 4 byte. 110 byte
tsh

@tsh Sembra che toLocaleStringstia utilizzando le impostazioni predefinite del sistema quando viene passata una stringa non riconosciuta o un valore numerico. Quindi, può essere qualsiasi cosa. Questo parametro è sostanzialmente inefficace su un'istanza TIO, poiché sono comunque installate solo impostazioni locali inglesi .
Arnauld

4

Smalltalk, 126 byte

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

1
Non conosco Smalltalk, ma è corretto 11th,12th,13th? Se leggessi correttamente dividi il numero intero per 10, ma ciò significherebbe che ciò comporterebbe 11st,12nd,13rd, a meno che qualcos'altro nel codice lo risolva mentre non ne sono consapevole.
Kevin Cruijssen,

@KevinCruijssen Hai ragione. Grazie per aver richiamato la mia attenzione su questo. Ho bisogno di spendere qualche altro byte per risolvere questo problema.
Leandro Caniglia,

1
@KevinCruijssen, Fatto. Grazie ancora.
Leandro Caniglia,

3

C # (compilatore interattivo Visual C #) , 141 139 133 124 122 byte

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

Grazie ad Arnauld per un metodo più rapido di rimozione di 11,12,13 ° salvataggio di 4 byte

Provalo online!


Utilizzando C # 8, questo può essere ridotto 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 Il compilatore interattivo non sembra supportare la modifica del suo livello di lingua in "anteprima" in questo momento, tuttavia.
Arcanox,


Sono abbastanza sicuro che devi aggiungere un punto e virgola dopo ilDataTime s
Incarnazione dell'ignoranza il


3

MySQL, 47 45 42 byte

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

Il 1901 può essere sostituito con qualsiasi anno che non è stato / non è un anno bisestile.

Modifica: salvato due byte rimuovendo gli spazi e altri tre byte modificando l'anno in 1, grazie a @Embodyment of Ignorance .


Riesci a rimuovere gli spazi tra 1901, ne la stringa?
Incarnazione dell'ignoranza

@EmbodimentofIgnorance sì, grazie!
NicolasB,

Inoltre, perché non sostituire il 1901 con un anno come 1? 1 non è un anno bisestile, ed è più corto di 3 byte
Incarnazione dell'ignoranza il

@EmbodimentofIgnorance fatto e fatto :-)
NicolasB

3

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

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

-9 byte grazie a @Grimy .
-1 byte grazie al standard thetrucco di @ JonathanAllan th,st,nd,rd, che ha usato nella sua risposta Jelly .

Provalo online o verifica tutti i possibili casi di test .

Spiegazione:

•ΘÏ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)

Vedi questo mio suggerimento 05AB1E per capire perché:

  • (sezione Come usare il dizionario? ) ”……‚應…ä†ï€¿…Ë…ê†Ä…æ…Ì…Í”è"December January February March April May June July August September October November"
  • (sezione Come usare il dizionario? ) …thŠØè"th standards"
  • (sezione Come comprimere numeri interi di grandi dimensioni? ) •ΘÏF•è5254545

1
-2 byte usando 5в28 + per la compressione: TIO
Grimmy

1
Usare S è una buona idea, -1 byte di nuovo: TIO
Grimmy

1
@Grimy Grazie per il -1 byte per •EË7Óæ•S₂+, ma il tuo golf -3 non funziona purtroppo. L'indicizzazione termina automaticamente in 05AB1E, quindi 5st,6nd,7rd,25st,26nd,27rd,29stsarà errato. PS: se avrebbe funzionato, avrebbe potuto essere per un ulteriore -1. :)
Kevin Cruijssen il

1
-1 di nuovo (usando "th standard" invece di "standard the" si rimuove la necessità di Á).
Grimmy

1
-1 ( •C.ñÒā•a •ΘÏF•º, le cifre extra non contano)
Grimmy

2

bash, 82 80 byte

-2 byte grazie solo a @ ASCII

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

TIO

bash + data GNU, 77 byte

a=(th st nd rd);set `date -d@$[$1*86399] +%e\ %B`;echo $1${a[$1%30%20]-th} $2


@ Solo ASCII, sì sottraendo 100s per ogni giorno, 100 * 365 = 36500s che è meno di un giorno (86400), funziona anche con 86399 (sottrai 1s al giorno)
Nahuel Fouilleul

: / sembra ancora molto lungo ma non ho ancora trovato un modo migliore
ASCII-only

2

Shell + coreutils, 112 90 byte

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

Provalo online! Il link include casi di test. Modifica: salvato 22 byte grazie a @NahuelFouilleul. Spiegazione:

date -d0-12-31\ $1day

Calcola il numero di giorni dopo il primo giorno che precede un anno non bisestile. (Purtroppo non è possibile eseguire calcoli relativi della data da@-1 .)

+%-dth\ %B|sed

Stampa il giorno del mese (senza zero iniziale), th e il nome completo del mese.

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

Sistemare 1st, 2nd, 3rd, 21st, 22nd,23rd e31st .

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

Ripristina 11thsu 13th.


ho visto questa risposta dopo la mia, ho potuto salvare 18bytes usando un comando sed, anche sin dayspuò essere rimosso, e 19in1969
Nahuel Fouilleul

@NahuelFouilleul Quest'ultimo utilizza un Bash-ism, quindi dovrebbe essere pubblicato come risposta separata, ma grazie per gli altri suggerimenti!
Neil

2

Gelatina , 115 114 101 97 byte

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

Provalo online!

Lungamente dagli standard di Jelly, ma fatto dai primi principi.

Grazie a @JonathanAllan per aver salvato 13 byte attraverso una migliore comprensione della compressione delle stringhe.


“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»Ḳ¤salverebbe 13 (Compress.dictionary cerca uno spazio iniziale e ha una gestione speciale per esso).
Jonathan Allan,

2

Fogli Google, 118 103 86 byte

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

Non posso modificare il mio commento , quindi, ecco una versione funzionante del codice di Fogli Google.

Provalo online!


1

Rosso , 124 byte

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

Provalo online!

Aggiunge n- 1 giorni a 1-1-1 (1-gennaio-2001) per formare una data, quindi utilizza il metodo di Arnauld per indicizzare i suffissi del mese. Peccato che il rosso sia 1 indicizzato, ciò richiede ulteriori modifiche. La cosa buona è che Red conosce i nomi dei mesi :)


1

APL (NARS), 235 caratteri, 470 byte

{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 è il numero che nella base 4 può essere sommato a (12⍴28) per ottenere la lunghezza di ogni mese ... test:

  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 

0

C (gcc) , 174 155 byte

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

Provalo online!


-2

Python 3 , 95 byte

Datecreded: P

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

Provalo online!


2
Questo non produce i suffissi ordinali e ha zero iniziali nel numero del giorno. Il ofè anche inutile
Jo Re
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.