Чи може моя 4-нотна музична скринька відтворити цю пісню?


51

У мене є музична скринька з рукояткою, яка може відтворювати серію з чотирьох нот. Коли я повертаю кривошип, він вищипує одну з чотирьох струн, залежно від положення кривошипа та напрямку повороту. Коли кривошип повернутий на північ, коробка (з її рядками пронумеровані від 1 до 4) виглядає так:

1  |  2
   |
   O   

4     3

Звідти я можу повернути кривошип за годинниковою стрілкою, щоб вирвати рядок №2 і вказати кривошип на схід:

1     2

   O---   

4     3

Крім того, я міг би також повернути кривошип проти годинникової стрілки з півночі, щоб зіграти рядок №1 і закінчити кривошипом, що вказує на захід:

1     2

---O   

4     3

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

Виклик

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

Деякі примітки:

  • Вхід не робить припущень щодо початкової стартової позиції. Входи 214(починаючи на схід і рухаючись суворо проти годинникової стрілки) і 234(починаючи на північ і рухаючись строго за годинниковою стрілкою) і обидва дійсні.

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

Зразки

Деякі trueвипадки:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

Деякі falseвипадки:

13     (note 3 is never available after note 1)
1224   (after `122`, the crank must be north, so 4 is not playable)
121    (after `12` the crank is east; 1 is not playable)
12221  (as above, after `1222` the crank is east)
43221  

Чи може введенням бути рядок, що включає лапки?
Луїс Мендо

@LuisMendo Звичайно, я дозволю - мене цікавить ваш алгоритм, не змушуючи вас стрибати через обручі, щоб отримати вхід. У будь-якому випадку, існує неофіційний консенсус спільноти, що це загалом нормально: введення рядків з "або"?
апсилери

1
Я цього не знав. Дякуємо за посилання!
Луїс Мендо

