Сортировка с обратной вставкой


19

Задача

Сформировать первоначальный зашифрованный список, от движений , что вставки Сортировать бы сортировать его. Исходный список будет содержать все числа от 0до N-1(включительно), где Nуказан размер ввода.

вход

Список, содержащий необходимые шаги для сортировки списка. Каждое значение представляет количество слотов, смещенных на исходное (скремблированное) число, чтобы быть в его правильном положении, имейте в виду, что этот процесс идет слева направо.
Значение в (0-индексированной) позиции iв списке ввода будет между 0и iвключительно.
Вам не нужно обрабатывать неправильные входные данные, в этом случае допустимо любое поведение (сбой, бесконечный цикл и т. Д.).

Выход

Скремблированный список

Пошаговая генерация ходов

Scrambled List | Moves to sort
[4,0,2,1,3,5]  | [0, , , , , ] #4 stay in place
[4,0,2,1,3,5]  | [0,1, , , , ] #0 is moved 1 slot to the left
[0,4,2,1,3,5]  | [0,1,1, , , ] #2 is moved 1 slot
[0,2,4,1,3,5]  | [0,1,1,2, , ] #1 is moved 2 slot
[0,1,2,4,3,5]  | [0,1,1,2,1, ] #3 is moved 1 slot
[0,1,2,3,4,5]  | [0,1,1,2,1,0] #5 is in the right place already
[0,1,2,3,4,5]

Итак, для ввода [0,1,1,2,1,0]ваша программа должна выводиться [4,0,2,1,3,5].
Имейте в виду, что движения не в положение в (окончательном) отсортированном списке, а в отсортированном сегменте (выделенный жирным шрифтом раздел)

Тестовые случаи

[0,0,0] -> [0,1,2]
[0,1,0,1] -> [1,0,3,2]
[0,0,0,0,0,5] -> [1,2,3,4,5,0]
[0,1,2,3] -> [3,2,1,0]
[0,1,1,1] -> [3,0,1,2]
[0,1,1,2,1,0] -> [4,0,2,1,3,5]

выигрыш

Это , поэтому выигрывает самый короткий ответ.

code-golf  array-manipulation  code-golf  code-golf  animation  code-golf  restricted-source  code-golf  java  code-golf  decision-problem  graph-theory  code-golf  conversion  electrical-engineering  code-golf  ascii-art  code-golf  string  substitution  code-golf  math  code-golf  string  set-theory  code-golf  code-golf  compile-time  code-golf  kolmogorov-complexity  binary  code-golf  sequence  cops-and-robbers  code-golf  subsequence  card-games  code-golf  sequence  primes  code-golf  code-golf  number  graphical-output  music  code-golf  ascii-art  code-golf  string  lambda-calculus  code-golf  string  code-generation  code-golf  unicode  code-golf  math  combinatorics  code-golf  balanced-string  code-golf  sequence  cops-and-robbers  code-golf  sequence  cops-and-robbers  code-challenge  fastest-code  chess  code-golf  math  graphical-output  code-golf  string  hello-world  animation  code-golf  number  arithmetic  code-golf  integer  code-golf  code-golf  combinatorics  code-golf  kolmogorov-complexity  graphical-output  code-golf  string  code-golf  code-golf  game  code-golf  math  combinatorics  code-golf  ascii-art  popularity-contest  random  code-golf  arithmetic  number-theory  integer  code-golf  tips  underload  code-golf  math  sequence  primes  code-golf  math  path-finding  code-golf  ascii-art  primes  code-golf  kolmogorov-complexity  alphabet 

1
Может ли программа также принять длину списка в качестве входных данных?
mbomb007

@ mbomb007 Нет.
Род

Можем ли мы использовать (n-1) шагов вместо этого? Первый из них не нужен, так как он всегда равен нулю.
ГБ

@ ГБ уверен, что до тех пор, пока вывод верен, вы можете использовать любой алгоритм
Род

