With strict I/O and outputting
NA when the date goes beyond the given input month+year: 204 bytes:
The cumbersome I/O and 05AB1E's lack of date builtins make for a pretty big program. 🙃
Try it online or verify all test cases.
With flexible I/O and just continue calculating instead of outputting
NA: 126 bytes:
Two inputs in the formats
month is an integer
weekday are integers
0-6 for Saturday to Friday.
Outputs in the format
Still pretty big with the manual calculations, but apparently more than 1/3rd of my top program's bytes are to deal with just the I/O formats.
Try it online.
Explanation (of the larger strict I/O version):
Step 0: Create a function to go to the next day, which we'll re-use later on (see this 05AB1E answer of mine for an in-depth explanation of how we're going to the next day manually of a given date):
# Push this string to act as function later on with an eval
ˆ # Add it to the global array†
† The reason I use the global array instead of a variable: I'm already using all three
©® variable setters/getters in the actual manual date calculations.
Step 1: Extract the year and month from the input, and parse it as
$ # Push 1 and the input-string
# Push dictionary string "January February March April May June July August September October November December"
# # Split it on spaces to a list
s # Swap so the input-string is at the top of the stack
# # Split it on spaces as well
© # Store this sextuple input-list in variable `®` (without popping)
1è # Pop and get the Month at (0-based) index 1
k # Get the (0-based) index of this month in the list
> # Increase it by 1 to a 1-based index
Dˆ # Add a copy to the global array as well
® # Push the input-list of variable `®` again
н # Pop and leave its first item (the year)
) # Wrap all three values into a list: [1,m,y]
V # Pop and store it in variable `Y`
Step 2: Parse the remainder of the input-string, and start looping:
® # Push the input-list from variable `®` again
2ô # Split it into parts of size 2
¦ # Remove the first part (the [year,"Month"])
R # Reverse the other two parts
v # For each over the pairs `y` in the pair:
yθ # Push the last item of the current pair (the amount of days)
F # Pop and inner loop that many times:
NĀi # If it's NOT the first iteration:
¯н.V # Go to the next day
# by evaluating the first item of the global array of step 0
} # Close the if-statement
[ # Start an inner infinite loop:
Step 3a: Calculate the DayOfWeek of the current date as
[Saturday,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday] respectively (see again this 05AB1E answer of mine for an in-depth explanation of how I calculate the Day of the Week manually of a given date):
Step 3b+c: If this day is equal to the input-date of the current pair
y, stop the infinite loop. If not, go to the next day and continue looping.
”ŒÍ‹Ó‹ŽŒ¹ŒêŒÛŠ¯” # Push dictionary string "Saturday Sunday Monday Tuesday Wednesday Thursday Friday"
# # Split it on spaces to a list
yн # Push the first item of the current pair (the day)
k # Get its 0-based index in the list of weekdays
Q # Check whether it's equal to the calculated DayOfWeek from step 3a
# # If they're equal:
# # Stop the inner infinite loop
¯н.V # (Else) Go to the next day by evaluating step 0 again
Step 4: Format the resulting date to the desired output-format:
] # Close the three loops
Y # Push the resulting date `Y`
Â # Bifurcate this triplet; short for Duplicate & Reverse copy
T‰J # Format the day/month with leading 0:
T‰ # Divmod each inner value by 10
J # Join each inner pair together
'-ý '# Join the triplet-list with "-" delimiter
s # Swap the triplet to the top of the stack again
Ås # Only leave its middle item (the month)
¯θ # Push the last item of the global array (the parsed input-month)
Êi # If they are NOT equal:
„NA # Push string "NA"
# (after which the top of the stack is output implicitly as result)
See this 05AB1E tip of mine (section How to use the dictionary?) to understand why
"January February March April May June July August September October November December" and
"Saturday Sunday Monday Tuesday Wednesday Thursday Friday".
”ŒÍ‹Ó‹ŽŒ¹ŒêŒÛŠ¯”#yнk can probably be golfed a bit with magic numbers of some sort, but since I suck at those and I also couldn't really be bothered in an answer already this big because of manual date calculations, the indexing into dictionary strings will do for now.
2021 November Monday 1 Tuesday 1is asking for "the first Tuesday that is after the first Monday in November, 2021". You should mentally parse it as (2021 November) (Monday 1) (Tuesday 1) \$\endgroup\$