Ottieni la data dell'ennesimo giorno della settimana in un determinato anno e mese


17

introduzione

Spesso, le persone si riferiscono alle date come il "secondo venerdì di agosto 2018" o la "quarta domenica di marzo 2012". Ma è difficile dire che data sia! Il tuo compito è quello di scrivere un programma che riceva un anno, un mese, un giorno della settimana e un numero intero e che generi quella data.

Sfida

  • Per l'input, otterrai un anno, un mese, un giorno della settimana e un numero.

  • Puoi prendere l'input in qualsiasi formato ragionevole, come usare una stringa per il giorno della settimana o usare un giorno della settimana indicizzato zero, o anche prendere l'anno e il mese in una singola stringa. Spiega il tuo formato di input nella tua risposta, però.

  • Il numero intero che ti dice quale giorno della settimana del mese scegliere come target sarà un numero intero compreso tra 1 e 5. L'intero non farà mai riferimento a un giorno della settimana che non esiste (ad es. Il quinto venerdì di febbraio 2019, che non esiste).

  • Gli anni saranno sempre positivi.

  • L'output può essere in qualsiasi formato ragionevole, inclusa la stampa della data finale. Tuttavia, si prega di spiegare il formato di output alla risposta.

  • Fornire l'anno e il mese nell'output è facoltativo. Inoltre, puoi presumere che la data sia valida.

Esempio di input e output

Considera questo input, con il formato che assume l'anno come un numero di 4 cifre, il mese come numero intero, il giorno della settimana come stringa e il numero ordinale come numero intero:

2019, 3, sabato, 2
2019, 12, domenica, 1
2019, 9 sabato, 1

Produzione:

9 marzo 1
dicembre
7 settembre

Questo è , quindi vince la risposta più breve.


1
Pensavo di poter usare GNU date, ma in modo divertente, il parser ha un'interpretazione ... interessante qui.
Maniglia della porta

Il numero della settimana può essere indicizzato 0?
Jo King

Certo, se si adatta al tuo programma
Incarnazione dell'ignoranza

Caso di prova suggerito: domenica 12, 2018 1
Adám

Caso di prova suggerito: il primo sabato di settembre 2019
Shaggy

Risposte:


4

Modello MediaWiki, 19 byte

