Ітераційна послідовність фі


13

Пов'язане: Ітераційна функція phi (n) .

Ваше завдання полягає в обчисленні повтореної функції фі:

f(n) = number of iterations of φ for n to reach 1.

Де φє тотієнтська функція Ейлера .

Пов'язані OEIS .

Ось його графік:

введіть тут опис зображення


Правила:

Ваша мета - вихід f(n)з n=2до n=100.

Це код-гольф, тому найкоротший код виграє.

Ось значення, з якими можна перевірити:

1, 2, 2, 3, 2, 3, 3, 3, 3, 4, 3, 4, 3, 4, 4, 5, 3, 4, 4, 4, 4, 5, 4, 5, 4, 4, 4, 5, 4, 5, 5, 5, 5, 5, 4, 5, 4, 5, 5, 6, 4, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 6, 4, 6, 5, 5, 5, 6, 5, 6, 5, 5, 6, 6, 5, 6, 6, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 6, 5, 6, 7, 5, 7, 5, 6, 6, 7, 5, 6, 6, 6, 6, 6, 6, 7, 5, 6, 6

@LuisMendo Виправлено, а також додано графік + значення для перевірки. :-)
Просто красиве мистецтво

1
Я відредагував тег kolmogorov-complexity , оскільки це, по суті, виводить фіксовану величину
caird coinheringaahing

1
@SimplyBeautifulArt Спочатку доведіть, що існує кінцево багато значень, xтаких phi(x)як певне фіксоване число.
користувач202729

2
Це приємне завдання, але я думаю, що було б краще просто попросити рішення для реалізації f(n), а не запускати його на діапазоні фіксованих чисел. Це також робить різницю між мовами з можливістю застосовувати функції в діапазонах з меншим числом байтів (частково хамелеонівський виклик?)
Уріель

1
: P Ви маєте на увазі, що я повинен змінити виклик, щоб дати вам перевагу? Незалежно від того, як зазначено ці правила, деякі мови матимуть перевагу, а деякі - ні. @Uriel
Просто красиве мистецтво

Відповіді:


10

Haskell , 53 52 байти

Дякую Німі за збереження 1 байта!

f<$>[2..100]
f 1=0
f n=1+f(sum[1|1<-gcd n<$>[1..n]])

Спробуйте в Інтернеті!

sum[1|1<-gcd n<$>[1..n]]дарує φ(n)(Взяте з недосконалості , дякую!)

f- це рекурсивна функція, яка обчислює, 1+φ(n)якщо n - ні 1, і виводить, 0якщо nє 1, оскільки більше ітерацій, які потрібно взяти для досягнення1

Нарешті f<$>[2..100]створюється список fзастосованих до кожного елемента[2..100]


7

Haskell , 70 69 68 байт

Функція (\n->sum[1|1<-gcd n<$>[1..n]])- це сумарна функція, яку ми неодноразово застосовуємо в анонімній функції. Дякую @laikoni за -1 байт!

EDIT: Я щойно з’ясував, що @xnor використовував цю точну функцію тотиента в попередньому виклику .

length.fst.span(>1).iterate(\n->sum[1|1<-gcd n<$>[1..n]])<$>[2..100]

Спробуйте в Інтернеті!


1
Це досить коротко для того, щоб не мати вбудованого тоталізатора!
Луїс Мендо

1
@LuisMendo H.PWiz знайшов рішення, яке ще коротше !
недолік

7

MATL , 16 15 байт

99:Q"@`_Zptq}x@

Спробуйте в Інтернеті!

Пояснення

