




from __future__ import annotations

import math
from collections import Counter
from string import ascii_lowercase







def 				lowerCAmelCase_	(     snake_case_     ):
      _A			,   _A							:     Tuple			=						analyze_text(snake_case_     )
      _A							:     List[str]			=						list(""" """ + ascii_lowercase     )
      # what is our total sum of probabilities.
      _A							:     Dict			=						sum(single_char_strings.values()     )

      # one length string
      _A							:     Union[str, Any]			=						0
      # for each alpha we go in our dict and if it is in it we calculate entropy
      for ch in my_alphas:
            if ch in single_char_strings:
                  _A							:     List[str]			=						single_char_strings[ch]
                  _A							:     Optional[Any]			=						my_str / all_sum
                  my_fir_sum += prob * math.loga(snake_case_     )  # entropy formula.

    # print entropy
      print(f'''{round(-1 * my_fir_sum     ):.1f}'''     )

      # two len string
      _A							:     str			=						sum(two_char_strings.values()     )
      _A							:     Union[str, Any]			=						0
      # for each alpha (two in size) calculate entropy.
      for cha in my_alphas:
            for cha in my_alphas:
                  _A							:     Union[str, Any]			=						cha + cha
                  if sequence in two_char_strings:
                        _A							:     List[Any]			=						two_char_strings[sequence]
                        _A							:     str			=						int(snake_case_     ) / all_sum
                        my_sec_sum += prob * math.loga(snake_case_     )

    # print second entropy
      print(f'''{round(-1 * my_sec_sum     ):.1f}'''     )

      # print the difference between them
      print(f'''{round((-1 * my_sec_sum) - (-1 * my_fir_sum)     ):.1f}'''     )







def 				lowerCAmelCase_	(     snake_case_     ):
      _A							:     List[str]			=						Counter()  # type: ignore
      _A							:     Optional[Any]			=						Counter()  # type: ignore
      single_char_strings[text[-1]] += 1

      # first case when we have space at start.
      two_char_strings[" " + text[0]] += 1
      for i in range(0,len(snake_case_     ) - 1     ):
            single_char_strings[text[i]] += 1
            two_char_strings[text[i : i + 2]] += 1
      return single_char_strings, two_char_strings







def 				lowerCAmelCase_	(     ):
      import doctest

      doctest.testmod()
      # text = (
      #     "Had repulsive dashwoods suspicion sincerity but advantage now him. Remark "
      #     "easily garret nor nay. Civil those mrs enjoy shy fat merry. You greatest "
      #     "jointure saw horrible. He private he on be imagine suppose. Fertile "
      #     "beloved evident through no service elderly is. Blind there if every no so "
      #     "at. Own neglected you preferred way sincerity delivered his attempted. To "
      #     "of message cottage windows do besides against uncivil.  Delightful "
      #     "unreserved impossible few estimating men favourable see entreaties. She "
      #     "propriety immediate was improving. He or entrance humoured likewise "
      #     "moderate. Much nor game son say feel. Fat make met can must form into "
      #     "gate. Me we offending prevailed discovery. "
      # )

      # calculate_prob(text)


if __name__ == "__main__":
  main()






'''simple docstring'''






