Кожна можлива довжина циклу


21

Можна сказати, що функція (або програма), яка приймає входи та забезпечує виходи, має цикл, якщо виклик функції на власному виході неодноразово досягає початкового числа. Наприклад, візьміть таку функцію:

Input:  n    1 2 3 4 5 6
Output: f(n) 5 7 1 3 4 9

Якщо ми починаємо з n=1, f(n)=5, f(f(n))=f(5)=4, f(f(f(n)))=f(4)=3, f(f(f(f(n))))=f(3)=1.

Це написано (1 5 4 3). Оскільки в цьому циклі є 4 унікальних числа, це цикл довжиною 4.


Ваше завдання полягає в тому, щоб написати програму або функцію, яка має цикли будь-якої можливої ​​довжини. Тобто повинен бути цикл довжиною 1, довжиною 2 тощо.

Крім того, ваша функція / програма повинна бути від натуральних цілих чисел до додатних цілих чисел, і вона повинна бути біективною , це означає, що для кожного можливого вихідного значення має бути рівно одне вхідне значення для всіх позитивних цілих чисел. Інакше кажучи, функція / програма повинна обчислити перестановку натуральних чисел.


Деталі: Дозволена будь-яка стандартна система вводу / виводу, включаючи STDIN, STDOUT, аргумент функції, повернення тощо. Стандартні лазівки заборонені.

Вам не потрібно турбуватися про обмеження типів даних - вищезазначені властивості потрібно мати лише під припущенням, що intабо, наприклад, floatможе містити будь-яке значення.

Не існує обмежень щодо поведінки функції на входах, які не є додатними цілими числами, і ці входи / виходи будуть ігноровані.


Підрахунок балів - це гольф коду в байтах.


"повинен бути цикл довжиною 1, довжиною 2 і т. д." Якщо це слід інтерпретувати як "повинен бути принаймні цикл довжиною 1, принаймні один довжиною 2 і так далі" або "повинен бути бути точно циклом довжиною 1, одна довжиною 2 і так далі ".
Бакуріу

@Bakuriu Принаймні один цикл кожної позитивної довжини.
isaacg

Відповіді:


11

Pyth, 11 8 байт

.<W-0zz1

Набагато нудніша, ніж моя попередня відповідь.

Кожне число, яке містить 0-значне відображення в собі. Будь-яке інше число відображається на число, у якого його цифри повернуті на 1. Так, наприклад:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

8

Python 2, 56 55 54 байт

n=input()
a=b=1
while a+b<=n:a+=b;b+=1
print(n+~a)%b+a

Ось перші 21 вихід:

[1, 3, 2, 6, 4, 5, 10, 7, 8, 9, 15, 11, 12, 13, 14, 21, 16, 17, 18, 19, 20]

Шаблон очевидний, якщо розбити список на шматки так:

 1    2  3    4  5  6    7  8  9  10    11  12  13  14  15    16  17  18  19  20  21
[1]  [3, 2]  [6, 4, 5]  [10, 7, 8, 9]  [15, 11, 12, 13, 14]  [21, 16, 17, 18, 19, 20]

Чорт, це та модель, яку я теж збирався, але із закритою формою.
orlp

1
Цікаво .. Значення a дотримуються послідовності A000124 . Але я здогадуюсь, ви вже знали це: П
Каде

Зауважте, що ця послідовність є oeis.org/A066182 .
orlp

8

Pyth, 25 байт