1
@AJMansfield Ні, рішення повинні забезпечувати довільно багато циклів. Звичайно, якщо деякий ввід змушує ваш код перевищити ліміт у перекладачі вашої мови чи пам’яті вашого комп’ютера, це добре (оскільки він обмежений лише тим, скільки пам'яті ви фізично маєте або дозволяє ваш перекладач), але ваше рішення не повинно накладати зайвих обмежень. про те, наскільки далеко або скільки разів рухається кривошип.
apsillers

1
Цей виклик виграв не так просто, як виглядає категорія в Best of PPCG 2016. На жаль, ми не можемо дати приємність викликам, але Згарб написав виклик на вашу честь . Вітаємо!
Мартін Ендер

Відповіді:


9

Pyth, 30 27 байт

f!-aVJ.u%-ysYN8zTtJ,1 7cR2T

Ось ідея:

 1.5  1  0.5

  2       0

 2.5  3  3.5

Рукоятка завжди знаходиться в положенні з півцілим числом c. На кожному кроці ми відображаємо його через цілу ноту позиції n, встановлюючи c = 2*n-c. Якщо nце дійсно, cзмінюється на ± 1 мод 8. Якщо nнедійсний, cзмінюється на ± 3 мод 8. Ми сукупно зменшуємо вхід, щоб зібрати всі значення c, а потім перевіряємо, чи всі примітки були дійсними. Ми робимо це для кожної початкової вартості c, оскільки це коротше, ніж перевірка лише тих, що примикають до першої ноти.

Відформатовано:

f
  ! -
      aV J .u
              % -
                  y s Y
                  N
                8
              z
              T
         t J
      ,
        1 
        7
  cR2 T

Тестовий набір .


18

CJam, 34 31 байт

8,q{~2*f{_@-_zF8b&,@@+8,=*}0-}/

Це робив на своєму телефоні, тому мені доведеться викласти пояснення пізніше. Вихід не є порожнім iff truthy.

Спробуйте в Інтернеті | Тестовий набір

Пояснення

Новий код трохи зміщує макет:

2    3    4

1    .    5

0/8  7    6

Непарні числа відповідають позиціям рядків, а непарні числа - позиціям кривошипа.

Ось що відбувається:

8,           Create the range [0 1 .. 7] of possible starting positions
             We can leave the string positions [0 2 4 6] in since it doesn't matter
q{ ... }/    For each character in the input...
  ~2*          Evaluate as integer and double, mapping "1234" -> [2 4 6 8]
  f{ ... }     Map over our possible current crank positions with the string
               position as an extra parameter
    _@-          Calculate (string - crank), giving some number in [-7 ... 7]
    _z           Duplicate and absolute value
    F8b          Push 15 base 8, or [1 7]
    &,           Setwise intersection and get length. If (string - crank) was in
                 [-7 -1 1 7] then the move was valid and this evaluates to 1, otherwise 0
    @@+          Calculate ((string - crank) + string)
    8,=          Take modulo 8, giving the new crank position. x%y in Java matches the
                 sign of x, so we need to do ,= (range + index) to get a number in [0 .. 7]
    *            Multiply the new crank position by our previous 0 or 1
  0-           Remove all 0s, which correspond to invalid positions

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

Якби тільки CJam мав фільтр із додатковими параметрами ...


Редагувати: Тимчасово відкочується, поки я переконую себе, що цей 29-байт працює:

8,q{~2*f{_@-_7b1#@@+8,=|}W-}/

37
Кожен раз, коли хтось відповідає на такій важкій мові, як cjam, і каже "зробив це по телефону", я трохи помираю всередині
Dennis van Gils

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

7

Haskell, 93 88 87 байт

any(all(\(a,b:c)->1>mod(a!!1-b)4).(zip=<<tail)).mapM((\a->[[a,a+1],[a+1,a]]).read.pure)

Це оцінює анонімну функцію, яка бере рядок і повертає булеву форму. Тут ви знайдете тестовий набір.

Пояснення

Ідея полягає в тому, що лямбда праворуч відображає число aна [[a,a+1],[a+1,a]]два можливих "ходи", які переводять кривошип через це число відповідно до наступної схеми:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

У головній анонімній функції ми спочатку робимо mapM((...).read.pure), яка перетворює кожен символ у ціле число, застосовує до нього вищевказану лямбда і вибирає один з двох ходів, повертаючи список усіх послідовностей переміщення. Потім ми перевіряємо, чи будь-яка з цих послідовностей має властивість, що друге число кожного ходу дорівнює першому номеру наступного модуля 4, що означає, що це фізично можлива послідовність. Для цього ми zipкожен пересуваємо послідовність з її tail, перевіряємо умову для allпар і бачимо, чи відповідає anyпослідовність True.



6

Сітківка , 127 109 байт

^((1|2)|(2|3)|(3|4)|(4|1))((?<2-5>1)|(?<5-2>1)|(?<3-2>2)|(?<2-3>2)|(?<4-3>3)|(?<3-4>3)|(?<5-4>4)|(?<4-5>4))*$

Це друкує 0або 1, відповідно.

Спробуйте в Інтернеті! (Це дещо змінена версія, яка позначає всі збіги у вводі замість друку 0або 1.)

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

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

^
(
    (?<a>1|2)
  | (?<b>2|3)
  | (?<c>3|4)
  | (?<d>4|1)
)
(
    (?<a-d>1) | (?<d-a>1)
  | (?<b-a>2) | (?<a-b>2)
  | (?<c-b>3) | (?<b-c>3)
  | (?<d-c>4) | (?<c-d>4)
)*
$

І ось натяк:

1  a  2

d  O  b

4  c  3

6

MATL , 57 55 байт

1t_hjnZ^!t1tL3$)2_/wvG1)UGnl2$Ov+Ys.5tv3X53$Y+4X\G!U=Aa

Для цього використовується поточний випуск (10.2.1) , який є раніше, ніж цей виклик.

EDIT (17 січня 2017): з - за змін в мові,v необхідно , щоб замінити &v, і tL3$)шляхом Y)(крім того, деякі інші поліпшення може бути зроблено). Наступне посилання включає ці дві модифікації

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

Пояснення

Це засновано на двох моїх улюблених інструментах для кодового гольфу: грубі сили та згортання .

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