Ответы:


14

Желе , 12 байт

L!_UÆ¡$œ?J’U

Попробуйте онлайн!

объяснение

Мы можем в основном видеть два списка (вход и выход) как кодирование целого числа; вход кодирует целое число в факториальной базе, а выход кодирует целое число как перестановку. К счастью, у Jelly есть встроенные функции, которые уже очень близки к обеим этим кодировкам, так что это просто вопрос написания небольших фрагментов кода для преобразования в целое число, а затем обратно в другую кодировку.

L!_UÆ¡$œ?J’U
   U           Reverse {the input}
    Æ¡         and convert from base factorial to integer;
  _   $        subtract that from
L!             the factorial of the length of {the input};
       œ?      then take the nth permutation of
         J     [1,2,...,l], where l is the length of {the input},
          ’    subtract 1 from every elevent,
           U   and reverse it

В случае базового факториала мы можем заметить, что первый элемент списка должен быть 0, второй может быть 0 или 1, третий должен быть 0/1/2 и так далее. Таким образом, мы должны обратить ввод, чтобы привести его элементы в обычный порядок записи для базового преобразования.

Кроме того, чтобы относительные порядки преобразования факториала и преобразования перестановки соответствовали операции, которую использует сортировка вставки, нам нужно сделать две корректировки: изменить последовательность перестановок и изменить порядок списка вывода. Перевернуть список вывода достаточно просто, для этого требуется только Uконец программы. Чтобы изменить последовательность перестановок, мы вычитаем из факториала входную длину (это работает, потому что базовый факториал производит число в диапазоне от 0 до (длина! -1), тогда как перестановки нумеруются Jelly от 1 до длины! создавая неявное значение off-by-one, которое компенсирует значение off-by-one, которое вы обычно получаете при вычитании индекса перестановки из факториала).

Желе , 9 байт, в сотрудничестве с @JonathanAllan

UÆ¡Nœ?J’U

Эта версия программы очень похожа, но использует другой метод изменения последовательности перестановок; простого отрицания ввода с помощью Nдостаточно, чтобы œ?обработать порядок в обратном порядке. Кроме того, он работает так же, как и в предыдущей программе.

Попробуйте онлайн!


4
О_О Что колдовство это такое?
DLosc

О, хорошо - я знал, что мои Æ¡и œ?атомы будут работать для этого (я уже начал пытаться использовать их для этой задачи раньше - я был так близко, мне просто нужно было L!там).
Джонатан Аллан

Отличный код!
Грег Мартин

1
Фактически, вы можете сделать это в 9 байтах с помощью, UÆ¡Nœ?L’Uпотому что я реализовал œ?(и подобное), чтобы действовать модульно (как если бы они использовали списки Jelly). В Nтолько индексы со значением отрицательной. Примечание: я изменился Jна L- это просто потому, что, учитывая число, оно в любом случае делает диапазон незаметным).
Джонатан Аллан

6

Mathematica, 92 байта

