[Question]
  [
In mathematics an exclamation mark `!` often means [factorial](https://en.wikipedia.org/wiki/Factorial) and it comes after the argument.
In programming an exclamation mark `!` often means [negation](https://en.wikipedia.org/wiki/Negation#Programming) and it comes before the argument.
For this challenge we'll only apply these operations to zero and one.
```
Factorial
0! = 1
1! = 1
Negation
!0 = 1
!1 = 0
```
Take a string of zero or more `!`'s, followed by `0` or `1`, followed by zero or more `!`'s ([`/!*[01]!*/`](https://regex101.com/r/0lEuae/1)).  
For example, the input may be `!!!0!!!!` or `!!!1` or `!0!!` or `0!` or `1`.
The `!`'s before the `0` or `1` are negations and the `!`'s after are factorials.
Factorial has higher precedence than negation so factorials are always applied first.  
For example, `!!!0!!!!` truly means `!!!(0!!!!)`, or better yet `!(!(!((((0!)!)!)!)))`.
Output the resultant application of all the factorials and negations. The output will always be `0` or `1`.
### Test Cases
```
0 -> 0
1 -> 1
0! -> 1
1! -> 1
!0 -> 1
!1 -> 0
!0! -> 0
!1! -> 0
0!! -> 1
1!! -> 1
!!0 -> 0
!!1 -> 1
!0!! -> 0
!!!1 -> 0
!!!0!!!! -> 0
!!!1!!!! -> 0
```
The shortest code in bytes wins.
  
[Answer]
## Mathematica, ~~25~~ 17 bytes
```
Input[]/.!x_:>1-x
```
Takes input from a user prompt. Assumes Mathematica's [notebook environment](http://meta.codegolf.stackexchange.com/a/7844/8478) for implicit printing. To make it a command-line script, wrap it in `Print[...]` or to make it an argumentless function (which then takes input from the prompt), append `&`.
Mathematica has both of the required operators (with the required precedence), so we can just "eval" the input (which is done automatically by `Input[]`), but the logical negation operator doesn't work on integers (so it will remain unevaluated). If there's a `!x` left in the result, we replace it with `1-x`.
A couple of fun facts about the evaluation:
1. Mathematica actually *also* has the double factorial operator `!!`, which computes `n*(n-2)*(n-4)*...`, but applied to `0` or `1` it still gives `1`, so it doesn't matter that `0!!!!!` will actually be parsed as `((0!!)!!)!`.
2. Even though Mathematica leaves `!0` and `!1` unevaluated, it does know that `!` is self-inverse, so it will automatically cancel all pairs of leading `!`. After the `ToExpression` we're *always* left with one of `0`, `1`, `!0`, `!1`.
[Answer]
# [Bash](https://www.gnu.org/software/bash/) + Unix utilities, ~~21~~ 17 bytes
```
sed s/.!!*$/1/|bc
```
[Verify the test cases online!](https://tio.run/##TY6xCoMwGIT3PMUlWIQWTDIW1K1d@wwatTpoJLGQwXdPTdKWLsfd99/B3zZ29KrZUK9GP00zoyzZ7XFn3vYdLC8oPWdc8r1V/sCEqHHWHV4Xh4J/JmTQBg7TAgGJXNAcuQxCRRAZXcyRCpoKkaTKt5NQSjTkH4mWAJ0@BFjNtGwD2OlqUdVgAMsci6dejRqZw/73YNgtvX8D "Bash – Try It Online")
*Added a TIO link to the test suite.*
This must be saved in a file and run as a program. If you try to enter the command directly from the command line, it won't work because !! is expanded due to history substitution being enabled in bash's interactive mode. (Alternatively, you can turn history substitution off with `set +H`.)
[Answer]
## [Retina](https://github.com/m-ender/retina), ~~20~~ ~~15~~ 14 bytes
*Thanks to Leo for saving 1 byte.*
```
0!
1
!!
^1|!0
```
[Try it online!](https://tio.run/nexus/retina#LYm5DYBAEANzdzEBEqGvCro4UQi9L7Ygm@c4r3uMlkDa68EzjrYhLLIixExjuPnrlRLl3wov "Retina – TIO Nexus")
### Explanation
```
0!
1
```
Turn `0!` into `1`. We don't care about any other trailing `!`s, the resulting number is the same as if we had applied all factorials.
```
!!
```
Cancel pairs of negations. This may also cancel some factorials, but that's irrelevant.
```
^1|!0
```
Count the number of matches of this regex, which is either `1` or `0` and gives the desired result.
[Answer]
## [Grime](https://github.com/iatorm/grime), ~~14 12~~ 9 bytes
```
e`\0!~\!_
```
[Try it online!](https://tio.run/nexus/grime#@5@aEGOgWBejGP//vyIQGCgCAA)
## Explanation
This matches the input against a pattern, printing `1` for match and `0` for no match.
```
e`\0!~\!_
e`         Match entire input against this pattern:
    !      not
  \0       a sole 0
     ~     xor
      \!   exclamation mark
        _  followed by this pattern matched recursively.
```
The idea is this.
If the input begins with a digit, then the recursive part `\!_` always fails, and `\0!` succeeds unless we have a single `0`.
Their xor succeeds unless the input is a single `0`.
If the input begins with a `!`, then `\0!` always succeeds, and `\!_` succeeds if the recursive match succeeds.
Their xor succeeds exactly when the recursive match fails, thus negating it.
[Answer]
# Brainfuck, ~~85~~ 72 (84) bytes
```
,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]<+.
```
to return numerically, or
```
,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]-[-----<+>]<--.
```
for ASCII text. > may also be prefixed to avoid memory wrapping.
[Try it online!](https://tio.run/nexus/brainfuck#NYzRCcBADEJnyXfO0gHERcT9x0hzHxVEwYdzLBhXhMJuq1cGbyhNu3NsRGASmdx54W05Qpj/YXkCz0xVveuaDw "brainfuck – TIO Nexus")
---
```
Loops over the input.
On 1, ends.
On "!", toggles bool a stored as 0 or 255.
On "0", toggles if there is no trailing bit, then ends.
Memory labels  | BOOL | INPUT | FLAG |
,                   first input 
[                     # loop on INPUT
  >-[-----<->]<++     subtract 49 == "1"
  [                     # case not "1"
    >++++[-<++++>]      add 16 since 49 take 16 == "!"
    +                   set FLAG
    <                   move to INPUT
    [                     # case "0"
      [+],                clear and new INPUT
      [                     # case "0!"
        [-]>-<              clear INPUT and FLAG
      ]
    ]
  ]
  >                   move to FLAG
  [                     # case "!" or "0" without tail
    <<+[-->]>[<]        not the BOOL
    ,                   take new input
    >-                  clear FLAG
  ]
  <                   move to INPUT
]
+.                    return 0 or 1
```
Or for text response, replace the last line with 
```
-[-----<+>]<--.       add 49 for "0" or "1" conversion and return
```
[Answer]
# Brainfuck - way to many bytes (232 bytes)
Clearly the wrong language for winning in code golf. Mainly I noticed a lack of anyone using this esolang. There is a good online interpreter [bf interpeter](https://sange.fi/esoteric/brainfuck/impl/interp/i.html) or you can actually watch what the program does using this [bf visualizer](https://fatiherikli.github.io/brainfuck-visualizer/#).
```
>>>>>,[>+++[<---------------->-]<<<<<<[-]+>[-]>>>>[-[<<[>+<<<<->>>[<<+>>-] ]<<[>>+<<-]<[>>+<<[-]]>>>>>[-]]<<<<<[>>>++<<<-]>+>>>>[-]]<<<<-[>>+<<[-]]>>>>,]<<->[<[-]+>[-]]<<[<[-]>>[<<+>>[-]]+<<[->>-<<]>-]>>[-]+++[<++++++++++++++++>-]<.
```
[Answer]
# Python, ~~-44-~~ 42 bytes
Saved 2 bytes thanks to Zgarb!
```
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2
```
Step by step:
1. `x[-1]!='0'`  
if `x` ends with `1` or `!` ⇔ `x` doesn't end with `0`, the factorial portion must have value `1`, else `0`
2. `^len(x.rstrip('!'))%2`  
exploit xor's property as a "conditional not". The condition in this case is if the length of initial `!`s is odd. However, `.rstrip` doesn't remove the number from the string so the length calculated is offset by 1, therefore the condition is inverted
3. The offset by 1 in step 2 is corrected by changing `!=` to `==` in step 1. Zgarb suggested using a difference comparison operator rather than applying another inversion, saving 2 bytes.
[Try it online!](https://tio.run/nexus/python3#LYxBCsMgEEX3c4oxUBwJKdplqCcJLaSkgjAxQV3Y06fadBbDe2/xnaWD5/W1zFhGKtNgHtZKLdWT34HKNaYc/U5SSKUut0OBi9uK6ZPQr/sWM6a8@ABui8jow6kjYD22PI117yd79CFTHSNHrFTf4X3Armd1aDCgBRgBQoMw9VeqpkWLlVs@e5NGovHfGnwB "Python 3 – TIO Nexus")
[Answer]
## JavaScript (ES6), ~~43~~ ~~41~~ 29 bytes
```
s=>+eval(s.replace(/.!+$/,1))
```
### Non-regex method (~~41~~ 31 bytes)
Below is my initial approach. It's slightly more interesting, but ~~significantly longer~~ *still a bit longer even after a significant optimization by Neil (10 bytes saved)*.
```
f=([c,...s])=>1/c?c|s>'':1-f(s)
```
### Test cases
```
let f =
s=>+eval(s.replace(/.!+$/,1))
;[
  "0", "1", "0!", "1!", "!0", "!1", "!0!", "!1!", "0!!",
  "1!!", "!!0", "!!1", "!0!!", "!!!1", "!!!0!!!!", "!!!1!!!!"
].map(
  s => console.log(s, '=>', f(s))
)
```
[Answer]
# [Retina](https://github.com/m-ender/retina), 13 bytes
A somewhat weird approach, but it's short and it works.
```
0$
!1
!!
^\d
```
With the first two lines we replace an ending `0` with `!1`: with this replacement we now know that the part of our string from the digit onwards is equal to 1.
Next two lines, remove pairs of `!`: double negation erases itself, and we already accounted for factorial with the previous step.
Last line, match a digit at the start of the string and return the number of matches: if the negations have all been eliminated we'll find a match (and as we said before we know this is equal to 1), if there's still a negation this won't match.
[Try it online!](https://tio.run/nexus/retina#U9VwT/hvoMKlaMilqMjFFReT8v@/AZchl4Eil6Eil6IBWALIUQTyDBRBgkA2SBgiDuKAtYLYUB6IAQA "Retina – TIO Nexus")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 5 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
VeMḂ$
```
**[Try it online!](https://tio.run/nexus/jelly#@x@W6vtwR5PK/6N7Drc/alrzqHG7tXvk///RSgZKOkqGQGygCGKACEWQkKIhmAXmg0UNFCEKwCIQJTA1ECEITxHEh4uAmbEA)**
Monadic function expecting a string. Inputs with leading `!`s cause a `1` to be printed to STDOUT along the way, so the TIO link I give is a test harness that prints the input-output pairs beneath the first line of output.
### How?
```
VeMḂ$ - Monadic link: string
V     - eval the string
          - the implicit input of 0 causes !...! to evaluate to 1 (which gets printed),
          - the result is the evaluation of the rest: "0"=0; "0!"=1; "1"=1; "1!"=1; ...
 e    - exists in?
    $ - last two links as a monad:
  M   -     Maximal indexes - the "0" and "1" characters are greater than "!",
                            - so this results in a list of one item [i] where
                            - i is the 1-based index of the 0 or 1 character.
   Ḃ  -     %2 (vectorises) - [i%2], so a 0 if we need to logically negate and a 1 if not
                            - hence we check equality with e rather than inequality.
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 9 bytes
Code:
```
.V¹'!ÜgG_
```
Uses the **CP-1252** encoding. [Try it online!](https://tio.run/nexus/05ab1e#@68XdminuuLhOenu8f//KxooKgIA "05AB1E – TIO Nexus") or [Verify all test cases!](https://tio.run/nexus/05ab1e#qymr/K8XVqmueHhOunv8/9pKJQVdOwWlQ6uLD63W@W/AZchloMhlqMilaMClaAgkgSwgz0ARJAhkg4Qh4iAOiKUIYkN5IAYA)
Explanation:
```
.V         # Evaluate the input as 05AB1E code. This computes the factorial part.
   '!Ü     # Remove trailing exclamation marks..
  ¹        # ..from the first input
      g    # Get the length of the resulting string
       G   # Do the following length - 1 times:
        _  #   Negate the number
```
[Answer]
# Ruby, 12+1 = ~~39~~ ~~24~~ ~~15~~ 13 bytes
Uses the `-n` flag. Thanks to [@GB](https://codegolf.stackexchange.com/users/18535/g-b) for -9 bytes!
```
p~/!*$|0$/%2
```
[Answer]
# [Perl](https://www.perl.org/), 20 bytes
19 bytes of code + `-p` flag.
```
s/\d!+/1/;$_=0+eval
```
[Try it online!](https://tio.run/nexus/perl#U1YsSC3KUdAt@F@sH5OiqK1vqG@tEm9roJ1alpjz/78BlyGXgSKXoSKXogGXoiGQBLKAPANFkCCQDRKGiIM4IJYiiA3lgRgA "Perl – TIO Nexus")
Perl's negation returns `undef` or `1`, so I use `0+` to numerify the result `0+undef` returns `0`. Besides that, not much to say about the code.
[Answer]
# C, 68 62 61 53 bytes
```
c;e(char*a){for(c=1;*a<34;a++)c^=1;c=a[1]?c:*a&1^!c;}
```
Squeezed out a few more bytes with some abuse
[Try it online!](https://tio.run/nexus/c-gcc#fY7NDsIgEITvPsXSRgNYTYmexNYH8SchQFMSoabVgxqfvRa9mOjKiZmd/XZSF/TxYiysu7NxzbwuR6mxlQsWDPUM4ju1Lpwrmow7mJUwNruQZOAzsEOA9VpaqmvVcsXuVdNSXQjJ1XqxlGo6ZfowSF2ordhv9IqriTgQLR/9QASvXKDxc8vgReBXBvdRPBklcPDypTwUkOTJW8RaH7b4becEiSM@QfBEYHkMhF3ICVoJQ6Gl/rRCWegOiVv/9r6mj/4J "C (gcc) – TIO Nexus")
[Answer]
# [Perl 6](http://perl6.org/), ~~32~~ ~~28~~ 23 bytes
```
{m/(\!)*(1|0.)*/.sum%2}
```
### How it works
```
{                     }  # A lambda.
{m/            /      }  # Match the lambda argument against the regex:
   (\!)*                 #   Zero or more `!`.
                         #     (First capture will be an array with one element per negation).
        (1|0.)*          #   A `1`, or a `0` and another character, zero or more times.
                         #     (Second capture will be a one-element array if the factorial
                         #     part evaluates to 1, and an empty array otherwise.)
                .sum     # Add the lengths of the two captures,
                    %2   # and return that sum modulo 2.
```
[Answer]
## [Haskell](https://www.haskell.org/), 39 bytes
```
f('!':b)="10"!!read[f b]
f[a]=a
f _='1'
```
Defines a function `f`, which takes a string and returns a character.
[Try it online!](https://tio.run/nexus/haskell#y03MzFOwVSgoyswrUVBRSFNQUlRUNFBU@p@moa6obpWkaatkaAAUK0pNTIlOU0iK5UqLToy1TeRKU4i3VTdU//8fAA "Haskell – TIO Nexus")
## Explanation
There are three cases: input begins with `!`, input has length 1, and everything else.
```
f('!':b)=    -- If input has head '!' and tail b,
 "10"!!      -- we index into the string "10"
  read[f b]  -- using f b converted to int. This essentially inverts f b.
f[a]=        -- If input has only one character, we know it's a digit,
 a           -- so we can just return it.
f _=         -- In all other cases, we know the input is a digit followed by !s,
 '1'         -- so we can return '1'.
```
[Answer]
# Befunge, 24 bytes
```
~"!"-:#v_$1+
*+2%!.@>0~`
```
[Try it online!](http://befunge.tryitonline.net/#code=fiIhIi06I3ZfJDErCiorMiUhLkA+MH5g&input=ISEhMCEhISE)
This starts by counting the number of `!` characters read from stdin. The first character that isn't a `!` will either be a `0` or `1`, but in the process of testing for `!` we will have subtracted 33, making it either 15 or 16. We then read one more character, that will either be an `!` or EOF, and compare if that is less than 0 (i.e. EOF).
Taking those three data points - the exclamation count (*c*), the digit value, (*d*), and the end-of-file condition (*e*) - we can calculate the result as follows:
```
!((c + d*e) % 2)
```
Multiplying the digit value by the end-of-file condition means it will be converted to zero if the digit was followed by a `!`, thus giving it the same modulo 2 value as a `1` (which remember has been converted to 16). But before applying the modulo 2, we add the initial exclamation count, which effectively toggles the modulo 2 result as many times as their were `!` prefixes. And finally we *not* the result since our baseline values for `0` and `1` are the opposite of what we need.
Looking at the code in more detail:
```
~                Read a character from stdin.
 "!"-            Subtract 33 (ASCII for '!').
     :  _        Make a duplicate and check if zero (i.e. is it a '!').
         $1+     If so, drop the duplicate, increment a counter, and repeat.
       v         Otherwise move to the second line, leaving the digit value on the stack.
       >0~`      Read one more character and check if less than 0 (i.e. EOF).
*                Multiple by the digit value, making it zero if not followed by EOF.
 +               Add to the exclamation count.
  2%             Modulo 2 the result.
    !            Then not that value.
     .@          And finally write to stdout and exit.
```
[Answer]
# [Haskell](https://www.haskell.org/), 27 bytes
```
f('!':b)=1-f b
f"0"=0
f _=1
```
[Try it online!](https://tio.run/nexus/haskell#y03MzFOwVSgoyswrUVBRyE0sUEhTiFYyUNJRUFI0BJMGihAOhFI0gApCuVBFiiARhBiMDZaEGADVbwARgQpBNRgqxf5P01BXVLdK0rQ11E1TSOJKA7rB1oArTSHe1vD/fwA "Haskell – TIO Nexus")
Each leading `!` complements the output for the rest of the expression, done as `1-`. We keep flipping until we hit a digit. If the remaining is just `"0"`, the result is 0. Otherwise, it's a `1` or is followed by one or more `!`, so the result is 1.
[Answer]
# Python, 38 bytes
```
lambda s:(s[1::2]>s[::2])^ord(s[-1])%2
```
**[TryItOnline!](https://tio.run/nexus/python3#RY3RCsMgDEWf51fow7BCB9pHof0RsdDRCYWtHcb/d0viupfknpMLqWl8Lq/7ukjwHQTn/RAnCLjMfOT1624umusgygMKjEFb3UvtcFhFkaYirRxnVnyxqtVYtuLZbLaxQvN3lKNIR5b4Xm47bfDi8s7bXjok84PEeLKp9QM)**
An unnamed function taking an input string `s` and returning an integer `0` or `1`.
`s[1::2]` is a slice of the input string that starts at index 1 and has a step size of two:  
`'Like this' -> 'ieti'`
`s[::2]` is similar but starts at the default index of 0:  
`'Like this' -> 'Lk hs'`
The test `(s[1::2]>s[::2])` checks if the 0-based index of the `'0'` or `'1'` is odd, i.e. if we need to complement.  
This works because the ordering of strings is checked lexicographically with any non-empty string greater than the empty string, and with ASCII ordering, so `'1'>'0'>'!'`. This is a byte shorter than the simpler `s.index(max(s))%2`.
The `ord(s[-1])%2` checks to see if the last character is not a `'0'` (for valid input), and results in an integer (whereas the same length `(s[-1]!='0')` would return a boolean).  
This works because the last character of the input, `s[-1]`, will be a `'0'`, `'1'`, or `'!'` which have ASCII code points 48, 49, and 33 respectively, which are 0, 1, and 1 modulo 2.
The `^` then performs a bitwise exclusive or operation on the two above values, returning an integer since one input, the right one, is an integer. If the left is True the complement of the right is returned, if the left is False the right is returned, as required.
[Answer]
## Ruby, ~~22 21~~ 20 bytes
```
->s{(s=~/!*$|0$/)%2}
```
Explanation:
* First case, I got some '!' at the end, remove them, get length modulo 2.
* Second case, no '!', if last character is zero then remove it, get length modulo 2
* If the last character is 1, back to the first case
(-1 byte stealing @Value Ink's idea)
[Answer]
# [APL (Dyalog Extended)](https://github.com/abrudz/dyalog-apl-extended), 21 bytes
```
⍎⌽'!(\d.*)'⎕R'\1~'⍣≡⍞
```
Repeatedly shift any !s to the right with the fixpoint ⍣≡
!!!!0! -> !!!0!~ -> !!0!~~ -> !0!~~~ -> 0!~~~~
Then reverse with ⌽, and execute with ⍎
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNrShJzUtJTfn/qKM97f@j3r5HPXvVFTViUvS0NNUf9U0NUo8xrFN/1Lv4UefCR73zQMr@K4BBGpcBF4xlCGcZKCIEEUxFhFJFQyRRJBVIqg0UkQ1BUoNsjKIhAA "APL (Dyalog Extended) – Try It Online")
[Answer]
# [///](https://esolangs.org/wiki////), 27 bytes
```
/0!/1//!!///!1/0//!0/1//!//
```
[Try it online!](https://tio.run/##TYyxDYAwEAN7pogHQLYXYBcKJAq67K8nIZ@Ixvdv2a7PWe@rRlCgSYBNTDXVZ5Chsh9Fmzu8CYNOQkmPGEagHc5DWJXZQW4CniuYNawldPfvry9e "/// – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 8 bytes
```
œr”!LḂ=V
```
[Try it online!](https://tio.run/nexus/jelly#@390ctGjhrmKPg93NNmG/X/UMMcAiA1BtCKIASIUQUKKhmAWmA8WNVCEKACLQJTA1ECEIDxFEB8uAmHOPdz@qGnN0UkPd874DwA "Jelly – TIO Nexus")
This is a *function* (monadic link) that takes one argument and returns via its return value. (It also often writes junk to standard output as a side effect, but we don't care about that.)
## Explanation
```
œr”!LḂ=V
œr”!      Take {the input}, with all trailing ! deleted
    L     Take the length of this
     Ḃ    Take the parity of that length
      =   Return 0 if unequal, 1 if equal to:
       V    the value of {the input} when eval'ed as a niladic Jelly program
```
First, note that as the input always consists of some number of `!`, followed by a digit, followed by more `!`, that if we delete the trailing `!` and take the length, we'll end up with one plus the number of leading `!` in the program. Taking the parity of this will return 0 if there were an odd number of `!`, or 1 if there were an even number of `!`. Comparing to 0 is a "not" function, whereas comparing to 1 is the identity function; thus `œr”!LḂ=` effectively implements the "treat leading `!` as NOT operators" part of the question.
As for the second half, handling factorials, `!` is a factorial operation in Jelly, so if the program has no leading `!`, we can solve the problem directly with a simple `eval` (`V`). If the program *does* have leading `!`, those will be interpreted as taking the factorial of 0 (possibly multiple times), producing a return value of 1, which will be printed to standard output and discarded once a digit is seen; thus, they have no impact on the return value of the function that's my submission to the question.
[Answer]
# Java 7, ~~105~~ ~~82~~ 81 bytes
```
int a(char[]a){int b=0,c=0;for(;a[b++]<34;c^=1);return(b<a.length?1:a[b-1]&1)^c;}
```
[Try it online!](https://tio.run/nexus/java-openjdk#lZDBisIwFEX3/YrExZDgGBJ0ZSyDzHpWLqXCa6waqGlJX2eQ0m/vRF0rvFUI3HfP4bZ9WXvHXA1dx37ABzZMPiAD4S4Q9wXI4f4tc/3pcm1PTRQW9uV8XmyWK@sOuZE2VtjHIMoNqLoKZ7x8mXXKLEzxYeTB2XFqn5QOAdPz2/gjuyaW2GH04ZwoUbIhe@CB5SxUfw8XIW22u3VYXVXTo2pTGOsgQIGY6ZnC5js5bmOEm5DyTdYQsppTiilhTlHmhtRM8iBZa04bhGRCm4S6CU2F1s7v/WTCi5MxG6d/ "Java (OpenJDK) – TIO Nexus")
### Old regex-ish solution
```
int a(String a){a=a.replace("0!","1").replaceAll("1.*","1");int b=a.length()-1;return b%2^a.charAt(b)&1;}
```
[Answer]
## [CJam](https://sourceforge.net/p/cjam), ~~12~~ 11 bytes
```
r_W='0=!\~;
```
[Try it online!](https://tio.run/nexus/cjam#@18UH26rbmCrGFNn/f@/oqKigaIiAA "CJam – TIO Nexus") [Test suite](https://tio.run/nexus/cjam#K/TTr1ZS0LVTUNLXsAqy/h8UH26rbmCrGFNn/T@mrs42v1b/vwFI3oDLEEQZchkoQmhDKK1oAKUNIcoUIQqADEMow0ARrgWmRxFqpqKiIcwURZg2RbhJiiBRZHE4DwA) (prints a `1` for each correct test case).
```
r      e# Read input.
_W='0= e# Duplicate and check whether the string ends in '0'. This is the
       e# only case in which the factorial part results in 0.
!      e# Negate this to get the actual result of the factorial part.
\      e# Swap with the input.
~      e# Evalute the input as CJam code. The leading `!` will apply the logical
       e# negations to the factorial result. The 0 or 1 will then push a junk value
       e# which is potentially negated a few times as well, by the factorials.
;      e# Discard the junk value.
```
[Answer]
# [Haskell](https://www.haskell.org/), ~~67~~ 65 bytes
```
f s|foldr(\_->not)(last s`elem`"1!")$fst.span(<'0')$s="1"|1<3="0"
```
[Try it online!](https://tio.run/nexus/haskell#DcNBCoAgEADAr2yLoB4Kpav2kiClFAK1aPfY362B6RnozVc5HrVu49Iu1qpEYqCQSqoB7YBaZOKJ7tiUk0ZqQR4tvtbNHg32Gs8GHs7G6Yk7g4Dch5/5fw "Haskell – TIO Nexus") Usage: `f "!!!0!!!!"`
Saved two bytes thanks to @nimi.
[Answer]
# Brainfuck, 115 bytes
```
>,[->++++[<-------->-]<[--------------->,[<[-]+>-]<<[->-[>+<+]>[-<+>]<<]>>++++++[-<++++++++>]<.>>+<]>-[<<+>,>[-]]<]
```
[Try it online!](https://tio.run/nexus/brainfuck#VYxBCsBADALfknPWQu/iR4L/f8bWlr10IBBGcWsN1GGIg2AO/qQW536zPMKo2daArSjrG8lMxCH@ik6GYWorbZveu6ruXD0 "brainfuck – TIO Nexus")
## Ungolfed:
```
% 0: inverter count
% 1: result
% 2: if/else flag; tmpspace in inner loop 0
>1,[
    ->2++++[<-------->-]<1 subtract 33 (!)
    [ 
        % we've reached the number
        ---------------
        % now it's either 0 or 1
        % check next char; If it's not 0 then it's '!'
        % 0! = 1! = 1!...! so we only need to determine if at least one ! exists
        >2,
                [<[-]+>-]<1
        % apply inversions
        <0
        [->1
            % invert cell 1 once each iteration
                       % cell 1 is 0 or 1
            -          % cell 1 is 255 or 1
            [>+<+]     % cell 1 is 0; cell 2 is 1 iff cell 1 should be 1
            >2[-<+>]<1 % cell 1 is 1 or 0
        <0]
        % print result
        >1>++++++[-<++++++++>]<1.
        >>2+< % tape={0 r 0 1}
    ]
    >2-[ % we haven't seen the number yet
        <<0+>1,>2 % add to inverter count
        [-]
    ]<1
]
```
[Answer]
# sed, ~~36~~ ~~33~~ 31 bytes
Pure sed, no bc / shell utils. Works on GNU sed < 4.3; 33 bytes on BSD and GNU 4.3+.
```
s/.!!*$/1/
:
s/!0/1/
s/!1/0/
t
```
Straightforward enough if you're familiar with `sed`; commented for those who aren't:
```
# Since 0! == 1! == 1 and factorial has precedence, just collapse any trailing "!" 
s/.!!*$/1/
# Define an anonymous label
:
# Invert 0 if needed
s/!0/1/
# Invert 1 if needed
s/!1/0/
# If a change was made, go back to the anonymous label.
t
```
Test:
```
% cat 109248.sed
s/.!!*$/1/
:l
s/!0/1/
s/!1/0/
tl
% wc -c 109248.sed
      33 109248.sed
% cat cases
0
1
0!
1!
!0
!1
!0!
!1!
0!!
1!!
!!0
!!1
!0!!
!!!1
!!!0!!!!
!!!1!!!!
% sed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
% gsed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
%
```
[Answer]
# [><>](https://esolangs.org/wiki/Fish), 18 bytes
```
ib%:?\
+2%n;\i+3=l
```
[Try it online!](https://tio.run/##S8sszvj/PzNJ1co@hkvbSDXPOiZT29g25/9/RUVFAyAGAA "><> – Try It Online")
Solved as part of [LYAL CMC](https://chat.stackexchange.com/transcript/message/59147177#59147177).
The basic idea is to process from left to right, doing the following:
* If the current char is `!` (boolean negation), keep it on the stack so that stack height can be used for negation count.
* If the current char is `0` or `1`, take one more char and test if there's a factorial (modifying the number to 1 if there is). Apply negation, print as number, and halt.
Optimizations:
* To get the final number, we can simply do `2%` at the end, which means we can just add the stack height + 1 (because the final stack height would be one more than the number of negations).
* To discriminate between 48/49 and 33, we can do `b%` (modulo 11, [idea](https://chat.stackexchange.com/transcript/message/59147302#59147302) by Jo King).
* The (digit, factorial-or-EOF) combinations to handle are:
```
(48, 33) -> 1
(49, 33) -> 1
(48, -1) -> 0
(49, -1) -> 1
```
We can use `48%11 = 4` and `49%11 = 5`. Then a simple way to handle these combinations is to check if the sum of two numbers is 3 or not. We could use "is not 3" for the condition, but it turns out that we can negate it and remove the extra `1+`.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 16 bytes
```
`\d!+`1øṙ\!\¬VṘĖ
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=&code=%60%5Cd!%2B%601%C3%B8%E1%B9%99%5C!%5C%C2%ACV%E1%B9%98%C4%96&inputs=!!0&header=&footer=)
We do a little regex.
## Explained
```
`\d!+`1øṙ\!\¬VṘĖ
`\d!+`            # The string "\\d!+" ( a regex that matches the digit followed by !)
      1øṙ         # and replace it with "1" (because 0! = 1! = 1)
         \!\¬V    # replace any remaining "!" with "¬" (not)
              ṘĖ  # then reverse and evaluate
```
]