192 lines
5.9 KiB
Python
192 lines
5.9 KiB
Python
import unittest
|
|
from random import randint
|
|
from typing import List, Optional, Tuple, Iterable
|
|
|
|
REC_CHANNEL_COUNT = 12
|
|
|
|
CHANNEL_INS2MUX = (10, 0, 1, 2, 3, 8, 7, 6, 5, 4, 9, 8)
|
|
'''index:ins -> value:mux'''
|
|
|
|
CHANNEL_MUX2INS = (1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 0, 11)
|
|
'''index:mux -> value:ins'''
|
|
|
|
|
|
def to_channel_table(*channel: int) -> List[bool]:
|
|
return [i in channel for i in range(REC_CHANNEL_COUNT)]
|
|
|
|
|
|
def to_mux_channel(channel: Iterable[int], sort=False) -> List[int]:
|
|
ret = [CHANNEL_INS2MUX[ch] for ch in channel]
|
|
|
|
if sort:
|
|
ret.sort()
|
|
|
|
return ret
|
|
|
|
|
|
def to_ins_channel(channel: Iterable[int], sort=False) -> List[int]:
|
|
ret = [CHANNEL_MUX2INS[ch] for ch in channel]
|
|
|
|
if sort:
|
|
ret.sort()
|
|
|
|
return ret
|
|
|
|
|
|
def to_mux_channel_table(*channel: int) -> List[bool]:
|
|
return [CHANNEL_MUX2INS[i] in channel for i in range(REC_CHANNEL_COUNT)]
|
|
|
|
|
|
def to_ins_channel_table(*channel: int) -> List[bool]:
|
|
return [CHANNEL_INS2MUX[i] in channel for i in range(REC_CHANNEL_COUNT)]
|
|
|
|
|
|
def rearrange_channel_mux_table(channel_table: List[bool]) -> Tuple[int, 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 0, None
|
|
|
|
channel_mux = [0 for _ in range(REC_CHANNEL_COUNT)]
|
|
|
|
if enable_channel_number == 1:
|
|
channel_mux[0] = last_enable_channel
|
|
|
|
return 1, 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 last_enable_channel + 1, channel_mux
|
|
|
|
|
|
def count_used_channel(channel_mux: List[int]):
|
|
ret = [0] * REC_CHANNEL_COUNT
|
|
|
|
for ch in channel_mux:
|
|
ret[ch] += 1
|
|
|
|
return ret
|
|
|
|
|
|
def expect_channel_count(*channel: int) -> List[int]:
|
|
channel_mux = to_mux_channel_table(*channel)
|
|
used, mux_arrange = rearrange_channel_mux_table(channel_mux)
|
|
if used == 0:
|
|
ins_arrange = to_ins_channel([])
|
|
else:
|
|
ins_arrange = to_ins_channel(mux_arrange[:used], sort=False)
|
|
return count_used_channel(ins_arrange)
|
|
|
|
|
|
def loop_repeat(col: List[int]) -> Iterable[int]:
|
|
while True:
|
|
yield from iter(col)
|
|
|
|
|
|
def channel_count(*channel: int) -> List[int]:
|
|
if len(channel) == 0:
|
|
return [0] * REC_CHANNEL_COUNT
|
|
|
|
elif len(channel) == 1:
|
|
channel = channel[0]
|
|
return [1 if ch == channel else 0 for ch in range(REC_CHANNEL_COUNT)]
|
|
|
|
else:
|
|
channel_mux = to_mux_channel(channel, sort=True)
|
|
ret = [0] * REC_CHANNEL_COUNT
|
|
i = max(channel_mux) + 1
|
|
|
|
for ch in loop_repeat(channel_mux[::-1]):
|
|
ret[CHANNEL_MUX2INS[ch]] += 1
|
|
i -= 1
|
|
if i == 0:
|
|
break
|
|
|
|
return ret
|
|
|
|
|
|
class UniRearrangeMuxChannelTest(unittest.TestCase):
|
|
def test_empty_channel(self):
|
|
i, a = rearrange_channel_mux_table(to_channel_table())
|
|
self.assertEqual(0, i)
|
|
self.assertIsNone(a)
|
|
|
|
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)]
|
|
self.assertTupleEqual((1, expect), rearrange_channel_mux_table(to_channel_table(c)))
|
|
|
|
def test_two_channel(self):
|
|
self.assertTupleEqual((8, [1, 7, 1, 7, 1, 7, 1, 7, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(7, 1)))
|
|
self.assertTupleEqual((3, [2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(2, 1)))
|
|
self.assertTupleEqual((8, [3, 7, 2, 3, 7, 2, 3, 7, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(7, 3, 2)))
|
|
|
|
def test_many_channel(self):
|
|
self.assertTupleEqual((2, [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(1, 0)))
|
|
|
|
self.assertTupleEqual((6, [2, 5, 2, 5, 2, 5, 0, 0, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(2, 5)))
|
|
|
|
self.assertTupleEqual((6, [1, 3, 5, 1, 3, 5, 0, 0, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(1, 3, 5)))
|
|
|
|
self.assertTupleEqual((6, [4, 5, 1, 3, 4, 5, 0, 0, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(4, 1, 3, 5)))
|
|
|
|
self.assertTupleEqual((6, [5, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(4, 1, 2, 3, 5)))
|
|
|
|
self.assertTupleEqual((9, [6, 7, 8, 3, 4, 5, 6, 7, 8, 0, 0, 0]),
|
|
rearrange_channel_mux_table(to_channel_table(3, 4, 5, 6, 7, 8)))
|
|
|
|
def test_count_channel(self):
|
|
self.assertEqual(expect_channel_count(), channel_count())
|
|
self.assertEqual(expect_channel_count(0), channel_count(0))
|
|
self.assertEqual(expect_channel_count(4), channel_count(4))
|
|
self.assertEqual(expect_channel_count(2, 4), channel_count(4, 2))
|
|
self.assertEqual(expect_channel_count(7, 3, 2), channel_count(7, 3, 2))
|
|
self.assertEqual(expect_channel_count(0, 1, 2), channel_count(0, 1, 2))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|