Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	io := NewIo()
	defer io.Flush()
	for {
		S := io.NextLine()
		if S == "." {
			break
		}
		P := io.NextLine()
		i := 0
		val := hash(S, P, &i)
		cnt := 0
		for j := 0; j < 10000; j++ {
			i = 0
			if hash(S, fmt.Sprintf("%04d", j), &i) == val {
				cnt++
			}
		}
		io.Println(val, cnt)
	}
}

func hash(s, n string, i *int) int {
	if s[*i] == '[' {
		*i++
		switch s[*i] {
		case '+':
			*i++
			l := hash(s, n, i)
			r := hash(s, n, i)
			*i++
			return l | r
		case '*':
			*i++
			l := hash(s, n, i)
			r := hash(s, n, i)
			*i++
			return l & r
		case '^':
			*i++
			l := hash(s, n, i)
			r := hash(s, n, i)
			*i++
			return l ^ r
		}
	}
	x := int(n[s[*i]-'a'] - '0')
	*i++
	return x
}

// I/O template
type Io struct {
	reader    *bufio.Reader
	writer    *bufio.Writer
	tokens    []string
	nextToken int
}

func NewIo() *Io {
	return &Io{
		reader: bufio.NewReader(os.Stdin),
		writer: bufio.NewWriter(os.Stdout),
	}
}

func (io *Io) Flush() {
	err := io.writer.Flush()
	if err != nil {
		panic(err)
	}
}

func (io *Io) NextLine() string {
	var buff []byte
	for {
		line, isPrefix, err := io.reader.ReadLine()
		if err != nil {
			panic(err)
		}
		buff = append(buff, line...)
		if !isPrefix {
			break
		}
	}
	return string(buff)
}

func (io *Io) Next() string {
	for io.nextToken >= len(io.tokens) {
		line := io.NextLine()
		io.tokens = strings.Fields(line)
		io.nextToken = 0
	}
	s := io.tokens[io.nextToken]
	io.nextToken++
	return s
}

func (io *Io) NextInt() int {
	i, err := strconv.Atoi(io.Next())
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) NextFloat() float64 {
	i, err := strconv.ParseFloat(io.Next(), 64)
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) Println(a ...interface{}) {
	fmt.Fprintln(io.writer, a...)
}

func (io *Io) Printf(format string, a ...interface{}) {
	fmt.Fprintf(io.writer, format, a...)
}

func (io *Io) PrintIntSlice(a []int) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func (io *Io) PrintStringSlice(a []string) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func Log(name string, value interface{}) {
	fmt.Fprintf(os.Stderr, "%s=%+v\n", name, value)
}

