Рассчитать Фи (не Пи)


73

Нет, я не имею в виду ϕ = 1.618...и π = 3.14159.... Я имею в виду функции .

  • φ (x) - число целых чисел, меньших или равных числу, к xкоторому относятся простые числа x.
  • π (x) - число простых чисел, меньших или равных x.
  • Допустим, что «не пи» - это тогда π̅ (x), и определим его как число композитов, меньшее или равное x.

задача

Учитывая , строго положительное целое число x, вычислить ф (П (х)) . Оценка в байтах.

Примеры

Каждая строка состоит из ввода (от 1 до 100 включительно) и соответствующего вывода, разделенных пробелом.

1 0 
2 0 
3 0 
4 1 
5 1 
6 1 
7 1 
8 2 
9 2 
10 4 
11 4 
12 2 
13 2 
14 6 
15 4 
16 6 
17 6 
18 4 
19 4 
20 10 
21 4 
22 12 
23 12 
24 6 
25 8 
26 8 
27 16 
28 6 
29 6 
30 18 
31 18 
32 8 
33 12 
34 10 
35 22 
36 8 
37 8 
38 20 
39 12 
40 18 
41 18 
42 12 
43 12 
44 28 
45 8 
46 30 
47 30 
48 16 
49 20 
50 16 
51 24 
52 12 
53 12 
54 36 
55 18 
56 24 
57 16 
58 40 
59 40 
60 12 
61 12 
62 42 
63 20 
64 24 
65 22 
66 46 
67 46 
68 16 
69 42 
70 20 
71 20 
72 32 
73 32 
74 24 
75 52 
76 18 
77 40 
78 24 
79 24 
80 36 
81 28 
82 58 
83 58 
84 16 
85 60 
86 30 
87 36 
88 32 
89 32 
90 48 
91 20 
92 66 
93 32 
94 44 
95 24 
96 70 
97 70 
98 24 
99 72 
100 36

Используйте эту ссылку для расчета ожидаемого результата для любого входа. Кроме того , список входов и выходов для x <= 1000предусмотрен здесь на Pastebin . ( Создано с помощью этой программы Minkolang .)


Leaderboards

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

## Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Если вы хотите включить в заголовок несколько чисел (например, потому что ваш результат равен сумме двух файлов или вы хотите перечислить штрафы за флаг интерпретатора отдельно), убедитесь, что фактический результат является последним числом в заголовке:

## Perl, 43 + 2 (-p flag) = 45 bytes

Вы также можете сделать название языка ссылкой, которая затем будет отображаться во фрагменте списка лидеров:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


Есть ли ограничения на размер ввода?
lirtosiast

4
Является ли этот вопрос данью уважения пользователю PhiNotPi ?
Примо

24
@primo Почему ты так думаешь?
Mego

2
@primo: Это было вдохновлено его именем, и определенно каламбуром на нем, но не совсем дань ему.
El'endia Starman

1
@ edc65: Да, видимо так , как я узнал вчера.
Эльендия Старман

Ответы:


27

GS2 , 12 10 байт

V@'◄l.1&‼l

Исходный код использует кодировку CP437 . Попробуйте онлайн!

Тестовый забег

$ xxd -r -ps <<< 564027116c2e3126136c > phinotpi.gs2
$ wc -c phinotpi.gs2 
10 phinotpi.gs2
$ gs2 phinotpi.gs2 <<< 1000
552

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

V          Read an integer n from STDIN.
 @         Push a copy of n.
  '        Increment the copy of n.
   ◄l      Push 1 and call primes; push the list of all primes below n+1.
     .     Count the primes.
      1    Subtract the count from n.
       &   Decrement to account for 1 (neither prime nor composite).
        ‼l Push 3 and call primes; apply Euler's totient function.

25
Имя файла длиннее, чем у программы.
Флорис

43

Regex (.NET), 122 113 байтов