{{#time:r|{{{1}}}}}

Questa è una porta ParserFunctions modello MediaWiki di questa risposta PHP

Nota: #timeutilizzare PHP strtotimeinternamente.


Input di esempio

{{#time: r | secondo sabato di marzo 2019}}

Uscita campione

Sab, 09 mar 2019 00:00:00 +0000


3

Japt, 19 15 byte

L'input è: anno, indice del mese in base 0, indice del giorno in settimana 0 ( 0è domenica) & n.

_XµW¶Ze}f@ÐUVYÄ

Provalo

                    :Implicit input of U=year, V=month, W=weekday & X=n
       }f           :Output the first element generated by the right function that returns
                    : falsey (0) when passed through the left function
         @          :Right function. Y=0-based index of current iteration
          ÐUVYÄ     :  new Date(U,V,Y+1)
_                   :Left function. Z=date being passed
 Xµ                 :  Decrement X by
   W¶               :   Test W for equality with
     Ze             :    Z.getDay()

2

C # (compilatore interattivo Visual C #) , 59 byte

(y,m,d,w)=>1+(d-(int)new DateTime(y,m,1).DayOfWeek+7)%7+7*w

Provalo online!

-27 byte grazie a @EmbodimentOfIgnorance!

Meno codice golf ...

// y: year
// m: month
// d: day of week (0 is Sunday)
// w: week number (0 based)
(y,m,d,w)=>
  // start on the first day of the month
  1+
  // determine the number of days to
  // the first occurrence of the
  // requested weekday
  (d-(int)new DateTime(y,m,1).DayOfWeek+7)%7+
  // add the number of requested weeks
  7*w

Il valore restituito è un numero intero per il giorno del mese della data richiesta.


Se restituisci solo il giorno del mese, che è consentito, puoi giocare a golf fino a 59 byte
Incarnazione dell'ignoranza

Grazie ancora per il suggerimento - (oggi è 2x;) aggiornerò le mie risposte.
dana,

2

SmileBASIC, 58 51 48 46 45 byte

READ N,M$DTREAD M$OUT,,D,W?(5-W+D*2)MOD 7+N*7

L'input è nella forma: week,year/month/weekday

  • week: numero della settimana, indicizzato 0
  • year: anno, 4 cifre
  • month: mese (1 indicizzato), 2 cifre- 0imbottito
  • weekday: Giorno della settimana (1-indicizzato, 1 = Domenica), 2 cifre 0-padded

L'output è il giorno del mese, 0 indicizzato.
Il 2 ° sabato di marzo 2019 sarebbe 1,2019/03/078(9 marzo)

Ungolfed

READ WEEK,M$
DTREAD M$ OUT ,,D,W
'Functions in SB can output multiple values using OUT.
'In this case, we don't need the first 2 values, so no variables are given.

PRINT (5-W+ D*2) MOD 7 +WEEK*7

Spiegazione

Il modulo di input è stato scelto in modo specifico in modo che l'anno / mese / giorno della settimana possa essere passato direttamente a DTREAD, che è una funzione che analizza una YYYY/MM/DDstringa e restituisce l'anno / mese / giorno come numeri, oltre a calcolare il giorno della settimana.

Tuttavia, si noti che, laddove si DTREADprevede il giorno del mese, invece, viene assegnato il giorno della settimana. Questo complica le cose, ma significa anche che ci sono meno valori di input e non abbiamo bisogno di aggiungere /01alla fine della stringa della data.

DTREADuscite We D.
Wè il giorno della settimana ed Dè il giorno della settimana del Wth giorno del mese.
(Quindi, se inserisci 7come giorno della settimana, Dsarà 7e Wsarà qualsiasi giorno della settimana il 7 ° giorno del mese)

L'espressione (5-W+D*2)MOD 7viene utilizzata per ottenere la prima occorrenza del giorno della settimana di input, come un giorno del mese con indice 0. (L'ho capito principalmente attraverso tentativi ed errori)

Successivamente, il programma aggiunge semplicemente WEEK*7.


Vorrei davvero che ci fossero parole separate per "giorno della settimana" e "giorno del mese".


2

Perl 6 , 52 48 byte

{1+($^c+4-Date.new($^a,$^b,1).daycount)%7+$^d*7}

Provalo online!

Blocco di codice anonimo che accetta input come anno, mese, giorno della settimana (domenica è 0) e numero della settimana (0 indicizzato). L'output è un oggetto data.

Vecchia spiegazione:

{                                                  } # Anonymous code block
 (   Date.new(         ))   # Create a new date with
              $^a,$^b,1     # With year, month and the first day
  $_=                       # Save in the variable $_
                         +  # Add to this
                           $^c+4                     # The given day plus 4
                          (     -.daycount)          # The number of days since 17 Nov, 1858
                                           %7        # Modulo 7 to get the correct day
                                             +$^d*7  # Plus the 7 times the number of weeks

Penso che il numero della settimana debba essere 1-indicizzato
Mee

@ 12Me21 La domanda dice che l'input è flessibile, ma ho chiesto se abbiamo un numero della settimana take indicizzato 0
Jo King

Questo non sembra funzionare per altri mesi. Penso che tu abbia bisogno $^c+4-$!.daycount.
nwellnhof

@nwellnhof Ah, avrei dovuto pensarci invece di tentativi ed errori, lol. Ora dovrebbe essere risolto
Jo King

1

MATL , 28 27 byte

'1 'ihYO31:q+t8XOi=!A)i)1XO

Questo utilizza tre input:

  • Stringa con mese e anno: 'March 2019'
  • Stringa con tre lettere, maiuscole, che indica il giorno della settimana: "Sat '
  • Numero: 2 .

L'output è una stringa con giorno, anno e mese separati da trattini: 09-Mar-2019 .

Provalo online!

Spiegazione

Considerate ingressi 'March 2019', 'Sat', 2.

