Перестановка блоку


14

Отже, ваше завдання - взяти блок 3x3, де -середні порожні пробіли, і *середні заповнені пробіли, наприклад:

-**
-*-
*-*

і переставити блок так, щоб *форми утворили X, як це:

*-*
-*-
*-*

Введення: 3x3 квадрати, як вище, вони можуть бути 3 рядками, масивом або як би ви хочете.

Вихід: найкоротша кількість рухів переставити в X. Кожен хід - гортання двох символів, які торкаються, і горизонтальні один від одного, вертикальні один від одного або діагональні один від одного. Якщо це неможливо, поверніть будь-який неможливий вихід, наприклад, 999або -4242. 5- найменша така кількість.

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

1) Вихід: 1

-**
-*-
*-*

2) Вихід: -1

-*-
-*-
*-*

3) Вихід: 3

---
-**
***

4) Вихід: 0

*-*
-*-
*-*

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

Код гольф

Пам'ятайте, що це код гольфу, який виграє найкоротший код!


1
Перегортаючи 2 символи, ти мав на увазі перевернути з простору на *та навпаки, чи обміняти їх?
користувач202729

Що робити, якщо їх більше п'яти *? Чи можете ви додати ще кілька тестових випадків?
Стюі Гріффін

@ user202729, наприклад, abc буде acb, якщо ви перевернете останні два символи.
Ной Крістіно

@StewieGriffin "якщо неможливо повернути -1" більше 5 *або менше 5, це робить неможливим.
Ной Крістіно

6
Чи можемо ми використовувати щось інше, ніж -1? Наприклад 5(неможливо інакше) чи помилка кидання?
Джонатан Аллан

Відповіді:


12

Python 3 , 104 78 байт

lambda n:-(sum(n)!=5)or sum(n[1::2])+n[4]*(max(n,n[6:],n[::3],n[2::3])>=[1]*3)

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

Редагувати: Застосувавши пропозиції @Jonathan Allan та @ xnor, щоб різко зменшити кількість байтів.

Вхід - це рядковий список довжиною 9 із нулями та одиницями, серед яких -* s.

Ось кілька спостережень:

  • Нам ніколи не потрібно переміщувати зірки вже за правильними клітинками. Будь-яка неправильно розміщена зірка має 5 оточуючих комірок, які не можна заблокувати відразу (інакше відповідь вже -1).
  • Вартість кожної зірваної зірки становить 1 або 2, і вона 2, лише якщо вона оточена трьома правильно розміщеними зірками.
  • Вартість кожної зірваної зірки не залежить одна від одної.

Тому ми спочатку перевіряємо, чи є рядок п'ять, а потім підраховуємо ці речі:

  • Кількість неправильно розміщених зірок (= одиниць за непарними показниками)
  • Кількість недоречних зірок вартості 2 (= осередки на 0124, 0346, 2458,4678 будучи все з них)
    • Виділіть фактор n[4]як один, а потім протестуйте кожну істоту вилучення діапазону'111' .
    • Оскільки така зірка є максимум однією, ми можемо сміливо використовувати її maxзамість sum.

Збережіть 17 байт, прийнявши список замість рядка (замінивши counts на sumі '111'на [1]*3) TIO (Я намагався бути хитрою з n[i::j]>=[1]*3циклом, але коротший не знайшов).
Джонатан Аллан

Оскільки тут може бути лише одна зірка, яка коштує 2 ціни, схоже, що ви можете це зробити max(n,n[6:],n[::3],n[2::3])>='1'*3.
xnor

Є й інші домовленості, які мають зірку за ціною 2. Я думаю [0,1,1,1,1,0,1,0,0] слід повернути 3 замість 2.
RootTwo

Також [1,1,1,1,0,0,1,0,0] має бути 3 замість 2.
RootTwo

Також [1,1,1,1,0,0,1,0,0] має бути 3 замість 2.
RootTwo

4

Желе , 26 байт

5ḶḤd3ạŒ!Ṁ€€ḅ1Ṃ
T’d3Ç-L=5Ɗ?

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


Візьміть плоский список як вхідний.

Шкода, що у Jelly немає "багатовимірних трибунних індексів" ... T€ṭ€"JẎтакож працює, але займає ще 1 байт.


Алгоритм: Є 5 поточних позицій блоку та 5 цілей (напрямків), алгоритм намагається здійснити кожне з 5! узгодження та виведення мінімальної суми [джерело, призначення] відстань Чебишева.