З цього масиву контурів виходить масив нот , де кожен стовпець є реалізованою послідовністю відтворених нот. Наприклад, переміщення з позиції 0.5для 1.5створення ноти 1. Це полягає у прийнятті середнього значення між положеннями, а потім застосуванні операції модуля 4. Середнє середнє значення уздовж кожного стовпця проводиться з двовимірною згорткою .

Нарешті, програма перевіряє, чи який-небудь стовпчик масиву приміток збігається з вхідним.

1t_h        % row array [1, -1]
j           % input string
nZ^!        % Cartesian power of [1, -1] raised to N, where "N" is length of string
t           % duplicate
1tL3$)      % extract first row
2_/         % divide by -2
wv          % attach that modified row to the top of Cartesian power array
G1)U        % first character of input string converted to number, "x"
Gnl2$O      % column array of N-1 zeros, where N is length of input
v           % concat vertically into column array [x;0;0...;0]
+           % add with singleton expansion
Ys          % cumulative sum along each column. Each column if this array is a path
.5tv        % column array [.5;.5]
3X5         % predefined string 'same' (for convolution)
3$Y+        % 2D convolution of path array with [.5;.5]
4X\         % modified modulo operation. This gives note array with values 1,2,3,4
G!U         % column array of input string characters converted to numbers
=Aa         % true if any column of the note array equals this

5

Піта, 43

Km-R2sMdc`M%R4-VJjQTtJ`0|Fm!s-VKdCm_B^_1dlK

Тестовий сюїт

Це, мабуть, дуже гольф, а також не оптимальний алгоритм для гри в гольф (я думаю, що перерахування всіх шляхів буде коротшим?) ... У будь-якому випадку, якщо ви виявите помилку з алгоритмом, будь ласка, повідомте мене, я думаю, це має працювати, але я я помилявся раніше!

Я поясню свій алгоритм на прикладі введення 1221. Ця програма відображає перші цифри проти їхніх спадкоємців, так як: [[1,2],[2,2],[2,1]]. Тоді він отримує їх відмінність мод 4(Pyth отримує результат , який відповідає знаку правого аргументу %, так що це завжди позитивно) [3,0,1]. Тоді результати розщеплюються на 0і 2віднімається з кожного з них: [[1],[-1]].

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


Що ви маєте на увазі під "результати розбиті на 0"? Зокрема, що б ви отримали 1221221і 1221441?
Ніл

1
@Neil 1221221неправдивий і 1221441дає загальну істину, але якщо я зрозумів, що потрібно результат після цього кроку в алгоритмі? Якщо це так , це дає: від [3, 0, 1, 3, 0, 1]до [[3], [1, 3], [1]]і [3, 0, 1, 1, 0, 3]до [[3], [1, 1], [3]]. Повідомте мене, якщо ви хочете щось інше пояснити :)
FryAmTheEggman

Мені здається, я більше розгублений, ніж раніше, тому ви можете, будь ласка, закінчити ці два приклади, щоб пояснити, як досягаються (правильні) результати?
Ніл

1
@Neil Звичайно, немає проблем :) Звідти ми робимо віднімання , щоб отримати: [[1], [-1, 1], [-1]]і [[1], [-1, -1], [1]]звідси, ви можете побачити , що перший не мають списків , які чергуються між -1і в 1той час як інший список робить, що дає кінцевий результат. Алгоритм трохи тупий, але він в основному відображає зміни напрямку 0і напрямок як +/-1, а потім перевіряє, чи не виконуються стрибки, і напрямки мають сенс.
FryAmTheEggman

О, тож біт, який мені бракувало, полягав у тому, що кожен розділений список повинен складатися з одного і того ж значення, і ці значення повинні чергуватися. Дякую!
Ніл

4

Матлаб, 279 180 байт

o=eye(4);a=input('')-'0';M=[o,o(:,[4,1:3]);o(:,[2:4,1:4,1])];x=2;for p=[a(1),mod(a(1),4)+1];for k=a;i=find(M*[o(:,k);o(:,p)]>1);if i;p=mod(i-1,4)+1;else;x=x-1;break;end;end;end;x>0