class 							lowercase       :


 """simple docstring"""


 def __init__(							self							)		->   List[str]:
        _UpperCAmelCase  :						int			     = 0
        _UpperCAmelCase  :						Union[str, Any]			     = 0
        _UpperCAmelCase  :						Optional[int]			     = {}







 def _snake_case (							self  ,a_							)		->   Optional[Any]:
        if vertex not in self.adjacency:
               _UpperCAmelCase  :						int			     = {}
               self.num_vertices += 1







 def _snake_case (							self  ,a_  ,a_  ,a_							)		->   int:
        self.add_vertex(a_							)
        self.add_vertex(a_							)

        if head == tail:
               return

        _UpperCAmelCase  :						List[Any]			     = weight
        _UpperCAmelCase  :						Dict			     = weight







 def _snake_case (							self							)		->   Dict:
        _UpperCAmelCase  :						Optional[int]			     = self.get_edges()
        for edge in edges:
               _UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase  :						Dict			     = edge
               edges.remove((tail, head, weight)							)
        for i in range(len(a_							)							):
               _UpperCAmelCase  :						str			     = list(edges[i]							)

        edges.sort(key=lambda a_							: e[2]							)
        for i in range(len(a_							) - 1							):
               if edges[i][2] >= edges[i + 1][2]:
                      _UpperCAmelCase  :						Optional[Any]			     = edges[i][2] + 1
        for edge in edges:
               _UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase  :						Union[str, Any]			     = edge
               _UpperCAmelCase  :						str			     = weight
               _UpperCAmelCase  :						List[str]			     = weight







 def __str__(							self							)		->   Any:
        _UpperCAmelCase  :						List[Any]			     = """"""
        for tail in self.adjacency:
               for head in self.adjacency[tail]:
                      _UpperCAmelCase  :						List[str]			     = self.adjacency[head][tail]
                      string += f'''{head} -> {tail} == {weight}\n'''
        return string.rstrip("""\n"""							)







 def _snake_case (							self							)		->   str:
        _UpperCAmelCase  :						int			     = []
        for tail in self.adjacency:
               for head in self.adjacency[tail]:
                      output.append((tail, head, self.adjacency[head][tail])							)
        return output







 def _snake_case (							self							)		->   Optional[int]:
        return self.adjacency.keys()







 @staticmethod
 def _snake_case (							a_=None  ,a_=None							)		->   Tuple:
        _UpperCAmelCase  :						List[Any]			     = Graph()
        if vertices is None:
               _UpperCAmelCase  :						List[str]			     = []
        if edges is None:
               _UpperCAmelCase  :						Optional[Any]			     = []
        for vertex in vertices:
               g.add_vertex(a_							)
        for edge in edges:
               g.add_edge(*a_							)
        return g



 class 							lowercase       :


  """simple docstring"""


  def __init__(							self							)		->   int:
         _UpperCAmelCase  :						List[str]			     = {}
         _UpperCAmelCase  :						int			     = {}







  def __len__(							self							)		->   Tuple:
         return len(self.parent							)







  def _snake_case (							self  ,a_							)		->   str:
         if item in self.parent:
                return self.find(a_							)

         _UpperCAmelCase  :						Optional[Any]			     = item
         _UpperCAmelCase  :						List[Any]			     = 0
         return item







  def _snake_case (							self  ,a_							)		->   List[str]:
         if item not in self.parent:
                return self.make_set(a_							)
         if item != self.parent[item]:
                _UpperCAmelCase  :						List[Any]			     = self.find(self.parent[item]							)
         return self.parent[item]







  def _snake_case (							self  ,a_  ,a_							)		->   Union[str, Any]:
         _UpperCAmelCase  :						Any			     = self.find(a_							)
         _UpperCAmelCase  :						List[str]			     = self.find(a_							)

         if roota == roota:
                return roota

         if self.rank[roota] > self.rank[roota]:
                _UpperCAmelCase  :						Any			     = roota
                return roota

         if self.rank[roota] < self.rank[roota]:
                _UpperCAmelCase  :						Any			     = roota
                return roota

         if self.rank[roota] == self.rank[roota]:
                self.rank[roota] += 1
                _UpperCAmelCase  :						List[str]			     = roota
                return roota
         return None







 @staticmethod
 def _snake_case (							a_							)		->   List[Any]:
        _UpperCAmelCase  :						int			     = graph.num_vertices

        _UpperCAmelCase  :						int			     = Graph.UnionFind()
        _UpperCAmelCase  :						Optional[int]			     = []
        while num_components > 1:
               _UpperCAmelCase  :						int			     = {}
               for vertex in graph.get_vertices():
                      _UpperCAmelCase  :						Union[str, Any]			     = -1

               _UpperCAmelCase  :						Tuple			     = graph.get_edges()
               for edge in edges:
                      _UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase  :						str			     = edge
                      edges.remove((tail, head, weight)							)
               for edge in edges:
                      _UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase  :						Optional[Any]			     = edge
                      _UpperCAmelCase  :						Any			     = union_find.find(a_							)
                      _UpperCAmelCase  :						Any			     = union_find.find(a_							)
                      if seta != seta:
                             if cheap_edge[seta] == -1 or cheap_edge[seta][2] > weight:
                                    _UpperCAmelCase  :						Tuple			     = [head, tail, weight]

                             if cheap_edge[seta] == -1 or cheap_edge[seta][2] > weight:
                                    _UpperCAmelCase  :						List[str]			     = [head, tail, weight]
               for vertex in cheap_edge:
                      if cheap_edge[vertex] != -1:
                             _UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase  :						str			     = cheap_edge[vertex]
                             if union_find.find(a_							) != union_find.find(a_							):
                                    union_find.union(a_  ,a_							)
                                    mst_edges.append(cheap_edge[vertex]							)
                                    _UpperCAmelCase  :						Tuple			     = num_components - 1
        _UpperCAmelCase  :						Optional[int]			     = Graph.build(edges=a_							)
        return mst



