#include "io.hpp" void read_problem(const char *f_name, short int *W, short int *H, short int *blocks, short int *line_num, short int block_info[][5][3], short int line_info[][2][5]) { ifstream inputfile(f_name); if(!inputfile) { cout << f_name << ": Cannot open" << endl; exit(1); } for(int i = 0; i < MAX_BLOCKS+1; i++) { for(int j = 0; j < 5; j++) { for(int k = 0; k < 3; k++) { block_info[i][j][k] = -1; } } } for(int i = 0; i < MAX_LINES+1; i++) { for(int j = 0; j < 2; j++) { for(int k = 0; k < 5; k++) { line_info[i][j][k] = -1; } } } *line_num = 0; int now_block = 0, count; short int size_x = -1, size_y = -1, now_x, now_y, num; while(1) { string line, tmp; string::size_type pos; if(!getline(inputfile, line)) break; if(line.find("\n") != string::npos || line.find("\r") != string::npos) { line.replace(line.length()-1, 1, ""); // Remove '\n' or '\r' } int len = line.length(); if(len == 0) continue; if(line.find("SIZE") != string::npos) { replace(line.begin(), line.end(), 'X', ' '); istringstream iss(line); iss >> tmp >> *W >> *H; continue; } else if(line.find("BLOCK_NUM") != string::npos) { istringstream iss(line); iss >> tmp >> *blocks; continue; } else if(line.find("BLOCK") != string::npos) { now_block++; replace(line.begin(), line.end(), 'X', ' '); istringstream iss(line); iss >> tmp >> size_x >> size_y; now_y = 0; count = 1; block_info[now_block][0][0] = size_x; block_info[now_block][0][1] = size_y; continue; } // Replace ' ' -> "" pos = 0; while((pos = line.find(' ', pos)) != string::npos) { line.replace(pos, 1, ""); } // Replace '+' -> "-1" pos = 0; while((pos = line.find('+', pos)) != string::npos) { line.replace(pos, 1, "-1"); } // Replace ',' -> " " pos = 0; while((pos = line.find(',', pos)) != string::npos) { line.replace(pos, 1, " "); } istringstream iss(line); for(now_x = 0; now_x < size_x; now_x++) { iss >> num; if(num > 0) { block_info[now_block][count][0] = now_x; block_info[now_block][count][1] = now_y; block_info[now_block][count][2] = num; if(line_info[num][0][0] == -1) { line_info[num][0][0] = now_block; } else if(line_info[num][1][0] == -1) { line_info[num][1][0] = now_block; } else { cout << "Error(RE0): Line#" << num << endl; exit(1); } if(num > *line_num) { *line_num = num; } count++; } else if(num < 0) { block_info[now_block][count][0] = now_x; block_info[now_block][count][1] = now_y; block_info[now_block][count][2] = 0; count++; } } now_y++; } cout << "W: " << *W << ", H: " << *H << endl; /// Print block information /// cout << "== Block information ==" << endl; cout << "#Blocks = " << *blocks << endl; for(int i = 1; i <= *blocks; i++) { short int sx = block_info[i][0][0]; short int sy = block_info[i][0][1]; cout << "Block#" << i << ": (" << sx << ", " << sy << ")" << endl; if(sx == 1 && sy == 1) { // monomino short int tx = block_info[i][1][0]; short int ty = block_info[i][1][1]; short int tn = block_info[i][1][2]; cout << "- (" << tx << ", " << ty << ") " << tn << endl; } else { for(int it = 1; it < 5; it++) { short int tx = block_info[i][it][0]; short int ty = block_info[i][it][1]; short int tn = block_info[i][it][2]; cout << "- (" << tx << ", " << ty << ") " << tn << endl; } } } /// Print block information /// } void extract_line_info(short int line_num, short int blocks, short int block_info[][5][3], short int line_info[][2][5]) { short int lines_x[4], lines_y[4]; // # of nums in a block for X- & Y- axes for(int i = 1; i <= blocks; i++) { short int sx = block_info[i][0][0]; short int sy = block_info[i][0][1]; if(sx == 1 && sy == 1) { // monomino //short int tx = block_info[i][1][0]; //short int ty = block_info[i][1][1]; short int tn = block_info[i][1][2]; if(tn == 0) continue; short int n_idx = 0; while(line_info[tn][n_idx][1] != -1) { n_idx++; if(n_idx >= 2) { cout << "Error(EL0): Line#" << tn << endl; exit(1); } } line_info[tn][n_idx][LE] = 2; line_info[tn][n_idx][TO] = 2; line_info[tn][n_idx][RI] = 2; line_info[tn][n_idx][BO] = 2; continue; } for(short int p = 0; p < 4; p++) lines_x[p] = 0; for(short int q = 0; q < 4; q++) lines_y[q] = 0; for(int it = 1; it < 5; it++) { short int tx = block_info[i][it][0]; short int ty = block_info[i][it][1]; short int tn = block_info[i][it][2]; if(tn > 0) { lines_x[tx] += 1; lines_y[ty] += 1; } } for(int it = 1; it < 5; it++) { short int tx = block_info[i][it][0]; short int ty = block_info[i][it][1]; short int tn = block_info[i][it][2]; if(tn == 0) continue; short int n_idx = 0; while(line_info[tn][n_idx][1] != -1) { n_idx++; if(n_idx >= 2) { cout << "Error(EL1): Line#" << tn << endl; exit(1); } } short int compe_cost, wall_cost; // Map to left compe_cost = 2; compe_cost += lines_x[tx] - 1; for(short int p = tx - 1; p >= 0; p--) { compe_cost += lines_x[p] * 2; } wall_cost = 1; for(int it2 = 1; it2 < 5; it2++) { short int cx = block_info[i][it2][0]; short int cy = block_info[i][it2][1]; if(cx == tx && cy == ty) continue; if(cy == ty && cx < tx) { if(sx == 2 && sy == 3 && ty == 1) { wall_cost = 4; } else { wall_cost = 2; } } } line_info[tn][n_idx][LE] = compe_cost * wall_cost; // Map to top compe_cost = 2; compe_cost += lines_y[ty] - 1; for(short int q = ty - 1; q >= 0; q--) { compe_cost += lines_y[q] * 2; } wall_cost = 1; for(int it2 = 1; it2 < 5; it2++) { short int cx = block_info[i][it2][0]; short int cy = block_info[i][it2][1]; if(cx == tx && cy == ty) continue; if(cx == tx && cy < ty) { if(sx == 3 && sy == 2 && tx == 1) { wall_cost = 4; } else { wall_cost = 2; } } } line_info[tn][n_idx][TO] = compe_cost * wall_cost; // Map to right compe_cost = 2; compe_cost += lines_x[tx] - 1; for(short int p = tx + 1; p < sx; p++) { compe_cost += lines_x[p] * 2; } wall_cost = 1; for(int it2 = 1; it2 < 5; it2++) { short int cx = block_info[i][it2][0]; short int cy = block_info[i][it2][1]; if(cx == tx && cy == ty) continue; if(cy == ty && cx > tx) { if(sx == 2 && sy == 3 && ty == 1) { wall_cost = 4; } else { wall_cost = 2; } } } line_info[tn][n_idx][RI] = compe_cost * wall_cost; // Map to bottom compe_cost = 2; compe_cost += lines_y[ty] - 1; for(short int q = ty + 1; q < sy; q++) { compe_cost += lines_y[q] * 2; } wall_cost = 1; for(int it2 = 1; it2 < 5; it2++) { short int cx = block_info[i][it2][0]; short int cy = block_info[i][it2][1]; if(cx == tx && cy == ty) continue; if(cx == tx && cy > ty) { if(sx == 3 && sy == 2 && tx == 1) { wall_cost = 4; } else { wall_cost = 2; } } } line_info[tn][n_idx][BO] = compe_cost * wall_cost; } } /// Print line information /// cout << "== Line information ==" << endl; cout << "#Lines = " << line_num << endl; for(int l = 1; l <= line_num; l++) { short int block1 = line_info[l][0][0]; short int block2 = line_info[l][1][0]; cout << "Line#" << l << ": "; cout << "Block#" << block1 << "("; for(int i = 1; i < 5; i++) { cout << (float)line_info[l][0][i] / 2; if(i != 4) { cout << ", "; } } cout << "), "; cout << "Block#" << block2 << "("; for(int i = 1; i < 5; i++) { cout << (float)line_info[l][1][i] / 2; if(i != 4) { cout << ", "; } } cout << ")" << endl; } /// Print line information /// }