Досить ліниве рішення, але найкоротше мені вдалося придумати. Я створив спеціальну матрицю: Коли ви кодуєте стан грабіжника і останню рядок, який повинен бути вирваний, він повертає вектор, який кодує нове положення грабіжника, і чи можливий був попередній планк взагалі. Тепер ми просто перебираємо всі ноти з двох можливих стартових позицій і бачимо, чи одна з них призводить до відтворюваної мелодії. Можливо, може бути гольф набагато більше.

Розширене та пояснене джерело:

o=eye(4);
a=input('')-'0';

% encoding of plucker/notes
%      1
%   1     2
%4           2
%   4     3
%      3
%

M=[...
%12 3 4 1 2 3 4 <
1,0,0,0,0,1,0,0; %1  k = current note
0,1,0,0,0,0,1,0; %2  
0,0,1,0,0,0,0,1; %3  
0,0,0,1,1,0,0,0; %4  
0,0,0,1,0,0,0,1; %1  p = current position of plucker
1,0,0,0,1,0,0,0; %2
0,1,0,0,0,1,0,0; %3
0,0,1,0,0,0,1,0];%4
% the vector we multiply with this matrix has following structure,
% the k-th and the p+4 th entries are 1, the rest 0
% when we multiply this vecotr with this matrix, we get a vector with an
% entry of value 2 IF this is a valid move ( mod(positionOfThe2 -1,4)+1 is
% the position of the plucker now)
% or only entries less than 2 it is impossible
x=2;  %number of "chances" to get it right
for p=[a(1),mod(a(1),4)+1] %check both starting values;
    for k=a;                %loop throu the notes
        size(M);

        c = M * [o(:,k);o(:,p)];
        i=find(c>1);               %did we find a 2?
        if i;
           p=mod(i-1,4)+1;         %if yes, valid move
        else;
            x=x-1;                 %if no, invalid, 
            break;
        end 
    end
end
x=x>0 %if we failed more than once, it is not possible

4

ES6, 104 100 байт

s=>!/13|24|31|42|3[24]{2}1|4[13]{2}2|1[24]{2}3|2[13]{2}4|(.).\1/.test(s.replace(/(.)(\1\1)+/g,"$1"))

Редагувати: Збережено 4 байти завдяки @DigitalTrauma.

Це повне переписування, оскільки мій попередній підхід був хибним.

Я починаю, зменшуючи всі прогони цифр до 1 або 2, залежно від того, чи було непарне чи парне число в ході. Потім я шукаю всі незаконні комбінації:

  • 13|24|31|42 (протилежні сторони)
  • 3[24]{2}1як 3221і 3441є незаконними
  • аналогічно для 4xx2, 1xx3і 2xx4де xє одна з пропущених цифр
  • (.).\1так як 121такі речі, як незаконні ( 111зводилися 1раніше)

Якщо немає незаконних пар або «трійки», то вся струна є законною (доказ за допомогою індукції залишається як вправа, оскільки тут пізно вночі).

Я спробував спростити 3[24]{2}1|1[24]{2}3використання негативного твердження lookahead, але це виявилося довше.


f("1122") => true@DigitalTrauma
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Я не бачу нічого поганого в цьому. З іншого боку, я зрозумів, що дає f("1221221")неправильну відповідь, тому мені доведеться переосмислити.
Ніл

Завжди приємно включити тестовий набір, "43221" не вдається: jsbin.com/vafitotequ/1/edit?js,console
Павло

@Pavlo Whoops, я б грав [24][24]у гольф, (2|4)\1але не пройшов належну перевірку. Вибач за те.
Ніл

Можете чи ви в гольф , [24][24]щоб [24]{2}?
Цифрова травма

2

JavaScript (ES6), 80 байт

s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r

Пояснення

i%4 є поточне положення кривошипа:

    1 (i%4 == 1) 2   

(i%4 == 0) (i%4 == 2)

    4 (i%4 == 3) 3   

Відступ та коментар

s=>
  [r=0,1,2,3].map(i=> // i = crank position, test for i starting at 0 to 3, r = result
    [...s].map(n=>    // for each note n
      n-1-i%4?        // if n is not at the position after i
        n%4-i%4?      // if n is not at the position before i
          v=0         // set the result of this test to invalid
        :i+=3         // else i-- (+3 used because i%4 would break for negative values)
      :i++,           // else i++
      v=1             // v = result of test, initialise to 1 (valid)
    )
    |v?r=1:0          // if the test returned true, set the result to true
  )
  |r                  // return the result

