Проверьте теорему Вольстенхольма

14

Определение

Теорема Вольстенхольма утверждает, что:

Теорема Вольстенхольма

где aи b- положительные целые числа и pпростые числа, а большие круглые скобки - это биномиальный коэффициент .

задача

Для того, чтобы убедиться в том, что вам будет дано три входа: a, b, p, где aи bположительные целые числа , и pявляется простым.

Compute:

Проверка теоремы Вольстенхольма

где aи bявляются положительными целыми числами и pпростыми числами , а в круглых скобках - биномиальный коэффициент .

Спекуляции

Поскольку:

комбинаторика

где и в скобках вещь является биномиальным коэффициентом .

Вы можете предположить, что 2b <= a

Testcases

a b p  output
6 2 5  240360
3 1 13 3697053
7 3 13 37403621741662802118325
Дрянная Монахиня
источник
2
Я чувствую, что выходные данные должны иметь .0в конце, чтобы действительно показать, что нет остатка от деления.
El'endia Starman
3
@ El'endiaStarman Давай.
Утренняя монахиня
1
Будет ли [240360](одноэлементный массив) приемлемым выходным форматом?
Деннис
1
Я не думаю, что есть один, поэтому я спрашиваю.
Деннис
2
@ Деннис Тогда сделай один.
Утренняя монахиня

Ответы:

5

Haskell, 73 71 байт

Из-за рекурсии эта реализация очень медленная. К сожалению, мое определение биномиального коэффициента имеет ту же длину, что и import Math.Combinatorics.Exact.Binomial.

n#k|k<1||k>=n=1|1>0=(n-1)#(k-1)+(n-1)#k --binomial coefficient
f a b p=div((a*p)#(b*p)-a#b)p^3       --given formula

Интересная странность состоит в том, что Haskell 98 действительно допускал арифметические шаблоны, которые сократили бы тот же код до 64 байтов:

g a b p=div((a*p)#(b*p)-a#b)p^3
n+1#k|k<1||k>n=1|1>0=n#(k-1)+n#k
flawr
источник
5
Разве версия Haskell 98 не должна быть верной версией?
Майкл Кляйн
4

Желе , 12 11 10 байт

ż×c/I÷S÷²}

Ожидается a, bи в pкачестве аргументов командной строки.

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это устроено

ż×c/I÷S÷²}  Main link. Left argument: a, b. Right argument: p

 ×          Multiply; yield [pa, pb].
ż           Zipwith; yield [[a, pa], [b, pb]].
  c/        Reduce columns by combinations, yielding [aCb, (pa)C(pb)].
    I       Increments; yield [(pa)C(pb) - aCb].
     ÷      Divide; yield [((pa)C(pb) - aCb) ÷ p].
      S     Sum; yield ((pa)C(pb) - aCb) ÷ p.
        ²}  Square right; yield p².
       ÷    Divide; yield  ((pa)C(pb) - aCb) ÷ p³.
Деннис
источник
4

Python 2, 114 109 85 71 байт

Простая реализация. Предложения по игре в гольф приветствуются.

Изменить: -29 байт благодаря Дрянной Монахине и -14 байт благодаря Деннису.

lambda a,b,p,f=lambda n,m:m<1or f(n-1,m-1)*n/m:(f(a*p,b*p)-f(a,b))/p**3

Более простая альтернатива той же длины, благодаря Деннису, это

f=lambda n,m:m<1or f(n-1,m-1)*n/m
lambda a,b,p:(f(a*p,b*p)-f(a,b))/p**3
Sherlock9
источник
Вот факториальная лямбда в гольфе
NonlinearFruit,
3

05AB1E , 11 байт

Принимает вход как:

[a, b]
p

Код:

*`c¹`c-²3m÷

Использует кодировку CP-1252 . Попробуйте онлайн! ,

Аднан
источник
Вы вышли из игры в гольф с Деннисом?
Дрянная Монахиня
9
Если бы я был в шкуре Денниса, думаю, я бы немного устал от всех этих комментариев "Денниса вне игры" ...
Луис Мендо
7
@LuisMendo Я могу или не могу использовать их на регулярной основе.
Деннис
2
и он в 10. это было весело, пока это продолжалось мальчики
downrep_nation
3

R, 50 48 байтов

function(a,b,p)(choose(a*p,b*p)-choose(a,b))/p^3

Как можно проще ... Спасибо @Neil за сохранение 2 байта.

Forgottenscience
источник
1
Сколько из этих мест необходимо?
Нил
42 байт путем переименования chooseи с помощью pryr::fопределения функции: B=choose;pryr::f((B(a*p,b*p)-B(a,b))/p^3).
rturnbull
2

