Скільки перетасовань


18

Стрілецьке переміщення - це тип перетасовки, де колоду розбивають на дві секції, а потім перегородки з'єднуються назад, щоб створити нову колоду перетасованих.

Картки з'єднані таким чином, що картки підтримують свій відносний порядок у розділі, до якого вони входять . Наприклад, якщо карта A знаходиться перед карткою B на колоді, а картки A і B знаходяться в одному розділі, то карта A повинна бути перед карткою B в остаточному результаті, навіть якщо кількість карт між ними збільшилася. Якщо A і B знаходяться в різних розділах, вони можуть бути в будь-якому порядку, незалежно від їх початкового порядку, у кінцевому результаті.

Кожен переміщення стрілецької зброї можна розглядати як перестановку оригінальної колоди карт. Наприклад перестановка

1,2,3 -> 1,3,2

являє собою стрілецький перетасування. Якщо ви розділите колоду так

1, 2 | 3

ми бачимо, що кожна карта в 1,3,2такому ж відносному порядку, як і для кожної іншої карти в її розділі. 2все ще після 1.

З іншого боку, наступна перестановка не є стрілецьким переміщенням.

1,2,3 -> 3,2,1

Ми можемо це побачити, оскільки для всіх двох (нетривіальних) розділів

1, 2 | 3
1 | 2, 3 

є пара карток, які не підтримують свого відносного впорядкування. У першому розділі 1і 2зміни їх упорядкування, а в другому розділі 2і 3зміни їх упорядкування.

Однак ми бачимо, що 3, 2, 1це можна зробити, склавши два стрілецькі мішки,

1, 3, 2 + 2, 3, 1 = 3, 2, 1

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

Завдання

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

Це тому відповіді будуть набрані в байтах, а менша кількість байтів буде кращою.

Ви можете вивести або 1, або 0 для перестановки ідентичності.

Випробування

1,3,2 -> 1
3,2,1 -> 2
3,1,2,4 -> 1
2,3,4,1 -> 1
4,3,2,1 -> 2

3
Отже, чи скоро ми побачимо алгоритми RiffleSort?
mbomb007

Не повинно 4,3,2,1бути 2? Спочатку ми розбиваємося на середині та отримуємо, 3,1,4,2а потім знову розділяємо середину і використовуємо ту саму перестановку
Halvard Hummel

@HalvardHummel Це правильно. Мені доведеться знайти проблему з моєю базовою реалізацією.
Опублікувати Rock Garf Hunter

Відповіді:


2

Python 3 , 255 байт

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

lambda x:f(range(1,len(x)+1),x)
f=lambda x,y,i=0:x==y and i or i<len(x)and min(f(q,y,i+1)for a in range(1,len(x))for q in g(x[:a],x[a:]))or i
g=lambda x,y:(x or y)and[[v]+q for v in x[:1]for q in g(x[1:],y)]+[[v]+q for v in y[:1]for q in g(x,y[1:])]or[[]]

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


2

Чистота , 206 ... 185 байт

import StdEnv
f=flatten
$a b#[c:d]=b
|a>[]#[u:v]=a
=[a++b,b++a:f[[[u,c:e],[c,u:e]]\\e<- $v d]]=[b]
@l#i=length l
=hd[n\\n<-[0..],e<-iter n(f o map(uncurry$o splitAt(i/2)))[[1..i]]|l==e]

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

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

Безголовки:

import StdEnv
shuffle [] l
    = [l]
shuffle [a: b] [c: d]
    = [[a: b]++[c: d], [c: d]++[a: b]: flatten [
        [[a, c: e], [c, a: e]]
        \\ e <- shuffle b d
        ]]
numReq l
    = until cond ((+)1) 0
where
    cond n 
        = let
            mapper
                = map (uncurry shuffle o splitAt (length l/2))
            options
                = iter n (removeDup o flatten o mapper) [[1..length l]]
        in isMember l options

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

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