Ви можете взяти плоский список ("як би ви хочете") ... можливо, ви навіть можете взяти 0-базисні індекси і мати 24?
Джонатан Аллан

4

Haskell , 176 132 126 104 байт

w=0:1:w
m a|sum a/=5=5|1>0=sum$[a!!4|3<-sum.map(a!!)<$>[[0,1,2],[0,3,6],[2,5,8],[6,7,8]]]++zipWith(*)a w

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


Приймає список цілих чисел з 1 як непорожній символ. Підсумовує кількість ненульових рівних індексованих квадратів, а потім додає 1, якщо знайдено будь-який з подвійних шаблонів переміщення (центральний квадрат та край стовпця / ряду повністю заповнені). Остання частина є трохи марною, я думаю, що, можливо, можна було б значно покращити цей метод грубої сили. Повертає 5 (неможливий вихід) на неможливий вхід.


2
Деякі поради: lengthтест можна скоротити до sum[1|1<-a]. Функція sдо: (1-e,n+sum[1|b>e])яку можна вбудувати, щоб зберегти ще один байт. Ви можете використовувати otherwiseохоронець в , mщоб зберегти пару (). Нарешті, &&на верхньому рівні в охороні можна замінити ,. ...
німі

2
Ви можете зберегти інший байт, скориставшись sumсписком розуміння, щоб передати булеве значення до int. Спробуйте в Інтернеті!
Post Rock Garf Hunter

2
Насправді ви можете зекономити досить багато байтів, тому що, як тільки охоронці шаблону відійдуть, ви можете просто перемістити всю справу вгору m. Спробуйте в Інтернеті!
Опублікувати Rock Garf Hunter

2
Крім того, оскільки кожен не-1 елемент aповинен бути 0не можна використовувати sum aзамість нього sum[1|1<-a]? Спробуйте в Інтернеті!
Пост Рок-Гарф Мисливець

1
Я щойно зрозумів, оскільки не може бути більше 1 сторони з усіма 1s, якщо не центр 0, ви можете робити 3<-замість elem 3$. Також ви можете використовувати sum.map(a!!)замість sum<$>map(a!!).
Пост Рок-Гарф Мисливець


3

JavaScript (ES6), 123 байти

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

f=(n,k=b=-1)=>n^341?k>2?b:[3,6,9,10,17,18,20,34,36].map(m=>[1,8,8].map(M=>(x=n&(m*=M))&-x^x||f(n^m,k+1)))|b:!~b|k<b?b=k+1:b

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

Прокоментував

f = (                           // f = recursive function taking:
  n,                            //   n = input
  k =                           //   k = number of moves, initialized to -1
  b = -1                        //   b = best result so far, initialized to -1
) =>                            //
  n ^ 341 ?                     // if n does not match the target pattern:
    k > 2 ?                     //   if we've already done more than 3 moves:
      b                         //     we're not going to find a solution -> abort
    :                           //   else:
      [3,6,9,10,17,18,20,34,36] //     for each swap bitmask m
      .map(m =>                 //     and
      [1,8,8]                   //     for each multiplier M:
      .map(M =>                 //       apply the multiplier to m and
        (x = n & (m *= M))      //       apply the final bitmask to n -> this gives x
        & -x                    //       isolate the least significant bit of x
        ^ x ||                  //       if it's the only bit set,
        f(n ^ m, k + 1)         //       then swap the bits and make a recursive call
      )) | b                    //     end of both map() loops; return b
  :                             // else:
    !~b | k < b ? b = k + 1 : b //   this is a solution in k+1 moves: update b

NB : Цей код виконує деякі незаконні переміщення за межі верхньої частини дошки, коли m помножується на 64. Але їх просто ігнорують, оскільки вони, можливо, не можуть призвести до коротшого рішення, ніж найкращого юридичного рішення.

Нижче наведено 9 базових рапортів підкачки та цільовий шаблон. Лівий верхній кут - найзначніший біт.

000  000  001  001  010  010  010  100  100     101
011  110  001  010  001  010  100  010  100     010 (341)
(3)  (6)  (9)  (10) (17) (18) (20) (34) (36)    101

Чи можете ви зв’язати шестикутник для тестування? Крім того, я не знав, що 9 бітових цілих чисел можливі в JS
Stan Strum

@StanStrum Оновлено до коротшої версії з більш простим кодуванням. (І так: JS підтримує побітові операції до 32 біт.)
Арнольд,

