merge_solver.py 2.61 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
import re

from roles import Solver

class MergeSolver(Solver):

    def __init__(self, config):
        super().__init__(config)

        self.type = 'merge_solver'
        self.partial_mode = False

    def __repr__(self):
        return "MergeSolver"

    def start_solver(self, params):

        if 'merge_problem' in params:
            return super().start_solver(params)
        else:
            return {'status': 'N/A'}

    def submit_solution(self, params, solution):

        if solution['status'] == 'done':
            _lines = solution['solution'].splitlines()

            parts_pos = list()

            for _l in _lines:
                l = _l.strip()
                if l.startswith('SIZE'):
                    board_size_str = l.strip().split()[1]
                    board_solution_size = [int(v) for v in board_size_str.split('X')]
                    bw = board_solution_size[0]
                    bh = board_solution_size[1]
                elif l.startswith('BLOCK'):
                    print(l)
                    p = r'BLOCK#([0-9]+) +@\(([0-9]+), *([0-9]+)\)'
                    m = re.match(p, l)
                    bi = int(m.group(1))
                    bx = int(m.group(2))
                    by = int(m.group(3))
                    parts_pos.append((bx, by))
            
            _map = list()
            _blocks = dict()
            for _y in range(bh):
                _map.append([0 for _x in range(bw)])

            for (px, py), part in zip(parts_pos, params['parts']):
                for _y, _r in enumerate(part['remap']):
                    for _x, _c in enumerate(_r):
                        if _c != 0:
                            _map[py+_y][px+_x] = _c
            
            for (px, py), part in zip(parts_pos, params['parts']):
                for bi, (_bx, _by) in part['remap_block'].items():
                    _blocks[bi] = (px+_bx, py+_by)
            
            _sorted_blocks = sorted(_blocks.items(), key=lambda x:x[0])

            solution_text = ''
            solution_text += f'SIZE {bw}X{bh}\n'
            for _r in _map:
                solution_text += ','.join([str(v) for v in _r])
                solution_text += '\n'
            for bi, (_bx, _by) in _sorted_blocks:
                solution_text += f'BLOCK#{bi} @({_bx},{_by})\n'

            solution['solution'] = solution_text

        data = {
            'request_id': params['request_id'],
            'problem': params['name'],
            'worker': self.address
        }
        data.update(solution)
        self.post('problem/solution', data)