^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*))((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+

Предполагая, что входные и выходные данные унарные, а выходные данные берутся из основного совпадения регулярного выражения.

Разбивка регулярного выражения:

  • ^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*)) вычисляет π̅ (x) и захватывает остальную часть строки в группе 6 захвата для утверждения во второй части.

    • .*$устанавливает указатель на конец строки, чтобы у нас было целое число xв одном направлении.
    • (?<=^(\3+(.+.))(.*?(?>(.\4)?))) совпадает справа налево и проверяет составное число, выполняя цикл от x до 0.
      • (.*?(?>(.\4)?))является «переменной», которая начинается с 0 в первой итерации и продолжается от числа в предыдущей итерации и повторяется до x. Поскольку наименьшее составное число равно 4, оно (.\4)?никогда не будет совпадать, если доступна группа захвата 4.
      • ^(\3+(.+.))проверяет, что осталось от «переменной» выше (то есть x - "variable"), является ли она составным числом.
  • ((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+вычисляет φ (π̅ (x)), ограничивая операции слева направо с (?=\6$).

    • .*(?=\6$)устанавливает указатель в положение π̅ (x). Обозначим y = π̅ (x).
    • (?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?))) совпадает справа налево и проверяет относительное простое число, повторяя цикл от (y - 1) до 0
      • (.+?(?>\9?)) является «переменной», которая начинается с 1 в первой итерации и продолжается от числа в предыдущей итерации и повторяется до y
      • (?!(.+.)\8*(?=\6$)(?<=^\8+))соответствует слева направо 1 и проверяет, являются ли «переменная» и y относительными простыми числами.
        • (.+.)\8*(?=\6$) выбирает делитель «переменной», который больше 1, и побочным эффектом является то, что у нас есть целое число у слева.
        • (?<=^\8+) проверяет, является ли делитель «переменной» также делителем у.

1 В .NET упреждающий просмотр устанавливает направление на LTR вместо того, чтобы следовать текущему направлению; просмотр сзади устанавливает направление на RTL, а не наоборот.

Проверьте регулярное выражение в RegexStorm .

Редакция 2 отбрасывает группы без захвата и использует атомарные группы вместо условного синтаксиса.


24
Сэр, вы сошли с ума.
РК.

9
Я думаю, что у него есть прикосновение к сальго.
curiousdannii

11
И теперь у вас есть две проблемы. (Серьезно понятия не имел, что вы могли бы делать такие вещи с Regex ...)
Даррел Хоффман

21

J 15 15 байт

5 p:<:-_1 p:>:

Это молчаливый, монадический глагол. Попробуйте его в Интернете с J.js .

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

                Right argument: y
            >:  Increment y.
       _1 p:    Calculate the number of primes less than y+1.
    <:          Decrement y.
      -         Calculate the difference of the results to the left and right.
5 p:            Apply Euler's totient function to the difference.

14
я могу дать объяснение? : P
anOKsquirrel

23
я хаз добавил объяснение
Деннис