Тест

var solution = s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r
<input type="text" value="1221441" oninput="result.textContent=solution(this.value)" />
<pre id="result"></pre>


Чудово зроблено. Ви б пояснили, як |працює в цьому випадку?
Павло

1
@pavlo Дякую Це коротший спосіб написання (x.map(...),v). Він працює тому, що масив, який mapповертає, передає 0і 0|v == v.
користувач81655

2

Луа , 146 142 108 162 159 149 144 135 132 118 113 байт

z,q,s=0,0,io.read()for i in s:gmatch'.'do t=i-z if 2==math.abs(t)or t==q then return''end q=-t z=i end return 2>1

Повертає істинне або хибне, задане рядком чисел між 1 і 4. (Не обробляє дані або номери поза діапазоном).

Просто відслідковуйте, яким був останній рух, і перевіряєте, чи цей рух є переворотом останнього руху (IE, 121 або 12221) або якщо переміщення відстані більше, ніж можливо.

EDIT 1 :

Збережено 6 байт. Я забув, що if (int) thenповертає істину, якщо int не дорівнює нулю.

Таким чином:

if t~=0 then

зміни до:

if t then

Також зберегли кілька байт шляхом реструктуризації.

EDIT 2 :

Я повільно це з'ясовую. Я читав тут документацію: http://www.lua.org/pil/ І одна з більш корисних сторінок для гри в гольф - це http://www.lua.org/pil/3.3.html

Зокрема, це дуже корисно:

Як і керуючі структури, всі логічні оператори вважають false та nil хибними, а все інше - правдивим.

Це означає для мене, що я можу йти вперед і видалити свою декларацію для q ( яка спочатку була встановлена ​​на 0 ), оскільки вона буде вважатися "помилковою", поки вона не буде встановлена. Тому я економлю ще кілька байтів через це.

Ще одна річ, яку варто згадати, хоча я не використовую її, якщо ви хочете поміняти місцями значення в Lua, ви можете просто обійтися a,b=b,a без необхідності тимчасової змінної.

EDIT 3

Таким чином, завдяки розумній реконструкції, а також новій функції я отримав кількість байтів ще на 9.

Найкращий режим для отримання вводу

Якщо вам потрібно прочитати в списку чисел і робити по черзі операції над ними, ви можете використовувати:

for x in string:gmatch('.') do
    print(x) --This is our number
end

У порівнянні з вашою альтернативою за допомогою string: sub, ви можете побачити значення для гольфу (або загального використання):

for x=1,string:len() do
    print(string:sub(x,x)) --This is our number
end

Функції реструктуризації або рядки

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

x,y,z=io.read(),0,0 print('test')

if math.abs(x)==2 then

реструктуризувавши його, так що дужки, що закриваються, є останнім символом в умові або декларації, ви можете вирізати такий символ:

y,z,x=0,0,io.read()print('test') --Notice no space

if 2==math.abs(x)then --If we put the '2' first in the conditional statement, we can now remove a space character

Умови повернення, які відповідають істинним або помилковим, а не "істинним" або "помилковим"

Я знайшов напівсмішний спосіб зменшити кількість байтів ще далі. Якщо вам потрібно повернути true або false, ви можете повернути твердження, яке прирівнюється до true або false, яке містить менше символів, ніж самі "true" або "false".

Наприклад, порівняйте:

return true
return false

До:

return 2>1
return 1>2

121має вивести помилкове.
lirtosiast

Ах, ніколи не маю на увазі. Я бачу. Виправить невдовзі
Skyl3r

Можливо, вам буде цікаво додати деякі з цих порад щодо Луа в Поради щодо гольфу в Луа, якщо ви вже не бачите їх у списку.
апсилери

2

MATL, 49 байт (не конкуруючий 1 )

1. У відповіді (ab) використовується менш сувора індексація новіших версій MATL, і вона не працювала б під час опублікування цього виклику.