MATL , 13 байт

y*hZ}Xnd2G3^/

Попробуйте онлайн!

Последний тестовый пример не дает точное целое число из-за числовой точности. Тип данных по умолчанию MATL ( double) может обрабатывать только точные целые числа до 2^53.

объяснение

y   % Implicitly input [a; b] (col vector) and p (number). Push another copy of [a; b]
    %   Stack: [a; b], p, [a; b]
*   % Multiply the top two elements from the stack
    %   Stack: [a; b], [a*p; b*p]
h   % Concatenate horizontally
    %   Stack: [a, a*p; b, b*p]
Z}  % Split along first dimension
    %   Stack: [a, a*p], [b, b*p]
Xn  % Vectorize nchoosek
    %   Stack: [nchoosek(a,b), nchoosek(a*p,b*p)]
d   % Consecutive differences of array
    %   Stack: nchoosek(a,b)-nchoosek(a*p,b*p)
2G  % Push second input again
    %   Stack: nchoosek(a,b)-nchoosek(a*p,b*p), p
3^  % Raise to third power
    %   Stack: nchoosek(a,b)-nchoosek(a*p,b*p), p^3
/   % Divide top two elements from the stack
    %   Stack: (nchoosek(a,b)-nchoosek(a*p,b*p))/p^3
    % Implicitly display
Луис Мендо
источник
2

J, 17 байт

(!/@:*-!/@[)%]^3:

использование

(b,a) ( (!/@:*-!/@[)%]^3: ) p

Например:

   2 6 ( (!/@:*-!/@[)%]^3: ) 5
240360

Пока это просто прямая реализация формулы.

Примечание : для 3-го тестового набора входные числа должны быть определены как расширенные (для обработки большой арифметики):

   3x 7x ( (!/@:*-!/@[)%]^3: ) 13x
37403621741662802118325
Дэн Дуб
источник
2

Брахилог , 52 байта

tT;T P&t^₃D&h↰₁S&h;Pz×₎ᵐ↰₁;S-;D/
hḟF&⟨{-ḟ}×{tḟ}⟩;F↻/

Попробуйте онлайн!

Принимает ввод [[a, b], p].

% Predicate 1 - Given [n, r], return binomial(n, r)
hḟF              % Compute n!, set as F
&⟨               % Fork:
  {-ḟ}           % (n - r)!
  ×              % times
  {tḟ}           % r!
⟩                
;F↻              % Prepend n! to that
/                % Divide n! by the product and return

% Predicate 0 (Main)
tT;T P           % Set P to the array [p, p] 
&t^₃D            % Set D as p^3
&h↰₁S            % Call predicate 1 on [a, b], 
                 %  set S as the result binomial(a, b)
&h;Pz×₎ᵐ         % Form array [ap, bp]
↰₁               % Call predicate 1 on that to get binomial(ap, bp)
;S-              % Get binomial(ap, bp) - binomial(a, b)
;D/              % Divide that by the denominator term p^3
                 % Implicit output
sundar - Восстановить Монику
источник
1

Python 3 с SciPy , 72 байта

from scipy.special import*
lambda a,b,p:(binom(a*p,b*p)-binom(a,b))/p**3

Анонимная функция, которая принимает входные данные через аргумент и возвращает результат.

Здесь не так много происходит; это прямая реализация желаемого вычисления.

Попробуйте это на Ideone (результат возвращается в экспоненциальной записи для последнего контрольного примера)

TheBikingViking
источник
1

Ним , 85 82 75 59 байт

import math,future
(a,b,p)=>(binom(a*p,b*p)-binom(a,b))/p^3

Это анонимная процедура; чтобы использовать его, он должен быть передан в качестве аргумента другой процедуре, которая его печатает. Полная программа, которую можно использовать для тестирования, приведена ниже.

import math,future
proc test(x: (int, int, int) -> float) =
 echo x(3, 1, 13) # substitute in your input or read from STDIN
test((a,b,p)=>(binom(a*p,b*p)-binom(a,b))/p^3)

mathМодуль Нима binomвычисляет биномиальный коэффициент двух аргументов.

медь
источник
0

JavaScript (ES6), 70 байт

(a,b,p,c=(a,b)=>a==b|!b||c(--a,b)+c(a,--b))=>(c(a*p,b*p)-c(a,b))/p/p/p

Сохраните 1 байт, используя ES7 ( /p**3вместо /p/p/p).

Нил
источник