sortowanie

 avatar
unknown
python
4 years ago
4.4 kB
5
Indexable
def sort(filename):
    if filename not in os.listdir('.'):
        print(f'[ERROR] Can\'t find {filename}!')
        return None

    curr_dest = 'dest'
    while True:
        if curr_dest == 'dest':
            source_read = open(filename, 'rb')
            dest_file = 'temp_dest.bin'
        else:
            source_read = open('temp_dest.bin', 'rb')
            dest_file = filename

        left = True
        # divide to tapes
        while pack_records := source_read.read(12 * 10):
            records = [bytes_to_record(pack_records[i:i + 12]) for i in range(0, len(pack_records), 12)]

            left_container = records[0].to_list()
            right_container = []

            for i in range(1, len(records)):
                if records[i].value() < records[i - 1].value():
                    left = not left

                if left:
                    left_container = left_container + records[i].to_list()
                else:
                    right_container = right_container + records[i].to_list()

            # save to tapes
            with open('left_tape.bin', 'wb') as f:
                array('i', left_container).tofile(f)
            with open('right_tape.bin', 'wb') as f:
                array('i', right_container).tofile(f)

        # merge
        open(dest_file, 'w').close()

        dest_records = []
        with open('left_tape.bin', 'rb') as left_tape:
            with open('right_tape.bin', 'rb') as right_tape:
                with open(dest_file, 'ab') as dest:
                    left_container = left_tape.read(12 * 5)
                    right_container = right_tape.read(12 * 5)
                    left_records = [bytes_to_record(left_container[i:i + 12]) for i in range(0, len(left_container), 12)]
                    right_records = [bytes_to_record(right_container[i:i + 12]) for i in range(0, len(right_container), 12)]
                    left_i = 0
                    right_i = 0
                    while True:
                        if left_i != 0 and left_i == len(left_records):
                            left_container = left_tape.read(12 * 5)
                            left_records = [bytes_to_record(left_container[i:i + 12]) for i in
                                            range(0, len(left_container), 12)]
                            left_i = 0
                        if right_i != 0 and right_i == len(right_records):
                            right_container = right_tape.read(12 * 5)
                            right_records = [bytes_to_record(right_container[i:i + 12]) for i in
                                             range(0, len(right_container), 12)]
                            right_i = 0

                        if len(left_records) + len(right_records) == 0:
                            array('i', dest_records).tofile(dest)
                            break

                        if len(right_records) == 0:
                            dest_records = dest_records + left_records[left_i].to_list()
                            left_i += 1
                        elif len(left_records) == 0:
                            dest_records = dest_records + right_records[right_i].to_list()
                            right_i += 1
                        elif left_records[left_i].value() <= right_records[right_i].value():
                            dest_records = dest_records + left_records[left_i].to_list()
                            left_i += 1
                        elif right_records[right_i].value() < left_records[left_i].value():
                            dest_records = dest_records + right_records[right_i].to_list()
                            right_i += 1

                        if len(dest_records) == 3 * 10:  # 10 records - 30 numbers
                            array('i', dest_records).tofile(dest)
                            dest_records = []

        with open(dest_file, 'rb') as f:
            dest_records = f.read()

        dest_records = [bytes_to_record(dest_records[i:i + 12]) for i in range(0, len(dest_records), 12)]
        if all(dest_records[i].value() <= dest_records[i + 1].value() for i in range(len(dest_records) - 1)):
            if curr_dest == 'source':
                break

        if curr_dest == 'dest':
            curr_dest = 'source'
        else:
            curr_dest = 'dest'
Editor is loading...