dt~aX`tt~f1)q:)w3MQJh)_ht~a]tT-3hX|n2=wT_3hX|n2=+

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

Я бачив цей виклик на Best of PPCG 2016 і зрозумів, що це може використовувати мій улюблений оператор :

d

Або diffв MATLAB / Octave (я вільно буду використовувати терміналогію MATLAB / Octave у своєму поясненні, оскільки її легше читати для людей). Ця команда обчислює елементну різницю у векторі або, у цьому випадку, у масиві символів.

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

Зміна напрямку повинна означати, що нота відтворюється двічі .

Для картини різниці (ігнорування 1-4переходу на даний момент) це означає, що

Зміни входу diff(input)повинні мати непарну кількість нулів між ними. І навпаки, знак не дозволяється змінювати після парного числа нулів.


Я реалізував це, для кожного масиву, знайшовши перший нуль. Я обрізаю нуль і множу всі елементи після нього на -1. Для кінцевого результату це означає, що всі елементи повинні мати однаковий знак. Звичайно, існує невелике питання про -3рівність +1і 2взагалі заборонено. Я вирішив це, взявши встановлене об'єднання результату [1 -3]і перевіривши, чи він має розмір 2 (тобто жодні заборонені елементи не вводили набір через об'єднання). Повторіть для цього [-1 3]і перевірте, чи однаково (або обидва, у випадку введення 1 довжини) вірно.

d                                % Difference of input
 t~a                             % Check if any element equals 0
    X`                     t~a]  % Start while loop, ending in the same check
       t~                           % Get a new vector, logical negated to find zeroes.
          f1)                       % Find the position of the first zero. 
      t         q:)                 % Decrement by 1, to index all elements before that zero.
                   w3MQJh)          % Push the result of 'find', but increment to get all elements after.
                         _h         % Multiply the second half by -1, and concatenate horizontally.

  T-3hX|n2=                      % Check if set union with [1 -3] is size 2
 t        wT_3hX|n2=             % Check if set union with [-1 3] is size 2
                    +            % Logical OR. 

@LuisMendo Дякую Мені справді потрібно читати далі M, коли я останній раз пробував це, воно працювало інакше, ніж очікувалося, тому я просто проігнорував це. Чи правильно сказати, що це потрібно, 3Mтому що тоді я отримую вклад не ), :а не q(пропускаючи, wоскільки це не нормальна функція)?
Санчіз

Так, саме. wпропускається, оскільки це не нормальна функція. Звичайні функції, які не беруть ніяких входів, також будуть пропущені
Луїс Мендо

2

Python (3,5) 160 151 150 байт

Рекурсивне рішення

def f(s):g=lambda s,c:s==''or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])if s==''or s[0]in c[:2]else 0;return any([g(s,"1234123"[i:])for i in range(4)])

Безумовно без лямбда

def f(s):
    def g(s,c):
        if s=='' or s[0] in c[:2] :
            return s=='' or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])
        else:
            return False
    return any([g(s,"1234123"[i:]) for i in range(4)])

Я обертаю всю коробку замість кривошипа. Положення кривошипа знаходиться між першим і другим символом рядка c. Мені потрібно перевірити все початкове положення кривошипа.

Використовуйте трюк для обертання рядка

Звичайний спосіб обертання рядка в python ( s[i:]+s[:i]) також повинен повторювати і індекс, і рядок. У цьому випадку я дублюю рядки та обрізаю перші символи.

(c*2)                        # duplicate the string
     [(s[0]==c[0])*2+1       # test that return 1 if firsts characters match 3 instead 
                      :]     
                        [:4] # crop again to have a 4 characters string

Тестові справи

[f(i) for i in ["1", "1234", "1221", "3333", "143332", "22234", "2234", "22214", "1221441", "41233", "13", "1224", "121", "12221", "43221"]]
[True, True, True, True, True, True, True, True, True, True, False, False, False, False, False]

1
Ви можете видалити місце в 3"[i:]) for.
Ерік Аутгольфер

@EriktheOutgolfer дякую, що я його видаляю.
Ерван


1

JavaScript (ES2015), 110 95

p=(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))