5
Я собирался сказать, что я проголосовал за это, потому что у него много смайликов, но текст сказал мне, чтобы избежать этого :(
Doddy

@Dennis: Ваш первый ответ заставил меня смеяться довольно сильно, спасибо за это!
Мердад

19

Серьезно , 27 байтов

,;R`p`MΣ(-D;n;;╟@RZ`ig1=`MΣ

Я победил CJam! Попробуйте онлайн

Пояснение ( aотносится к вершине стека, bотносится к секунде сверху):

,;       take input and duplicate it
R`p`MΣ   push sum([is_prime(i) for i in [1,...,a]]) (otherwise known as the pi function)
(-D      rotate stack right by 1, subtract top two elements, subtract 1, push
            (@ could be used instead of (, but I was hoping the unmatched paren would bother someone)
;n;;     dupe top, push a b times, dupe top twice (effectively getting a a+1 times)
╟        pop n, pop n elements and append to list, push
@        swap top two elements
RZ       push [1,...,a], zip a and b
`ig1=`   define a function:
  i        flatten list
  g1=      compute gcd(a,b), compare to 1 (totient function)
MΣ       perform the function a on each element of b, sum and push

Примечание: с момента публикации этого ответа я добавил функции pi и phi в Seriously. Вот неконкурентный ответ с этими функциями:

,;▓1-@-▒

Пояснение (некоторые команды смещены, чтобы не перекрывать другие):

,    get input (hereafter referred to as x)
;    duplicate x
 ▓   calculate pi(x) (we'll call this p)
1-   calculate 1-p
@-   bring x back on top, calculate x-1-p (not pi(x))
  ▒  calculate phi(not pi(x))

1
У тебя СЕРЬЕЗНО ОГОЛЬФ @ Деннис!
TanMath

Пожалуйста, не говорите мне, что вы знали это на вершине своей головы ..
DividedByZero

1
GJ победил CJam =)
flawr

14

Юлия, 52 50 байт

x->count(i->gcd(i,p)<2,1:(p=x-endof(primes(x))-1))

Это создает безымянную функцию, которая принимает и целое число и возвращает целое число. Чтобы назвать его, дайте ему имя, например f=x->....

Ungolfed:

function phinotpi(x::Integer)
    # The number of composites less than or equal to x is
    # x - the number of primes less than or equal to x -
    # 1, since 1 is not composite
    p = x - length(primes(x)) - 1

    # Return the number of integers i between 1 and p such
    # that gcd(i, p) = 1. This occurs when i is relatively
    # prime to p.
    count(i -> gcd(i, p) == 1, 1:p)
end

Используйте sumвместо того, countчтобы сохранить пару символов. Это немного расстраивает, хотя - другой способ подсчета простых чисел, sum(isprime,1:x)точно такой же длины, как endof(primes(x)).
Глен О

1
@GlenO Спасибо за предложение, но sumне для пустых коллекций, а countвозвращает 0. Таким образом sum, не даст желаемого результата для x<4.
Алекс А.

8

Mathematica, 24 байта

EulerPhi[#-PrimePi@#-1]&

2
Из Конечно Mathematica имеет все это построено в ...
хлопать

@ConfusedMr_C Очевидно :) Тем не менее, он не был дисквалифицирован, по понятным причинам: математическое программное обеспечение не может бить гольф languges в простых комбинаторных задачах :)
йо»

@ConfusedMr_C PhiNotPi@#&: 11 байт: P
LegionMammal978

8

Pyth, 14 байт

JlftPTSQ/iLJJ1

Демонстрация , Верификатор

Мы вычисляем композиты с помощью простого фильтра, берем его длину и сохраняем в J. Затем мы берем gcd of Jс каждым числом до Jи считаем, сколько результатов равно 1.


7

Минколанг 0,11 , 12 байт (НЕ конкурентно)

Этот ответ не является конкурентным. Я реализовал пи и фи как встроенные модули, прежде чем опубликовать вопрос, что дает мне несправедливое преимущество. Я публикую это только для тех, кто интересуется языком.

nd9M-1-9$MN.

Попробуй это здесь.

объяснение

n      Read in integer from input
d      Duplicate
9M     Pops off the top of stack as x and pushes pi(x)
-      Subtracts the top two elements on the stack (x - pi(x))
1-     Subtracts 1 (x-1 - pi(x))
9$M    Pops off the top of stack as x and pushes phi(x) (phi(x-1 - pi(x)))
N.     Outputs as integer and stops.

2
Я не думаю, что публикация неверных ответов - это хорошая идея ...
Йети

20
Пока у них есть отказ от ответственности, я не думаю, что с этим что-то не так. Это на самом деле довольно распространено для старых задач.
Деннис

4
@yeti: Технически, это не недействительно. Используемые здесь функции были реализованы еще до того, как было опубликовано задание. Я просто дисквалифицирую его, потому что я отложил публикацию запроса до тех пор, пока не были реализованы две конкретные функции (которые я использовал для генерации списков примеров, между прочим).
El'endia Starman

1
Такой же. Я делаю это много, когда 𝔼𝕊𝕄𝕚𝕟 постоянно обновляется.
Мама Fun Roll

6

CJam, 28 байтов

ri){mf1>},,_,f{){_@\%}h)=}1b

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

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

