# Path: tryalgo/next_permutation.py
# def next_permutation(tab):
#     """find the next permutation of tab in the lexicographical order
# 
#     :param tab: table with n elements from an ordered set
#     :modifies: table to next permutation
#     :returns: False if permutation is already lexicographical maximal
#     :complexity: O(n)
#     """
#     n = len(tab)
#     pivot = None                         # find pivot
#     for i in range(n - 1):
#         if tab[i] < tab[i + 1]:
#             pivot = i
#     if pivot is None:                    # tab is already the last perm.
#         return False
#     for i in range(pivot + 1, n):        # find the element to swap
#         if tab[i] > tab[pivot]:
#             swap = i
#     tab[swap], tab[pivot] = tab[pivot], tab[swap]
#     i = pivot + 1
#     j = n - 1                            # invert suffix
#     while i < j:
#         tab[i], tab[j] = tab[j], tab[i]
#         i += 1
#         j -= 1
#     return True
# 
# def solve_word_addition(S):         # returns number of solutions
#     """returns number of solutions"""
#     n = len(S)
#     letters = sorted(list(set(''.join(S))))
#     not_zero = ''                   # letters that cannot be 0
#     for word in S:
#         not_zero += word[0]
#     tab = ['@'] * (10 - len(letters)) + letters  # minimal lex permutation
#     count = 0
#     while True:
#         ass = {tab[i]: i for i in range(10)}  # dict = associative array
#         if tab[0] not in not_zero:
#             difference = -convert(S[n - 1], ass)  # do the addition
#             for word in S[:n - 1]:
#                 difference += convert(word, ass)
#             if difference == 0:                   # does it add up?
#                 count += 1
#         if not next_permutation(tab):
#             break
#     return count


import unittest
from tryalgo.next_permutation import next_permutation, solve_word_addition
# jill-jênn vie et christoph dürr - 2020
# coding=utf8

# pylint: disable=missing-docstring


class TestNextPermutation(unittest.TestCase):

    def test_solve_word_addition(self):
        self.assertEqual(solve_word_addition(["A", "B", "C"]), 32)
        self.assertEqual(solve_word_addition(["A", "B", "A"]), 0)

    def test_next_permutation(self):
        L = [2, 2, 0, 0, 1, 1, 0]
        self.assertEqual(next_permutation(L), True)
        self.assertEqual(L, [2, 2, 0, 1, 0, 0, 1])
        L = [2, 2, 1, 1, 0, 0, 0]
        self.assertEqual(next_permutation(L), False)
        L = [2]

# Path: tryalgo/next_permutation.py
# def next_permutation(tab):
#     """find the next permutation of tab in the lexicographical order
# 
#     :param tab: table with n elements from an ordered set
#     :modifies: table to next permutation
#     :returns: False if permutation is already lexicographical maximal
#     :complexity: O(n)
#     """
#     n = len(tab)
#     pivot = None                         # find pivot
#     for i in range(n - 1):
#         if tab[i] < tab[i + 1]:
#             pivot = i
#     if pivot is None:                    # tab is already the last perm.
#         return False
#     for i in range(pivot + 1, n):        # find the element to swap
#         if tab[i] > tab[pivot]:
#             swap = i
#     tab[swap], tab[pivot] = tab[pivot], tab[swap]
#     i = pivot + 1
#     j = n - 1                            # invert suffix
#     while i < j:
#         tab[i], tab[j] = tab[j], tab[i]
#         i += 1
#         j -= 1
#     return True
# 
# def solve_word_addition(S):         # returns number of solutions
#     """returns number of solutions"""
#     n = len(S)
#     letters = sorted(list(set(''.join(S))))
#     not_zero = ''                   # letters that cannot be 0
#     for word in S:
#         not_zero += word[0]
#     tab = ['@'] * (10 - len(letters)) + letters  # minimal lex permutation
#     count = 0
#     while True:
#         ass = {tab[i]: i for i in range(10)}  # dict = associative array
#         if tab[0] not in not_zero:
#             difference = -convert(S[n - 1], ass)  # do the addition
#             for word in S[:n - 1]:
#                 difference += convert(word, ass)
#             if difference == 0:                   # does it add up?
#                 count += 1
#         if not next_permutation(tab):
#             break
#     return count


# Path: tests/test_next_permutation.py
import unittest
from tryalgo.next_permutation import next_permutation, solve_word_addition

# jill-jênn vie et christoph dürr - 2020
# coding=utf8

# pylint: disable=missing-docstring


class TestNextPermutation(unittest.TestCase):

    def test_solve_word_addition(self):
        self.assertEqual(solve_word_addition(["A", "B", "C"]), 32)
        self.assertEqual(solve_word_addition(["A", "B", "A"]), 0)

    def test_next_permutation(self):
        L = [2, 2, 0, 0, 1, 1, 0]
        self.assertEqual(next_permutation(L), True)
        self.assertEqual(L, [2, 2, 0, 1, 0, 0, 1])
        L = [2, 2, 1, 1, 0, 0, 0]
        self.assertEqual(next_permutation(L), False)
        L = [2]

        self.assertEqual(next_permutation(L), False)