'1 '    % Push this string
        % STACK: '1 '
ih      % Input string: month and year. Concatenate
        % STACK: '1 March 2019'
YO      % Convert to serial date number
        % STACK: 737485
31:q+   % Create vector [0 1 2 ... 30] and add element-wise
        % STACK: [737485 737486 737487 ... 737515]
t8XO    % Duplicate. Convert to date format 'ddd': day of week in three letters. Gives
        % a 2D char array
        % STACK: [737485 737486 737487 ... 737515], ['Fri'; 'Sat'; 'Sun'; ...; 'Sun']
i=      % Input string: day of week in three letters. Compare element-wise with broadcast
        % STACK: [737485 737486 737487 ... 737515],
        % [0 0 0; 0 0 0; ...; 1 1 1; 0 0 0; ... 1 1 1; ...]
!A      % True for rows containing only 1
        % STACK: [737485 737486 737487 ... 737515], [0 0 ... 1 ... 0 ... 1 ...]
)       % Index: uses the second vector as a mask into the first
        % STACK: [737486 737493 737500 737507 737514]
i)      % Input number. Index
        % STACK: 737493
1XO     % Convert to date format 'dd-mmm-yyyy'. Implicit display
        % STACK: '09-Mar-2019'

1

Python 3 , 92 82 byte

82 byte grazie a @Jo King

lambda y,m,d,w:z(y,m)[w-(z(y,m)[0][d]>0)][d]
from calendar import*
z=monthcalendar

Provalo online!

Versione originale, 92 byte

from calendar import*
def f(y,m,d,w):
 x=monthcalendar(y,m)
 if x[0][d]:w-=1
 return x[w][d]

Provalo online!

Prende l'anno come numero intero, il mese come numero intero con 1 indice, il giorno della settimana come numero intero con indice 0 dove lunedì è 0e domenica è6 , e la settimana del mese come numero intero con 1 indice.

Come funziona:

# import monthcalendar
from calendar import*
# function with 4 inputs
def f(y,m,d,w):
 # get a 2-D array representing the specified month
 # each week is represented by an array
 # and the value of each element is its date of the month
 # Monday is the 0th element of each week, Sunday is the 6th element
 # days of the first week of the month before the 1st are 0s 
 x=monthcalendar(y,m)
 # if the first week of the month includes the desired day of week
 # convert the week of month to 0-index so that it takes into account the first week
 if x[0][d]:w-=1
 # return the weekday of the week number specified
 return x[w][d]

1

R , 72 69 byte

function(y,m,d,n,D=as.Date(paste0(y,-m,-1))+0:31)D[weekdays(D)==d][n]

Provalo online!

Prendendo input come:

  • Numero dell'anno
  • Numero del mese (1-12)
  • Stringa del giorno della settimana nella locale corrente (TIO richiede il nome inglese con la lettera maiuscola)
  • Numero ordinale (1 indicizzato)


0

Groovy , 46 byte

{y,m,d,w->r=new Date(y,m,7*w)
r-(r.day+7-d)%7}

Provalo online!

Inserire come anni dal 1900, mese indicizzato 0, giorno indicizzato 0 (domenica 0) e numero settimana



0

Rosso , 64 60 byte

func[y m d n][a: to-date[1 m y]d - a/10 - 7 % 7 +(n * 7)+ a]

Provalo online!

Prende l'anno, il mese e il giorno della settimana come numeri, 1 indicizzati, il lunedì è il primo giorno della settimana.


eh, to-dateè una cosa. forse questo sarebbe utile nella sfida del formato della vigilia di Natale
solo ASCII il

@ Solo ASCII Abbiamo usato nowper quella sfida
Galen Ivanov il

1
sì, ma stavo pensando a metodi alternativi (vale a dire, <ripetizione " Eve"data2-data1 volte> metodo iirc)
solo ASCII

@ Solo ASCII>> 25-Dec-2019 - 1-1-2019 == 358
Galen Ivanov

0

APL (Dyalog Unicode) , 36 byte SBCS

Programma completo. Richiede [year,month](gennaio è 1), quindi per giorno (domenica è 0), quindi per n (prima è 1).

