Commit 809c4323 authored by kazushi.kawamura's avatar kazushi.kawamura
Browse files

upload solver

parents
Loading
Loading
Loading
Loading

README.md

0 → 100644
+0 −0

Empty file added.

solver_soft/Makefile

0 → 100755
+14 −0
Changes for solver_soft/Makefile: 14 added lines, 0 removed lines.
Original line number Diff line number Diff line
TARGET = sim
OBJS = $(CPPS:.cpp=.o)
CPPS = $(wildcard *.cpp)
CXX = g++
CXXFLAGS = -O3

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CXX) -o $@ $(OBJS)

clean:
	rm *.o
	rm $(TARGET)

solver_soft/io.cpp

0 → 100644
+281 −0
Changes for solver_soft/io.cpp: 281 added lines, 0 removed lines.
Original line number Diff line number Diff line
#include "io.hpp"

void read_problem(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]) {
	
	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(cin,line)) break; // stdin
		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 ///
}

solver_soft/io.hpp

0 → 100644
+16 −0
Changes for solver_soft/io.hpp: 16 added lines, 0 removed lines.
Original line number Diff line number Diff line
#ifndef __IO_HPP__
#define __IO_HPP__

#include <iostream>
#include <sstream>   // for istringstream
#include <algorithm> // for replace

#include "param.hpp"

using namespace std;

void read_problem(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]);
void extract_line_info(short int line_num, short int blocks, short int block_info[][5][3], short int line_info[][2][5]);


#endif /* __IO_HPP__ */
 No newline at end of file

solver_soft/main.cpp

0 → 100644
+95 −0
Changes for solver_soft/main.cpp: 95 added lines, 0 removed lines.
Original line number Diff line number Diff line
#include <iostream>
#include <getopt.h>

#include "param.hpp"
#include "io.hpp"
#include "solver.hpp"
#include "tools.hpp"

using namespace std;

int main(int argc, char *argv[]) {
	
	char *out_filename = NULL;
	uint32_t seed_v = 214;
	
	// Get options
	struct option longopts[] = {
		{"output", required_argument, NULL, 'o'},
		{"seed", required_argument, NULL, 's'},
		{0, 0, 0, 0}
	};
	int opt, optidx;
	while((opt = getopt_long(argc, argv, "o:s:", longopts, &optidx)) != -1) {
		switch(opt) {
		case 'o':
			out_filename = optarg;
			break;
		case 's':
			sscanf(optarg, "%u", &seed_v);
			break;
		default:
			usage();
		}
	}
	
	// Init seed value
	uint32_t seed[3];
	srand(seed_v);
	seed[0] = rand();
	seed[1] = rand();
	seed[2] = rand();
	
	// W: Max width of a board (specified in a problem file)
	// H: Max height of a board (specified in a problem file)
	// blocks: # of blocks (specified in a problem file)
	short int W, H, blocks, line_num;
	// W_ext: Width of a current solution
	// H_ext: Height of a current solution
	short int W_ext, H_ext;
	
	// block data
	short int block_info[MAX_BLOCKS+1][5][3];
	
	// line data
	short int line_info[MAX_LINES+1][2][5];
	
	// An opt. result will be stored in the array
	short int opt_result[MAX_CELLS];
	
	// Check problem
	read_problem(&W, &H, &blocks, &line_num, block_info, line_info);
	extract_line_info(line_num, blocks, block_info, line_info);
	
	// Solver body
	int status = solver(seed, W, H, blocks, line_num, block_info, line_info, &W_ext, &H_ext, opt_result);
	
	// Check answer
	if(status == 0) {
		cout << "Fail re-routing" << endl;
	}
	else {
		cout << "== Answer ==" << endl;
		cout << "SIZE " << W_ext << "X" << H_ext << endl;
		pair<short int,short int> block_place_basis[MAX_BLOCKS+1];
		for(int i = 1; i <= blocks; i++) {
			block_place_basis[i] = make_pair(block_info[i][0][0], block_info[i][0][1]);
		}
		show_result(line_num, blocks, W_ext, H_ext, opt_result, block_place_basis);
	}
	if(W_ext > W || H_ext > H) {
		cout << "Fail satisfying constraint" << endl;
	}
	else {
		cout << "Satisfy constraint ^_^" << endl;
		if(out_filename == NULL) return 0;
		cout << "Output to " << out_filename << endl;
		pair<short int,short int> block_place_basis[MAX_BLOCKS+1];
		for(int i = 1; i <= blocks; i++) {
			block_place_basis[i] = make_pair(block_info[i][0][0], block_info[i][0][1]);
		}
		output_to_file(out_filename, line_num, blocks, W_ext, H_ext, opt_result, block_place_basis);
	}
	
	return 0;
}
Loading