

from __future__ import annotations

from collections import deque





class 				__lowerCAmelCase  :




  def __init__(       self							,     lowerCAmelCase      )						->				Optional[int]:
      '''simple docstring'''






      _lowercase			 =[]
      self.adlist.append(
          {'value': '', 'next_states': [], 'fail_state': 0, 'output': []}      )

      for keyword in keywords:
          self.add_keyword(lowerCAmelCase      )
      self.set_fail_transitions()




  def 						A__  (       self							,     lowerCAmelCase							,     lowerCAmelCase      )						->				int | None:
      '''simple docstring'''






      for state in self.adlist[current_state]["next_states"]:
          if char == self.adlist[state]["value"]:
              return state
      return None




  def 						A__  (       self							,     lowerCAmelCase      )						->				None:
      '''simple docstring'''






      _lowercase			 =0
      for character in keyword:
          _lowercase			 =self.find_next_state(lowerCAmelCase							,     lowerCAmelCase      )
          if next_state is None:
              self.adlist.append(
                  {
                      'value': character,
                      'next_states': [],
                      'fail_state': 0,
                      'output': [],
                  }      )
              self.adlist[current_state]["next_states"].append(len(self.adlist      ) - 1      )
              _lowercase			 =len(self.adlist      ) - 1
          else:
              _lowercase			 =next_state
      self.adlist[current_state]["output"].append(lowerCAmelCase      )




  def 						A__  (       self      )						->				None:
      '''simple docstring'''






      _lowercase			 =deque()
      for node in self.adlist[0]["next_states"]:
          q.append(lowerCAmelCase      )
          _lowercase			 =0
      while q:
          _lowercase			 =q.popleft()
          for child in self.adlist[r]["next_states"]:
              q.append(lowerCAmelCase      )
              _lowercase			 =self.adlist[r]['fail_state']
              while (
                  self.find_next_state(lowerCAmelCase							,     self.adlist[child]['value']      ) is None
                  and state != 0
              ):
                  _lowercase			 =self.adlist[state]['fail_state']
              _lowercase			 =self.find_next_state(
                  lowerCAmelCase							,     self.adlist[child]['value']      )
              if self.adlist[child]["fail_state"] is None:
                  _lowercase			 =0
              _lowercase			 =(
                  self.adlist[child]['output']
                  + self.adlist[self.adlist[child]['fail_state']]['output']
              )




  def 						A__  (       self							,     lowerCAmelCase      )						->				dict[str, list[int]]:
      '''simple docstring'''






      _lowercase			 ={}  # returns a dict with keywords and list of its occurrences
      _lowercase			 =0
      for i in range(len(lowerCAmelCase      )      ):
          while (
              self.find_next_state(lowerCAmelCase							,     string[i]      ) is None
              and current_state != 0
          ):
              _lowercase			 =self.adlist[current_state]['fail_state']
          _lowercase			 =self.find_next_state(lowerCAmelCase							,     string[i]      )
          if next_state is None:
              _lowercase			 =0
          else:
              _lowercase			 =next_state
              for key in self.adlist[current_state]["output"]:
                  if key not in result:
                      _lowercase			 =[]
                  result[key].append(i - len(lowerCAmelCase      ) + 1      )
      return result


if __name__ == "__main__":
  import doctest

  doctest.testmod()





import unittest

from knapsack import knapsack as k





class 				__lowerCAmelCase  (      unittest.TestCase							):




  def 						A__  (       self      )						->				List[str]:
        '''simple docstring'''






        _lowercase			 =0
        _lowercase			 =[0]
        _lowercase			 =[0]
        _lowercase			 =len(lowerCAmelCase      )
        self.assertEqual(k.knapsack(lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase      )							,     0      )

        _lowercase			 =[60]
        _lowercase			 =[10]
        _lowercase			 =len(lowerCAmelCase      )
        self.assertEqual(k.knapsack(lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase      )							,     0      )




  def 						A__  (       self      )						->				List[Any]:
        '''simple docstring'''






        _lowercase			 =3
        _lowercase			 =[1, 2, 3]
        _lowercase			 =[3, 2, 1]
        _lowercase			 =len(lowerCAmelCase      )
        self.assertEqual(k.knapsack(lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase      )							,     5      )




  def 						A__  (       self      )						->				str:
        '''simple docstring'''






        _lowercase			 =50
        _lowercase			 =[60, 100, 120]
        _lowercase			 =[10, 20, 30]
        _lowercase			 =len(lowerCAmelCase      )
        self.assertEqual(k.knapsack(lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase							,     lowerCAmelCase      )							,     220      )


if __name__ == "__main__":
  unittest.main()