99:       % Push [1 2 ... 99]
Q         % Add 1 element-wise: gives [2 3 ... 100]
"         % For each k in that array
  @       %   Push k
  `       %   Do...while
    _Zp   %     Euler's totient function
     tq   %     Duplicate, subtract 1. This is the loop condition
  }       %   Finally (execute on loop exit)
  x       %     Delete
  @       %     Push latest k
          %   End (implicit)
          % End (implicit)
          % Display stack (implicit)

Стара версія, 16 байт

99:Qt"t_Zp]v&X<q

Спробуйте в Інтернеті!

Пояснення

99:       % Push [1 2 ... 99]
Q         % Add 1 element-wise: gives [1 2 ... 100]
t"        % Duplicate. For each (i.e. do the following 100 times)
  t       %   Duplicate
  _Zp     %   Euler's totient function, element-wise
]         % End
v         % Concatenate vertically. Gives a 100×100 matrix
&X<       % Row index of the first minimizing entry for each column.
          % The minimum is guaranteed to be 1, because the number of
          % iterations is more than sufficient.
q         % Subtract 1. Display stack (implicit)

1
Виведені значення вимикаються на одне, я думаю, спробуйте це в Інтернеті! виправляє це (але я раніше ніколи не використовував MATL)
caird coinheringaahing

Перевірте кінець моєї публікації. Він забезпечує очікуваний вихід, до якого ви відключаєтесь по одному на кожного.
Просто красиве мистецтво

Перші 5 значень, отриманих вашою нинішньою відповіддю, - 2 3 3 4 3коли виклик говорить, що вони повинні бути1 2 2 3 2
caird coinheringaahing

@cairdcoinheringaahing та SimplyBeautifulArt Ах, бачу. Спасибі! Виправлено зараз
Луїс Мендо

6

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

³ḊÆṪÐĿ>1S

Спробуйте в Інтернеті!

-1 байт завдяки HyperNeutrino!

-1 байт дякую містеру Xcoder!

-1 байт завдяки Деннісу

Як це працює

³ḊÆṪÐĿ>1S - Main link. No arguments
³         - Yield 100
 Ḋ        - Dequeue. Creates the list [2, 3 ... 99, 100]
    ÐĿ    - For each element, while the results of the next function
          - aren't unique, collect the results...
  ÆṪ      -   Next function: Totient
      >1  - Greater than one?
        S - Sum the columns

Оскільки це зробив Денніс, я (зрозуміло) не маю поняття, чому це працює, тільки що це робиться.


1
@dylnan Усі три відповіді виводять список f(n)від 2до 100, і це питання не вказує на введення, тому я думаю, що це правильна версія
caird coinheringaahing

@dylnan Завдання просить виходу fна n=2до n=100, а не тільки одне значення.
Просто красиве мистецтво

Ви маєте рацію, я прочитав початок виклику і не прочитав чітко частину правил
dylnan

Що стосується коду, чи можна було б користуватися #в цьому випадку? Що - щось на зразок цього (який явно не працює , але написана ким - то , хто розуміє синтаксис ясно!)
dylnan

@dylnan Можливо, але, як ми створюємо фіксований список, застосовувати над кожним елементом, як правило, краще, ніж #.
caird coinheringaahing

6

APL (Dyalog) , 50 29 25 байт

Подивися, мамо, ніякого вбудованого тутеця!

4 байти збережено завдяки @ H.PWiz

{⍵=1:01+∇+/1=⍵∨⍳⍵}¨1+⍳99

Спробуйте в Інтернеті!

Як?

Мабуть, я пішов за довшою (і важче) формулою спокусливих спершу. Перегляньте історію змін.

⍳⍵- 1доn

⍵∨ - gcd с n

1= - дорівнює 1?

+/ - сумуйте їх усіх

Це тотієнт. Все інше - обгортка для підрахунку ( 1+∇) та нанесення на діапазон 2..100( ¨1+⍳99).



4

J REPL, 23 байти

<:#@(5&p:^:a:)"0|2+i.99

Я не перевіряв, але це, ймовірно, працює у звичайному J, якщо ви визначаєте його як іменник (я гольфував це на своєму телефоні у відповідь).

Вбудовані, йо.

Я б сказав, що потрібно принаймні 2-3 байти для гоління (окремо через те, як це a:працює, доводиться використовувати |як шпилька тощо).


1
+/*<:5&p:^:a:2+i.99 для 19 байт Спробуйте в Інтернеті!
Гален Іванов

Для подальшої довідки ви можете використовувати aso "+замість "0, щоб це однаково могло стати<:#@(5&p:^:a:)"+i.99
Conor O'Brien

2
16 байт з+/1<a:5&p:2+i.99
миль

1
@ миль: Чи можете ви пояснити використання a:коду? Як це працює замість ^:?
Гален Іванов

1
@GalenIvanov (5&p:)^:a: mможна зробити так, як a: 5&p: mвикористовувати інше визначення, &коли діада пов'язана з іменником, а потім називається діадично.
миль

4

JavaScript (ES6), 115 ... 104 99 байт

Жорстке кодування може бути коротшим, але спробуємо суто математичний підхід.

f=n=>n>97?6:(P=(n,s=0)=>k--?P(n,s+(C=(a,b)=>b?C(b,a%b):a<2)(n,k)):s>1?1+P(k=s):1)(k=n+2)+' '+f(-~n)

console.log(f())


Жорстке кодування становить 90 байт ( пастбінне посилання )
Herman L

@HermanLauenstein Чудово виконано.
Арнольд


3

Python 2 , 82 байти

l=0,1
exec"n=len(l);p=2\nwhile n%p:p+=1\nl+=l[p-1]+l[n/p]-n%4%3/2,;print l[n];"*99

Спробуйте в Інтернеті!

Для цього використовуються спостереження, які:

  • f(a*b) = f(a) + f(b) - 1, за винятком -1опущеного, якщо aі bобидва рівні
  • f(p) = f(p-1) + 1коли pє простим, сf(2)=1

Звідси випливає, що якщо nє проста факторизація n = 2**a * 3**b * 5**c * 7**d * 11**e * ..., то f(n) = max(a,1) + b + 2*c + 2*d + 3*e + ...там, де кожна p>2в факторизації вносить свій внесок f(p-1).

Я не впевнений, чи вони продовжують тривати минуле n=100, але якщо так, вони дають спосіб визначити та обчислити fбез використання φ.



2

PowerShell , 110 байт

$a=,0*101;2..100|%{$i=$_;for($z=$j=0;++$j-lt$i;$z+=$k-eq1){for($k=$j;$j%$k-or$i%$k;$k--){}};($a[$i]=$a[$z]+1)}

Спробуйте в Інтернеті!

Математичний підхід.

Власне, переглядаючи його, дуже схожий на відповідь С , але розвивався незалежно. Створює масив 0s, циклів від 2до 100, а потім обчислює phiза допомогою gcdрецептури. Частина в паренах в кінці обох зберігає результат $aдля наступного кругообігу і розміщує копію на конвеєрі, що призводить до неявного виводу.


PowerShell, 112 байт

"122323333434344534444545444545555545455645555655565646555656556656665656565656656757566756666667566"-split'(.)'

Спробуйте в Інтернеті!

Жорстко кодований. Хо-гуд. Коротше, ніж я міг отримати математичний підхід приблизно на 10-15 байт.


Цікаво, чи справді вам потрібен роздільник, оскільки всі цифри є
одноцифровими

1
Чи можете ви показати нам свій математичний підхід? Це виглядає набагато цікавіше, безумовно: P
Conor O'Brien

2
@ ConorO'Brien На щастя, мені вдалося подивитися на це свіжими очима сьогодні вранці і розіграти математичний підхід нижче жорстко кодованого підходу.
AdmBorkBork

2

Python 2 , 83 байти

n=2
exec"print len(bin(n))-3+n%2-~n%9/8-(0x951a5fddc040419d4005<<19>>n&1);n+=1;"*99

Спробуйте в Інтернеті!

Поєднує евристичну оцінку з твердо кодованою константою, яка виправляє кожну оцінку як або, -0або -1.


2

Лушпиння , 10 17 байт

mö←LU¡Sȯṁε⌋ḣtḣ100

Спробуйте в Інтернеті!

Редагувати : +7 байт для фактичного відображення функції в діапазоні, про який вимагали, до цього була лише функція, що обчислює A003434 .

Пояснення

Наступні обчислення A003434 :

←LU¡S(ṁ(ε⌋))ḣ -- takes a number as input, for example: 39
   ¡          -- iterate the following function on the input: [39,24,8,4,2,1,1,1..]
    S(     )ḣ --   with itself (x) and the range [1..x]..
      ṁ(  )   --   ..map and sum the following
        ε⌋    --     0 if gcd not 1 else 1
  U           -- longest unique prefix: [39,24,8,4,2,1]
 L            -- length: 6
←             -- decrement: 5

m(....)ḣ100Частина просто відобразити цю функцію в діапазоні [2..100], не знаю , як я пропустив цю частину раніше: S


1

PHP, 98 байт

1,2,<?=join(',',str_split(unpack('H*','##3444E4DEEDEEUUEEVEUVUVVFUVVUfVfVVVVVegWVgVffgV')[1]))?>,6

Спробуйте в Інтернеті!

Я запакував усі цифри у двійковий рядок. Розпакувавши його, перетворивши його в масив і потім знову об'єднавши масив, мені довелося лише додати 1,2 та додати 6 у міру того, як вони не підходили б або викликали появу контрольного коду.



1

05AB1E , 11 байт

тL¦ε[DNs#sÕ

Спробуйте в Інтернеті!

Пояснення

тL¦           # push range [2 ... 100]
   ε          # apply to each
    [         # start a loop
     D        # duplicate the current number
      N       # push the loop iteration counter
       s      # swap one copy of the current number to the top of the stack
        #     # if true, break the loop
         s    # swap the second copy of the current number to the top of the stack
          Õ   # calculate eulers totient

1

C, 112 байт

a[101];f(i,j,k,t){for(a[i=1]=0;i++<100;printf("%d ",a[i]=a[t]+1))for(t=j=0;++j<i;t+=k==1)for(k=j;j%k||i%k;k--);}

Безголівки:

a[101];
f(i,j,k,t){
    for(a[1]=0,i=2;i<=100;i++) {   // initialize
        for(t=j=0;++j<i;t+=k==1)   // count gcd(i, j) == 1 (t = phi(i))
            for(k=j;j%k||i%k;k--); // calculate k = gcd(i, j)
        printf("%d ",a[i]=a[t]+1); // print and store results
    }
}

Спробуйте в Інтернеті!


0

Алюмін , 87 байт

hhhhhdadtqdhcpkkmzyhqkhwzydqhhwdrdhhhwrysrshhwqdrybpkshehhhwrysrarhcpkksyhaydhehycpkkmr

Спробуйте в Інтернеті!

Пояснення

hhhhhdadt      CONSTANT 100

RANGE FROM 100 to 0
q
  dhc
p

REMOVE 0 AND 1
kk

OVER EACH ELEMENT...
m
  zyh
  q
    kh
    wzyd
    q
      DUPLICATE TOP TWO ELEMENTS...
      hhwdrdhhhwrysrshhw
      GCD...
      qdryb
    p
    ks
    he
    hhhw
    ry
    s
    rarhc
  p
  IS IT ONE? IF SO TERMINATE (FIXPOINT)
  kksyhaydhehyc
p
kk
m
REVERSE THE VALUES
r

0

Pyth, 38 байт (не конкурентоспроможний)

.e-+1sl+1kb_jC"Éõ4ÕYHø\\uÊáÛ÷â¿"3

Спробуйте його на Pyth Herokuapp , оскільки він не працює з TIO з будь-якої причини.

Я не сумніваюсь, що явне рішення Pyth менше, але я хотів побачити, наскільки маленький я міг отримати код, стискаючи послідовність, і вивчити Pyth, я думаю. Для цього використовується той факт, що верхня межа послідовності є log2(n)+1.

Пояснення

.e-+1sl+1kb_jC"Éõ4ÕYHø\\uÊáÛ÷â¿"3
             C"Éõ4ÕYHø\\uÊáÛ÷â¿"   interpret string as base 256 integer
            j                   3  convert to array of base 3 digits
           _                       invert sequence (original had leading 0s)
.e                                 map with enumeration (k=index, b=element)
       +1k                                   k+1
     sl                            floor(log(   ))
   +1                                             +1
  -       b                                         -b

Я отримав стислий рядок через Ci_.e+1-sl+1ksb"122323333434344534444545444545555545455645555655565646555656556656665656565656656757566756666667566"3, що є якраз протилежним коду, наведеним вище, з кількома типами перетворень.


1
Чому неконкуренто?
Просто красиве мистецтво

@SimplyBeautifulArt насправді не означав неконкурентоспроможності у формальному розумінні; відредагував заголовок, щоб зробити це більш зрозумілим
ztellatedHexahedron

0

Ом v2 , 41 байт

“ ‽W3>€þΣÌιZ§Á HgüυH§u·β}Bā€ΣNπáÂUõÚ,3“8B

Спробуйте в Інтернеті!

Буквально повністю жорстко кодований ... Я насправді взяв послідовність, описану вище, позбавив усе, що не було числом, інтерпретував це як базу 8, а потім перетворив це на вбудоване базове представлення номера 255 Ома. Ось що роблять цитати. Потім програма знову перетворює це на базу 8.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.