Скажи мені, як flop


29

Як комп'ютерні працівники, ви, напевно, всі знайомі з основними списками операцій pop та push . Це прості операції, які змінюють список елементів. Однак ви коли-небудь чули про операцію флоп ? (як у фліп- флопі )? Це досить просто. Давши число n , переверніть перші n елементів списку. Ось приклад:

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a.flop(4)
[4, 3, 2, 1, 5, 6, 7, 8, 9, 10]

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

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

Це можна зробити флопами! Наприклад, візьміть такий список:

>>> a = [3, 2, 1, 4, 3, 3, 2]
>>> a.flop(4)
[4, 1, 2, 3, 3, 3, 2]
>>> a.flop(3)
[2, 1, 4, 3, 3, 3, 2]
>>> a.flop(6)
[3, 3, 3, 4, 1, 2, 2]

Це призводить нас до визначення сьогоднішнього виклику:

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

Використовуючи останній список як приклад, слід вивести:

4
3
6

оскільки пропуск списку на 4, потім на 3, потім на 6 призведе до суміжного списку. Майте на увазі, що вам не потрібно друкувати найкоротший можливий список флопів, які сусіди списку. Якщо ви надрукували:

4
4
4
3
1
1
6
2
2

натомість це все одно буде дійсним результатом. Однак ви можете ніколи не виводити число, яке перевищує довжину списку. Це тому, що для списку a = [1, 2, 3]дзвінки a.flop(4)є безглуздими.

Ось кілька прикладів:

#Input:
[2, 6, 0, 3, 1, 5, 5, 0, 5, 1]

#Output
[3, 7, 8, 6, 9]


#Input
[1, 2]

#Output
<any list of integers under 3, including an empty list>


#Input
[2, 6, 0, 2, 1, 4, 5, 1, 3, 2, 1, 5, 6, 4, 4, 1, 4, 6, 6, 0]

#Output
[3, 19, 17, 7, 2, 4, 11, 15, 2, 7, 13, 4, 14, 2]


#Input
[1, 1, 1, 1, 2, 2, 2, -1, 4]

#Output
[]


#Input
[4, 4, 8, 8, 15, 16, 16, 23, 23, 42, 42, 15]

#Output
[12, 7]

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

Ви можете приймати введення та вихід у будь-якому розумному форматі. Наприклад, аргументи функції / значення повернення, STDIN / STDOUT, читання / запис файлу тощо є дійсними. Як завжди, це , тому зробіть найкоротшу програму, яку ви можете, і отримайте задоволення! :)


3
Я почув це як fl (oating point) op (eration).
Вейджун Чжоу

3
@WeijunZhou Це міра обчислювальної швидкості для підрахунку операцій, які виконуються на апаратному рівні. en.wikipedia.org/wiki/FLOPS
iPhoenix

3
Чи повинні подання детерміновані чи я можу псевдовипадково пропускати флоп, поки масив не згрупується?
Денніс

3
Чи дозволяється нульовим флопам з'являтися у висновку?
Лайконі

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

Відповіді:


7

Haskell , 98 71 байт

h.r
h(x:s)|(a,b)<-span(/=x)s=l b:l s:h(b++r a)
h e=e
r=reverse
l=length

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

Пояснення

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

Для списку [1,2,3,1,2]алгоритм працює так:

[1,2,3,1,2]  flip longest prefix that ends in 2: flop 2
[2,1,3,1,2]  bring first element to second to last position: flop n-1 = flop 4
[1,3,1,2,2]  recursively work on n-1 list
[1,3,1,2]    there is no other 2: flop 0
[1,3,1,2]    flop n-1 = flop 3
[1,3,1,2]    recurse
[1,3,1]      flop 1
[1,3,1]      flop 2
[3,1,1]      recurse
[3,1]        flop 0
[3,1]        flop 1
 ...

Все разом це дає флоп [2,4,0,3,1,2,0,1,0,0]та список сусідів [3,1,1,2,2].


6

Мова Вольфрама (Mathematica) , 71 байт

