What have we got?












17












$begingroup$


Inspired by, and in memory of, our beloved genius,



John Scholes, 1948-2019



R.I.P.



He invented and implemented dfns — his magnum opus and the subject of the challenge.



For the interested: latest full dfns documentation and videos with John.



Task



Given an ASCII source code, answer in which of the following four categories it belongs:




  1. Dyadic dop


  2. Monadic dop


  3. Dfn


  4. Other



You may return any four consistent values, but please state your mapping if it isn't obvious.



Details



You may assume that the source code always begins with an opening curly brace { and ends with a closing curly brace }.



Recursively nested braces can occur (e.g. {{{}}}), but categories 1–3 can never have brace nesting depth go below 1 (so {}{} is "Other") and all braces must be balanced (so {{} is "Other").



Characters in the following contexts on a line are ignored:




  1. To the right of # (a comment): significant#ignored


  2. Enclosed in single quotes '' (i.e. in a string): significant'ignored'significant (This applies to # too: '#'significant)


  3. To the right of an unpaired quote ' (pairing quotes from the left): significant'ignored



In curly brace level one (i.e. excluding nested braces):




  • Dyadic dops contain the uninterrupted phrase ww


  • Monadic dops do not contain ww, but do contain aa


  • Dfns contain neither ww nor aa



Test cases



Dyadic dops



{ww}


{
www
}


{
''ww'
}


{aa

ww}


{'#''#'ww?aa}


Monadic dops



{aa}


{aaaa}


{aa{ww}'ww'}


{w#w'
aa'
}


{aaw*w}


{w''aa''}


Dfns



{}


{a a}


{aA}


{
{aa}
}


{w
w''w#
w}


{{
}}


{w'aa'}


Other



{}{}


{{}


{}}


{ww}}


{}
{}


{ww}{}


{#}


{'
'}









share|improve this question











$endgroup$












  • $begingroup$
    @LuisfelipeDejesusMunoz Dfn. If you see a reason to think otherwise, please let me know.
    $endgroup$
    – Adám
    Feb 19 at 13:38






  • 1




    $begingroup$
    Can string quotes be escaped, and if so do we need to handle them? (eg: {'#'ww?aa'} -> other?)
    $endgroup$
    – Οurous
    Feb 19 at 21:27






  • 1




    $begingroup$
    @Οurous No, the spec is as stated: Anything in quotes is insignificant. (Indeed, APL strings have no escape mechanism.) I'll add a case.
    $endgroup$
    – Adám
    Feb 20 at 5:14










  • $begingroup$
    Hm, may we assume that strings will not contain '' (apostrophe in string, can also be parsed as two adjacent strings for this challenge)?
    $endgroup$
    – Erik the Outgolfer
    Feb 20 at 16:23










  • $begingroup$
    @EriktheOutgolfer It may occur. I'll add a case, but as you say, it doesn't matter whether 'abc''def' is parsed as one or two strings for this challenge.
    $endgroup$
    – Adám
    Feb 20 at 16:57
















17












$begingroup$


Inspired by, and in memory of, our beloved genius,



John Scholes, 1948-2019



R.I.P.



He invented and implemented dfns — his magnum opus and the subject of the challenge.



For the interested: latest full dfns documentation and videos with John.



Task



Given an ASCII source code, answer in which of the following four categories it belongs:




  1. Dyadic dop


  2. Monadic dop


  3. Dfn


  4. Other



You may return any four consistent values, but please state your mapping if it isn't obvious.



Details



You may assume that the source code always begins with an opening curly brace { and ends with a closing curly brace }.



Recursively nested braces can occur (e.g. {{{}}}), but categories 1–3 can never have brace nesting depth go below 1 (so {}{} is "Other") and all braces must be balanced (so {{} is "Other").



Characters in the following contexts on a line are ignored:




  1. To the right of # (a comment): significant#ignored


  2. Enclosed in single quotes '' (i.e. in a string): significant'ignored'significant (This applies to # too: '#'significant)


  3. To the right of an unpaired quote ' (pairing quotes from the left): significant'ignored



In curly brace level one (i.e. excluding nested braces):




  • Dyadic dops contain the uninterrupted phrase ww


  • Monadic dops do not contain ww, but do contain aa


  • Dfns contain neither ww nor aa



Test cases



Dyadic dops



{ww}


{
www
}


{
''ww'
}


{aa

ww}


{'#''#'ww?aa}


Monadic dops



{aa}


{aaaa}


{aa{ww}'ww'}


{w#w'
aa'
}


{aaw*w}


{w''aa''}


Dfns



{}


{a a}


{aA}


{
{aa}
}


{w
w''w#
w}


{{
}}


{w'aa'}


Other



{}{}


{{}


{}}


{ww}}


{}
{}


{ww}{}


{#}


{'
'}









share|improve this question











$endgroup$












  • $begingroup$
    @LuisfelipeDejesusMunoz Dfn. If you see a reason to think otherwise, please let me know.
    $endgroup$
    – Adám
    Feb 19 at 13:38






  • 1




    $begingroup$
    Can string quotes be escaped, and if so do we need to handle them? (eg: {'#'ww?aa'} -> other?)
    $endgroup$
    – Οurous
    Feb 19 at 21:27






  • 1




    $begingroup$
    @Οurous No, the spec is as stated: Anything in quotes is insignificant. (Indeed, APL strings have no escape mechanism.) I'll add a case.
    $endgroup$
    – Adám
    Feb 20 at 5:14










  • $begingroup$
    Hm, may we assume that strings will not contain '' (apostrophe in string, can also be parsed as two adjacent strings for this challenge)?
    $endgroup$
    – Erik the Outgolfer
    Feb 20 at 16:23










  • $begingroup$
    @EriktheOutgolfer It may occur. I'll add a case, but as you say, it doesn't matter whether 'abc''def' is parsed as one or two strings for this challenge.
    $endgroup$
    – Adám
    Feb 20 at 16:57














17












17








17


2



$begingroup$


Inspired by, and in memory of, our beloved genius,



John Scholes, 1948-2019



R.I.P.



He invented and implemented dfns — his magnum opus and the subject of the challenge.



For the interested: latest full dfns documentation and videos with John.



Task



Given an ASCII source code, answer in which of the following four categories it belongs:




  1. Dyadic dop


  2. Monadic dop


  3. Dfn


  4. Other



You may return any four consistent values, but please state your mapping if it isn't obvious.



Details



You may assume that the source code always begins with an opening curly brace { and ends with a closing curly brace }.



Recursively nested braces can occur (e.g. {{{}}}), but categories 1–3 can never have brace nesting depth go below 1 (so {}{} is "Other") and all braces must be balanced (so {{} is "Other").



Characters in the following contexts on a line are ignored:




  1. To the right of # (a comment): significant#ignored


  2. Enclosed in single quotes '' (i.e. in a string): significant'ignored'significant (This applies to # too: '#'significant)


  3. To the right of an unpaired quote ' (pairing quotes from the left): significant'ignored



In curly brace level one (i.e. excluding nested braces):




  • Dyadic dops contain the uninterrupted phrase ww


  • Monadic dops do not contain ww, but do contain aa


  • Dfns contain neither ww nor aa



Test cases



Dyadic dops



{ww}


{
www
}


{
''ww'
}


{aa

ww}


{'#''#'ww?aa}


Monadic dops



{aa}


{aaaa}


{aa{ww}'ww'}


{w#w'
aa'
}


{aaw*w}


{w''aa''}


Dfns



{}


{a a}


{aA}


{
{aa}
}


{w
w''w#
w}


{{
}}


{w'aa'}


Other



{}{}


{{}


{}}


{ww}}


{}
{}


{ww}{}


{#}


{'
'}









share|improve this question











$endgroup$




Inspired by, and in memory of, our beloved genius,



John Scholes, 1948-2019



R.I.P.



He invented and implemented dfns — his magnum opus and the subject of the challenge.



For the interested: latest full dfns documentation and videos with John.



Task



Given an ASCII source code, answer in which of the following four categories it belongs:




  1. Dyadic dop


  2. Monadic dop


  3. Dfn


  4. Other



You may return any four consistent values, but please state your mapping if it isn't obvious.



Details



You may assume that the source code always begins with an opening curly brace { and ends with a closing curly brace }.



Recursively nested braces can occur (e.g. {{{}}}), but categories 1–3 can never have brace nesting depth go below 1 (so {}{} is "Other") and all braces must be balanced (so {{} is "Other").



Characters in the following contexts on a line are ignored:




  1. To the right of # (a comment): significant#ignored


  2. Enclosed in single quotes '' (i.e. in a string): significant'ignored'significant (This applies to # too: '#'significant)


  3. To the right of an unpaired quote ' (pairing quotes from the left): significant'ignored



In curly brace level one (i.e. excluding nested braces):




  • Dyadic dops contain the uninterrupted phrase ww


  • Monadic dops do not contain ww, but do contain aa


  • Dfns contain neither ww nor aa



Test cases



Dyadic dops



{ww}


{
www
}


{
''ww'
}


{aa

ww}


{'#''#'ww?aa}


Monadic dops



{aa}


{aaaa}


{aa{ww}'ww'}


{w#w'
aa'
}


{aaw*w}


{w''aa''}


Dfns



{}


{a a}


{aA}


{
{aa}
}


{w
w''w#
w}


{{
}}


{w'aa'}


Other



{}{}


{{}


{}}


{ww}}


{}
{}


{ww}{}


{#}


{'
'}






code-golf parsing classification apl






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 15 hours ago







Adám

















asked Feb 19 at 11:26









AdámAdám

28.5k274201




28.5k274201












  • $begingroup$
    @LuisfelipeDejesusMunoz Dfn. If you see a reason to think otherwise, please let me know.
    $endgroup$
    – Adám
    Feb 19 at 13:38






  • 1




    $begingroup$
    Can string quotes be escaped, and if so do we need to handle them? (eg: {'#'ww?aa'} -> other?)
    $endgroup$
    – Οurous
    Feb 19 at 21:27






  • 1




    $begingroup$
    @Οurous No, the spec is as stated: Anything in quotes is insignificant. (Indeed, APL strings have no escape mechanism.) I'll add a case.
    $endgroup$
    – Adám
    Feb 20 at 5:14










  • $begingroup$
    Hm, may we assume that strings will not contain '' (apostrophe in string, can also be parsed as two adjacent strings for this challenge)?
    $endgroup$
    – Erik the Outgolfer
    Feb 20 at 16:23










  • $begingroup$
    @EriktheOutgolfer It may occur. I'll add a case, but as you say, it doesn't matter whether 'abc''def' is parsed as one or two strings for this challenge.
    $endgroup$
    – Adám
    Feb 20 at 16:57


















  • $begingroup$
    @LuisfelipeDejesusMunoz Dfn. If you see a reason to think otherwise, please let me know.
    $endgroup$
    – Adám
    Feb 19 at 13:38






  • 1




    $begingroup$
    Can string quotes be escaped, and if so do we need to handle them? (eg: {'#'ww?aa'} -> other?)
    $endgroup$
    – Οurous
    Feb 19 at 21:27






  • 1




    $begingroup$
    @Οurous No, the spec is as stated: Anything in quotes is insignificant. (Indeed, APL strings have no escape mechanism.) I'll add a case.
    $endgroup$
    – Adám
    Feb 20 at 5:14










  • $begingroup$
    Hm, may we assume that strings will not contain '' (apostrophe in string, can also be parsed as two adjacent strings for this challenge)?
    $endgroup$
    – Erik the Outgolfer
    Feb 20 at 16:23










  • $begingroup$
    @EriktheOutgolfer It may occur. I'll add a case, but as you say, it doesn't matter whether 'abc''def' is parsed as one or two strings for this challenge.
    $endgroup$
    – Adám
    Feb 20 at 16:57
















$begingroup$
@LuisfelipeDejesusMunoz Dfn. If you see a reason to think otherwise, please let me know.
$endgroup$
– Adám
Feb 19 at 13:38




$begingroup$
@LuisfelipeDejesusMunoz Dfn. If you see a reason to think otherwise, please let me know.
$endgroup$
– Adám
Feb 19 at 13:38




1




1




$begingroup$
Can string quotes be escaped, and if so do we need to handle them? (eg: {'#'ww?aa'} -> other?)
$endgroup$
– Οurous
Feb 19 at 21:27




$begingroup$
Can string quotes be escaped, and if so do we need to handle them? (eg: {'#'ww?aa'} -> other?)
$endgroup$
– Οurous
Feb 19 at 21:27




1




1




$begingroup$
@Οurous No, the spec is as stated: Anything in quotes is insignificant. (Indeed, APL strings have no escape mechanism.) I'll add a case.
$endgroup$
– Adám
Feb 20 at 5:14




$begingroup$
@Οurous No, the spec is as stated: Anything in quotes is insignificant. (Indeed, APL strings have no escape mechanism.) I'll add a case.
$endgroup$
– Adám
Feb 20 at 5:14












$begingroup$
Hm, may we assume that strings will not contain '' (apostrophe in string, can also be parsed as two adjacent strings for this challenge)?
$endgroup$
– Erik the Outgolfer
Feb 20 at 16:23




$begingroup$
Hm, may we assume that strings will not contain '' (apostrophe in string, can also be parsed as two adjacent strings for this challenge)?
$endgroup$
– Erik the Outgolfer
Feb 20 at 16:23












$begingroup$
@EriktheOutgolfer It may occur. I'll add a case, but as you say, it doesn't matter whether 'abc''def' is parsed as one or two strings for this challenge.
$endgroup$
– Adám
Feb 20 at 16:57




$begingroup$
@EriktheOutgolfer It may occur. I'll add a case, but as you say, it doesn't matter whether 'abc''def' is parsed as one or two strings for this challenge.
$endgroup$
– Adám
Feb 20 at 16:57










4 Answers
4






active

oldest

votes


















9












$begingroup$

JavaScript (ES6),  145 ... 138  136 bytes



Returns $0$ for dyadic dops, $1$ for monadic dops, $2$ for dfns and $3$ for other.



s=>[...s].map(c=>s=(n=`
aw}{#'`.indexOf(c))?n>5?i^=2:i?0:n>4?i=1:n>3?d++:n>2?x+=!d--:(o|=n<0|d|s!=c?0:n,c):i=0,o=i=0,x=d=-1)|x|~d?3:2>>o


Try it online!



Alternate versions





  • 131 bytes by taking an array of characters as input


  • 132 bytes by using Buffer() (Node.js)


How?



The input string is parsed character by character.



Translation of characters into codes



Each character $c$ is translated into a code $n$ according to the following table:



 character | code | triggered operation
-----------+------+---------------------------------------------------------
n | 0 | i = 0
a | 1* | o |= n < 0 | d | s != c ? 0 : n
w | 2* | o |= n < 0 | d | s != c ? 0 : n
} | 3* | x += !d--
{ | 4* | d++
# | 5* | i = 1
' | 6 | i ^= 2
other | -1* | same as 'a' or 'w', but always fails because of 'n < 0'


Codes marked with a '$*$' have no effect when $ineq 0$.



Variables describing the parser state



The following variables are used during the parsing:





  • $o$: a bitmask keeping track of encountered phrases




    • bit 0: a valid phrase aa has been encountered

    • bit 1: a valid phrase ww has been encountered




  • $i$: a bitmask telling whether some characters should be ignored




    • bit 0: we're currently located inside a comment

    • bit 1: we're currently located inside a string (this bit is still updated within a comment, but this is harmless)



  • $s$: the result of the previous iteration



  • $d$: the current depth of nested braces (starting at $-1$)


  • $x$: the number of times we went from depth $0$ to depth $-1$, minus $1$


Final result



We output $3$ if $x$ is not equal to $0$ or $d$ is not equal to $-1$. Otherwise, we output $0$, $1$ or $2$ according to the value held in $o$.






share|improve this answer











$endgroup$





















    6












    $begingroup$


    Jelly,  50 48 46  45 bytes



    Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤


    A monadic Link accepting a list of characters which yields:



    5 - Dyadic dop
    4 - Monadic dop
    3 - Dfn
    0 - Other


    Try it online! Or see a test-suite.
    uses Python quoting to avoid the possibility of evaluating input as a Python set or dictionary



    How?



    Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Link: list of characters
    - breaking long Link up...
    Ỵµṣ”'m2Kṣ”#Ḣ)K - Replace any strings or comments with (single) spaces
    Ỵ - split at newline characters
    µ ) - monadic chain for each:
    ṣ”' - split at apostrophe characters
    m2 - modulo 2 slice (i.e. every other part starting with the first
    - - that is, non-string code. Will remove strings from within comments)
    K - join with spaces
    ṣ”# - split at octothorp characters
    Ḣ - head (i.e. non-comment code)
    K - join with spaces

    µċⱮƤØ{IF©<-oµ - Replace characters of code at depth > 1 with the integer 1
    µ µ - monadic chain, call previous result A:
    Ø{ - literal ['{','}']
    Ƥ - for prefixes of A:
    Ɱ - map across right argument with:
    ċ - count
    I - deltas (i.e. [count('}') - count('{')] for each prefix)
    F - flatten (i.e. count('}') - count('{') for each prefix)
    - -- i.e -1*depth of each character of A; closing braces at depth+1
    © - (copy this list of depths to the register for later use)
    <- - less than -1? (vectorises)
    o - logical OR with A (vectorises, replacing deep code with 1s)

    ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Categorise the result, R
    ¤ - nilad followed by link(s) as a nilad:
    ⁾wa - literal ['w', 'a']
    ż - zip with itself = [['w','w'],['a','a']]
    ẇ€ - for €ach: is a sublist of R? i.e. one of: [0,0] [1,0] [0,1] [1,1]
    ‘ - increment (vectorises) [1,1] [2,1] [1,2] [2,2]
    Ḅ - unbinary 3 5 4 6
    «5 - minimum with five 3 5 4 5
    ¤ - nilad followed by link(s) as a nilad:
    ® - recall depths from the register
    ¬ - logical NOT (vectorises) (0->1, other depths->0)
    Ḅ - unbinary
    ⁼1 - equal one -- i.e. depths ends with a 0 and contains no other zero
    × - multiply





    share|improve this answer











    $endgroup$





















      3












      $begingroup$


      Clean, 309 293 284 bytes



      We can get away with only using 3 variable names at a time, so we'll call them a, p, and l.



      import StdEnv,Text,Data.List
      a=isInfixOf o zip2[2,2]
      @ =[''']
      $p#p=join@[foldl(([a:p]_|p>=a++[';':join@(tl p)]=split['#']a!!0)o split@)l l\l<-mklines p]
      #l=[(?a- ?l,p)\a<-inits p&[p:l]<-tails p]
      |{p\(a,p)<-l|a<2}<>"{}"=0|a['ww']l=1|a['aa']l=2=3
      ?l=sum[1\'{'<-l]-sum[1\'}'<-l]


      Try it online!



      Defines the function $ :: [Char] -> Int and some helpers, giving the mapping:





      • 0: Other


      • 1: Dyadic dop


      • 2: Monadic dop


      • 3: Dfn


      Expanded (first version), and with more than 3 variable names:



      $ s
      # s // remove strings and comments
      = join [';'] [ // join the second argument with semicolons
      limit ( // take the first repeated element of
      iterate // an infinite list of applications of the first argument
      (
      (
      (p, q) = p ++ case q of // join the first half with a modified second half
      ['''': q] = [';': q] // replace two quotes with a semicolon
      [c, _: q] = [c: q] // drop the character after a quote or hash
      _ = // leave unmatched strings unchanged
      ) o span // split the string on the first occurrence of
      c = c <> ''' && c <> '#' // a quote or hash
      ) l // applied to l
      )
      \ l <- mklines s // for line l in s split at newlines
      ]
      # b // generate a map of nesting levels
      = [
      ( // the pair of
      ?i - ?t, // the nesting level
      c // the character c
      )
      \ i <- inits s // for init i of s
      & // synchronously iterated with
      [c: t] <- tails s // character c at the start of tail [c:t] of s
      ]
      // determine what the code is
      | {c \(n, c) <- b | n < 2} // if the string made of characters with nesting level of less than 2
      <> "{}" // is not the same as the paired braces at the beginning and end
      = 0 // return zero
      | m ['ww'] b // if there are two consecutive 'w's at nesting level 2
      = 1 // return 1
      | m ['aa'] b // if there are two consecutive 'a's at nesting level 2
      = 2 // return 2
      = 3 // otherwise return 3





      share|improve this answer











      $endgroup$





















        0












        $begingroup$


        Retina 0.8.2, 91 bytes



        m`'.*?('|$)|#.*

        s(+`(?!^){[^{}]*}(?!$)

        ^(?!{[^{}]*}$).+
        3
        ^.+ww.+
        2
        ^.+aa.+
        1
        ..+
        0


        Try it online! Link includes test suite. Explanation:



        m`'.*?('|$)|#.*



        Remove strings and comments.



        s(+`(?!^){[^{}]*}(?!$)



        Remove matched brackets, working out from the innermost, but leave the first and last brackets.



        ^(?!{[^{}]*}$).+
        3


        If we don't have matched brackets then this is Other.



        ^.+ww.+
        2


        Otherwise if we have ww then this is Dyadic Dop.



        ^.+aa.+
        1


        Otherwise if we have aa then this is Monadic Dop.



        ..+
        0


        Otherwise if this is anything not covered above then this is Dfn.






        share|improve this answer









        $endgroup$













          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "200"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f180134%2fwhat-have-we-got%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          9












          $begingroup$

          JavaScript (ES6),  145 ... 138  136 bytes



          Returns $0$ for dyadic dops, $1$ for monadic dops, $2$ for dfns and $3$ for other.



          s=>[...s].map(c=>s=(n=`
          aw}{#'`.indexOf(c))?n>5?i^=2:i?0:n>4?i=1:n>3?d++:n>2?x+=!d--:(o|=n<0|d|s!=c?0:n,c):i=0,o=i=0,x=d=-1)|x|~d?3:2>>o


          Try it online!



          Alternate versions





          • 131 bytes by taking an array of characters as input


          • 132 bytes by using Buffer() (Node.js)


          How?



          The input string is parsed character by character.



          Translation of characters into codes



          Each character $c$ is translated into a code $n$ according to the following table:



           character | code | triggered operation
          -----------+------+---------------------------------------------------------
          n | 0 | i = 0
          a | 1* | o |= n < 0 | d | s != c ? 0 : n
          w | 2* | o |= n < 0 | d | s != c ? 0 : n
          } | 3* | x += !d--
          { | 4* | d++
          # | 5* | i = 1
          ' | 6 | i ^= 2
          other | -1* | same as 'a' or 'w', but always fails because of 'n < 0'


          Codes marked with a '$*$' have no effect when $ineq 0$.



          Variables describing the parser state



          The following variables are used during the parsing:





          • $o$: a bitmask keeping track of encountered phrases




            • bit 0: a valid phrase aa has been encountered

            • bit 1: a valid phrase ww has been encountered




          • $i$: a bitmask telling whether some characters should be ignored




            • bit 0: we're currently located inside a comment

            • bit 1: we're currently located inside a string (this bit is still updated within a comment, but this is harmless)



          • $s$: the result of the previous iteration



          • $d$: the current depth of nested braces (starting at $-1$)


          • $x$: the number of times we went from depth $0$ to depth $-1$, minus $1$


          Final result



          We output $3$ if $x$ is not equal to $0$ or $d$ is not equal to $-1$. Otherwise, we output $0$, $1$ or $2$ according to the value held in $o$.






          share|improve this answer











          $endgroup$


















            9












            $begingroup$

            JavaScript (ES6),  145 ... 138  136 bytes



            Returns $0$ for dyadic dops, $1$ for monadic dops, $2$ for dfns and $3$ for other.



            s=>[...s].map(c=>s=(n=`
            aw}{#'`.indexOf(c))?n>5?i^=2:i?0:n>4?i=1:n>3?d++:n>2?x+=!d--:(o|=n<0|d|s!=c?0:n,c):i=0,o=i=0,x=d=-1)|x|~d?3:2>>o


            Try it online!



            Alternate versions





            • 131 bytes by taking an array of characters as input


            • 132 bytes by using Buffer() (Node.js)


            How?



            The input string is parsed character by character.



            Translation of characters into codes



            Each character $c$ is translated into a code $n$ according to the following table:



             character | code | triggered operation
            -----------+------+---------------------------------------------------------
            n | 0 | i = 0
            a | 1* | o |= n < 0 | d | s != c ? 0 : n
            w | 2* | o |= n < 0 | d | s != c ? 0 : n
            } | 3* | x += !d--
            { | 4* | d++
            # | 5* | i = 1
            ' | 6 | i ^= 2
            other | -1* | same as 'a' or 'w', but always fails because of 'n < 0'


            Codes marked with a '$*$' have no effect when $ineq 0$.



            Variables describing the parser state



            The following variables are used during the parsing:





            • $o$: a bitmask keeping track of encountered phrases




              • bit 0: a valid phrase aa has been encountered

              • bit 1: a valid phrase ww has been encountered




            • $i$: a bitmask telling whether some characters should be ignored




              • bit 0: we're currently located inside a comment

              • bit 1: we're currently located inside a string (this bit is still updated within a comment, but this is harmless)



            • $s$: the result of the previous iteration



            • $d$: the current depth of nested braces (starting at $-1$)


            • $x$: the number of times we went from depth $0$ to depth $-1$, minus $1$


            Final result



            We output $3$ if $x$ is not equal to $0$ or $d$ is not equal to $-1$. Otherwise, we output $0$, $1$ or $2$ according to the value held in $o$.






            share|improve this answer











            $endgroup$
















              9












              9








              9





              $begingroup$

              JavaScript (ES6),  145 ... 138  136 bytes



              Returns $0$ for dyadic dops, $1$ for monadic dops, $2$ for dfns and $3$ for other.



              s=>[...s].map(c=>s=(n=`
              aw}{#'`.indexOf(c))?n>5?i^=2:i?0:n>4?i=1:n>3?d++:n>2?x+=!d--:(o|=n<0|d|s!=c?0:n,c):i=0,o=i=0,x=d=-1)|x|~d?3:2>>o


              Try it online!



              Alternate versions





              • 131 bytes by taking an array of characters as input


              • 132 bytes by using Buffer() (Node.js)


              How?



              The input string is parsed character by character.



              Translation of characters into codes



              Each character $c$ is translated into a code $n$ according to the following table:



               character | code | triggered operation
              -----------+------+---------------------------------------------------------
              n | 0 | i = 0
              a | 1* | o |= n < 0 | d | s != c ? 0 : n
              w | 2* | o |= n < 0 | d | s != c ? 0 : n
              } | 3* | x += !d--
              { | 4* | d++
              # | 5* | i = 1
              ' | 6 | i ^= 2
              other | -1* | same as 'a' or 'w', but always fails because of 'n < 0'


              Codes marked with a '$*$' have no effect when $ineq 0$.



              Variables describing the parser state



              The following variables are used during the parsing:





              • $o$: a bitmask keeping track of encountered phrases




                • bit 0: a valid phrase aa has been encountered

                • bit 1: a valid phrase ww has been encountered




              • $i$: a bitmask telling whether some characters should be ignored




                • bit 0: we're currently located inside a comment

                • bit 1: we're currently located inside a string (this bit is still updated within a comment, but this is harmless)



              • $s$: the result of the previous iteration



              • $d$: the current depth of nested braces (starting at $-1$)


              • $x$: the number of times we went from depth $0$ to depth $-1$, minus $1$


              Final result



              We output $3$ if $x$ is not equal to $0$ or $d$ is not equal to $-1$. Otherwise, we output $0$, $1$ or $2$ according to the value held in $o$.






              share|improve this answer











              $endgroup$



              JavaScript (ES6),  145 ... 138  136 bytes



              Returns $0$ for dyadic dops, $1$ for monadic dops, $2$ for dfns and $3$ for other.



              s=>[...s].map(c=>s=(n=`
              aw}{#'`.indexOf(c))?n>5?i^=2:i?0:n>4?i=1:n>3?d++:n>2?x+=!d--:(o|=n<0|d|s!=c?0:n,c):i=0,o=i=0,x=d=-1)|x|~d?3:2>>o


              Try it online!



              Alternate versions





              • 131 bytes by taking an array of characters as input


              • 132 bytes by using Buffer() (Node.js)


              How?



              The input string is parsed character by character.



              Translation of characters into codes



              Each character $c$ is translated into a code $n$ according to the following table:



               character | code | triggered operation
              -----------+------+---------------------------------------------------------
              n | 0 | i = 0
              a | 1* | o |= n < 0 | d | s != c ? 0 : n
              w | 2* | o |= n < 0 | d | s != c ? 0 : n
              } | 3* | x += !d--
              { | 4* | d++
              # | 5* | i = 1
              ' | 6 | i ^= 2
              other | -1* | same as 'a' or 'w', but always fails because of 'n < 0'


              Codes marked with a '$*$' have no effect when $ineq 0$.



              Variables describing the parser state



              The following variables are used during the parsing:





              • $o$: a bitmask keeping track of encountered phrases




                • bit 0: a valid phrase aa has been encountered

                • bit 1: a valid phrase ww has been encountered




              • $i$: a bitmask telling whether some characters should be ignored




                • bit 0: we're currently located inside a comment

                • bit 1: we're currently located inside a string (this bit is still updated within a comment, but this is harmless)



              • $s$: the result of the previous iteration



              • $d$: the current depth of nested braces (starting at $-1$)


              • $x$: the number of times we went from depth $0$ to depth $-1$, minus $1$


              Final result



              We output $3$ if $x$ is not equal to $0$ or $d$ is not equal to $-1$. Otherwise, we output $0$, $1$ or $2$ according to the value held in $o$.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Feb 20 at 16:20

























              answered Feb 19 at 12:41









              ArnauldArnauld

              76.9k693322




              76.9k693322























                  6












                  $begingroup$


                  Jelly,  50 48 46  45 bytes



                  Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤


                  A monadic Link accepting a list of characters which yields:



                  5 - Dyadic dop
                  4 - Monadic dop
                  3 - Dfn
                  0 - Other


                  Try it online! Or see a test-suite.
                  uses Python quoting to avoid the possibility of evaluating input as a Python set or dictionary



                  How?



                  Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Link: list of characters
                  - breaking long Link up...
                  Ỵµṣ”'m2Kṣ”#Ḣ)K - Replace any strings or comments with (single) spaces
                  Ỵ - split at newline characters
                  µ ) - monadic chain for each:
                  ṣ”' - split at apostrophe characters
                  m2 - modulo 2 slice (i.e. every other part starting with the first
                  - - that is, non-string code. Will remove strings from within comments)
                  K - join with spaces
                  ṣ”# - split at octothorp characters
                  Ḣ - head (i.e. non-comment code)
                  K - join with spaces

                  µċⱮƤØ{IF©<-oµ - Replace characters of code at depth > 1 with the integer 1
                  µ µ - monadic chain, call previous result A:
                  Ø{ - literal ['{','}']
                  Ƥ - for prefixes of A:
                  Ɱ - map across right argument with:
                  ċ - count
                  I - deltas (i.e. [count('}') - count('{')] for each prefix)
                  F - flatten (i.e. count('}') - count('{') for each prefix)
                  - -- i.e -1*depth of each character of A; closing braces at depth+1
                  © - (copy this list of depths to the register for later use)
                  <- - less than -1? (vectorises)
                  o - logical OR with A (vectorises, replacing deep code with 1s)

                  ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Categorise the result, R
                  ¤ - nilad followed by link(s) as a nilad:
                  ⁾wa - literal ['w', 'a']
                  ż - zip with itself = [['w','w'],['a','a']]
                  ẇ€ - for €ach: is a sublist of R? i.e. one of: [0,0] [1,0] [0,1] [1,1]
                  ‘ - increment (vectorises) [1,1] [2,1] [1,2] [2,2]
                  Ḅ - unbinary 3 5 4 6
                  «5 - minimum with five 3 5 4 5
                  ¤ - nilad followed by link(s) as a nilad:
                  ® - recall depths from the register
                  ¬ - logical NOT (vectorises) (0->1, other depths->0)
                  Ḅ - unbinary
                  ⁼1 - equal one -- i.e. depths ends with a 0 and contains no other zero
                  × - multiply





                  share|improve this answer











                  $endgroup$


















                    6












                    $begingroup$


                    Jelly,  50 48 46  45 bytes



                    Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤


                    A monadic Link accepting a list of characters which yields:



                    5 - Dyadic dop
                    4 - Monadic dop
                    3 - Dfn
                    0 - Other


                    Try it online! Or see a test-suite.
                    uses Python quoting to avoid the possibility of evaluating input as a Python set or dictionary



                    How?



                    Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Link: list of characters
                    - breaking long Link up...
                    Ỵµṣ”'m2Kṣ”#Ḣ)K - Replace any strings or comments with (single) spaces
                    Ỵ - split at newline characters
                    µ ) - monadic chain for each:
                    ṣ”' - split at apostrophe characters
                    m2 - modulo 2 slice (i.e. every other part starting with the first
                    - - that is, non-string code. Will remove strings from within comments)
                    K - join with spaces
                    ṣ”# - split at octothorp characters
                    Ḣ - head (i.e. non-comment code)
                    K - join with spaces

                    µċⱮƤØ{IF©<-oµ - Replace characters of code at depth > 1 with the integer 1
                    µ µ - monadic chain, call previous result A:
                    Ø{ - literal ['{','}']
                    Ƥ - for prefixes of A:
                    Ɱ - map across right argument with:
                    ċ - count
                    I - deltas (i.e. [count('}') - count('{')] for each prefix)
                    F - flatten (i.e. count('}') - count('{') for each prefix)
                    - -- i.e -1*depth of each character of A; closing braces at depth+1
                    © - (copy this list of depths to the register for later use)
                    <- - less than -1? (vectorises)
                    o - logical OR with A (vectorises, replacing deep code with 1s)

                    ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Categorise the result, R
                    ¤ - nilad followed by link(s) as a nilad:
                    ⁾wa - literal ['w', 'a']
                    ż - zip with itself = [['w','w'],['a','a']]
                    ẇ€ - for €ach: is a sublist of R? i.e. one of: [0,0] [1,0] [0,1] [1,1]
                    ‘ - increment (vectorises) [1,1] [2,1] [1,2] [2,2]
                    Ḅ - unbinary 3 5 4 6
                    «5 - minimum with five 3 5 4 5
                    ¤ - nilad followed by link(s) as a nilad:
                    ® - recall depths from the register
                    ¬ - logical NOT (vectorises) (0->1, other depths->0)
                    Ḅ - unbinary
                    ⁼1 - equal one -- i.e. depths ends with a 0 and contains no other zero
                    × - multiply





                    share|improve this answer











                    $endgroup$
















                      6












                      6








                      6





                      $begingroup$


                      Jelly,  50 48 46  45 bytes



                      Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤


                      A monadic Link accepting a list of characters which yields:



                      5 - Dyadic dop
                      4 - Monadic dop
                      3 - Dfn
                      0 - Other


                      Try it online! Or see a test-suite.
                      uses Python quoting to avoid the possibility of evaluating input as a Python set or dictionary



                      How?



                      Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Link: list of characters
                      - breaking long Link up...
                      Ỵµṣ”'m2Kṣ”#Ḣ)K - Replace any strings or comments with (single) spaces
                      Ỵ - split at newline characters
                      µ ) - monadic chain for each:
                      ṣ”' - split at apostrophe characters
                      m2 - modulo 2 slice (i.e. every other part starting with the first
                      - - that is, non-string code. Will remove strings from within comments)
                      K - join with spaces
                      ṣ”# - split at octothorp characters
                      Ḣ - head (i.e. non-comment code)
                      K - join with spaces

                      µċⱮƤØ{IF©<-oµ - Replace characters of code at depth > 1 with the integer 1
                      µ µ - monadic chain, call previous result A:
                      Ø{ - literal ['{','}']
                      Ƥ - for prefixes of A:
                      Ɱ - map across right argument with:
                      ċ - count
                      I - deltas (i.e. [count('}') - count('{')] for each prefix)
                      F - flatten (i.e. count('}') - count('{') for each prefix)
                      - -- i.e -1*depth of each character of A; closing braces at depth+1
                      © - (copy this list of depths to the register for later use)
                      <- - less than -1? (vectorises)
                      o - logical OR with A (vectorises, replacing deep code with 1s)

                      ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Categorise the result, R
                      ¤ - nilad followed by link(s) as a nilad:
                      ⁾wa - literal ['w', 'a']
                      ż - zip with itself = [['w','w'],['a','a']]
                      ẇ€ - for €ach: is a sublist of R? i.e. one of: [0,0] [1,0] [0,1] [1,1]
                      ‘ - increment (vectorises) [1,1] [2,1] [1,2] [2,2]
                      Ḅ - unbinary 3 5 4 6
                      «5 - minimum with five 3 5 4 5
                      ¤ - nilad followed by link(s) as a nilad:
                      ® - recall depths from the register
                      ¬ - logical NOT (vectorises) (0->1, other depths->0)
                      Ḅ - unbinary
                      ⁼1 - equal one -- i.e. depths ends with a 0 and contains no other zero
                      × - multiply





                      share|improve this answer











                      $endgroup$




                      Jelly,  50 48 46  45 bytes



                      Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤


                      A monadic Link accepting a list of characters which yields:



                      5 - Dyadic dop
                      4 - Monadic dop
                      3 - Dfn
                      0 - Other


                      Try it online! Or see a test-suite.
                      uses Python quoting to avoid the possibility of evaluating input as a Python set or dictionary



                      How?



                      Ỵµṣ”'m2Kṣ”#Ḣ)KµċⱮƤØ{IF©<-oµ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Link: list of characters
                      - breaking long Link up...
                      Ỵµṣ”'m2Kṣ”#Ḣ)K - Replace any strings or comments with (single) spaces
                      Ỵ - split at newline characters
                      µ ) - monadic chain for each:
                      ṣ”' - split at apostrophe characters
                      m2 - modulo 2 slice (i.e. every other part starting with the first
                      - - that is, non-string code. Will remove strings from within comments)
                      K - join with spaces
                      ṣ”# - split at octothorp characters
                      Ḣ - head (i.e. non-comment code)
                      K - join with spaces

                      µċⱮƤØ{IF©<-oµ - Replace characters of code at depth > 1 with the integer 1
                      µ µ - monadic chain, call previous result A:
                      Ø{ - literal ['{','}']
                      Ƥ - for prefixes of A:
                      Ɱ - map across right argument with:
                      ċ - count
                      I - deltas (i.e. [count('}') - count('{')] for each prefix)
                      F - flatten (i.e. count('}') - count('{') for each prefix)
                      - -- i.e -1*depth of each character of A; closing braces at depth+1
                      © - (copy this list of depths to the register for later use)
                      <- - less than -1? (vectorises)
                      o - logical OR with A (vectorises, replacing deep code with 1s)

                      ⁾waż¤ẇ€‘Ḅ«5×®¬Ḅ⁼1¤ - Categorise the result, R
                      ¤ - nilad followed by link(s) as a nilad:
                      ⁾wa - literal ['w', 'a']
                      ż - zip with itself = [['w','w'],['a','a']]
                      ẇ€ - for €ach: is a sublist of R? i.e. one of: [0,0] [1,0] [0,1] [1,1]
                      ‘ - increment (vectorises) [1,1] [2,1] [1,2] [2,2]
                      Ḅ - unbinary 3 5 4 6
                      «5 - minimum with five 3 5 4 5
                      ¤ - nilad followed by link(s) as a nilad:
                      ® - recall depths from the register
                      ¬ - logical NOT (vectorises) (0->1, other depths->0)
                      Ḅ - unbinary
                      ⁼1 - equal one -- i.e. depths ends with a 0 and contains no other zero
                      × - multiply






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Feb 19 at 22:28

























                      answered Feb 19 at 20:00









                      Jonathan AllanJonathan Allan

                      52.3k535170




                      52.3k535170























                          3












                          $begingroup$


                          Clean, 309 293 284 bytes



                          We can get away with only using 3 variable names at a time, so we'll call them a, p, and l.



                          import StdEnv,Text,Data.List
                          a=isInfixOf o zip2[2,2]
                          @ =[''']
                          $p#p=join@[foldl(([a:p]_|p>=a++[';':join@(tl p)]=split['#']a!!0)o split@)l l\l<-mklines p]
                          #l=[(?a- ?l,p)\a<-inits p&[p:l]<-tails p]
                          |{p\(a,p)<-l|a<2}<>"{}"=0|a['ww']l=1|a['aa']l=2=3
                          ?l=sum[1\'{'<-l]-sum[1\'}'<-l]


                          Try it online!



                          Defines the function $ :: [Char] -> Int and some helpers, giving the mapping:





                          • 0: Other


                          • 1: Dyadic dop


                          • 2: Monadic dop


                          • 3: Dfn


                          Expanded (first version), and with more than 3 variable names:



                          $ s
                          # s // remove strings and comments
                          = join [';'] [ // join the second argument with semicolons
                          limit ( // take the first repeated element of
                          iterate // an infinite list of applications of the first argument
                          (
                          (
                          (p, q) = p ++ case q of // join the first half with a modified second half
                          ['''': q] = [';': q] // replace two quotes with a semicolon
                          [c, _: q] = [c: q] // drop the character after a quote or hash
                          _ = // leave unmatched strings unchanged
                          ) o span // split the string on the first occurrence of
                          c = c <> ''' && c <> '#' // a quote or hash
                          ) l // applied to l
                          )
                          \ l <- mklines s // for line l in s split at newlines
                          ]
                          # b // generate a map of nesting levels
                          = [
                          ( // the pair of
                          ?i - ?t, // the nesting level
                          c // the character c
                          )
                          \ i <- inits s // for init i of s
                          & // synchronously iterated with
                          [c: t] <- tails s // character c at the start of tail [c:t] of s
                          ]
                          // determine what the code is
                          | {c \(n, c) <- b | n < 2} // if the string made of characters with nesting level of less than 2
                          <> "{}" // is not the same as the paired braces at the beginning and end
                          = 0 // return zero
                          | m ['ww'] b // if there are two consecutive 'w's at nesting level 2
                          = 1 // return 1
                          | m ['aa'] b // if there are two consecutive 'a's at nesting level 2
                          = 2 // return 2
                          = 3 // otherwise return 3





                          share|improve this answer











                          $endgroup$


















                            3












                            $begingroup$


                            Clean, 309 293 284 bytes



                            We can get away with only using 3 variable names at a time, so we'll call them a, p, and l.



                            import StdEnv,Text,Data.List
                            a=isInfixOf o zip2[2,2]
                            @ =[''']
                            $p#p=join@[foldl(([a:p]_|p>=a++[';':join@(tl p)]=split['#']a!!0)o split@)l l\l<-mklines p]
                            #l=[(?a- ?l,p)\a<-inits p&[p:l]<-tails p]
                            |{p\(a,p)<-l|a<2}<>"{}"=0|a['ww']l=1|a['aa']l=2=3
                            ?l=sum[1\'{'<-l]-sum[1\'}'<-l]


                            Try it online!



                            Defines the function $ :: [Char] -> Int and some helpers, giving the mapping:





                            • 0: Other


                            • 1: Dyadic dop


                            • 2: Monadic dop


                            • 3: Dfn


                            Expanded (first version), and with more than 3 variable names:



                            $ s
                            # s // remove strings and comments
                            = join [';'] [ // join the second argument with semicolons
                            limit ( // take the first repeated element of
                            iterate // an infinite list of applications of the first argument
                            (
                            (
                            (p, q) = p ++ case q of // join the first half with a modified second half
                            ['''': q] = [';': q] // replace two quotes with a semicolon
                            [c, _: q] = [c: q] // drop the character after a quote or hash
                            _ = // leave unmatched strings unchanged
                            ) o span // split the string on the first occurrence of
                            c = c <> ''' && c <> '#' // a quote or hash
                            ) l // applied to l
                            )
                            \ l <- mklines s // for line l in s split at newlines
                            ]
                            # b // generate a map of nesting levels
                            = [
                            ( // the pair of
                            ?i - ?t, // the nesting level
                            c // the character c
                            )
                            \ i <- inits s // for init i of s
                            & // synchronously iterated with
                            [c: t] <- tails s // character c at the start of tail [c:t] of s
                            ]
                            // determine what the code is
                            | {c \(n, c) <- b | n < 2} // if the string made of characters with nesting level of less than 2
                            <> "{}" // is not the same as the paired braces at the beginning and end
                            = 0 // return zero
                            | m ['ww'] b // if there are two consecutive 'w's at nesting level 2
                            = 1 // return 1
                            | m ['aa'] b // if there are two consecutive 'a's at nesting level 2
                            = 2 // return 2
                            = 3 // otherwise return 3





                            share|improve this answer











                            $endgroup$
















                              3












                              3








                              3





                              $begingroup$


                              Clean, 309 293 284 bytes



                              We can get away with only using 3 variable names at a time, so we'll call them a, p, and l.



                              import StdEnv,Text,Data.List
                              a=isInfixOf o zip2[2,2]
                              @ =[''']
                              $p#p=join@[foldl(([a:p]_|p>=a++[';':join@(tl p)]=split['#']a!!0)o split@)l l\l<-mklines p]
                              #l=[(?a- ?l,p)\a<-inits p&[p:l]<-tails p]
                              |{p\(a,p)<-l|a<2}<>"{}"=0|a['ww']l=1|a['aa']l=2=3
                              ?l=sum[1\'{'<-l]-sum[1\'}'<-l]


                              Try it online!



                              Defines the function $ :: [Char] -> Int and some helpers, giving the mapping:





                              • 0: Other


                              • 1: Dyadic dop


                              • 2: Monadic dop


                              • 3: Dfn


                              Expanded (first version), and with more than 3 variable names:



                              $ s
                              # s // remove strings and comments
                              = join [';'] [ // join the second argument with semicolons
                              limit ( // take the first repeated element of
                              iterate // an infinite list of applications of the first argument
                              (
                              (
                              (p, q) = p ++ case q of // join the first half with a modified second half
                              ['''': q] = [';': q] // replace two quotes with a semicolon
                              [c, _: q] = [c: q] // drop the character after a quote or hash
                              _ = // leave unmatched strings unchanged
                              ) o span // split the string on the first occurrence of
                              c = c <> ''' && c <> '#' // a quote or hash
                              ) l // applied to l
                              )
                              \ l <- mklines s // for line l in s split at newlines
                              ]
                              # b // generate a map of nesting levels
                              = [
                              ( // the pair of
                              ?i - ?t, // the nesting level
                              c // the character c
                              )
                              \ i <- inits s // for init i of s
                              & // synchronously iterated with
                              [c: t] <- tails s // character c at the start of tail [c:t] of s
                              ]
                              // determine what the code is
                              | {c \(n, c) <- b | n < 2} // if the string made of characters with nesting level of less than 2
                              <> "{}" // is not the same as the paired braces at the beginning and end
                              = 0 // return zero
                              | m ['ww'] b // if there are two consecutive 'w's at nesting level 2
                              = 1 // return 1
                              | m ['aa'] b // if there are two consecutive 'a's at nesting level 2
                              = 2 // return 2
                              = 3 // otherwise return 3





                              share|improve this answer











                              $endgroup$




                              Clean, 309 293 284 bytes



                              We can get away with only using 3 variable names at a time, so we'll call them a, p, and l.



                              import StdEnv,Text,Data.List
                              a=isInfixOf o zip2[2,2]
                              @ =[''']
                              $p#p=join@[foldl(([a:p]_|p>=a++[';':join@(tl p)]=split['#']a!!0)o split@)l l\l<-mklines p]
                              #l=[(?a- ?l,p)\a<-inits p&[p:l]<-tails p]
                              |{p\(a,p)<-l|a<2}<>"{}"=0|a['ww']l=1|a['aa']l=2=3
                              ?l=sum[1\'{'<-l]-sum[1\'}'<-l]


                              Try it online!



                              Defines the function $ :: [Char] -> Int and some helpers, giving the mapping:





                              • 0: Other


                              • 1: Dyadic dop


                              • 2: Monadic dop


                              • 3: Dfn


                              Expanded (first version), and with more than 3 variable names:



                              $ s
                              # s // remove strings and comments
                              = join [';'] [ // join the second argument with semicolons
                              limit ( // take the first repeated element of
                              iterate // an infinite list of applications of the first argument
                              (
                              (
                              (p, q) = p ++ case q of // join the first half with a modified second half
                              ['''': q] = [';': q] // replace two quotes with a semicolon
                              [c, _: q] = [c: q] // drop the character after a quote or hash
                              _ = // leave unmatched strings unchanged
                              ) o span // split the string on the first occurrence of
                              c = c <> ''' && c <> '#' // a quote or hash
                              ) l // applied to l
                              )
                              \ l <- mklines s // for line l in s split at newlines
                              ]
                              # b // generate a map of nesting levels
                              = [
                              ( // the pair of
                              ?i - ?t, // the nesting level
                              c // the character c
                              )
                              \ i <- inits s // for init i of s
                              & // synchronously iterated with
                              [c: t] <- tails s // character c at the start of tail [c:t] of s
                              ]
                              // determine what the code is
                              | {c \(n, c) <- b | n < 2} // if the string made of characters with nesting level of less than 2
                              <> "{}" // is not the same as the paired braces at the beginning and end
                              = 0 // return zero
                              | m ['ww'] b // if there are two consecutive 'w's at nesting level 2
                              = 1 // return 1
                              | m ['aa'] b // if there are two consecutive 'a's at nesting level 2
                              = 2 // return 2
                              = 3 // otherwise return 3






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Feb 20 at 3:22

























                              answered Feb 20 at 1:23









                              ΟurousΟurous

                              7,32111035




                              7,32111035























                                  0












                                  $begingroup$


                                  Retina 0.8.2, 91 bytes



                                  m`'.*?('|$)|#.*

                                  s(+`(?!^){[^{}]*}(?!$)

                                  ^(?!{[^{}]*}$).+
                                  3
                                  ^.+ww.+
                                  2
                                  ^.+aa.+
                                  1
                                  ..+
                                  0


                                  Try it online! Link includes test suite. Explanation:



                                  m`'.*?('|$)|#.*



                                  Remove strings and comments.



                                  s(+`(?!^){[^{}]*}(?!$)



                                  Remove matched brackets, working out from the innermost, but leave the first and last brackets.



                                  ^(?!{[^{}]*}$).+
                                  3


                                  If we don't have matched brackets then this is Other.



                                  ^.+ww.+
                                  2


                                  Otherwise if we have ww then this is Dyadic Dop.



                                  ^.+aa.+
                                  1


                                  Otherwise if we have aa then this is Monadic Dop.



                                  ..+
                                  0


                                  Otherwise if this is anything not covered above then this is Dfn.






                                  share|improve this answer









                                  $endgroup$


















                                    0












                                    $begingroup$


                                    Retina 0.8.2, 91 bytes



                                    m`'.*?('|$)|#.*

                                    s(+`(?!^){[^{}]*}(?!$)

                                    ^(?!{[^{}]*}$).+
                                    3
                                    ^.+ww.+
                                    2
                                    ^.+aa.+
                                    1
                                    ..+
                                    0


                                    Try it online! Link includes test suite. Explanation:



                                    m`'.*?('|$)|#.*



                                    Remove strings and comments.



                                    s(+`(?!^){[^{}]*}(?!$)



                                    Remove matched brackets, working out from the innermost, but leave the first and last brackets.



                                    ^(?!{[^{}]*}$).+
                                    3


                                    If we don't have matched brackets then this is Other.



                                    ^.+ww.+
                                    2


                                    Otherwise if we have ww then this is Dyadic Dop.



                                    ^.+aa.+
                                    1


                                    Otherwise if we have aa then this is Monadic Dop.



                                    ..+
                                    0


                                    Otherwise if this is anything not covered above then this is Dfn.






                                    share|improve this answer









                                    $endgroup$
















                                      0












                                      0








                                      0





                                      $begingroup$


                                      Retina 0.8.2, 91 bytes



                                      m`'.*?('|$)|#.*

                                      s(+`(?!^){[^{}]*}(?!$)

                                      ^(?!{[^{}]*}$).+
                                      3
                                      ^.+ww.+
                                      2
                                      ^.+aa.+
                                      1
                                      ..+
                                      0


                                      Try it online! Link includes test suite. Explanation:



                                      m`'.*?('|$)|#.*



                                      Remove strings and comments.



                                      s(+`(?!^){[^{}]*}(?!$)



                                      Remove matched brackets, working out from the innermost, but leave the first and last brackets.



                                      ^(?!{[^{}]*}$).+
                                      3


                                      If we don't have matched brackets then this is Other.



                                      ^.+ww.+
                                      2


                                      Otherwise if we have ww then this is Dyadic Dop.



                                      ^.+aa.+
                                      1


                                      Otherwise if we have aa then this is Monadic Dop.



                                      ..+
                                      0


                                      Otherwise if this is anything not covered above then this is Dfn.






                                      share|improve this answer









                                      $endgroup$




                                      Retina 0.8.2, 91 bytes



                                      m`'.*?('|$)|#.*

                                      s(+`(?!^){[^{}]*}(?!$)

                                      ^(?!{[^{}]*}$).+
                                      3
                                      ^.+ww.+
                                      2
                                      ^.+aa.+
                                      1
                                      ..+
                                      0


                                      Try it online! Link includes test suite. Explanation:



                                      m`'.*?('|$)|#.*



                                      Remove strings and comments.



                                      s(+`(?!^){[^{}]*}(?!$)



                                      Remove matched brackets, working out from the innermost, but leave the first and last brackets.



                                      ^(?!{[^{}]*}$).+
                                      3


                                      If we don't have matched brackets then this is Other.



                                      ^.+ww.+
                                      2


                                      Otherwise if we have ww then this is Dyadic Dop.



                                      ^.+aa.+
                                      1


                                      Otherwise if we have aa then this is Monadic Dop.



                                      ..+
                                      0


                                      Otherwise if this is anything not covered above then this is Dfn.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Feb 21 at 19:36









                                      NeilNeil

                                      81.1k744178




                                      81.1k744178






























                                          draft saved

                                          draft discarded




















































                                          If this is an answer to a challenge…




                                          • …Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.


                                          • …Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
                                            Explanations of your answer make it more interesting to read and are very much encouraged.


                                          • …Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.



                                          More generally…




                                          • …Please make sure to answer the question and provide sufficient detail.


                                          • …Avoid asking for help, clarification or responding to other answers (use comments instead).





                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f180134%2fwhat-have-we-got%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          How to change which sound is reproduced for terminal bell?

                                          Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

                                          Can I use Tabulator js library in my java Spring + Thymeleaf project?