Створення перестановок мурашок


13

Вступ

Я визначив клас перестановок анцій у попередньому виклику . Нагадування, перестановка p чисел від 0 до r-1 є анци, якщо для кожного запису p [i], крім першого, є якийсь попередній запис p [ik], такий, що p [i] == p [ ik] ± 1 . Як цікавий факт, я також зазначив , що при г ^ 1 , існує рівно 2 г-1 неспокійних перестановки довжина г . Це означає, що між перестановками анцій довжиною r та двійковими векторами довжини r-1 існує відповідність один на один.. У цьому виклику ваше завдання - реалізувати таке листування.

Завдання

Ваше завдання - написати програму або функцію, яка займає двійковий вектор довжиною 1 ≤ n ≤ 99 і виводить перестановку мурах довжиною n + 1 . Перестановка може бути як 0 на основі 1 (але це повинно бути узгоджено), і введення та вихід можуть бути у будь-якому розумному форматі. Крім того, різні входи повинні завжди давати різні результати; окрім цього, ви можете повернути будь-яку перестановку мурашок.

Виграє найменший байт.

Приклад

Перестановки мурашок довжиною 4 становлять 0 (на основі 0)

0 1 2 3
1 0 2 3
1 2 0 3
1 2 3 0
2 1 0 3
2 1 3 0
2 3 1 0
3 2 1 0

і ваша програма повинна повернути один з них для кожного з восьми бітових векторів довжиною 3:

0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

Чи може програма замість цього приймати ціле представлення кожного бінарного вектора?
mbomb007

1
@ mbomb007 Ні, тому що провідні нулі значущі. 0 1і 0 0 1має давати виходи різної довжини.
Згарб

Відповіді:


3

Желе , 12 11 10 байт

ḟẋLṭ+
0;ç/

Спробуйте в Інтернеті! або генерувати всі перестановки довжиною 4 .

Як це працює

0;ç/   Main link. Argument: B (bit array)

0;     Prepend a 0 to B.
  ç/   Reduce [0] + B by the helper link.


ḟẋLṭ+  Helper link. Left argument: A (array or 0). Right argument: b (bit)

 ẋ     Repeat A b times, yielding A or [].
ḟ      Filter false; remove the elements of A or [] from A.
  L    Get the length of the resulting array.
       This yield len(A) if b = 0 and 0 if b = 1.
    +  Add b to all elements of A.
   ṭ   Tack; append the result to the left to the result to the right.

3

Python 2, 62 60 байт

x=0,
for n in input():x=[t-n+1for t in x]+[n*len(x)]
print x

Дякуємо @xnor за те, що виграли 2 байти!

Перевірте це на Ideone .


Вам потрібна кома x=0,?
ETHproductions

0,є кортеж. Без коми слід відобразити збіг через x .
Денніс

Я думаю , що ви можете перевернути , nщоб зробити [n*len(x)]і змінити відображення в списку комп.
xnor

@xnor Дійсно. Спасибі!
Денніс

3

Пітон, 54 байти

lambda l:[i-i*x+sum(l[i:])for i,x in enumerate([1]+l)]

Використовується наступна процедура:

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

Наприклад, l=[1,0,1,0]даєf(l) == [2,1,3,0,4]

List with prepended 1         1 1 0 1 0

0-indexed position for 0's        2   4
Number of 1's to right        2 1 1 0 0
Sum of above two              2 1 3 0 4

Попередження 0 також дасть такий же результат. The enumerateclunky, я побачу, чи може це зробити краще рекурсивно.


Розумна техніка! Захоплююче, як різні методи найкращі для кожної мови. Я спробував перенести це до JS, але він закінчився у 57 через відсутність sumсинтаксису та нарізки.
ETHproductions

3

JavaScript (ES6), 48 47 45 байт

a=>[h=l=0,...a.map(c=>c?--l:++h)].map(e=>e-l)

Це виявилося схожим на метод @ETHproductions, за винятком того, що я почав безпосередньо з обчислення першого елемента, а потім з використанням двійкового вектора, щоб визначити, чи є кожна цифра новою високою чи новою низькою. Редагувати: Збережено 1 байт завдяки @ETHproductions. Збережено 2 байти, починаючи з нуля і після цього коригуючи. Мій попередній метод виявився схожим на метод @ Денніса, але він займав 54 байти:

a=>a.reduce((r,b)=>[...r.map(e=>b+e),r.length*!b],[0])

2

Perl, 33 байти

Включає +1 для -p

Дайте вектор у вигляді рядка без пробілів на STDIN:

antsy.pl <<< 110

antsy.pl:

#!/usr/bin/perl -p
s%^|.%y/0//+($&?++$a:$b--).$"%eg

2

JavaScript (ES6), 52 байти

v=>[...v,l=0].map(x=>x?l++:h--,h=v.length).reverse()

Перевірте це:

f=v=>[...v,l=0].map(x=>x?l++:h--,h=v.length).reverse()
g=v=>console.log(f((v.match(/[01]/g)||[]).map(x=>+x)))
<input oninput="g(this.value)" value="010">

Пояснення

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

Найкраще, що я міг зробити з технікою Денніса, це 57 51 байт:

v=>v.reduce((x,n)=>[...x.map(i=>i+n),!n*++j],[j=0])
v=>v.map(n=>x=[...x.map(i=>i+n),!n*++j],x=[j=0])&&x

Рішення xnor становить 56 (збережено 1 байт завдяки @Neil):

l=>[1,...l].map((x,i)=>i*!x+eval(l.slice(i).join`+`||0))

i-i*xмогло бути i*!x.
Ніл

@Neil Ах, так, спасибі
ETHproductions


0

Пакетна, 127 байт

@set s=%*
@set/an=h=l=%s: =+%
@for %%b in (%*)do @call:%%b
:0
@echo %n%
@set/an=h+=1
@exit/b
:1
@echo %n%
@set/an=l-=1

Приймає введення як параметри командного рядка, вихід - розділений рядком. (Можна вводити STDIN як розділене простір на STDIN без зайвих витрат.)

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