帮助pannenkoek数A印刷机


28

pannenkoek2012的目标是通过尽可能少地按A按钮来完成Super Mario 64,这会使Mario跳跃。每个“印刷机”都由三个部分组成:

  • 按下按钮
  • 持有任何时间
  • 发布

A印刷机的零件,摘自Pannenkoek2012的视频

请观看此视频(1:15-3:23),以获取包含上述图片的精彩说明。(但是,此挑战将不使用半按A术语,并且会提出需要释放A的障碍。)

任务:

给定一系列需要按下(P),按住(H)或释放(R)A按钮的障碍物,请按给定的顺序输出克服这些障碍物所需的最少按下次数。最初不按住A按钮。

正式表示:给定一个字符串S,将包含S PHR的形式的字符串(PH*R)*视为子序列,并P在这样的字符串中输出尽可能少的。或者,找到P?H*R?可以拆分为S 的形式的最小块数。

让我们看一下input 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

排行榜:


1
要求不按住A按钮的障碍物怎么办?图中有四个按钮状态(我认为它们也可能确实存在于游戏中)
Random832 '18

3
实际上,有3种状态:按下,保持和不保持。没有状态要求释放A按钮。与现实相比,这一挑战略有错误。
user202729

1
@ 11684“关于版本,好吧,目前尚无有用或重要的案例,因此不必担心该部分。” (1:
48-1

3
任何人都想在MIPS组装中这样做吗?(用于对Super Mario 64进行编程的语言)
user202729

1
@ user202729哇,那真是个薄煎饼。谢谢!
11684

Answers:



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?H * R?”。
 l | 得到长度。
t | 减量(因为拆分包括空字符串)。

有关正则表达式的更多信息:

P?| P –文字字符P,区分大小写。
       | ?–量词。匹配上一个字符的一倍或零倍。
  H * | H –文字字符H,区分大小写。
       | * –量词。匹配任意数量的前一个字符。
    R?| R –文字字符R,区分大小写。
       | ?–量词。匹配上一个字符的一倍或零倍。

啊,老兄,你击败了我!
毛茸茸的

真好!regexp描述中的倒数第二行应该说“字母R”,对吗?
vidstige

@vidstige是的,谢谢。已修正
Xcoder先生18年

2

果冻,10字节

o5ḄƝ%⁵>4S‘

单链,带有一个列表(P,H,R : 0,1,2选项)并返回一个整数,即计数。

在线尝试!或见测试人员

怎么样?

通过让所有相邻的一对,然后计算任何不在“的延续对”有效地工作(PRPHHR,或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为模,求和并加1)。


新果冻快!
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链接使用字母,以便于复制和粘贴测试用例)。

说明

我使用与乔纳森·艾伦Jonathan Allan)的果冻(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

Javascript(ES6),30个字节

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



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字节

在caird coinheringaahing的帮助下保存了1个字节。

ḅ3Ɲf⁽vḲD¤L‘

在线尝试!


噢,我错过了成为第一个快速使用邻居的机会了:(
Caird coinheringaahing

您可以μ从第三者中删除
Caird coinheringaahing

1

Kotlin,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")
        }
    }
}

蒂奥

在线试用


0

J18 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聪明,我将其编辑。–
cole

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.