+hK/*J/h@h*8tQ2 2tJ2%-QKJ

Це та сама послідовність, що і @ Sp3000, але із закритою формою. Закрита форма:

M (n) = підлога ((1 + sqrt (1 + 8 * (n - 1))) / 2) B (n) = M (n) * (M (n) - 1) / 2 f (n) = B (n) + ((n - B (n) + 1) mod M (n))


5

Python3, 40 байт

n=input();print([n[1:]+n[0],n]['0'in n])

Кожне число, яке містить 0-значне відображення в собі. Будь-яке інше число відображається на число, у якого його цифри повернуті на 1. Так, наприклад:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

1
Дежавю! Прикольно бачити це двома мовами!
Denham Coote

3

Рубі, 22 + 1 = 23

З прапором командного рядка -pзапустіть

~/(.)(.?)/
$_=$1+$'+$2

Коли вводиться як введення рядкове представлення числа (без зворотного нового рядка), він зберігає першу цифру постійною, потім обертає решту вліво, так 1234стає 1342.

Це може бути скорочено до 21 символу $_=$1+$'+$2if/(.)(.)/, але друкує попередження.


3

Рубі, 16 + 1 = 17

З прапором командного рядка -pзапустіть

$_=$_[/.0*$/]+$`

Це є більш складною функцією, ніж моя інша відповідь, але, здається, є більш грізною (і толерантною до нових рядків). Він бере останню ненульову цифру введення плюс будь-які проміжні нулі і переміщує її на початок числа. Так 9010300стає 3009010. Будь-яке число з n ненульовими цифрами буде частиною циклу n довжини.

Вхід - це рядок у будь-якій базі через STDIN, вихід - рядок у цій базі.


2

Пітона, 43

Зворотна функція Sp3000 в , реалізовано рекурсивно.

f=lambda n,k=1:n>k and k+f(n-k,k+1)or n%k+1

Функція - це одноцикл, за яким слідує двоцикл, за яким трицикл, ...

(1)(2 3)(4 5 6)(7 8 9 10)(11 12 13 14 15)...

Операція n%k+1діє як k-цикл на числа 1..k. Щоб знайти відповідне kдля використання, змістіть усе вниз на k=1, потім k=2, і так далі, до n<=k.


2

Pyth, 15 байт

Найкоротший відповідь поки що використовує числові операції, а не рядкові операції.

.|.&Q_=.&_=x/Q2

    Q                input
            /Q2      input div 2
           x   Q     that XOR input
          =          assign that to Q
         _           negate that
       .&       Q    that AND Q
      =              assign that to Q
     _               negate that
  .&                 input AND that
.|               Q   that OR Q

Вплив цієї функції на бінарне подання полягає в тому, щоб розширити крайній правий блок з 1s на наступний 0; або якщо немає 0, повернути його до одного 1:

10010110100000 ↦  
10010110110000 ↦  
10010110111000 ↦  
10010110111100 ↦  
10010110111110 ↦  
10010110111111 ↦
10010110100000  

Pyth, 26 байт, цікавий варіант

.|.&Q_h.&/Q2+Qy=.&/Q2_h.|y

    Q                           input
         /Q2                    input div 2
             Q                  input
                  /Q2           input div 2
                         yQ     twice input
                       .|  Q    that OR input
                     _h         NOT that
                .&              (input div 2) AND that
               =                assign that to Q
              y                 twice that
            +                   input plus that
       .&                       (input div 2) AND that
     _h                         NOT that
  .&                            input AND that
.|                          Q   that OR Q

Виконує вищевказану операцію одночасно на всіх блоках 1s, а не лише правому правому - все ще використовуючи лише побітові та арифметичні операції.

1000010001001 ↦
1100011001101 ↦
1110011101001 ↦
1111010001101 ↦
1000011001001 ↦
1100011101101 ↦
1110010001001 ↦
1111011001101 ↦
1000011101001 ↦
1100010001101 ↦
1110011001001 ↦
1111011101101 ↦
1000010001001

1

Швидкий 1.2, 66 байт

func a(b:Int){var c=0,t=1,n=b
while n>c{n-=c;t+=c++}
print(n%c+t)}
Input:  1,   2, 3,  4, 5, 6,   7, 8, 9, 10,   11, 12, 13, 14, 15
Output: 1,   3, 2,  5, 6, 4,   8, 9, 10, 7,   12, 13, 14, 15, 11

1

Брахілог , 5 байт

∋0&|↺

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

Порт відповіді Pyth @ orlp. Виходить просто і акуратно:

∋0    % If input contains a 0 (since input is a single number, "contains" ∋ treats it as an array 
      %   of its digits, so this means "if any of input's digits are 0")
&     % Then output is the input
|     % Otherwise
↺     % Circularly shift the input once, and unify that with the output

Спочатку я хотів перенести рішення Python на @ @ Sp3000, але це займало колосальні 23 байти :

⟧∋B-₁⟦++₁A≤?;A--₁;B%;A+

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



0

Матлаб (189)

  function u=f(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if ~isempty(z),t=y(y~=max(y));if isempty(t),u=y(end)*2^(nnz(y)-1);else,g=max(t);e=primes(g*2);u=n/g*e(find(e==g)+1);end,end,end

  • Функція:

    Відображає будь-яке ціле число відповідно до його простих коефіцієнтів, якщо число дорівнює нулю або множиться на 2 або 1, число відображається на себе, інакше ми вибираємо найбільший простий коефіцієнт цього числа, тоді ми збільшуємо решта різних простих коефіцієнтів на найближчі більший основний коефіцієнт, поки ми не досягнемо числа, biggest_prime^nде nє сума всіх показників усіх факторів, як тільки ми досягнемо цієї суми, ми повернемось до max_prime*2^(n-1)і знову відтворимо той самий цикл.


0

Матлаб (137)

  function u=h(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if~isempty(z),e=nnz(y);f=nnz(z);if(~mod(e,f)&e-f)u=n/2^(e-f);else,u=u*2;end

  • Трохи подібний підхід, помножуючи поступово будь-яке число, не рівне {0,1,2 ^ n} на, 2поки ми не натрапимо на показник, 2який ділиться на суму показників інших простих факторів. потім переходимо до початку циклу, що ділиться на 2^(sum of exponents of other primes). інші нуми відображаються на собі.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.