Permute[Range[l=Length@#]-1,(c=Cycles@{#}&)@{}©##&@@c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]&

Чистая функция, принимающая список неотрицательных целых чисел в качестве входных данных и возвращающая список неотрицательных целых чисел. Приведенный выше код содержит a ©, что неверно: это заполнитель для 3-байтового символа U + F3DE, который Mathematica представляет кругом с точкой в ​​нем, и который представляет композицию перестановок.

c=Cycles@{#}&определяет функцию, которая преобразует список целых чисел в Cyclesобъект, представляющий перестановку; например, c[{3,4}]это транспонирование местами перестановки элементов 3 и 4 списка. c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]берет список ввода и генерирует перестановки, необходимые для отмены сортировки вставки. Затем c@{}©##&@@сочиняет все эти перестановки вместе, начиная с перестановки тождеств c@{}. Наконец, Permute[Range[l=Length@#]-1,...]применяет эту перестановку к 0-индексированному списку соответствующей длины.


1
Что нет встроенного ?! Конечно ...
Джонатан Аллан

3
@{#}&)@{}©##&@@выглядит страшно.
Yytsi

6

Python 2, 79 68 байт

Спасибо Krazor за сохранение 10 байтов

Спасибо TuukkaX за сохранение 1 байта

a=input();b=range(len(a));print[b.pop(j-a[j])for j in b[::-1]][::-1]

Работает, генерируя ходы в обратном направлении


2
Сделай это 66 ! Как насчет: a=input();b=range(len(a));print[b.pop(j-a[j]) for j in b[::-1]][::-1]. Список понятий ftw!
FMaz

1
@Krazor У вас есть место, которое можно было удалить раньше for, так что сделайте это 65, я думаю: D
Yytsi

@Krazor Оказывается, что понимание списка не сработало, но мне понравилась идея использования b [:: - 1]!
математик наркоман

Ни за что? Я прокомментировал с мобильного, может я что-то опечатал. Какая часть не работает? Для меня это правильно истолковано и выполнено все контрольные примеры.
FMaz

@Krazor Ой ой, нет, ты прав. Я тот, кто ошибся при тестировании.
математик наркоман

5

JavaScript (ES6), 69 65 63 байта

a=>a.reverse(b=[...a.keys()]).map(o=>+b.splice(~o,1)).reverse()

Досадно, что и вход, и выход находятся в неправильном порядке. Редактировать: 4 байта сохранены благодаря @Arnauld. Сохранено 2 байта благодаря @ETHproductions.


Я все еще пытался найти лучший путь, но ты был намного быстрее. Хороший!
Арно

1
Вам не нужно i, не так ли?
Арно

@ Arnauld Очевидно нет. Я начал с попытки понять ответ Python, и я только что заметил, что он на самом деле не использует i...
Нил

1
Легко -2:o=>+b.splice(~o,1)
ETHпродукция

3

JavaScript (ES6), 73 71 байт

Сохранено 2 байта благодаря ETHproductions

m=>(a=m.map((_,i)=>j=i)).map(_=>a.splice(j,0,+a.splice(j-m[j--],1)))&&a

Контрольные примеры


Хороший способ получить длину и диапазон одновременно. Я собирался предложить a=m.map(_=>j++,j=0), но это та же самая длина, и я уверен, что вы уже попробовали это.
ETHproductions

@ETHproductions Ты прав: я тоже пробовал. :-) (Может быть , стоит отметить , что это не эквивалентно: это было бы установить jв a.lengthчем a.length-1и потребует a.splice(--j,0,a.splice(j-m[j],1)[0]))
Arnauld

Хех, я тоже об этом думал, но не думал, что стоит упоминать, потому что он такой же длины
ETHproductions

1
Легко -2:+a.splice(j-m[j--],1)
ETHпродукция

2

Haskell , 85 байт

f x|n<-length x-1=reverse x#[n,n-1..0]
(n:r)#l=r#(take n l++drop(n+1)l)++[l!!n]
x#l=x

Попробуйте онлайн! Пример использования: f [0,1,1,2,1,0]доходность[4,0,2,1,3,5] .

f xвызывает функцию #с xобращенным списком и списком [length x - 1, length x - 2, ... , 0]. (n:r)#lвыполняет обратную вставку сортировать по рекурсивно принимая nй элемент из l, где l!!nдает nй элемент и take n l++drop(n+1)lдает список lс nго элемента удален.


Хаскелл, такой красивый.
FMaz

1

perl, 61 байт

@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p

Выход заканчивается в массиве @o. Пример с входным массивом в качестве аргументов командной строки:

perl -le'@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p;print@o' 0 1 1 2 1 0
402135

1

Рубин, 49 байтов

->l{(w=l.size).times{l.insert(l.shift+w-=1,w)};l}

Выполняет «обратную вставку» внутри списка, начиная с наибольшего числа.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.