Context
In APL, trains are tacit sequences of monadic/dyadic functions that can be called with one or two arguments. We'll code something to check if a given train follows the correct structure we need in order to have a sound train.
Task
Given the sequence of function arities in the train, determine if the train is valid as a monad and/or as a dyad. Don't forget that APL reads from right to left, so when I mention the "start" I mean the end of the array! A train is valid as a monad if
- is starts with an arbitrary number of
DM
(0 or more) and then ends in 1 or 2 monadic functions; e.g.MM
,MDM
,MMDM
andMDMDM
are valid monadic trains.
A dyadic train is valid if
- the train starts with an odd number of dyadic functions, possibly ending with a monadic function; e.g.
D
,MDDD
andDDDDD
are valid dyadic trains.
Input
Your input is going to be a non-empty list of the arities of the functions in the train, where said list contains up to 3 different elements; one for purely monadic functions, another for purely dyadic functions and another for functions that can be either monadic or dyadic, depending on usage.
The input list can be taken in any sensible format and likewise the elements can be whatever 3 distinct elements you choose. E.g. take a string with the letters MDB
or take a list of integers 0,1,2
. I don't mind you play around with this, just let us know what your answer uses.
APL reads from right to left and we will embody this in the challenge; input cannot be reversed.
Output
Your function should adhere to one of the two output formats:
output one of 4 distinct values; one for a train that only works monadically, one for a train that works dyadically, one for a train that works both ways and yet another one for a train that doesn't work in any way; any consistent 4 distinct values will do;
output two Truthy/Falsy values, with respect to the standard Truthy/Falsy defaults of your language, where the first value flags if the train works monadically and the second to flag if the train works dyadically, or vice-versa.
Test cases:
The pair (a, b)
is used, where a
says if the train is valid to be used monadically and b
says if the train is valid dyadically.
DB
(False, False)
DD
(False, False)
DM
(False, False)
MBDBMDD
(False, False)
DDBB
(False, False)
DMMDDM
(False, False)
DBDDBDMMD
(False, False)
BMDBDD
(False, False)
MMMDD
(False, False)
MMBMBMMBM
(False, False)
DDBBMDDMMD
(False, False)
DDMB
(False, False)
D
(False, True)
MD
(False, True)
BD
(False, True)
BBBDBDDBD
(False, True)
MDBBBBDB
(False, True)
M
(True, False)
MM
(True, False)
BM
(True, False)
MMDM
(True, False)
MDM
(True, False)
BDM
(True, False)
MMBBDMDB
(True, False)
MBM
(True, False)
B
(True, True)
MB
(True, True)
BB
(True, True)
BBB
(True, True)
BBBB
(True, True)
BBBBB
(True, True)
MBBBBBBB
(True, True)
BDBBBBBDB
(True, True)
Generated and tested with this Python code. Feel free to use the TIO link and edit the final printing loop to print all the test cases in a format that is easier for you to use in your answer.
"21333313"
, or written in base 10 as21333313
would be acceptable, but encoded as40951
it no longer has the "each element encodes a function valence" feel and thus would not be acceptable. Does this make sense? \$\endgroup\$