func ExampleIo() {
	io := NewIo()
	defer io.Flush()
	a := make([]int, 0, 3)
	a[0], a[1], a[2] = io.NextInt(), io.NextInt(), io.NextInt()
	io.Println(a)
	io.PrintIntSlice(a)
	Log("io", a)
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
typedef long long ll;

string s;

int hsh(int pw) {
    char x[4];
    if (pw < 10) {
        x[0] = x[1] = x[2] = '0';  x[3] = char(pw + '0');
    }
    else if (pw < 100){
        x[0] = x[1] = '0'; x[2] = char(pw/10 + '0');  x[3] = char(pw%10 + '0');
    }
    else if (pw < 1000){
        int ic = pw;
        x[0] = '0'; 
        x[1] = char(ic/100 + '0');
        ic %= 100;
        x[2] = char(ic/10 + '0');  
        x[3] = char(ic%10 + '0');
    }
    else {
        int ic = pw;
        x[0] = char(ic/1000 + '0'); 
        ic %= 1000;
        x[1] = char(ic/100 + '0');
        ic %= 100;
        x[2] = char(ic/10 + '0');  
        x[3] = char(ic%10 + '0');
    }
    
    int depth = 0;
    vector<int> ope, value[30];
    for (int i = 0; i < s.size(); i++) {
        if (char(s[i]) == '[') depth++;
        else if (char(s[i]) == ']') {
            if (ope[ope.size() - 1] == 1) 
            value[depth - 1].push_back(value[depth][0] | value[depth][1]);
            if (ope[ope.size() - 1] == 2) 
            value[depth - 1].push_back(value[depth][0] & value[depth][1]);
            if (ope[ope.size() - 1] == 3) 
            value[depth - 1].push_back(value[depth][0] ^ value[depth][1]);
            
            //cout << ope[ope.size() - 1] << endl;
            ope.pop_back();
            value[depth].pop_back();
            value[depth].pop_back();
            
            depth--;
        }
        else if (char(s[i]) == '+') ope.push_back(1);
        else if (char(s[i]) == '*') ope.push_back(2);
        else if (char(s[i]) == '^') ope.push_back(3);
        else {
            if (char(s[i]) == 'a') value[depth].push_back(int(x[0] - '0'));
            if (char(s[i]) == 'b') value[depth].push_back(int(x[1] - '0'));
            if (char(s[i]) == 'c') value[depth].push_back(int(x[2] - '0'));
            if (char(s[i]) == 'd') value[depth].push_back(int(x[3] - '0'));
        }
    }
    
    return value[0][0];
}

int main(void){
    while (1) {
        cin >> s;
        if (s == ".") return 0;
        
        int p;
        cin >> p;
        
        int check = hsh(p);
        
        int ans = 0;
        for (int i = 0; i < 10000; i++) {
            if (hsh(i) == check) ans++;
        }
        
        cout << check << " " << ans << endl;
    }
}

C++: #include"bits/stdc++.h"

using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

#define FOR(k,m,n) for(ll (k)=(m);(k)<(n);(k)++)
#define REP(i,n) FOR((i),0,(n))
#define WAITING(str) int str;std::cin>>str;
#define DEBUGING(str) cout<< #str << " " str<<endl

constexpr int INF = (1 << 30);
constexpr ll INFL = (1ll << 60);
constexpr ll MOD = 1000000007;// 10^9+7

int mhash(string s, string p) {
	stack<int> st;
	for (char c : s) {
		if (isalpha(c))st.push(p[c - 'a'] - '0');

		if (c == '+' || c == '*' || c == '^') {
			int r = st.top(); st.pop();
			int l = st.top(); st.pop();
			switch (c) {
			case '+':st.push(l | r); break;
			case '*':st.push(l&r); break;
			case '^':st.push(l^r); break;
			}
		}
	}
	assert(st.size() == 1);
	return st.top();
}

int main()
{
	ostringstream ss;
	while (true) {
		string s, p; cin >> s;
		if (s == ".")break;
		cin >> p;
		reverse(s.begin(), s.end());

		int cnt = 0;
		int tgt = mhash(s, p);
		REP(i, 10000) {
			ss.fill('0');
			ss << setw(4) << i;
			if (tgt == mhash(s, ss.str()))cnt++;
			ss.str("");
		}
		cout << tgt << " " << cnt << endl;
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0,i##_cond=(n);i<i##_cond;++i)
#define pb push_back
using vi  = vector<int>;

vi mp; // a : mp[0], b : mp[1], c : mp[2], d : mp[3]
vector<function<int(int,int)>> ops;

typedef string::const_iterator State;
int letter(State &begin){
  int res = mp[*begin - 'a'];
  ++begin;
  return res;
}
int hashf(State &begin){
  if(*begin == '['){
    ++begin; // '['
    
    int optype;
    if(*begin == '+') optype = 0;
    else if(*begin == '*') optype = 1;
    else if(*begin == '^') optype = 2;
    else assert(false);
    ++begin; // operator
    
    int lop = hashf(begin), rop = hashf(begin);

    ++begin; // ']' 
    
    return ops[optype](lop,rop);
  }else{
    return letter(begin);
  }
}

int main(){
  string s;
  mp.resize(4);
  ops.push_back([](int a, int b){ return a|b; });
  ops.push_back([](int a, int b){ return a&b; });
  ops.push_back([](int a, int b){ return a^b; });
  while(cin >> s, s != "."){
    string p; cin >> p;
    rep(i,4) mp[i] = p[i] - '0';
    State begin = s.begin();
    int ans = hashf(begin);
    int cnt = 0;
    rep(a,10) rep(b,10) rep(c,10) rep(d,10){
      mp[0] = a; mp[1] = b; mp[2] = c; mp[3] = d;
      begin = s.begin();
      if(ans == hashf(begin)) cnt++;
    }
    cout << ans << " " << cnt << endl;
  }
}