#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MOV 0
#define ADD 4
#define SUB 5
static char* delimiter = " \t:=+-";
static char* terminator = "END";
struct token_list_node
{
char name[21];
int id;
token_list_node* next;
};
struct ins_list_node
{
int operand_id;
int operator_id;
};
token_list_node token_list_header;
ins_list_node ins_stream[2][101];
int token_list_size, ins_count[2];
char line_buffer[256];
double value[101][101][14];
double probability[101][101];
int cas;
// if the specified token has already existed in the token list,
// just return the id of the token which identified the token uniquely.
// if not, insert a new node to the ascendingly sorted token list and return its
// id.
int find_token(char* token)
{
token_list_node *last, *node, *temp;
int cmp_result = -1;
last = &token_list_header;
node = token_list_header.next;
while(node)
{
cmp_result = strcmp(node->name, token);
if(cmp_result == 0)
return node->id;
else if(cmp_result > 0)
break;
last = node;
node = node->next;
}
temp = (token_list_node*)malloc(sizeof(token_list_node));
strcpy(temp->name, token);
temp->next = node;
temp->id = token_list_size++;
last->next = temp;
return temp->id;
}
// free the token list
void destroy_token_list()
{
token_list_node* temp;
while(token_list_header.next)
{
temp = token_list_header.next;
token_list_header.next = temp->next;
free(temp);
}
token_list_size = 0;
}
// get the next token from the given line
// return values:
// = 0 -- a token terminated by 0 has been copied to the region pointed by buffer
// > 0 -- return value is a constant
int next_token(char* line, char* buffer)
{
int value = 0;
char* token = strtok(line, delimiter);
if(token != NULL)
{
if(*token >= '0' && *token <= '9')
{
while(*token)
value = value * 10 + *(token++) - '0';
return value;
}
else
{
do
{
if(*token >= 'A' && *token <= 'Z')
*(buffer++) = *(token++) - 'A' + 'a';
else
*(buffer++) = *(token++);
}
while(*token);
*buffer = 0;
}
}
return 0;
}
// get the operator type of either '+' or '-' of a line
// zero will be returned if not found.
int get_operator(char* line)
{
while(*line && *line != '+' && *line != '-')
line++;
if(*line == '+')
return ADD;
else if(*line == '-')
return SUB;
else
return 0;
}
// parse a line and store the result into instruction streams
int parse_line(char* line, int start_index, int program_id)
{
static int i, token_index[4];
static char token_name[21];
ins_stream[program_id][start_index + 2].operator_id = get_operator(line);
next_token(line, token_name);
token_index[0] = find_token(token_name);
ins_stream[program_id][start_index].operator_id = 0;
for(i = 1; i < 4; ++i)
{
if(token_index[i] = next_token(NULL, token_name))
token_index[i] += 100; // the constant itself will increase by 100, then the value is used as its 'id'
else
token_index[i] = find_token(token_name);
if(i != 2)
ins_stream[program_id][start_index + i].operator_id = i;
}
ins_stream[program_id][start_index + 0].operand_id = token_index[1];
ins_stream[program_id][start_index + 1].operand_id = token_index[2];
ins_stream[program_id][start_index + 3].operand_id = token_index[0];
return start_index + 4;
}
// execute an instruction and store the result in dest_var_list
void execute_ins(int program_id, ins_list_node* ins, double* dest_var_list, double* orig_var_list)
{
// THIS PART HAS BEEN HIDDEN !!!
}
// solve the problem with DP method
void dynamic_programming()
{
int i, j, k;
double var_list[2][14], p1;
// compute the probabilities
probability[0][0] = 1.0;
for(i = 1; i <= ins_count[0]; ++i)
probability[i][0] = probability[i - 1][0] * 0.5;
for(j = 1; j <= ins_count[1]; ++j)
probability[0][j] = probability[0][j - 1] * 0.5;
for(i = 1; i <= ins_count[0]; ++i)
{
for(j = 1; j <= ins_count[1]; ++j)
{
if(i == ins_count[0])
probability[i][j] = probability[i - 1][j] * 0.5 + probability[i][j - 1];
else if(j == ins_count[1])
probability[i][j] = probability[i - 1][j] + probability[i][j - 1] * 0.5;
else
probability[i][j] = (probability[i - 1][j] + probability[i][j - 1]) * 0.5;
}
}
probability[ins_count[0]][ins_count[1]] = 1.0;
// compute variable values
memset(value[0][0], 0, sizeof(double) * 14);
for(i = 1; i <= ins_count[0]; ++i)
execute_ins(0, &ins_stream[0][i], value[i][0], value[i - 1][0]);
for(j = 1; j <= ins_count[1]; ++j)
execute_ins(1, &ins_stream[1][j], value[0][j], value[0][j - 1]);
for(i = 1; i <= ins_count[0]; ++i)
{
for(j = 1; j <= ins_count[1]; ++j)
{
execute_ins(0, &ins_stream[0][i], var_list[0], value[i - 1][j]);
execute_ins(1, &ins_stream[1][j], var_list[1], value[i][j - 1]);
if(i == ins_count[0])
p1 = probability[i][j - 1] / probability[i][j];
else
p1 = probability[i][j - 1] * 0.5 / probability[i][j];
for(k = 0; k < token_list_size; ++k)
value[i][j][k] = var_list[0][k] * (1.0 - p1) + var_list[1][k] * p1;
value[i][j][10] = var_list[0][10] * (1.0 - p1) + var_list[1][10] * p1;
value[i][j][11] = var_list[0][11] * (1.0 - p1) + var_list[1][11] * p1;
value[i][j][12] = var_list[0][12] * (1.0 - p1) + var_list[1][12] * p1;
value[i][j][13] = var_list[0][13] * (1.0 - p1) + var_list[1][13] * p1;
}
}
}
// output our result
void output_result()
{
int i, j, k;
token_list_node* node = token_list_header.next;
for(; node;)
{
printf("%.4lf\n", value[ins_count[0]][ins_count[1]][node->id]);
node = node->next;
}
if(cas > 0)
printf("\n");
}
int main()
{
scanf("%d", &cas);
while(cas--)
{
// absurb the blank line
gets(line_buffer);
// parse the first program
ins_count[0] = 1;
while(gets(line_buffer) && strcmp(line_buffer, terminator))
ins_count[0] = parse_line(line_buffer, ins_count[0], 0);
// parse the second program
ins_count[1] = 1;
while(gets(line_buffer) && strcmp(line_buffer, terminator))
ins_count[1] = parse_line(line_buffer, ins_count[1], 1);
ins_count[0]--;
ins_count[1]--;
// solve the problem with DP method
dynamic_programming();
// output the result
output_result();
// free the token list
destroy_token_list();
}
return 0;
}