date⎕⊃d/⍨⎕=7|d←(⍳31)+days⎕⊣⎕CY'dfns'

Provalo online!

⎕CY'dfns'c o p y nella dfns libreria

 scartare il risultato a favore di ...

 pronta console per i [year,month]numeri

days[c]  giorni [n] dal 1899/12/31 del 0 ° del mese

(⍳31)+ aggiungi l' i nteger 1 ... 31 a quello

d← negozio a d(per d numeri ay)

7| resto della divisione quando si divide per 7 (giorno della settimana con domenica pari a 0 a causa di una buona epoca)

⎕= prompt della console per il numero del giorno della settimana e ottenere maschera dove sono uguali i numeri del giorno della settimana

d/⍨ filtra dcon quella maschera

⎕⊃ richiede console per n e usalo per scegliere dall'elenco dei numeri dei giorni

date[c]  datetime stamp [n] (ha zeri finali per ore, minuti, secondi, millisecondi)


Fai clic su [c] per il codice e [n] per le note.


0

JavaScript (ES6), 49 48 byte

f=
(a,d,n)=>(d+6-new Date(...a,7).getDay())%7+n*7-6
<div oninput=o.textContent=f([+y.value,+m.value],+d.value,+n.value)>Year: <input id=y type=number value=2019><br>Month: <select id=m><option value=0>Jan<option value=1>Feb<option value=2>Mar<option value=3>Apr<option value=4>May<option value=5>Jun<option value=6>Jul<option value=7>Aug<option value=8>Sep<option value=9>Oct<option value=10>Nov<option value=11>Dec</select><br>Day: <select id=d><option value=0>Sun<option value=1>Mon<option value=2>Tue<option value=3>Wed<option value=4>Thu<option value=5>Fri<option value=6>Sat</select><br>Count: <input id=n type=number value=1 min=1 max=5><pre id=o>

Prende i parametri come f([year, month], day, number). Il mese e il giorno della settimana (a partire da domenica) sono indicizzati a zero. Modifica: salvato 1 byte grazie a @Shaggy.


Il giorno della settimana è nel formato domenica-sabato o lunedì-domenica?
Incarnazione dell'ignoranza

@EmbodimentofIgnorance Mi dispiace, sapevo di aver dimenticato qualcosa. (Lo snippet ora utilizza select per renderlo più semplice.)
Neil

@EmbodimentofIgnorance, Sunday is 0in JS.
Shaggy

Oh. Non lo sapevo, non ho familiarità con Javascript.
Incarnazione dell'ignoranza


0

TSQL, 106 byte

DECLARE @ datetime='2019',@m int=3,@w char(2)='saturday',@p int=2

SELECT dateadd(wk,datediff(d,x,dateadd(m,@m-1,@)-1)/7,x)+@p*7FROM(SELECT
charindex(@w,' tuwethfrsasu')/2x)x

Produzione:

2019-03-09 00:00:00.000

Provalo


0

Kotlin , 131 84 byte

47 byte grazie al codice e al commento solo ASCII.

Input: anno, meseNumero, giorno della settimanaNumero, settimanaNumero

Tutti i numeri interi da 1 a massimo su riga singola. Il numero del giorno della settimana va da domenica 1 a sabato di 7. Il programma principale fa perdere l'anno 1900 per la classe Date e il mese e il giorno della settimana vengono spostati per iniziare con zero anziché uno prima di chiamare lambda. Puoi inserire i tuoi argomenti nella casella di testo di input per provare le tue date.

Output: un'istanza della classe Date. Il programma principale visualizza il risultato come: sab mar 09 00:00:00 UTC 2019.

Esiste una versione estesa con commenti che spiegano il codice per coloro che desiderano saperne di più.

{y,m,d,w->val r=java.util.Date(y,m,7*w)
r.setDate(r.getDate()-(r.getDay()+7-d)%7)
r}

Provalo online!


1
74 - usa lo stesso metodo delle risposte di Scala e Groovy
ASCII-only


1
Non è più necessario il comando di importazione, quindi non è un problema: P
ASCII il
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.