15 байт, збережених Нілом! Оригінальна версія ungolfed:

p = (s, d) => {
  h = s[0]
  t = s.substr(1)

  if (!t[0]) return true
  if (!d) return p(s, 1) || p(s, -1)
  if (t[0] == h) return p(t, d*-1)
  if (t[0] == (h-d > 4 ? 1 : h-d || 4)) return p(t, d)

  return false
}

Тести: https://jsbin.com/cuqicajuko/1/edit?js,console


1
Врятувало вас 17 байт:(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))
Ніл

Все-таки не така коротка, як відповідь @ user81655.
Ніл

1

Код машини Тьюрінга, 395 байт

0 1 _ r a
0 2 _ r b
0 3 _ r c
0 4 _ r d
a 1 _ r a
a 2 _ r E
a 3 _ r h
a 4 _ r S
b 1 _ r W
b 2 _ r b
b 3 _ r S
b 4 _ r h
c 1 _ r h
c 2 _ r N
c 3 _ r c
c 4 _ r W
d 1 _ r N
d 2 _ r h
d 3 _ r E
d 4 _ r d
N 1 _ r W
N 2 _ r E
N _ _ r r
N * _ r h
E 2 _ r N
E 3 _ r S
E _ _ r r
E * _ r h
S 3 _ r E
S 4 _ r W
S _ _ r r
S * _ r h
W 4 _ r S
W 1 _ r N
W _ _ r r
W * _ r h
h _ 0 r halt
h * _ r h
r _ 1 r halt

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

Це в основному підхід, заснований на державі:

  • Початковий стан дорівнює 0.
  • a, b, cІ dє «не визначився державою» , які тільки відбуваються на початку
  • N, E, S, І Wє «вирішили держави», очевидно , стоячи на NОрт, Eаст, South і WЕСТА.

1

Чт, 203 байти

Я не можу придумати, як далі гольфу.

0::=:::
>11::=>1
>22::=>2
>33::=>3
>44::=>4
>12::=b
>21::=d
>14::=c
>41::=a
>23::=c
>32::=a
>34::=d
>43::=b
a1::=d
a2::=b
b2::=a
b3::=c
c3::=b
c4::=d
d4::=c
d1::=a
a<::=~n
b<::=~e
c<::=~s
d<::=~w
::=
>0<

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


1

Пролог (SWI) , 117 байт

a(N,P):-P=N;N=1,P=4,!;P is N-1.
m([A,B|C],[X,Y|Z]):-a(A,X),a(B,X),a(B,Y),X\=Y,m([B|C],[Y|Z]).
m([_],_).
p(N):-m(N,_).

Визначає присудок, pякий досягає успіху на відтворюваних введеннях (подається у вигляді списку цілих чисел), а на невідтворюваних - невдалий. Спробуйте в Інтернеті!

Пояснення

aвизначає співвідношення суміжності між нотою Nта позицією кривошипа P. Позицію p визначаємо між примітками p і p + 1 . Таким чином, положення суміжне з приміткою Niff

  • вона дорівнює N( P=N); або
  • примітка - 1, а позиція - 4 ( N=1,P=4); або
  • вищезазначений випадок не відповідає дійсності ( !), а позиція дорівнює N-1( P is N-1).

mбере список нотаток і намагається сформувати список позицій, які будуть відтворювати ці нотатки. A- нота щойно відіграна, B- це нота, яку потрібно відтворити; X- поточне положення кривошипа, Yнаступне положення кривошипа. Хід дійсний iff

  • щойно відтворена нота прилягає до поточного положення кривошипа ( a(A,X));
  • примітка про відтворення також суміжна з поточним положенням кривошипа ( a(B,X));
  • примітка про відтворення прилягає до наступної позиції кривошипа ( a(B,Y)); і
  • два положення кривошипа не рівні ( X\=Y).

Якщо все це дотримано, повторіть. Якщо ми успішно переходимо до будь-якої однієї ноти ( m([_],_)), послідовність нот відтворюється.

Для цього питання нас цікавить лише те, чи існує послідовність рухів, тому ми визначаємо pдля виклику mта відкидання створеного списку позицій кривошипів.

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

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