我的“钥匙孔”让我感到无聊!帮我找到最小的按键


13

感谢@ Agawa001提出了这个问题。

说明

我的新“键盘孔”只有2个按钮,分别是+-

内存中的数字从开始0

每次连续按+或,-将精确地增加/减少内存连续被按下的次数。

因此,如果按+4次,则第一次加1,第二次加2,第三次加3,第四次加4,为您10(十)。

现在,如果您按-3次,则第一次按1,第二次为2,第三次为3,剩下的是4(四)。

TL; DR

给定一个字符串+和-,请在每次更改字符时将其分开。然后,每个生成的m个+符号字符串将第m个三角形数相加,而n个-符号的每个字符串将第n个三角形数相减。

演练

现在,如果您仍然不了解,我将向您展示如何+++--+--创建1

Program   | Counter | Memory
----------------------------
          |  0      | 0
+         | +1      | 1
++        | +2      | 3
+++       | +3      | 6
+++-      | -1      | 5
+++--     | -2      | 3
+++--+    | +1      | 4
+++--+-   | -1      | 3
+++--+--  | -2      | 1

任务

  • 您将使用正整数作为输入,可以作为函数参数或来自STDIN。
  • 然后,您将使用上述方法输出/打印创建该数字所需的最小击键次数。

测试用例

由于重新排列+-运行的次数相同,因此,对于每个此类组,仅列出字典顺序最早的序列。

Input | Output | Possible corresponding sequences
-------------------------------------------------
    4 |      5 | -+++-
    6 |      3 | +++
    9 |      5 | ++++-
   11 |      7 | +++-+++
   12 |      7 | +++++--, ++++-++
   19 |      8 | -++++++-
   39 |     12 | +++++++++---
   40 |     13 | +++++++++---+, ++++++++-+++-
   45 |      9 | +++++++++
   97 |     20 | ++++++++++++++--+---, +++++++++++++-++++--, ++++++++++++-++++++-
  361 |     34 | ++++++++++++++++++++++++++-+++-+++

额外资源

计分

这是。以字节为单位的最短解决方案获胜。


9
这是否意味着...您感到无聊?
busukxuan

我认为您现在可以接受10个测试用例(包括我的测试用例)。
暴民埃里克(Erik the Outgolfer)'16年

@ΈρικΚωωσταντόπουλος添加了12个测试用例,并进行了一些修改(因为+++++--这也是一种选择,但我删除了它,++-++++因为它等效于++++-++)。如果我设法生成一个有效的解决方案,我仍然想再添加一个案例。
Sp3000 '16

@ Sp3000我不想++-++++删除。另外,这是我的编辑,不是您的。
暴民埃里克(Erik)

@eachρικΚωωσταντόπουλος每列等效解决方案中仅列出了一个解决方案-我认为如果列出所有最小解决方案,则测试用例会不必要地冗长(对于40个解决方案,有6个解决方案,对于97个而言,有17个解决方案)。如果意图不明确,我对此表示歉意。您也丢失了+++++--(或等价地--+++++),这就是为什么我觉得首先需要进行编辑的原因。
Sp3000 '16

Answers:


2

Python 2,119字节

def g(n,i=0,s=''):
 c=x=t=0
 for d in s:C=int(d)*2-1;t=(c==C)*t+1;c=C;x+=c*t
 return(x==n)*len(s)or g(n,i+1,bin(i)[3:])

非常慢的暴力破解方法。第三行计算字符串的分数x; 另一行遍历所有可能的二进制字符串,直到找到分数等于该参数的二进制字符串为止。

@Leaky保存了三个字节!


s/x==n and len/(x==n)*len/
Leaky Nun

它可能会节省一些字节来摆脱,s而只是使用重复的除法,例如:def f(n): \n while n>0:print n%2;n/=2
Leaky Nun

2

Pyth,25个字节

ffqyQ.as-Mc*RhdY2{s.pM./T

在线尝试。

这效率极低,并且内存用完了f(n)≥11。f(22)在我的笔记本电脑上,这大约在10秒钟内就得出= 10。

说明

  • 从1开始,遍历数字T。(f
    • 生成的所有分区T。(./T
    • 生成所有这些排列。(.pM
    • 整理列表。(s
    • 统一列表。({)这个步骤可以被删除,但它使代码更快。
    • 过滤分区的结果排列:(f
      • d分区的每个数字(*R)本身乘以一个(hd)。这使要加/减结果的数字加倍。
      • 将列表切成长度为2的部分。(c2
      • 从第二个数字中减去那些部分中的任何第二个数字。(-M
      • 对结果求和。如果分区排列被解释为加法,减法等,则结果数将加倍。
      • 取绝对值。(.a)如果结果为负,则交换加法和减法将得到正结果。
      • 检查结果是否等于输入的两倍。(qyQ)在这种情况下,分区排列是正确的,将其返回。
    • 如果过滤器返回任何结果,则存在长度的解决方案T。返回并打印T

2

MATL43 29字节

E:"@TFEqZ^!"@Y'tQ**s]vGE=a?@.

这是内存和时间效率低下的。在线编译器最多只能处理输入45

在线尝试!

这是所有测试用例最多的修改版本40(在线编译器需要将近一分钟的时间)。

说明

这将按照长度递增的顺序测试每个长度的所有可能的按键序列,直到找到有效的序列为止。

E:       % Range [1 2 ... 2*N] where N is implicit input. The required sequence length is
         % less than 2*N, so this is enough
"        % For each
  @      %   Push current value: length of sequence
  TFEq   %   Push array [1 -1]
  Z^     %   Cartesian power. Gives all possible sequences of 1, -1 of that length
  !      %   Transpose. Each sequence is now a row
  "      %   For each sequence
    @    %     Push current sequence
    Y'   %     Run-length decoding: Pushes an array of values 1 and -1, and then an
         %     array of run-lengths
    tQ*  %     Duplicate, add 1, multiply. Gives twice the triangular number for each run
    *    %     Multiply element-wise by 1 or -1 to produce correct sign
    s    %     Sum of array. This is the number produced by the current sequence
  ]      %   End for
  v      %   Concatenate all numbers into an array
  GE=a   %   True if any of those numbers equals twice the input
  ?      %   If so
    @    %     Push current sequence length. This is the final result
    .    %     Break loop
         %   End if
         % End for
         % Implicit display

@ Sp3000我也添加了一个,因此,作为参考,依次引用了4、6、9和19个测试用例。
乡村大佬埃里克(Erik)

1

Python,105 100字节

使用效率低的广度优先搜索。

def k(n):
 m=t=l=0;h=[]
 while m-n:o=1-2*(t>0);(m,t,l),*h=h+[(m+t-o,t-o,l+1),(m+o,o,l+1)]
 return l
  • h 是用作队列的列表
  • m 是列表顶部的序列值
  • t 是最后添加到的数字 m
  • l 是生成的序列的长度 m
  • o 是+/- 1,符号与的符号相反 t

编辑:泄漏尼姑剃了五个字节。


s/m,t,l,h=0,0,0,[]/m=t=l=0,h=[]/
Leaky Nun

s/while m!=n/while m-n/
Leaky Nun
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.