2

Желе , 26 байт

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ

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

Монадійне посилання.

Як?

Натхненний відповіддю Бабблера Python ; гольф, щоб відповідати Jelly ...

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ - Link: length 9 list of ones & zeros, X
“ċȤ‘                       - list of code-page indices     = [232,154]
    Ḥ                      - double                        = [464,308]
     B                     - to binary     = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0]]
        $                  - last two links as a monad:
       U                   -   upend       = [[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
      ;                    -   concatenate = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0],[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
           ¥               - last two links as a dyad:
          a                -   logical AND (vectorises)
         =                 -   equal? (vectorises)
                Ɗ          - last three links as a monad:
             Ḋ             -   dequeue X (remove leftmost element)
               2           -   literal two
              m            -   modulo slice (keeps the "edge-elements") 
            ;              - concatenate
                 Ạ€        - all? for €ach (edge-elements: no-op
                           -                else: 1 for any cost-2 element 0 otherwise)
                   S       - sum
                    ɓ      - new dyadic chain ^that on the right; X on the left
                     S     - sum X
                       5   - literal five
                      n    - not equal?
                        N  - negate (-1 if not exactly 5 1s, 0 otherwise)
                         ȯ - logical OR with right

2

JavaScript, 85 байт

s=>/^0*(10*){5}$/.test(s)*s.match(/(?=1.(..)*$|^1(..)?11.1|1.11(..)?1$)|$/g).length-1

Це порт регулярного вираження відповіді Bubbler .

Введіть як рядок 0/1.


2

Стакс , 23 22 байти

Ç╙╤Ü┤└åVτ┐├Y-²▼░█∩¡3ëâ

Запустіть і налагоджуйте його

Ця програма приймає масив [0, 1]як вхідний і повертає ціле число рухів або порожній рядок, якщо рішення неможливо.

Розглянемо ці показники для сітки

0 1 2
3 4 5
6 7 8
  • Якщо 1на вході немає рівно 5 с, тоді рішення не існує, тому ми не виробляємо вихід.
  • Центри кожної сторони - неправильні положення. Це індекси 1, 3, 5 і 7. Підсумовування відстані для кожної 1з цих позицій дасть кінцевий результат.
  • Для кожного 1з неправильних положень його відстань дорівнює 1 або 2. Це буде 2, якщо він оточений іншими 1s. Наприклад, якщо 1в індексах є s [0, 1, 2, 4], то відстань для невірного1 дорівнює 2.
  • Зважаючи на це, розглянемо цей псевдокод для отримання відстані, що сприяло результату, за допомогою індексу 1.

    1. Прочитайте 4 біти з індексів [1, 0, 2, 4]. Це ставить неправильну позицію в найбільш значущу позицію.
    2. Перетворити ці біти в число b від 0 до 15.
    3. Коли 0 <= b <= 7відстань дорівнює 0. Коли 8 <= b <= 14відстань дорівнює 1. Коли b == 15відстань дорівнює 2. Це можна обчислити, використовуючи ціле ділення на b * 2 / 15.

Тож загальну відстань можна обчислити, повторивши цей процес 4 рази і обертаючи сітку між ними.

1#5=4*  if the number of 1s is 5, then 4, else 0
D       repeat the rest of the program that many times
  x     push the value in the x register, which is initially the input
  3/    split into 3 rows
  rM    rotate 90 degrees
  $X    flatten back into single array, and save the "rotated" array in the X register
  A|2E  get the digits of 2^10 i.e. [1,0,2,4]
  @     read the bits from the current rotation at indices [1,0,2,4]
  :b    convert bits to integer
  H15/  double, then divide by 2
  +     add to running total

Виконати цей


Перевірте редагування, будь-яке неможливе значення прийнято, а не лише -1, якщо це допоможе вам
Ной Крістіно

Так. Це зберегло 2 байти.
рекурсивна

1

Excel, 86 81 байт

=SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3))/(SUM(A1:C3)=5)

Старий: Коли було "неможливо" вихід-1

=IF(SUM(A1:C3)=5,SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3)),-1)

Використовується як 1для заповненого, так і 0для порожнього, введення в діапазоні A1:C3. Можливо додатково грати в гольф, якщо ми зможемо повернути інші значення, ніж -1"неможливо". Повертає a#DIV/0! помилку на неможливих сітках

Діє за тією ж логікою, що і відповідь Bubbler's Python .


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