Помогите панненькоек посчитать А прессами


28

Pannenkoek2012 стремится завершить Super Mario 64 с минимальным количеством нажатий кнопки A, что заставляет Mario прыгать. Каждый «Пресс» состоит из трех частей:

  • Нажатие кнопки
  • Держать его в течение любого промежутка времени
  • Выпуская это

Части пресса, из видео Pannenkoek2012

Посмотрите это видео (1:15 - 3:23) для лучшего объяснения, которое включает в себя изображение выше. (Тем не менее, эта задача не будет использовать терминологию полу-пресса и создаст препятствия, которые требуют освобождения А.)

Задача:

Учитывая последовательность препятствий, требующих нажатия (P), удерживания (H) или отпускания (R) кнопки A, выведите наименьшее количество нажатий, необходимых для их преодоления, в указанном порядке. Кнопка А изначально не удерживается.

Сформулируем формально: учитывая строку символов S PHR, рассмотрим строки формы, (PH*R)*которые содержат S как подпоследовательность, и выведите наименьшее возможное число P's в такой строке. Или, в качестве альтернативы, найдите наименьшее количество кусков в форме, на P?H*R?которые можно разбить S.

пример

Давайте посмотрим на вход RHRPHHHR. Кнопка A начинает не удерживаться, поэтому для преодоления начального препятствия Rнеобходимо нажать и отпустить кнопку (нажмите # 1). Затем мы должны удерживать кнопку H, которая снова требует, чтобы она сначала была нажата (нажмите # 2). Затем он может быть затем отпущен для удовлетворения Rпосле него. Наконец, оставшиеся PHHHRмогут быть удовлетворены с помощью одного нажатия (нажмите # 3), а затем удерживая HHHи отпуская R. Итак, количество выводов равно 3.

Другой способ увидеть это, это то, что мы можем разбить входную строку на 3 части формы, PHH..HHRгде буквы могут быть опущены.

R
HR
PHHHR    

Формат ввода

Входными данными будет список или строка элементов, представляющих нажатия, удержания и отпускания по вашему выбору:

  • P, H, R
  • p, h, r
  • 1, 2, 3
  • 0, 1, 2

соответствует в указанном порядке. Ввод не будет пустым.

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

P 1
H 1
R 1
HP 2
RHP 3
HHR 1
PHRH 2
RHRPHHHR 3
HHHHHH 1
PPRRHHPP 6
HPPRHRPRHPPRHPPHRP 12
PRHRHPHHPRRRHPPRHHPPRRRHRHPRPHPRPRHHRPPPRHPRP 28

Leaderboard:


1
Как насчет препятствий, требующих, чтобы кнопка A не удерживалась? На графике четыре состояния кнопок (я думаю, что они тоже могут существовать в игре)
Random832

3
В действительности существует 3 состояния: «Пресса», «Задержано» и «Не удержано». Никакое государство не требует выпуска кнопки A. Задача немного ошибочна по сравнению с реальностью.
user202729

1
@ 11684 "Что касается выпуска, ну, в настоящее время нет случаев, когда это полезно или важно, так что не беспокойтесь об этой части." (1:48 - 1:52)
user202729

3
Кто-нибудь хочет сделать это в сборке MIPS? (язык, используемый для программирования Super Mario 64)
user202729

1
@ user202729 Ого, это один полный блин. Благодарность!
11684

Ответы:



3

Pyth , 13 байт

tl:z"P?H*R?"3

Попробуй это здесь! или Проверьте все контрольные примеры.

Обратите внимание, что 1также работает вместо 3.

Как это работает?

tl: z "P? H * R?" 3 | Полная программа. Принимает ввод из STDIN, выводит в STDOUT.

  : z 3 | Разбить входную строку на совпадения ...
    «Р? Н * Р?» | Регулярное выражение «P? H * R?».
 л | Получить длину.
т | Уменьшение (потому что разделение включает в себя пустую строку).

Подробнее о регулярном выражении:

П? | P - буквенный символ P, чувствительный к регистру.
       | ? - Квантор. Соответствует одному или нулю умноженному на предыдущий символ.
  H * | H - Буквенный символ H, чувствителен к регистру.
       | * - Квантор Соответствует любому числу вхождений предыдущего символа.
    Р? | R - Буквенный символ R, чувствителен к регистру.
       | ? - Квантор. Соответствует одному или нулю умноженному на предыдущий символ.

Ах, чёрт, ты побил меня этим!
Лохматый

хороший! От второй до последней строки в описании регулярного выражения должно быть написано «Литеральный символ R», верно?
виджет

@vidstige Да, спасибо. Исправлено
г-н Xcoder

2

Желе , 10 байт

o5ḄƝ%⁵>4S‘

Монадическая цепочка, принимающая список ( P,H,R : 0,1,2опция) и возвращающая целое число, количество.

Попробуйте онлайн! или посмотрите набор тестов

Как?

Эффективно работает путем получать все смежные пары , то считая , что любой не «продолжение» пары ( PR, PH, HR, или HH) и добавив к нему один.

o5ḄƝ%⁵>4S‘ - Link: list of integers (in [0,1,2])  e.g.: [0,0,1,0,2,1,1,2,2,0] (representing PPHPRHHRRP)
o5         - logical OR with 5                          [5,5,1,5,2,1,1,2,2,5]
   Ɲ       - for all adjacent pairs:              i.e.: [5,5],[5,1],[1,5],[5,2],[2,1],[1,1],[1,2],[2,2],[2,5]
  Ḅ        -   convert from binary                      [ 15 ,  11 ,  7  ,  12 ,  5  ,  3  ,  4  ,  6  ,  9 ]
     ⁵     - literal ten
    %      - modulo                                     [  5 ,   1 ,  7  ,   2,   5  ,  3  ,  4  ,  6  ,  9 ]
      >4   - greater than four?                         [  1 ,   0 ,  1  ,   0,   1  ,  0  ,  0  ,  1  ,  1 ]
        S  - sum                                        5
         ‘ - increment                                  6

Предыдущее 11-байтовое решение:

ḅ3Ɲạ3ḟ1,2L‘

Попробуйте онлайн! или посмотрите набор тестов

Как?

Работает как выше, но совершенно по-другому ...

ḅ3Ɲạ3ḟ1,2L‘ - Link: list of integers (in [0,1,2])  e.g.: [0,0,1,0,2,1,1,2,2,0] (representing PPHPRHHRRP)
  Ɲ         - for all adjacent pairs:              i.e.: [0,0],[0,1],[1,0],[0,2],[2,1],[1,1],[1,2],[2,2],[2,0]
ḅ3          -   convert from base three                  [ 0  ,  1  ,  3  ,  2  ,  7  ,  4  ,  5  ,  8  ,  6 ]
   ạ3       - absolute difference with three             [ 3  ,  2  ,  0  ,  1  ,  4  ,  1  ,  2  ,  5  ,  3 ]
     ḟ1,2   - filter discard if in [1,2]                 [ 3        ,  0        ,  4              ,  5  ,  3 ]
         L  - length                                     5
          ‘ - increment                                  6

и другое, опять же совсем другое:

+19*Ɲ%13ḂS‘

(добавьте 19 к каждому, затем для соседних пар возведите в степень, по модулю 13, по модулю 2, суммируйте и добавьте единицу).


Новый желе быстро!
user202729

2

Пакетный, 69 байт

@set/ab=2,n=0
@for %%b in (%*)do @set/an+=b/2^|!%%b,b=%%b
@echo %n%

Принимает ввод как список 0-индексированных параметров командной строки, но вы можете использовать список букв p, h, rв верхнем или нижнем регистре, если вы наберете set /a p=0, h=1, r=2первый. Объяснение: bведется последний ввод (по умолчанию 2для выпущен) и nколичество нажатий. Каждый ввод добавляет нажатие, если последний вход был выпуском или текущий ввод является нажатием.


О, setможно установить несколько переменных одновременно? Полезно знать.
user202729

1
@ user202729 set /a- это арифметическая оценка, поэтому, пока все переменные, которые вы хотите установить, являются числовыми, вы можете просто использовать запятую для объединения выражений присваивания.
Нил

2

Python 2, 44 байта

Использует P-> 1 H-> 2 R-> 3

lambda a:sum(1/y|x/3for x,y in zip([3]+a,a))




1

Шелуха , 6 5 байт

Lġo&ε

Попробуйте онлайн! Ввод - это список поверх 0,1,2(ссылка TIO использует буквы для упрощения копирования тестовых случаев).

объяснение

Я использую ту же общую идею, что и в ответе Jelly на Джонатана Аллана : разбить на случаи появления «пар разрывов» PP, HP, RH, RR и RP и подсчитать полученные блоки. В кодировке 0,1,2 эти пары являются именно теми, чей левый элемент равен 2 или правый элемент равен 0.

Lġo&ε  Input is a list.
 ġ     Split between pairs that do not satisfy:
    ε  the left element is at most 1
  o&   and the right element is truthy.
L      Length.



1

Желе , 10 байт

Pn1></µƝS‘

Попробуйте онлайн! или тестовый набор! ( Украдено Заимствовано у Джонатана.)

Альтернатива:

P=1=</µƝS‘

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

Pn1></µƝS‘ | Monadic chain.

      µƝ   | Map over each pair of "neighbours" (x, y) in the list.
P          | And check whether their product...
 n1        | ... 1 if it doesn't equal 1, 0 otherwise...
   >       | Is higher than?
    </     | The pair reduced by "Smaller than?". 1 if x < y, else 0.
        S  | Sum.
         ‘ | Add 1.

Желе , 11 байт

Сохранено 1 байт с помощью caird.

ḅ3Ɲf⁽vḲD¤L‘

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


Ой, я упустил шанс первым быстро использовать соседей :(
caird coinheringaahing

Вы можете удалить μиз третьего
caird coinheringaahing

1

Котлин , 36 байт

Regex("P?H*R?").findAll(i).count()-1

украшенный

Regex("P?H*R?").findAll(i).count()-1

Тест

fun f(i:String) =
Regex("P?H*R?").findAll(i).count()-1
data class Test(val input: String, val output: Int)

val TESTS = listOf(
        Test("P", 1),
        Test("H", 1),
        Test("R", 1),
        Test("HP", 2),
        Test("RHP", 3),
        Test("HHR", 1),
        Test("PHRH", 2),
        Test("RHRPHHHR", 3),
        Test("HHHHHH", 1),
        Test("PPRRHHPP", 6),
        Test("HPPRHRPRHPPRHPPHRP", 12),
        Test("PRHRHPHHPRRRHPPRHHPPRRRHRHPRPHPRPRHHRPPPRHPRP", 28)
)

fun main(args: Array<String>) {
    for ((input, expectded) in TESTS) {
        val actual = f(input)
        if (actual != expectded) {
            throw AssertionError("$input $expectded $actual")
        }
    }
}

TIO

TryItOnline


0

J , 18 17 байт

-1 Спасибо @FrownyFrog

1+1#.}:(<+:1=*)}.

Принимает вход в виде 0,1,2. Вспомогательная функция в TIO преобразует контрольные примеры в эту форму.

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

Логика сравнений все еще может быть пригодна для игры в гольф. Я скручиваю свой мозг в узлы, пытаясь придумать более эквивалентные и короткие выражения.

Пояснение (предыдущее решение)

1+1#.2(</+:1=*/)\]

Единственная разница между текущим решением и предыдущим заключается в том, как создаются сравнения. Текущее решение явно сравнивает соседние элементы путем смещения массива, а предыдущее решение сравнивает соседние элементы, просматривая инфиксы 2.

1 + 1 #. 2 (</ +: 1 = */)\ ]
         2               \ ]  On infixes of 2 on the input
                  1 = */        Is the infix 1 1 (two holds)?
            </                  Is the infix x y such that x < y?
               +:               These results NORed
    1 #.                       Add all of the results together (debase to base 1)
1 +                            Add one

Это было бы намного чище, если бы два трюма ничего не сделали. Код принимает инфиксы из двух и проверяет, не являются ли они восходящими и не являются ли они двумя. Если это так, то мы добавляем один к нашему окончательному счету. Мы должны добавить 1 к концу, так как иначе мы на единицу (или вы можете добавить _или любое значение больше 2).

Он проверяет, является ли инфикс двумя удержаниями, путем умножения двух значений вместе и проверки, является ли оно одним (два удержания являются 1 1).


1
1+1#.}:(<+:1=*)}.один короче.
FrownyFrog

Умный @FrownyFrog, я отредактирую это в.
Коул

1
14:1+1#.0=}.*2-}:
FrownyFrog

0

Vim + wc, 25 байт

:s/P\?H*R\?/a/g␊V!wc -c␊␘

является ключом возврата и является Ctrl+X

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

объяснение

:s/P\?H*R\?/a/g␊    Replace all button presses with the character a
V!wc -c␊␘          Count the characters using the wc command
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.