Pomóż pannenkoek liczyć prasy A.

28

Pannenkoek2012 ma na celu ukończenie Super Mario 64 przy jak najmniejszej liczbie naciśnięć przycisku A, co powoduje, że Mario skacze. Każda „prasa” składa się z trzech części:

  • Naciśnięcie przycisku
  • Trzymając go przez dowolny czas
  • Zwolnienie go

Części prasy A, z wideo Pannenkoek2012

Zobacz to wideo (1:15 - 3:23), aby uzyskać świetne wyjaśnienie obejmujące powyższy obraz. (Jednak to wyzwanie nie będzie korzystało z terminologii pół-A i będzie stanowić przeszkodę wymagającą zwolnienia A.)

Zadanie:

Biorąc pod uwagę sekwencję przeszkód wymagających naciśnięcia (P), przytrzymania (H) lub zwolnienia (R) przycisku A, wypisz najmniejszą liczbę naciśnięć wymaganych do ich pokonania w podanej kolejności. Przycisk A początkowo nie jest trzymany.

Formalnie sformułowane: biorąc pod uwagę ciąg S znaków PHR, rozważ ciągi znaków (PH*R)*zawierające S jako podsekwencję i wyprowadzaj najmniejszą możliwą liczbę Ptakich ciągów. Lub, alternatywnie, znajdź najmniejszą liczbę części formy, na P?H*R?którą można podzielić S.

Przykład

