def calculateNthWeekdayOfYear( year, nth, weekday ): if isinstance( year, RPNDateTime ): year = year.year else: year = real_int( year ) if real( nth ) > 0: firstDay = RPNDateTime( year, 1, 1 ) firstWeekDay = real( weekday ) - firstDay.isoweekday( ) + 1 if firstWeekDay < 1: firstWeekDay += 7 result = RPNDateTime( year, 1, firstWeekDay ).add( RPNMeasurement( nth - 1, 'week' ) ) result.setDateOnly( ) return result elif nth < 0: lastDay = RPNDateTime( year, 12, 31 ) lastWeekDay = real( weekday ) - lastDay.isoweekday( ) if lastWeekDay > 0: lastWeekDay -= 7 lastWeekDay += 31 result = RPNDateTime( year, 12, lastWeekDay, dateOnly = True ).add( RPNMeasurement( ( nth + 1 ), 'week' ) ) result.setDateOnly( ) return result
def isRough( n, k ): if real( n ) < real( k ): return 0 factors = getECMFactors( n ) if g.ecm else getFactors( n ) return 1 if min( [ i[ 0 ] for i in factors ] ) >= k else 0
def isSmooth( n, k ): if real( n ) < real( k ): return 0 factors = getECMFactors( n ) if g.ecm else getFactors( n ) return 1 if max( [ i[ 0 ] for i in factors ] ) <= k else 0
def getNthKFibonacciNumber( n, k ): if real( n ) < 0: raise ValueError( 'non-negative argument expected' ) if real( k ) < 2: raise ValueError( 'argument <= 2 expected' ) if n < k - 1: return 0 nth = int( n ) + 4 precision = int( fdiv( fmul( n, k ), 8 ) ) if ( mp.dps < precision ): mp.dps = precision poly = [ 1 ] poly.extend( [ -1 ] * int( k ) ) roots = polyroots( poly ) nthPoly = getNthFibonacciPolynomial( k ) result = 0 exponent = fsum( [ nth, fneg( k ), -2 ] ) for i in range( 0, int( k ) ): result += fdiv( power( roots[ i ], exponent ), polyval( nthPoly, roots[ i ] ) ) return floor( fadd( re( result ), fdiv( 1, 2 ) ) )
def getGreedyEgyptianFraction( n, d ): if real( n ) > real( d ): raise ValueError( "'egypt' requires the numerator to be smaller than the denominator" ) # Create a list to store the Egyptian fraction representation. result = [ ] rational = Fraction( int( n ), int( d ) ) # Now, iteratively subtract out the largest unit fraction that may be # subtracted out until we arrive at a unit fraction. while True: # If the rational number has numerator 1, we're done. if rational.numerator == 1: result.append( rational ) return result # Otherwise, find the largest unit fraction less than the current rational number. # This is given by the ceiling of the denominator divided by the numerator. unitFraction = Fraction( 1, rational.denominator // rational.numerator + 1 ) result.append( unitFraction ) # Subtract out this unit fraction. rational = rational - unitFraction return result
def calculateNthWeekdayOfMonth( year, month, nth, weekday ): if real( weekday ) > Sunday or weekday < Monday: raise ValueError( 'day of week must be 1 - 7 (Monday to Sunday)' ) if isinstance( year, RPNDateTime ): year = year.year else: year = real_int( year ) firstDayOfWeek = arrow.Arrow( real( year ), real( month ), 1 ).isoweekday( ) if nth < 0: day = ( ( real( weekday ) + 1 ) - firstDayOfWeek ) % 7 while day <= getLastDayOfMonth( year, month ): day += 7 day += nth * 7 else: day = ( real( weekday ) - firstDayOfWeek + 1 ) + nth * 7 if weekday >= firstDayOfWeek: day -= 7 return RPNDateTime( year, month, day, dateOnly = True )
def getNthKFibonacciNumberTheSlowWay( n, k ): ''' This is used for testing getNthKFibonacciNumber( ). ''' precision = int( fdiv( fmul( real( n ), real( k ) ), 8 ) ) if ( mp.dps < precision ): mp.dps = precision return getNthLinearRecurrence( [ 1 ] * int( k ), [ 0 ] * ( int( k ) - 1 ) + [ 1 ], fadd( n, 1 ) )
def getAntiprismSurfaceArea( n, k ): if real( n ) < 3: raise ValueError( 'the number of sides of the prism cannot be less than 3,' ) if not isinstance( k, RPNMeasurement ): return getAntiprismSurfaceArea( n, RPNMeasurement( real( k ), 'meter' ) ) if k.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'antiprism_area\' argument 2 must be a length' ) result = getProduct( [ fdiv( n, 2 ), fadd( cot( fdiv( pi, n ) ), sqrt( 3 ) ), getPower( k, 2 ) ] ) return result.convert( 'meter^2' )
def getRegularPolygonArea( n, k ): if real( n ) < 3: raise ValueError( 'the number of sides of the polygon cannot be less than 3,' ) if not isinstance( k, RPNMeasurement ): return getRegularPolygonArea( n, RPNMeasurement( real( k ), 'meter' ) ) dimensions = k.getDimensions( ) if dimensions != { 'length' : 1 }: raise ValueError( '\'polygon_area\' argument 2 must be a length' ) return multiply( fdiv( n, fmul( 4, tan( fdiv( pi, n ) ) ) ), getPower( k, 2 ) ).convert( 'meter^2' )
def makePythagoreanTriple( n, k ): if real( n ) < 0 or real( k ) < 0: raise ValueError( "'make_pyth_3' requires positive arguments" ) if n == k: raise ValueError( "'make_pyth_3' requires unequal arguments" ) result = [ ] result.append( fprod( [ 2, n, k ] ) ) result.append( fabs( fsub( fmul( n, n ), fmul( k, k ) ) ) ) result.append( fadd( fmul( n, n ), fmul( k, k ) ) ) return sorted( result )
def getConeVolume( r, h ): if not isinstance( r, RPNMeasurement ): return getConeVolume( RPNMeasurement( real( r ), 'meter' ), h ) if r.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'cone_volume\' argument 1 must be a length' ) if not isinstance( h, RPNMeasurement ): return getConeVolume( r, RPNMeasurement( real( h ), 'meter' ) ) if h.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'cone_volume\' argument 2 must be a length' ) return getProduct( [ pi, getPower( r, 2 ), divide( h, 3 ) ] )
def getTorusVolume( R, s ): if not isinstance( R, RPNMeasurement ): return getTorusVolume( RPNMeasurement( real( R ), 'meter' ), s ) if R.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'torus_volume\' argument 1 must be a length' ) if not isinstance( s, RPNMeasurement ): return getTorusVolume( R, RPNMeasurement( real( s ), 'meter' ) ) if s.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'torus_volume\' argument 2 must be a length' ) return getProduct( [ 2, power( pi, 2 ), R, getPower( s, 2 ) ] )
def getAliquotSequence( n, k ): ''' The aliquot sum of n is the sum of the divisors of n, not counting n itself as a divisor. Subsequent aliquot sums can then be computed. These sequences usually terminate, but some, like 276, get so large it has not been determined if they ever terminate. ''' yield real( floor( n ) ) a = n for i in arange( 0, real( k ) - 1 ): b = fsub( getSigma( a ), a ) yield b a = b
def getConeSurfaceArea( r, h ): if not isinstance( r, RPNMeasurement ): return getConeSurfaceArea( RPNMeasurement( real( r ), 'meter' ), h ) if r.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'cone_area\' argument 1 must be a length' ) if not isinstance( h, RPNMeasurement ): return getConeSurfaceArea( r, RPNMeasurement( real( h ), 'meter' ) ) if h.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'cone_area\' argument 2 must be a length' ) hypotenuse = getRoot( add( getPower( r, 2 ), getPower( h, 2 ) ), 2 ) return getProduct( [ pi, r, add( r, hypotenuse ) ] )
def findNthPolygonalNumber( n, k ): if real_int( k ) < 3: raise ValueError( 'the number of sides of the polygon cannot be less than 3,' ) return nint( fdiv( fsum( [ sqrt( fsum( [ power( k, 2 ), fprod( [ 8, k, real( n ) ] ), fneg( fmul( 8, k ) ), fneg( fmul( 16, n ) ), 16 ] ) ), k, -4 ] ), fmul( 2, fsub( k, 2 ) ) ) )
def getSigma( target ): ''' Returns the sum of the divisors of n, including 1 and n. http://math.stackexchange.com/questions/22721/is-there-a-formula-to-calculate-the-sum-of-all-proper-divisors-of-a-number ''' n = floor( target ) if real( n ) == 0: return 0 elif n == 1: return 1 factors = getECMFactors( n ) if g.ecm else getFactors( n ) result = 1 for factor in factors: numerator = fsub( power( factor[ 0 ], fadd( factor[ 1 ], 1 ) ), 1 ) denominator = fsub( factor[ 0 ], 1 ) #debugPrint( 'sigma', numerator, denominator ) result = fmul( result, fdiv( numerator, denominator ) ) if result != floor( result ): raise ValueError( 'insufficient precision for \'sigma\', increase precision (-p))' ) return result
def getNthOctagonalTriangularNumber( n ): sign = power( -1, real( n ) ) return nint( floor( fdiv( fmul( fsub( 7, fprod( [ 2, sqrt( 6 ), sign ] ) ), power( fadd( sqrt( 3 ), sqrt( 2 ) ), fsub( fmul( 4, real_int( n ) ), 2 ) ) ), 96 ) ) )
def getNthLucasNumber( n ): if real( n ) == 0: return 2 elif n == 1: return 1 else: return floor( fadd( power( phi, n ), 0.5 ) )
def getNthFibonorial( n ): result = 1 for i in arange( 2, real( n ) ): result = fmul( result, fib( i ) ) return result
def getNthDelannoyNumber( n ): result = 0 for k in arange( 0, fadd( real( n ), 1 ) ): result = fadd( result, fmul( binomial( n, k ), binomial( fadd( n, k ), k ) ) ) return result
def makeEulerBrick( _a, _b, _c ): a, b, c = sorted( [ real( _a ), real( _b ), real( _c ) ] ) if fadd( power( a, 2 ), power( b, 2 ) ) != power( c, 2 ): raise ValueError( "'euler_brick' requires a pythogorean triple" ) result = [ ] a2 = fmul( a, a ) b2 = fmul( b, b ) c2 = fmul( c, c ) result.append( fabs( fmul( a, fsub( fmul( 4, b2 ), c2 ) ) ) ) result.append( fabs( fmul( b, fsub( fmul( 4, a2 ), c2 ) ) ) ) result.append( fprod( [ 4, a, b, c ] ) ) return sorted( result )
def getOctahedronVolume( n ): if not isinstance( n, RPNMeasurement ): return getOctahedronVolume( RPNMeasurement( real( n ), 'meter' ) ) if n.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'octahedron_volume\' argument must be a length' ) return divide( multiply( sqrt( 2 ), getPower( n, 3 ) ), 3 )
def getDodecahedronVolume( n ): if not isinstance( n, RPNMeasurement ): return getDodecahedronVolume( RPNMeasurement( real( n ), 'meter' ) ) if n.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'dodecahedron_volume\' argument must be a length' ) return divide( multiply( fadd( 15, fmul( 7, sqrt( 5 ) ) ), getPower( n, 3 ) ), 4 ).convert( 'meter^3' )
def getIcosahedronSurfaceArea( n ): if not isinstance( n, RPNMeasurement ): return getIcosahedronVolume( RPNMeasurement( real( n ), 'meter' ) ) if n.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'icosahedron_area\' argument must be a length' ) return getProduct( [ 5, sqrt( 3 ), getPower( n, 2 ) ] ).convert( 'meter^2' )
def getIcosahedronVolume( n ): if not isinstance( n, RPNMeasurement ): return getIcosahedronVolume( RPNMeasurement( real( n ), 'meter' ) ) if n.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'icosahedron_volume\' argument must be a length' ) return getProduct( [ fdiv( 5, 12 ), fadd( 3, sqrt( 5 ) ), getPower( n, 3 ) ] ).convert( 'meter^3' )
def getAntiprismVolume( n, k ): if real( n ) < 3: raise ValueError( 'the number of sides of the prism cannot be less than 3,' ) if not isinstance( k, RPNMeasurement ): return getAntiprismVolume( n, RPNMeasurement( real( k ), 'meter' ) ) if k.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'antiprism_volume\' argument 2 must be a length' ) result = getProduct( [ fdiv( fprod( [ n, sqrt( fsub( fmul( 4, cos( cos( fdiv( pi, fmul( n, 2 ) ) ) ) ), 1 ) ), sin( fdiv( fmul( 3, pi ), fmul( 2, n ) ) ) ] ), fmul( 12, sin( sin( fdiv( pi, n ) ) ) ) ), sin( fdiv( fmul( 3, pi ), fmul( 2, n ) ) ), getPower( k, 3 ) ] ) return result.convert( 'meter^3' )
def getPrismVolume( n, k, h ): if real( n ) < 3: raise ValueError( 'the number of sides of the prism cannot be less than 3,' ) if not isinstance( k, RPNMeasurement ): return getPrismVolume( n, RPNMeasurement( real( k ), 'meter' ), h ) if not isinstance( h, RPNMeasurement ): return getPrismVolume( n, k, RPNMeasurement( real( h ), 'meter' ) ) if k.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'prism_volume\' argument 2 must be a length' ) if h.getDimensions( ) != { 'length' : 1 }: raise ValueError( '\'prism_volume\' argument 3 must be a length' ) return getProduct( [ fdiv( n, 4 ), h, getPower( k, 2 ), cot( fdiv( pi, n ) ) ] ).convert( 'meter^3' )
def getNthAperyNumber( n ): result = 0 for k in arange( 0, real( n ) + 1 ): result = fadd( result, fmul( power( binomial( n, k ), 2 ), power( binomial( fadd( n, k ), k ), 2 ) ) ) return result
def getEulerPhi( n ): if real( n ) < 2: return n if g.ecm: return reduce( fmul, ( fmul( fsub( i[ 0 ], 1 ), power( i[ 0 ], fsub( i[ 1 ], 1 ) ) ) for i in getECMFactors( n ) ) ) else: return reduce( fmul, ( fmul( fsub( i[ 0 ], 1 ), power( i[ 0 ], fsub( i[ 1 ], 1 ) ) ) for i in getFactors( n ) ) )
def getNthMotzkinNumber( n ): result = 0 for j in arange( 0, floor( fdiv( real( n ), 3 ) ) + 1 ): result = fadd( result, fprod( [ power( -1, j ), binomial( fadd( n, 1 ), j ), binomial( fsub( fmul( 2, n ), fmul( 3, j ) ), n ) ] ) ) return fdiv( result, fadd( n, 1 ) )