ri                            Read an integer N from STDIN.
  )                           Increment it. 
   {    },                    Filter; for each I in [0 ... N]:
    mf                          Push I's prime factorization.
      1>                        Discard the first prime.
                              If there are primes left, keep I.
          ,                   Count the kept integers. Result: C
           _,                 Push [0 ... C-1].
             f{          }    For each J in [0 ... C-1], push C and J; then:
               )                Increment J.
                {    }h         Do:
                 _                Push a copy of the topmost integer..
                  @               Rotate the integer below on top of it.
                   \%             Take that integer modulo the other integer.
                                If the residue is non-zero, repeat the loop.
                                This computes the GCD of C and J+1 using the
                                Euclidean algorithm.
                       )        Increment the 0 on the stack. This pushes 1.

                        =     Push 1 if the GCD is 1, 0 if not.
                          1b  Add all Booleans.

Я попробовал «проверить все случаи» ссылку и получил это: 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111. Это правильно?
El'endia Starman

Да, он проверяет, что применение кода к левому столбцу (ввод) равно правому столбцу (вывод).
Деннис

5
я могу дать объяснение на dis1?
anOKsquirrel

9
@anOKsquirrel я хаз объяснил dis1 2
Деннис

5
@Dennis kthxbai
anOKsquirrel

5

Python, 137 139

n=input()
print n,len([b for b in range(len([a for a in range(n)if not all(a%i for i in xrange(2,a))]))if all(b%i for i in xrange(2,b))])

2
Я думаю, что вы можете сэкономить 2 байта, удалив пробелы между range(n) ifи])) if
DankMemes

3
Учитывая относительно низкую способность Гольфа Python (из-за требований к пробелу и т. Д.), Это довольно впечатляет!
Феликсфью

@DankMemes, спасибо за совет!
wnnmaw

5

Сетчатка , 48 байт

.+
$*
M&`(..+)\1+$
.+
$*
(?!(..+)\1*$(?<=^\1+)).

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

объяснение

.+
$*

Преобразовать ввод в унарный.

M&`(..+)\1+$

Подсчитайте составные числа, не превышающие ввод, посчитав, как часто мы можем сопоставить строку, которая состоит как минимум из двух повторений с коэффициентом не менее 2.

.+
$*

Преобразовать в унарный снова.

(?!(..+)\1*$(?<=^\1+)).

Вычислите φ, посчитав, из скольких позиций невозможно найти коэффициент (по крайней мере 2) суффикса из этой позиции, который также является фактором префикса (если мы найдем такой коэффициент, то этот i <= nкоэффициент будет равен nпоэтому не взаимно к нему). В .конце гарантирует, что мы не считаем ноль (для которого мы не можем найти фактор по крайней мере 2).


5

Regex (.NET), 88 86 байт

^(?=((?=(..+)\2+$)?.)+)(?=(?<-2>.)*(.+))(?=(((?!(..+)\6*(?<=^\6+)\3$))?.)*\3)(?<-5>.)*

Попробуйте онлайн! (Как программа Retina.)

Использует тот же ввод / вывод, что и ответ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ , т.е. унарный ввод, и он соответствует подстроке длины результата.

Можно было бы еще больше сократить это, заменив одну или обе уравновешивающие группы прямыми ссылками.

Альтернатива при том же количестве байтов:

^(?=((?=(..+)\2+$)?.)+)(?=(?<-2>.)*(.+))(?=(?((..+)\4*(?<=^\4+)\3$).|(.))*\3)(?<-5>.)*

