code: public static double getPvalue(int n11, int ndot1, int ndot2, int n1dot, int n2dot) {
          int originalN11=n11;
  
          int n=ndot1+ndot2;
  
          int min=Math.max(0,n1dot+ndot1-n);
          int max=Math.min(n1dot,ndot1);
  
          Set<Integer> combinations = new HashSet<>();
          combinations.add(originalN11);
          for(int r=min;r<=max;++r) {
              combinations.add(r);
          }
  
          double standardPart = Arithmetics.factorial(n1dot)*Arithmetics.factorial(n2dot)*Arithmetics.factorial(ndot1)*Arithmetics.factorial(ndot2)/Arithmetics.factorial(n);
  
          double originalPvalue=0.0;
          double Psum=0;
          for(Integer r : combinations) {
              n11=r;
  
              int n21=ndot1-n11;
              int n12=n1dot-n11;
              int n22=n2dot-n21;
  
              double pvalue=standardPart/(Arithmetics.factorial(n11)*Arithmetics.factorial(n12)*Arithmetics.factorial(n21)*Arithmetics.factorial(n22));
  
              if(r==originalN11) {
                  originalPvalue=pvalue;
              }
  
              if(pvalue<=originalPvalue) {
                  Psum+=pvalue;
              }
          }
          //combinations = null;    
  
          return Psum;
      }
docs: Calculates the p-value of null Hypothesis
  
  @param n11
  @param ndot1
  @param ndot2
  @param n1dot
  @param n2dot
  @return