Skip to main content
8 of 9
Fixed issue pointed out by @Tim
  • 7.3k
  • 29
  • 41

JavaScript, 256 244 225 221 209 212 chars

function f(c,a){return a.big?B["z"[+/\W|_/.test(s=a.replace(/^!/,''))-!s].x,s]^a[0]=='!':,!c))[c?'some':'every'](Number)}q=f(0,A)}catch(_){q=null}alert(q)

(The last line break is non-significant.)

ECMASCript 6 variation, 213 194 190 189 192 chars


Ungolfed version with explanation

try {
  A = JSON.parse(prompt())  // Alice's data (the expression)
  B = JSON.parse(prompt())  // Bob's data (the variable assignments)

  /* f(c,a) returns the assignment of `a` if `a` is a string (throwing an exception if
   * it is a malformed literal), or maps `f` over `a` and folds it into a single value
   * depending on if it's an even or odd nesting (reducing it with `some` or `every`).
   * `c` is the "is-even-or-odd-nesting" parameter.
  function f(c,a) {
    return a.big? // Is `a` a string?
                  B[ // If so, look up the value of this literal

      // Ugly (but compact) literal syntax validation: strip out the eventual leading
      // '!' and assign to `s`, see if the string contains an illegal character,
      // coerce the result to a number (so
      // 1 = invalid string, 0 = valid), index a string with this number (yields
      // `undefined` if invalid, `'z'` otherwise), then try to access the `x` property
      // of this value (errors if `undefined`).
                    "z"[ + /\W|_/.test(s = a.replace(/^!/,'')) - !s ].x,

                    s] ^ a[0]=='!'  // xor:ing with whether this is a negated literal
                                    // takes care of negation

      // `a` is an array; map `f` over it (after flipping `c`), then fold it with
      // `some` or `every` depending on nesting parity.  (`Number` here is essentially
      // an identity function, as far as "truthiness" goes: `x` truthy iff `Number(x)`
      // truthy, at least for the relevant values.)
                :, !c))[c? 'some' : 'every'](Number)

  q = f(0, A)  // Process the entire expression recursively
} catch (_) {
  q = null     // If an error is thrown (either a parse error from `JSON.parse`, or the
               // error from `.x` for validating literals), assign `null` instead.
  • 7.3k
  • 29
  • 41