Кількість перетворень до повторення


12

Дано послідовність цілих чисел або, якщо бути більш конкретною перестановку, 0..N перетворіть цю послідовність наступним чином:

  • вихід [x] = зворотний (вхід [вхід [x]])
  • повторити

Наприклад: [2,1,0]стає [0,1,2]і повертається є [2,1,0]. [0,2,1]стає [0,1,2]і перевертається [2,1,0].

Приклад 1

In:   0 1 2
S#1:  2 1 0
S#2:  2 1 0
Output: 1

Приклад 2

In:   2 1 0
S#1:  2 1 0
Output: 0

Приклад 3

In:   3 0 1 2
S#1:  1 0 3 2
S#2:  3 2 1 0
S#3:  3 2 1 0
Output: 2

Приклад 4

In:   3 0 2 1
S#1:  0 2 3 1
S#2:  2 1 3 0
S#3:  2 0 1 3
S#4:  3 0 2 1
Output: 3

Ваше завдання - визначити функцію (або програму), яка виконує перестановку цілих чисел 0..Nі повертає (або виводить) кількість кроків, поки не відбудеться перестановка, яка вже відбулася. Якщо Xперетворення в Xто вихід повинен бути рівний нулю, якщо Xпереходить Yі Yдо X(або Y) , то вихід повинен бути 1.

Y -> Y: 0 steps
Y -> X -> X: 1 step
Y -> X -> Y: 1 step
A -> B -> C -> D -> C: 3 steps
A -> B -> C -> D -> A: 3 steps
A -> B -> C -> A: 2 steps
A -> B -> C -> C: 2 steps
A -> B -> C -> B: also 2 steps

Тести:

4 3 0 1 2 -> 0 3 4 1 2 -> 4 3 2 1 0 -> 4 3 2 1 0: 2 steps 
4 3 2 1 0 -> 4 3 2 1 0: 0 steps
4 3 1 2 0 -> 4 1 3 2 0 -> 4 3 2 1 0 -> 4 3 2 1 0: 2 steps
1 2 3 0 4 -> 4 1 0 3 2 -> 0 3 4 1 2 -> 4 3 2 1 0 -> 4 3 2 1 0: 3 steps
5 1 2 3 0 4 -> 0 5 3 2 1 4 -> 1 5 3 2 4 0 -> 1 4 3 2 0 5 -> 
  5 1 3 2 0 4 -> 0 5 3 2 1 4: 4 steps

Якщо ваша мова не підтримує "функції", ви можете припустити, що послідовність подається у вигляді розділеного пробілом списку цілих чисел, таких як 0 1 2або 3 1 0 2в одному рядку.

Цікаві факти:

  • послідовність 0,1,2,3, .., N завжди перетвориться на N, ..., 3,2,1,0
  • послідовність N, .., 3,2,1,0 завжди перетвориться на N, .., 3,2,1,0
  • послідовність 0,1,3,2, ..., N + 1, N завжди перетвориться на N, ..., 3,2,1,0

Бонусне завдання : Складіть математичну формулу.

Необов’язкові правила :

  • Якщо перший індекс вашої мови 1, а не 0, ви можете використовувати перестановки 1..N(ви можете просто додати їх до кожного цілого числа у прикладі та тестових скриньках).

Я мав на увазі більше як "закриту формулу", таку як $ f (a_ {0}, a_ {1}, a _ {...}} = a_ {0} ^ a_ {1} + ... $, де $ a_ { i} $ - i-й елемент у заданій послідовності.
mroman

Ви впевнені, що існує така "закрита формула"?
Тодд Сьюелл

" повертає (або виводить) кількість кроків, поки не відбулася перестановка, яка вже відбулася. " Це не відповідає майже всім, що йде за ним. Для початку це робить неможливим повернути значення 0 ...
Пітер Тейлор

Чи правильний 3-й приклад? Я бачу, 3,0,1,2слід перетворитися на2,3,0,1
FireCubez

Це кількість перетворень перед повторенням.
mroman

Відповіді:





3

Haskell, 52 байти

([]#)
a#x|elem x a= -1|n<-x:a=1+n#reverse(map(x!!)x)

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

a # x                -- function '#' takes a list of all permutations
                     -- seen so far (-> 'a') and the current p. (-> 'x')
  | elem x a = -1    -- if x has been seen before, return -1 
  | n<-x:a =         -- else let 'n' be the new list of seen p.s and return
    1 +              -- 1 plus
       n #           -- a recursive call of '#' with the 'n' and
        reverse ...  -- the new p.

([]#)                -- start with an empty list of seen p.s 

3

Perl 6 , 44 35 байт

-9 байт завдяки nwellnhof

{($_,{.[[R,] |$_]}...{%.{$_}++})-2}

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

Пояснення:

{                              }  # Anonymous code block
                  ...    # Create a sequence where:
  $_,  # The first element is the input list
     {.[[R,] |$_]} # Subsequent elements are the previous element reverse indexed into itself
                     {        }    # Until
                      %.{$_}       # The index of the listt in an anonymous hash is non-zero
                            ++     # Then post increment it
 (                            )-2  # Return the length of the sequence minus 2

2

J, 33 27 26 байт

-7 завдяки бульбашці

_1(+~:i.0:)|.@C.~^:(<@!@#)

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

як

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

1 <:@i.~ [: ({: e. }:)\ |.@C.~^:(<@!@#)
                        |.@C.~          NB. self-apply permutation and reverse
                              ^:        NB. this many times:
                                (<@!@#) NB. the box of the factorial of the
                                        NB. the list len.  this guarantees
                                        NB. we terminate, and the box means
                                        NB. we collect all the results
         [: ({: e. }:)\                 NB. apply this to those results:
                      \                 NB. for each prefix
             {: e. }:                   NB. is the last item contained in 
                                        NB. the list of previous items?
1 <:@i.~                                NB. in that result find:
1    i.~                                NB. the index of the first 1
  <:@                                   NB. and subtract 1

Зауважимо, вся заключна фраза 1<:@i.~[:({:e.}:)\присвячена пошуку «індексу першого елемента, який вже був помічений». Це здається жахливо довгим для отримання цього, але я більше не зміг його пограти в гольф. Пропозиції вітаються.




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