If[(n=Tr[1^#])<1,{},{i=Last@Ordering@#,n,n-1,i-1}~Join~#0[#~Drop~{i}]]&

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

Як це працює

Надаючи масив довжини n, виводить послідовність 4nфлопів, які сортують масив у порядку зростання: зокрема, розміщуючи дублікати елементів поруч.

Ідея полягає в тому, що для сортування масиву ми переміщуємо його найбільший елемент до кінця, а потім сортуємо перші n-1елементи масиву. Щоб уникнути здійснення операції на флопі, ми переміщуємо найбільший елемент до кінця таким чином, що не заважає іншим елементам:

{3, 2, 1, 5, 3, 3, 2}    starting array, with largest element in position 4
{5, 1, 2, 3, 3, 3, 2}    flop 4 to put the largest element at the beginning
{2, 3, 3, 3, 2, 1, 5}    flop 7 to put the largest element at the end
{1, 2, 3, 3, 3, 2, 5}    flop 6 (7-1) to reverse the effect of flop 7 on other elements
{3, 2, 1, 3, 3, 2, 5}    flop 3 (4-1) to reverse the effect of flop 4 on other elements

Загалом, якщо найбільший елемент знаходиться в положенні i, є послідовність флопів, яка переміщує його до кінця i, n, n-1, i-1.


Ви можете просто перемістити найбільший елемент до кінця i, n. Чому тоді це робити n-1, i-1? Немає потреби в стабільному сорті.
Пітер Тейлор

@PeterTaylor Я не думаю, що відповідь насправді виконує флопи, скоріше вона видаляє найбільший елемент щоразу і видає еквівалент цієї операції з точки зору флопів.
Ніл


3

Желе , 19 17 байт

ỤỤạ‘Ḣ
ỤÇÐƤĖµUż’ṚF

Сортує список.

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


Я думаю, що ỤŒ¿’Æ!‘ṚĖµUż’ṚFзворотні сорти, оскільки Œ¿це модуль L!.
Джонатан Аллан

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

І це дійсно не вдається для введення [4, 3, 2, 1, 3]. Бампер.
Денніс

О, бу; це ганьба.
Джонатан Аллан

Ụ>Ṫ$ƤSạỤĖµUż’ṚFекономія 2 байтів, замінивши помічник посилання.
милі

2

Чисто , 88 байт

Я думаю, що там можливо коротший із охоронцями, але я його ще не знайшов.

import StdEnv
$[h:t]#(a,b)=span((<>)h)t
=map length[b,t]++ $(b++r a)
$e=e
r=reverse

$o r

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

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


1

JavaScript, 150 байт

(a,f=n=>(a=[...a.slice(0, n).reverse(),...a.slice(n)],n),l=a.length,i=0)=>a.reduce(c=>[...c,f(a.indexOf(Math.max(...a.slice(0, l-i)))+1),f(l-i++)],[])

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

JavaScript, 151 байт

a=>{f=n=>(a=[...a.slice(0,n).reverse(),...a.slice(n)],n),r=[];for(i=a.length+1;--i>0;)r.push(f(a.indexOf(Math.max(...a.slice(0, i)))+1),f(i));return r}

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

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

Безголовки:

array => {
  let flop = n => {
    array = [...array.slice(0, n).reverse(), ...array.slice(n)]; 
    return n;
  }
  let flops = [];
  for (let i = array.length + 1; --i > 0;) 
  {
    let maxIndex = array.indexOf(Math.max(...array.slice(0, i)));
    flops.push(flop(maxIndex + 1), flop(i));
  }
  return flops;
}

0

Perl 5,10 (або вище), 66 байт

Включає +3в довести мову до рівня Perl 5,10 вважається вільним-nuse 5.10.0

#!/usr/bin/perl -n
use 5.10.0;
$'>=$&or$.=s/(\S+) \G(\S+)/$2 $1/*say"$. 2 $."while$.++,/\S+ /g

Запустити з введенням як один рядок на STDIN:

flop.pl <<< "1 8 3 -5 6"

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

На цьому напрочуд важко було потрапити в той самий бальний парк, що і пітон :-)


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