import itertools


def map2string(tag, groupop, mapping):
    """
    Takes in a map: tag, groupop, mapping and constructs a string representation
    to be dumped to a file. If we want to call using the tuple, ``map2string(*(map))`` will suffice.

    :param tag: string of initial state to rotate
    :param groupop: see crystal.GroupOp; we use the rot and trans. This is in the supercell coord.
    :param mapping: in "chemorder" format; list by chemistry of lists of indices of position
        in initial cell to use.
    :return string_rep: string representation (to be used by an external script)
    """
    string_rep = tag + """
{rot[0][0]:3d} {rot[0][1]:3d} {rot[0][2]:3d}
{rot[1][0]:3d} {rot[1][1]:3d} {rot[1][2]:3d}
{rot[2][0]:3d} {rot[2][1]:3d} {rot[2][2]:3d}
{trans[0]:.16f} {trans[1]:.16f} {trans[2]:.16f}
""".format(rot=groupop.rot, trans=groupop.trans)
    # the index shift needs to be added for each subsequent chemistry
    indexshift = [0] + list(itertools.accumulate(len(remap) for remap in mapping))
    string_rep += ' '.join(['{}'.format(m + shift)
                            for remap, shift in zip(mapping, indexshift)
                            for m in remap])
    # needs a trailing newline
    return string_rep + '\n'