Obtenez la date du nième jour de la semaine dans une année et un mois donnés


17

introduction

Souvent, les gens appellent les dates le "deuxième vendredi d'août 2018" ou le "quatrième dimanche de mars 2012". Mais c'est difficile de dire à quelle date c'est! Votre tâche consiste à écrire un programme qui reçoit un an, un mois, un jour de la semaine et un entier et à sortir cette date.

Défi

  • Pour la saisie, vous obtiendrez une année, un mois, un jour de la semaine et un nombre.

  • Vous pouvez prendre des entrées dans n'importe quel format raisonnable, comme utiliser une chaîne pour le jour de la semaine ou utiliser un jour de semaine indexé zéro, ou même prendre l'année et le mois dans une seule chaîne. Expliquez cependant votre format de saisie dans votre réponse.

  • Le nombre entier qui vous indique quel jour de la semaine du mois cibler sera un nombre entier de 1 à 5. L'entier ne fera jamais référence à un jour de la semaine qui n'existe pas (par exemple le cinquième vendredi de février 2019, qui n'existe pas).

  • Les années seront toujours positives.

  • Votre sortie peut être dans n'importe quel format raisonnable, y compris l'impression de votre date finale. Cependant, veuillez expliquer votre format de sortie et votre réponse.

  • Fournir l'année et le mois dans la sortie est facultatif. Vous pouvez également supposer que la date est valide.

Exemple d'entrée et de sortie

Considérez cette entrée, avec le format prenant l'année comme un nombre à 4 chiffres, le mois comme un entier, le jour de la semaine comme une chaîne et le nombre ordinal comme un entier:

2019, 3, samedi, 2
2019, 12, dimanche, 1
2019, 9 samedi, 1

Production:

9 mars
1er décembre
7 septembre

C'est le , donc la réponse la plus courte l'emporte.


1
Je pensais pouvoir utiliser GNU date, mais de manière amusante, l'analyseur a une ... interprétation intéressante ici.
Poignée de porte

Le numéro de semaine peut-il être indexé 0?
Jo King

Bien sûr, si cela convient à votre programme
Embodiment of Ignorance

Cas de test suggéré: 12, 2018, dimanche 1
Adám

Cas de test suggéré: le premier samedi de septembre 2019
Shaggy

Réponses:


4

Modèle MediaWiki, 19 octets

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

Il s'agit d'un port MediaWiki Template ParserFunctions de cette réponse PHP

Remarque: #timeutilisez PHP en strtotimeinterne.


Exemple d'entrée

{{#time: r | deuxième samedi de mars 2019}}

Exemple de sortie

Sam, 09 mars 2019 00:00:00 +0000


3

Japt, 19 15 octets

L'entrée est: année, indice 0 du mois, indice 0 du jour de la semaine ( 0dimanche) & n.

_XµW¶Ze}f@ÐUVYÄ

Essayez-le

                    :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 # (Visual C # Interactive Compiler) , 59 octets

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

Essayez-le en ligne!

-27 octets grâce à @EmbodimentOfIgnorance!

Moins de code 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

La valeur de retour est un entier pour le jour du mois de la date demandée.


Si vous ne renvoyez que le jour du mois, ce qui est autorisé, vous pouvez jouer au golf jusqu'à 59 octets
Embodiment of Ignorance

Merci encore pour l'astuce - (c'est 2x aujourd'hui;) Je mettrai à jour mes réponses.
dana

2

SmileBASIC, 58 51 48 46 45 octets

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

L'entrée est sous la forme: week,year/month/weekday

  • week: numéro de semaine, indexé 0
  • year: année, 4 chiffres
  • month: mois (1 indexé), 2 chiffres - 0rembourré
  • weekday: jour de la semaine (1 indexé, 1 = dimanche), 2 chiffres - 0capitonné

La sortie est le jour du mois, 0 indexé.
Le 2ème samedi de mars 2019 serait 1,2019/03/078(9 mars)

Non golfé

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

Explication

Le formulaire de saisie a été spécifiquement choisi pour que l'année / mois / jour de semaine puisse être transmis directement à DTREAD, qui est une fonction qui analyse une YYYY/MM/DDchaîne et renvoie l'année / mois / jour sous forme de nombres, ainsi que le calcul du jour de la semaine.

Cependant, notez que, où DTREADattend le jour du mois, nous lui donnons plutôt le jour de la semaine. Cela complique les choses, mais signifie également qu'il y a moins de valeurs d'entrée et que nous n'avons pas besoin d'ajouter /01à la fin de la chaîne de date.

DTREADsorties Wet D.
West le jour de la semaine et Dcorrespond au jour de la semaine du We jour du mois.
(Donc, si vous saisissez 7comme jour de la semaine, ce Dsera 7et Wsera quel que soit le jour de la semaine le 7e jour du mois)

L'expression (5-W+D*2)MOD 7est utilisée pour obtenir la 1ère occurrence du jour de la semaine en entrée, en tant que jour du mois indexé sur 0. (J'ai compris celui-ci principalement par essais et erreurs)

Après cela, le programme ajoute simplement WEEK*7.


Je souhaite vraiment qu'il y ait des mots séparés pour "jour de la semaine" et "jour du mois".


2

Perl 6 , 52 48 octets

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

Essayez-le en ligne!

Bloc de code anonyme qui accepte l'entrée comme l'année, le mois, le jour de la semaine (le dimanche vaut 0) et le numéro de la semaine (0 indexé). La sortie est un objet de date.

Ancienne explication:

{                                                  } # 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

Je pense que le numéro de semaine doit être indexé 1
12Me21

@ 12Me21 La question dit que l'entrée est flexible, mais j'ai demandé si nous prenons un numéro de semaine comme 0 indexé
Jo King

Cela ne semble pas fonctionner pendant d'autres mois. Je pense que tu as besoin $^c+4-$!.daycount.
nwellnhof

@nwellnhof Ah, j'aurais dû y penser au lieu d'essais et d'erreurs, lol. Devrait être corrigé maintenant
Jo King

1

MATL , 28 27 octets

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

Cela utilise trois entrées:

  • Chaîne avec mois et année: 'March 2019'
  • Chaîne à trois lettres, commençant par une majuscule, indiquant le jour de la semaine: ' Sat'
  • Numéro: 2.

La sortie est une chaîne avec le jour, l' année et le mois séparé par des tirets: 09-Mar-2019.

Essayez-le en ligne!

Explication

Tenez compte des entrées '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 octets

82 octets grâce à @Jo King

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

Essayez-le en ligne!

Version originale, 92 octets

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

Essayez-le en ligne!

Prend l'année comme un entier, le mois comme un entier indexé à 1, le jour de la semaine comme un entier à 0 indice où lundi est 0et dimanche est 6, et la semaine du mois comme un entier indexé à 1.

Comment ça fonctionne:

# 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 octets

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

Essayez-le en ligne!

Prendre en compte:

  • Numéro d'année
  • Numéro du mois (1-12)
  • Chaîne de jours de la semaine dans les paramètres régionaux actuels (TIO nécessite un nom anglais avec une majuscule)
  • Nombre ordinal (1 indexé)




0

Rouge , 64 60 octets

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

Essayez-le en ligne!

Prend l'année, le mois et le jour de la semaine sous forme de nombres, indexés 1, le lundi est le premier jour de la semaine.


hein, to-datec'est une chose. peut-être que cela serait utile dans le défi du format christmase eve
ASCII uniquement

@ ASCII uniquement Nous avons utilisé nowpour ce défi
Galen Ivanov

1
oui, mais je pensais à des méthodes alternatives (à savoir, la " Eve"méthode <répétition date2-date1 fois> iirc)
ASCII uniquement le

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

0

APL (Dyalog Unicode) , 36 octets SBCS

Programme complet. Demande pour [year,month](janvier est 1), puis pour jour (dimanche est 0), puis pour n (le premier est 1).

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

Essayez-le en ligne!

⎕CY'dfns'c o p y dans la bibliothèque dfns

 rejeter le résultat de cela en faveur de ...

 console d'invite pour les [year,month]nombres

days[c]  jours [n] depuis 31/12/1899 du 0 e de ce mois

(⍳31)+ ajoutez les i ntegers 1… 31 à cela

d← Magasin à d(pour d numéros de ay)

7| division restante lors de la division par 7 (jour de la semaine avec dimanche 0 en raison d'une bonne époque)

⎕= console d'invite pour le numéro du jour de la semaine et obtenir un masque où sont égaux les numéros du jour de la semaine

d/⍨ filtrer davec ce masque

⎕⊃ console d'invite pour n et l'utiliser pour choisir dans la liste des numéros de jour

date[c]  cachet datetime [n] (a des zéros de fin pour les heures, minutes, secondes, millisecondes)


Cliquez sur [c] pour le code et [n] pour les notes.


0

JavaScript (ES6), 49 48 octets

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>

Prend les paramètres comme f([year, month], day, number). Le mois et le jour de la semaine (à partir du dimanche) sont indexés zéro. Edit: sauvé 1 octet grâce à @Shaggy.


Le jour de la semaine est-il au format dimanche-samedi ou lundi-dimanche?
Incarnation de l'ignorance

@EmbodimentofIgnorance Désolé, je savais que j'avais oublié quelque chose. (L'extrait utilise désormais select pour vous faciliter la tâche.)
Neil

@EmbodimentofIgnorance, dimanche est 0en JS.
Shaggy

Oh. Je ne le savais pas, je ne connais pas bien Javascript.
Incarnation de l'ignorance


0

TSQL, 106 octets

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

Production:

2019-03-09 00:00:00.000

Essaye le


0

Kotlin , 131 84 octets

47 octets grâce au code et aux commentaires ASCII uniquement.

Entrée: année, moisNuméro, jour de semaineNuméro, semaineNuméro

Tous les entiers de 1 au maximum sur une seule ligne. Le numéro du jour de la semaine est le dimanche du 1 au samedi du 7. Le programme principal fait perdre l'année 1900 pour la classe Date et le mois et le jour de la semaine sont décalés pour commencer par zéro au lieu d'un avant d'appeler le lambda. Vous pouvez entrer vos arguments dans la zone de texte d'entrée pour essayer vos propres dates.

Sortie: une instance de classe Date. Le programme principal affiche le résultat comme: Sam Mar 09 00:00:00 UTC 2019.

Il existe une version étendue avec des commentaires expliquant le code pour ceux qui souhaitent en savoir plus.

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

Essayez-le en ligne!


1
74 - utilise la même méthode que les réponses Scala et Groovy
ASCII uniquement


1
Plus besoin de la commande d'importation donc ce n'est pas un problème: P
ASCII uniquement
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.