Spójrzmy na dane wejściowe RHRPHHHR. Przycisk A nie zaczyna się przytrzymywać, więc pokonanie początkowej przeszkody Rwymaga naciśnięcia i zwolnienia przycisku (naciśnij # 1). Następnie musimy przytrzymać przycisk H, który ponownie wymaga pierwszego naciśnięcia (naciśnij # 2). Następnie można go później zwolnić, aby zaspokoić Rpóźniej. Wreszcie, pozostałe PHHHRmożna zaspokoić pojedynczym naciśnięciem (naciśnij 3), a następnie przytrzymaniem HHHi zwolnieniem R. Tak więc liczba wyjść wynosi 3.

Innym sposobem, aby to zobaczyć, jest to, że możemy podzielić ciąg wejściowy na 3 części formularza, w PHH..HHRktórych litery można pominąć.

R
HR
PHHHR    

Format wejściowy

Dane wejściowe będą listą lub ciągiem elementów reprezentujących naciśnięcie, przytrzymanie i zwolnienie jako wybór:

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

dopasowane w podanej kolejności. Dane wejściowe nie będą puste.

Przypadki testowe:

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

Tabela liderów:

xnor
źródło
1
Co z przeszkodami, które wymagają, aby przycisk A nie był trzymany? Na wykresie są cztery stany przycisków ( myślę, że one również mogą istnieć w grze)
Random832
3
W rzeczywistości istnieją 3 stany: Prasa, Wstrzymane i Nie wstrzymane. Żaden stan nie wymaga zwolnienia przycisku A. Wyzwanie jest nieco błędne w porównaniu z rzeczywistością.
user202729,
1
@ 11684 „co do wydania, cóż, obecnie nie ma przypadków, w których jest to przydatne lub ważne, więc nie martw się o tę część”. (1:48 - 1:52)
user202729
3
Czy ktoś chce to zrobić podczas montażu MIPS? (język używany do programowania Super Mario 64)
202729
1
@ user202729 Wow, to jeden dokładny naleśnik. Dzięki!
11684

Odpowiedzi:

3

Pyth , 13 bajtów

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

Wypróbuj tutaj! lub Zweryfikuj wszystkie przypadki testowe.

Pamiętaj, że 1działa również zamiast 3.

Jak to działa?

tl: z "P? H * R?" 3 | Pełny program Pobiera dane wejściowe ze STDIN, dane wyjściowe do STDOUT.

  : z 3 | Podziel ciąg wejściowy na dopasowania ...
    „P? H * R?” | Wyrażenie regularne „P? H * R?”.
 l | Uzyskaj długość.
t | Zmniejszenie (ponieważ podział obejmuje pusty ciąg).

Więcej informacji o wyrażeniu regularnym:

P | P - Dosłowny znak P, wielkość liter ma znaczenie.
       | ? - Kwantyfikator. Dopasowuje jeden lub zero razy poprzedni znak.
  H * | H - Dosłowny znak H, wielkość liter ma znaczenie.
       | * - Kwantyfikator. Dopasowuje dowolną liczbę wystąpień poprzedniego znaku.
    R? | R - Dosłowny znak R, wielkość liter ma znaczenie.
       | ? - Kwantyfikator. Dopasowuje jeden lub zero razy poprzedni znak.
Pan Xcoder
źródło
Ach, kurwa, pobiłeś mnie!
Kudłaty
miły! Przedostatni wiersz w opisie wyrażenia regularnego powinien zawierać „literał R”, prawda?
vidstige
@vidstige Tak, dziękuję. Naprawiono
Mr. Xcoder
2

Galaretka , 10 bajtów

o5ḄƝ%⁵>4S‘

Monadyczny łańcuch pobierający listę ( P,H,R : 0,1,2opcja) i zwracający liczbę całkowitą - liczba.

Wypróbuj online! lub zobacz zestaw testowy

W jaki sposób?

Skutecznie działa poprzez uzyskanie wszystkich sąsiednich par następnie licząc te, które nie są „pary kontynuacja” ( PR, PH, HR, lub HH) i dodanie jednego.

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

Poprzednie 11 bajtowe rozwiązanie:

ḅ3Ɲạ3ḟ1,2L‘

Wypróbuj online! lub zobacz zestaw testowy

W jaki sposób?

Działa jak wyżej, ale w zupełnie inny sposób ...

ḅ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

i kolejny, znowu całkiem inny:

+19*Ɲ%13ḂS‘

(dodaj 19 do każdego, następnie dla sąsiednich par wykonaj potęgowanie, modulo o 13, modulo o 2, sumuj i dodaj jeden).

Jonathan Allan
źródło
Nowa galaretka szybko!
user202729,
2

Partia, 69 bajtów

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

Pobiera dane wejściowe jako listę parametrów wiersza polecenia o indeksie 0, ale możesz użyć listy liter p, h, rpisanych wielkimi lub małymi literami, jeśli wpiszesz set /a p=0, h=1, r=2najpierw. Objaśnienie: bzachowuje ostatnie wejście (domyślnie 2dla zwolnionego) i nliczbę naciśnięć. Każde wejście dodaje naciśnięcie, jeśli ostatnim wejściem było zwolnienie lub bieżącym wejściem jest naciśnięcie.

Neil
źródło
Och, czy setmożna ustawić wiele zmiennych jednocześnie? Warto wiedzieć.
user202729,
1
@ użytkownik202729 set /ajest obliczeniem arytmetycznym, więc tak długo, jak wszystkie zmienne, które chcesz ustawić, są liczbowe, możesz po prostu użyć operatora przecinka, aby połączyć wyrażenia przypisania.
Neil
2

Python 2, 44 bajty

Wykorzystuje P-> 1 H-> 2 R-> 3

lambda a:sum(1/y|x/3for x,y in zip([3]+a,a))
feersum
źródło
1

Python 2 , 48 bajtów

f=lambda a,*l:l==()or(a>l[0]or l[0]==a!=1)+f(*l)

Wypróbuj online!

Pobiera 0,1,2jako dane wejściowe.

ovs
źródło
1

Łuska , 6 5 bajtów

Lġo&ε

Wypróbuj online! Dane wejściowe to lista 0,1,2(link TIO używa liter w celu łatwiejszego wklejania przypadków testowych).

Wyjaśnienie

Używam tego samego ogólnego pomysłu, co odpowiedź Jelly'ego Allana : podzielenie na wystąpienia „par nieciągłości” PP, HP, RH, RR i RP, i liczę powstałe bloki. W kodowaniu 0,1,2 pary te są dokładnie tymi, których lewy element to 2 lub prawy element to 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.
Zgarb
źródło
1

JavaScript (ES6), 30 bajtów

f=s=>s.match(/P?H*R?/g).length-1
<input id=i oninput="o.innerText=f(i.value)" value="PHHR"><pre id=o>l

Herman L.
źródło
1

Galaretka , 10 bajtów

Pn1></µƝS‘

Wypróbuj online! lub pakiet testowy! ( Skradziony pożyczony od Jonathana).

Alternatywny:

P=1=</µƝS‘

Wypróbuj online!

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.

Galaretka , 11 bajtów

Zapisano 1 bajt dzięki pomocy Cairney Coheringaahing.

ḅ3Ɲf⁽vḲD¤L‘

Wypróbuj online!

Pan Xcoder
źródło
Aww, straciłem okazję, by jako pierwszy szybko skorzystać z sąsiadów :(
Cairn coinheringaahing
Możesz usunąć μz trzeciego
caird coinheringaahing
1

Kotlin , 36 bajtów

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

Upiększony

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

Test

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

jrtapsell
źródło
0

J , 18 17 bajtów

-1 Dzięki @FrownyFrog

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

Pobiera dane wejściowe w postaci 0,1,2. Funkcja pomocnicza w TIO konwertuje przypadki testowe do tego formularza.

Wypróbuj online!

Logika porównań może być nadal możliwa do gry w golfa. Przekręcam mózg w węzły, próbując wymyślić bardziej równoważne i krótsze stwierdzenia.

Wyjaśnienie (poprzednie rozwiązanie)

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

Jedyną różnicą między obecnym rozwiązaniem a poprzednim jest sposób generowania porównań. Obecne rozwiązanie wyraźnie porównuje sąsiednie elementy poprzez przesunięcie tablicy, a poprzednie rozwiązanie porównuje sąsiednie elementy, patrząc na przyrostki 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

Byłoby to o wiele czystsze, gdyby dwa ładownie nic nie zrobiły. Kod przyjmuje dwa ciągi znaków i sprawdza, czy nie rosną, a nie dwa wstrzymania. W takim przypadku dodajemy jeden do naszej ostatecznej liczby. Musimy dodać 1 na końcu, ponieważ w przeciwnym razie jesteśmy o jeden (lub możesz dodać wcześniej _dowolną wartość większą niż 2).

Sposób, w jaki sprawdza, czy infix jest dwoma blokadami, polega na pomnożeniu dwóch wartości razem i sprawdzeniu, czy jest to jedna (dwie blokady są 1 1).

kapusta
źródło
1
1+1#.}:(<+:1=*)}.jest jeden krótszy.
FrownyFrog,
@FrownyFrog sprytny, zmienię to w.
cole
1
14:1+1#.0=}.*2-}:
FrownyFrog,
0

Vim + wc, 25 bajtów

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

jest klawiszem powrotu i jest Ctrl+X

Wypróbuj online!

Wyjaśnienie

:s/P\?H*R\?/a/g␊    Replace all button presses with the character a
V!wc -c␊␘          Count the characters using the wc command
Herman L.
źródło