@@ -3001,8 +3001,8 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start)
3001
3001
/*[clinic input]
3002
3002
math.comb
3003
3003
3004
- n: object(subclass_of='&PyLong_Type')
3005
- k: object(subclass_of='&PyLong_Type')
3004
+ n: object
3005
+ k: object
3006
3006
3007
3007
Number of ways to choose *k* items from *n* items without repetition and without order.
3008
3008
@@ -3017,103 +3017,105 @@ Raises ValueError if the arguments are negative or if k > n.
3017
3017
3018
3018
static PyObject *
3019
3019
math_comb_impl (PyObject * module , PyObject * n , PyObject * k )
3020
- /*[clinic end generated code: output=bd2cec8d854f3493 input=565f340f98efb5b5 ]*/
3020
+ /*[clinic end generated code: output=bd2cec8d854f3493 input=b2160da8fe59df60 ]*/
3021
3021
{
3022
- PyObject * val = NULL ,
3023
- * temp_obj1 = NULL ,
3024
- * temp_obj2 = NULL ,
3025
- * dump_var = NULL ;
3022
+ PyObject * result = NULL , * factor = NULL , * temp ;
3026
3023
int overflow , cmp ;
3027
- long long i , terms ;
3024
+ long i , factors ;
3025
+
3026
+ n = PyNumber_Index (n );
3027
+ if (n == NULL )
3028
+ return NULL ;
3029
+ k = PyNumber_Index (k );
3030
+ if (k == NULL ) {
3031
+ Py_DECREF (n );
3032
+ return NULL ;
3033
+ }
3028
3034
3029
3035
cmp = PyObject_RichCompareBool (n , k , Py_LT );
3030
3036
if (cmp < 0 ) {
3031
- goto fail_comb ;
3037
+ goto error ;
3032
3038
}
3033
3039
else if (cmp > 0 ) {
3034
- PyErr_Format (PyExc_ValueError ,
3035
- "n must be an integer greater than or equal to k" );
3036
- goto fail_comb ;
3040
+ PyErr_SetString (PyExc_ValueError ,
3041
+ "n must be an integer greater than or equal to k" );
3042
+ goto error ;
3037
3043
}
3038
3044
3039
- /* b = min(b, a - b) */
3040
- dump_var = PyNumber_Subtract (n , k );
3041
- if (dump_var == NULL ) {
3042
- goto fail_comb ;
3043
- }
3044
- cmp = PyObject_RichCompareBool (k , dump_var , Py_GT );
3045
- if (cmp < 0 ) {
3046
- goto fail_comb ;
3045
+ /* k = min(k, n - k) */
3046
+ temp = PyNumber_Subtract (n , k );
3047
+ if (temp == NULL ) {
3048
+ goto error ;
3047
3049
}
3048
- else if ( cmp > 0 ) {
3049
- k = dump_var ;
3050
- dump_var = NULL ;
3050
+ cmp = PyObject_RichCompareBool ( k , temp , Py_GT );
3051
+ if ( cmp > 0 ) {
3052
+ Py_SETREF ( k , temp ) ;
3051
3053
}
3052
3054
else {
3053
- Py_DECREF (dump_var );
3054
- dump_var = NULL ;
3055
+ Py_DECREF (temp );
3056
+ if (cmp < 0 && PyErr_Occurred ()) {
3057
+ goto error ;
3058
+ }
3055
3059
}
3056
3060
3057
- terms = PyLong_AsLongLongAndOverflow (k , & overflow );
3058
- if (terms < 0 && PyErr_Occurred ()) {
3059
- goto fail_comb ;
3061
+ factors = PyLong_AsLongAndOverflow (k , & overflow );
3062
+ if (overflow > 0 ) {
3063
+ PyErr_NoMemory ();
3064
+ goto error ;
3060
3065
}
3061
- else if (overflow > 0 ) {
3062
- PyErr_Format (PyExc_OverflowError ,
3063
- "minimum(n - k, k) must not exceed %lld" ,
3064
- LLONG_MAX );
3065
- goto fail_comb ;
3066
+ else if (overflow < 0 || factors < 0 ) {
3067
+ if (!PyErr_Occurred ()) {
3068
+ PyErr_SetString (PyExc_ValueError ,
3069
+ "k must be a positive integer" );
3070
+ }
3071
+ goto error ;
3066
3072
}
3067
- else if ( overflow < 0 || terms < 0 ) {
3068
- PyErr_Format ( PyExc_ValueError ,
3069
- "k must be a positive integer" );
3070
- goto fail_comb ;
3073
+
3074
+ if ( factors == 0 ) {
3075
+ result = PyLong_FromLong ( 1 );
3076
+ goto done ;
3071
3077
}
3072
3078
3073
- if (terms == 0 ) {
3074
- return PyNumber_Long (_PyLong_One );
3079
+ result = n ;
3080
+ Py_INCREF (result );
3081
+ if (factors == 1 ) {
3082
+ goto done ;
3075
3083
}
3076
3084
3077
- val = PyNumber_Long (n );
3078
- for (i = 1 ; i < terms ; ++ i ) {
3079
- temp_obj1 = PyLong_FromSsize_t (i );
3080
- if (temp_obj1 == NULL ) {
3081
- goto fail_comb ;
3082
- }
3083
- temp_obj2 = PyNumber_Subtract (n , temp_obj1 );
3084
- if (temp_obj2 == NULL ) {
3085
- goto fail_comb ;
3085
+ factor = n ;
3086
+ Py_INCREF (factor );
3087
+ for (i = 1 ; i < factors ; ++ i ) {
3088
+ Py_SETREF (factor , PyNumber_Subtract (factor , _PyLong_One ));
3089
+ if (factor == NULL ) {
3090
+ goto error ;
3086
3091
}
3087
- dump_var = val ;
3088
- val = PyNumber_Multiply (val , temp_obj2 );
3089
- if (val == NULL ) {
3090
- goto fail_comb ;
3092
+ Py_SETREF (result , PyNumber_Multiply (result , factor ));
3093
+ if (result == NULL ) {
3094
+ goto error ;
3091
3095
}
3092
- Py_DECREF (dump_var );
3093
- dump_var = NULL ;
3094
- Py_DECREF (temp_obj2 );
3095
- temp_obj2 = PyLong_FromUnsignedLongLong ((unsigned long long )(i + 1 ));
3096
- if (temp_obj2 == NULL ) {
3097
- goto fail_comb ;
3096
+
3097
+ temp = PyLong_FromUnsignedLong ((unsigned long )i + 1 );
3098
+ if (temp == NULL ) {
3099
+ goto error ;
3098
3100
}
3099
- dump_var = val ;
3100
- val = PyNumber_FloorDivide ( val , temp_obj2 );
3101
- if (val == NULL ) {
3102
- goto fail_comb ;
3101
+ Py_SETREF ( result , PyNumber_FloorDivide ( result , temp )) ;
3102
+ Py_DECREF ( temp );
3103
+ if (result == NULL ) {
3104
+ goto error ;
3103
3105
}
3104
- Py_DECREF (dump_var );
3105
- Py_DECREF (temp_obj1 );
3106
- Py_DECREF (temp_obj2 );
3107
3106
}
3107
+ Py_DECREF (factor );
3108
3108
3109
- return val ;
3110
-
3111
- fail_comb :
3112
- Py_XDECREF (val );
3113
- Py_XDECREF (dump_var );
3114
- Py_XDECREF (temp_obj1 );
3115
- Py_XDECREF (temp_obj2 );
3109
+ done :
3110
+ Py_DECREF (n );
3111
+ Py_DECREF (k );
3112
+ return result ;
3116
3113
3114
+ error :
3115
+ Py_XDECREF (factor );
3116
+ Py_XDECREF (result );
3117
+ Py_DECREF (n );
3118
+ Py_DECREF (k );
3117
3119
return NULL ;
3118
3120
}
3119
3121
0 commit comments