import unittest from random import randint from typing import List, Optional REC_CHANNEL_COUNT = 16 def to_channel_table(*channel: int) -> List[bool]: return [i in channel for i in range(REC_CHANNEL_COUNT)] def rearrange_channel_mux_table(channel_table: List[bool]) -> Optional[List[int]]: enable_channel_number = 0 last_enable_channel = 0 for i in range(REC_CHANNEL_COUNT): if channel_table[i]: last_enable_channel = i enable_channel_number += 1 if enable_channel_number == 0: return None channel_mux = [0 for _ in range(REC_CHANNEL_COUNT)] if enable_channel_number == 1: channel_mux[0] = last_enable_channel return channel_mux next_enable_channel = last_enable_channel channel_mux_index = last_enable_channel channel_mux[channel_mux_index] = last_enable_channel channel_mux_index -= 1 while channel_mux_index >= 0: i = next_enable_channel - 1 while i >= 0: if channel_table[i]: next_enable_channel = i break i -= 1 if i < 0: break else: channel_mux[channel_mux_index] = next_enable_channel channel_mux_index -= 1 offset = last_enable_channel - channel_mux_index while channel_mux_index >= 0: channel_mux[channel_mux_index] = channel_mux[channel_mux_index + offset] channel_mux_index -= 1 return channel_mux def channel_used_count(channel_mux: List[int]): channel_uc = [0] * 16 channel_sel = [0] * 16 for i in range(15): for j in range(16): if channel_mux[i] == j: if channel_mux[i] != channel_mux[i+1]: channel_uc[j] += 1 channel_sel[j] = j return channel_uc, channel_sel def channel_table_transfer(channel_mux: List[bool]) -> Optional[List[bool]]: channel_look_up_table = [1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 0, 11] true_channel = [False] * 16 for i in range(16): if channel_mux[i]: true_channel[channel_look_up_table[i]] = True return true_channel def channel_table_tran(channel_mux: List[bool]): channel_look_up_table = [2, 3, 4, 5, 10, 9, 8, 7, 6, 11, 1, 12] channel_sel = [0] * 16 channel_index = 0 for i in range(16): if channel_mux[i]: channel_sel[channel_index] = channel_look_up_table[i] channel_index += 1 channel_sel.sort(reverse=True) return channel_sel, channel_index def channel_use_count(channel_sel: List[int], channel_index: int) -> Optional[List[int]]: repeat_times = int(channel_sel[0] / channel_index) remain_value = int(channel_sel[0] % channel_index) ch_use_cnt = [0] * 16 for i in range(channel_index): if i < remain_value: ch_use_cnt[i] = remain_value + repeat_times else: ch_use_cnt[i] = repeat_times return ch_use_cnt def count_channel_without_re(channel_mux: List[bool]) -> Optional[List[int]]: channel_sel, channel_index = channel_table_tran(channel_mux) ch_use_cnt = channel_use_count(channel_sel, channel_index) for i in range(channel_index): channel_sel[i] -= 1 print(channel_sel) print(ch_use_cnt) return ch_use_cnt def reverse_channel_table(original_ch: List[int]) -> Optional[List[int]]: reverse_look_up_table = [10, 0, 1, 2, 3, 8, 7, 6, 5, 4, 9, 8] reverse_ch = [0] * 16 for i in range(16): if original_ch[i] != 0: reverse_ch[reverse_look_up_table[i]] = original_ch[i] return reverse_ch def count_channel(channel_mux: List[bool]) -> Optional[List[int]]: real_ch = channel_table_transfer(channel_mux) ch_mux = rearrange_channel_mux_table(real_ch) ch_count, ch_sel = channel_used_count(ch_mux) reverse_ch = reverse_channel_table(ch_count) reverse_ch.sort(reverse=True) ch_sel.sort(reverse=True) print(ch_sel) print(reverse_ch) return reverse_ch class UniRearrangeMuxChannelTest(unittest.TestCase): def test_empty_channel(self): self.assertIsNone(rearrange_channel_mux_table(to_channel_table())) def test_single_channel(self): for _ in range(3): c = randint(0, REC_CHANNEL_COUNT - 1) expect = [c if i == 0 else 0 for i in range(REC_CHANNEL_COUNT)] print(expect) self.assertEqual(expect, rearrange_channel_mux_table(to_channel_table(c))) def test_two_channel(self): self.assertEqual([1, 7, 1, 7, 1, 7, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0], rearrange_channel_mux_table(to_channel_table(7, 1))) self.assertEqual([2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], rearrange_channel_mux_table(to_channel_table(2, 1))) self.assertEqual([3, 7, 2, 3, 7, 2, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0], rearrange_channel_mux_table(to_channel_table(7, 3, 2))) def test_many_channel(self): self.assertEqual([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], rearrange_channel_mux_table(to_channel_table(1, 0))) self.assertEqual([2, 5, 2, 5, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], rearrange_channel_mux_table(to_channel_table(2, 5))) self.assertEqual([1, 3, 5, 1, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], rearrange_channel_mux_table(to_channel_table(1, 3, 5))) self.assertEqual([4, 5, 1, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], rearrange_channel_mux_table(to_channel_table(4, 1, 3, 5))) self.assertEqual([5, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], rearrange_channel_mux_table(to_channel_table(4, 1, 2, 3, 5))) self.assertEqual([6, 7, 8, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, ], rearrange_channel_mux_table(to_channel_table(3, 4, 5, 6, 7, 8))) def test_count_channel(self): self.assertEqual(count_channel(to_channel_table(7, 3, 2)), count_channel_without_re(to_channel_table(7, 3, 2))) self.assertEqual(count_channel(to_channel_table(0, 10, 2)), count_channel_without_re(to_channel_table(0, 10, 2))) if __name__ == '__main__': unittest.main()