Есть также некоторые альтернативы для первой половины, например, использование отрицательного прогноза вместо положительного для композитных чисел, или использование там условного.

объяснение

Я предполагаю, что у вас есть базовое понимание балансировки групп , но вкратце, группы захвата в .NET являются стеками (поэтому каждый раз, когда вы повторно используете группу захвата, новый захват помещается сверху) и (?<-x>...)извлекает захват из стека x. Это очень полезно для подсчета вещей.

^                   # Only look at matches from the beginning of the input.
(?=                 # First, we'll compute the number of composites less than
                    # or equal to the input in group 2. This is done in a
                    # lookahead so that we don't actually advance the regex
                    # engine's position in the string.
  (                 #   Iterate through the input, one character at a time.
    (?=(..+)\2+$)?  #     Try to match the remainder of the input as a
                    #     composite number. If so the (..+) will add one
                    #     one capture onto stack 2. Otherwise, this lookahead
                    #     is simply skipped.
    .
  )+
)
(?=                 # It turns out to be more convienient to work with n minus
                    # the number of composites less than or equal to n, and to
                    # have that a single backreference instead of the depth of
                    # a stack.
  (?<-2>.)*         #   Match one character for each composite we found.
  (.+)              #   Capture the remainder of the input in group 3.
)
(?=                 # Now we compute the totient function. The basic idea is
                    # similar to how we computed the number of composites,
                    # but there are a few differences.
                    # a) Of course the regex is different. However, this one
                    #    is more easily expressed as a negative lookahead (i.e.
                    #    check that the values don't share a factor), so this
                    #    won't leave a capture on the corresponding stack. We
                    #    fix this by wrapping the lookahead itself in a group
                    #    and making the entire group optional.
                    # b) We only want to search up the number of composites,
                    #    not up to the input. We do this by asserting that we
                    #    can still match our backreference \3 from earlier.

  (                 #   Iterate through the input, one character at a time.
    ((?!            #     Try not to match a number that shares a factor with
                    #     the number of composites, and if so push a capture
                    #     onto stack 5.
      (..+)\6*      #     Look for a factor that's at least 2...
      (?<=^\6+)     #     Make sure we can reach back to the input with that
                    #     factor...
      \3$           #     ...and that we're exactly at the end of the number
                    #     of composites.
    ))?
    .
  )*
  \3                #   Match group 3 again to make sure that we didn't look
                    #   further than the number of composites.
)
(?<-5>.)*           # Finally, match one character for each coprime number we
                    # found in the last lookahead.


4

Желе неконкурентоспособное

7 байт. Этот ответ не является конкурирующим, поскольку он использует язык, который задним числом.

ÆC_@’ÆṪ

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

ÆC_@’ÆṪ  Input: n

ÆC       Count the primes less than or equal to n.
    ’    Yield n - 1.
  _@     Subtract the count from n - 1.
     ÆṪ  Apply Euler's totient function.

3

Октава, 52 51

@(b)nnz((d=[1:(c=b-1-nnz(primes(b)))])(gcd(d,c)<2))

Изменить: сохранено 1 байт благодаря Томасу Ква

Объяснение:

@(b)                                            # Define anonymous func with parameter b
  nnz(                                          # Count elements in φ(c)
    (                                           #
      d = [1:                                   # Create d= array of 1 to π̅(b)
            ( c = b - 1 - nnz(primes(b)) )      # Calculate c=π̅(b) by subtracting the
                                                #  number of elements in the array of prime
          ]                                     #  numbers from the number of ints in 2:b
    )(gcd(d, c) < 2)                            # Calculate φ(c) by using gcd to filter
  )                                             # relative primes from d


3

SageMath 26 байт

euler_phi(n-1-prime_pi(n))

Хорошо работает даже для n=0и n=1, благодаря реализации Sage.





2

MATL , 9 байт (не конкурирует)

Этот ответ не является конкурирующим, так как язык задним числом.

:Zp~sq_Zp

Использует версию (10.1.0) языка / компилятора.

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

