Розтягніть масив


13

Раніше я визначив процес дроблення масиву

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

Наприклад, ось процес дроблення наступного масиву

[5,2,2,4]
 ^
[5,2,2,4]
   ^
[5,2,2,4]
     ^
[5,4,4]
   ^
[5,4,4]
     ^
[5,8]
   ^

Зауважте, що один і той же елемент можна згортати кілька разів. У прикладі 2,2,4було розбито 8в один прохід.

Тепер дроблення масивів легко, те, що важко, видаляє їх. Ваше завдання - взяти масив додатних цілих чисел як вхід і вивести найбільший масив, який може сформувати вхід при повторному подрібненні. Наприклад, масив [4]формується дробленням, [2,2]яке, у свою чергу, формується дробленням [1,1,1,1]. Оскільки ми не можемо мати цілі значення, [1,1,1,1]то не можна більше розмивати, і тому наша відповідь.

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

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

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

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

[] -> []
[5] -> [5]
[6] -> [3,3]
[8] -> [1,1,1,1,1,1,1,1]
[4,8] -> [1,1,1,1,1,1,1,1,1,1,2]
[2,8] -> [1, 1, 1, 1, 2, 1, 1, 1, 1]
[4,4] -> [1,1,1,1,1,1,1,1]

1
Вибачте, але я все ще не можу зрозуміти правило. навіщо [1,1,1,1,1,1,1,1,1,1,2]виробляти [4, 8]замість [8, 4]? це повинно бути [1,>1,1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,>2,1,1,1,1,1,1,2], [4,1,>1,1,1,1,1,2], [4,2,1,>1,1,1,2], [4,2,>2,1,1,2], [4,>4,1,1,2], [8,1,>1,2], [8,2,>2], [8,4]?
tsh

2
@tsh Я думаю, що у вас є помилкове уявлення про спосіб дроблення. Ось шлях вона приймає перший прохід: [1,>1,1,1,1,1,1,1,1,1,2], [2,>1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,2,>1,1,1,1,1,1,2], [2,2,1,>1,1,1,1,1,2], [2,2,2,>1,1,1,1,2], [2,2,2,1,>1,1,1,2], [2,2,2,2,>1,1,2], [2,2,2,2,1,>1,2], [2,2,2,2,2,>2], [2,2,2,2,4>], другий прохід: [2,>2,2,2,4], [4,>2,2,4], [4,2,>2,4], [4,4,>4], [4,8>]. Сподіваюсь, що це очистить. Якщо ви хочете, щоб якийсь код поглянути на попереднє питання, має відповіді, які реалізують функцію дроблення.
Ad Hoc Hunter Hunter

Чи нормально, якщо я виводять номери, кожен розділений новим рядком?
scottinet

@scottinet Це розумний спосіб вивести список. Іди вперед.
Ad Hoc Garf Hunter

Тестовий випадок [4, 4]слід вилучити, оскільки ми ніколи не зможемо отримати цей масив після розтягування => послідовності розчавлення, оскільки це закінчиться[8]
scottinet

Відповіді:


2

JavaScript (Node.js) , 237 221 213 186 байт

f=a=>a.map(b=>{for(i=1;~b%2;b/=2)i*=2;return Array(i).fill(b)}).reduce((t,c,i,s)=>{b=c.slice();if(i)r=2*s[--i].length,b.length>=r&&b[0]==s[i][0]?b[r-2]+=b.pop():b;return t.concat(b)},[])

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

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

Наприклад:

[1, 1, 1, 1, 1, 1]дає [4,2]один раз подрібнений, але [1, 1, 1, 1, 2]призводить до[2, 4]

Завдання полягає в тому, щоб визначити, де саме слід розмістити блокатор роздавлення, щоб дроблення отриманого масиву дало правильний результат:

  • Блокатор подрібнення потрібно розміщувати лише в тому випадку, якщо попереднє розтягнуте число дорівнює поточному і якщо поточна розтягнута послідовність більша за попередню. Наприклад, [2, 4]потрібно розчавлювання блокатора (розтягнуте число 1, повторюється, і [1, 1]коротше [1,1,1,1]), але [4, 2]і [2, 6]цього не потрібно
  • якщо ми називаємо nпопередню розтягнуту послідовність, і якщо умова вище перевірена, то поточна послідовність є повторенням nпослідовності. Для переривання послідовності розчавлення попереднього числа нам потрібно розмістити блокатор розчавлення в кінці другої nпослідовності поточного числа, щоб розтягнути. Приклад: [2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]або[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]


1

Python 2 , 230 228 226 байт

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

Змінити: -2 байти, видаливши ifголовну функцію

Змінити: -2 байти, видаливши два непотрібних квадратних дужки

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]
def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)
b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

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

Пояснення

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

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]

Функція розчавлення, яка перевіряє, чи у y дорівнює одній із подрібнень.

def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)

Створіть усі можливі перестановки із заданою сумою

b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

0

05AB1E , 41 37 байт

vy[DÉ#2÷]DYQX©NoDU‹&sDV¸X∍sić·®·Íǝ}»,

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

Порт мого рішення Javascript.

Пояснення:

vy                   for each member of the list
[DÉ#2÷]              divide by 2 until odd: stack = stretched value, N = iterations
DYQ                  stetched value equal to the previous one?
X©NoDU‹              previous size < current one? (+store the new size in X)
&                    AND on the 2 previous tests
sDV¸X∍s              build a list of the new stretched value repeated X times
                      (+store the new stetched value in Y)
ić·®·Íǝ}             if the previous tests are true:
                       reduce the result list size by 1
                       multiply by 2 the number at the crush block position
»,                   join by newline + print the list
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.