объяснение

:       % implicitly input a number "N" and produce array [1,2,...,N]
Zp      % true for entries that are prime
~       % negate. So it gives true for entries of [1,2,...,N] that are non-prime
s       % sum elements of array. So it gives number of non-primes
q       % subtract 1. Needed because number 1 is not prime, but not composite either
_       % unary minus
Zp      % with negative input, computes totient function of absolute value of input
        % implicit display

2

GAP, 33 байта

n->Phi(n-Number([-2..n],IsPrime))

Number(l,p)подсчитывает, сколько элементов lудовлетворяют p. Чтобы компенсировать тот факт, что 1 не является ни простым, ни составным, мне нужно вычесть из n больше числа простых чисел до n. Вместо -1двух байтов я начинаю список с -2 вместо 1 или 2, добавляя еще одно число, которое считается простым IsPrimeдля только одного дополнительного байта.


2

Python 3,5 - 130 байт

from math import*
def p(n,k,g):
 for i in range(1,n+1):k+=factorial(i-1)%i!=i-1
 for l in range(1,k):g+=gcd(k,l)<2      
 return g

Если недопустимо передавать функцию как p (n, 0,0), тогда +3 байта.

Это использует тот факт, что я использую теорему Вильсона, чтобы проверить, является ли число составным, и должен вызвать математический модуль для факториальной функции. Python 3.5 добавил функцию gcd в математический модуль.

Первый цикл кода будет увеличивать k на единицу, если число составное, и увеличиваться на 0 в остальном. (Хотя теорема Вильсона справедлива только для целых чисел больше 1, она рассматривает 1 как простое число, поэтому позволяет нам использовать это).

Затем второй цикл перебирает диапазон количества композиций и увеличивает g только тогда, когда значения не pi и l взаимно просты.

g тогда число значений, меньших или равных количеству составных чисел, меньших или равных n.



1

05AB1E , 11 8 байт

LDpÈÏg<Õ

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

Это может быть не конкуренция - я не могу узнать, когда был сделан 05AB1E.

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

L             # this gets us the list of numbers [1 .. a]
 D            # duplicates this list
  p           # applies isPrime to each element of the list, vectorised.
   È          # is the element even? (does 05AB1E not have a logical not?)
    Ï         # push elements of the first list where the same index in the 
              # second list is 1
     g<       # finds the length and subtracts 1 (as the list contains 1)
              # this is the not pi function
       Õ      # euler totient function

1

Пыть , 6 байт

řṗ¬Ʃ⁻Ț

Объяснение:

                Implicit input
ř               Push [1,2,...,input]
 ṗ              [is 1 prime?, is 2 prime?, ..., is input prime?]
  ¬             [is 1 not prime?, is 2 not prime?, ... is input not prime?]
   Ʃ            Number of non-primes (sums the array - booleans implicitly converted to ints)
    ⁻           Subtract one to remove the counting of '1'
     Ț          Euler's totient function


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


1

APL NARS, 38 байтов, 19 символов

{⍵≤3:0⋄13π¯1+⍵-2π⍵}

13π - общая функция, а 2π - простая функция подсчета <= ее аргумент. Контрольная работа

  b←{⍵≤3:0⋄13π¯1+⍵-2π⍵}     
  (⍳12),¨b¨⍳12
1 0  2 0  3 0  4 1  5 1  6 1  7 1  8 2  9 2  10 4  11 4  12 2 
  (95..100),¨b¨(95..100)
95 24  96 70  97 70  98 24  99 72  100 36

1

Добавить ++ , 21 байт

L,RþPbL1_dRdVÞ%bLG!!+

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

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

π¯(n)φ(n)π¯(n)φ(n)

π¯(n)

RþPbL1_

RþPþPbL1_x=π¯(n)

φ(n)

dRdVÞ%bLG!!+

xdRÞ%xxbL

n1nG!!

Да, я действительно хотел попробовать новый LaTex

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.