寻找将计数器增加到特定数量的最短方法


10

我有一个柜台。这是一个小型设备,看起来像这样:

计数器

显示从00009999。它在顶部有一个小按钮,可将计数增加1,在右边有一个小旋钮,其目的是将计数器重置为0。

现在,关于小旋钮的事情是,如果您将其向后旋转,则可以使它再次增加任何所需的数字。因此,如果我按下计数器按钮10次以使计数器显示出来0010,则可以向后旋转旋钮,直到听到微小的喀哒声,然后再次将其向前旋转并直接转到0090

但是,旋钮每次向前推动数字时,都会始终使同一数字的所有出现次数增加1。因此,如果计数器显示6060,则只能使其增加到7070,而不能增加到60707060。另外,旋钮将9s 滚动0而不携带,因此0990将前进到0000而不是10001100


我想知道将计数器设置为特定数字的最有效方法。您的任务是编写一个程序或函数,该程序或函数将确定执行此操作所需的最短按钮按下和旋钮前进的顺序。

您的程序将输入从0000到的4位数字9999,并以以下格式返回一系列步骤:

> 0001
C
> 0093
C12345678C12345678CCC
> 1000
C12345678C12345678C12345678C12345678C12345678C12345678C12345678C
> 9999
012345678

其中C代表“按下计数器按钮”,而D0到9之间的任何数字代表“使用旋钮将所有出现的次数D增加1”。

您的程序必须针对所有可能的四位数组合生成有效的步骤顺序,并将对所有10,000个案例所需的步骤总数进行评分。在平局的情况下(最有可能在找到最佳算法时),较短的代码将获胜。


向前转动旋钮会怎样?它会变成00100020在这种情况下?还是只能向后旋转旋钮?而且,每个“ D”都算作旋钮前进的“ D”数1234567吗(例如,是否意味着先将旋钮先旋转1次,然后旋转2次,然后旋转3次,依此类推)?还是仅仅表示每个单独的旋钮旋转(例如,是否1234567仅意味着将旋钮旋转7次)?
R. Kap

看起来上面和下面是无关的。
Leaky Nun

旋钮甚至可以在下面选择数字。
Leaky Nun

向前旋转旋钮将使0010前进至0020或1111,具体取决于旋钮所处的位置。向后旋转旋钮以设置其位置,然后向前旋转以使数字前进。
Joe Z.

1
认真地,这个人需要他的计数器以正确的值!现在!!!
CalculatorFeline

Answers:


5

Lua,327763步(最佳,276字节)

高尔夫球版:

a={[0]=""}t=tonumber for i=0,52 do A={}for k,v in pairs(a)do A[k]=v L=("%04d"):format(k)for i=1,4 do c=L:sub(i,i)d=L:gsub(c,(t(c)+1)%10)e=a[t(d)]A[d]=(not e or #e>#v)and v..c or e end b=k+1 if k<9999then e=a[b]A[b]=(not e or #e>#v)and v.."C"or e end end a=A endprint(a[(...)])

有问题的示例的改进版本(仅1000得到改进):

0001:C
0093:CCCCCCCCCC12345678CCC
1000:0CCCCCCCCCCC2345678C23456789
     (0000>1111>1122>1199>1200>1000)
9999:012345678

非高尔夫版本:

a = {[0]=""}
for i=0,52 do
    A = {}
    for k,v in pairs(a) do
        A[k] = v
        L=("%04d"):format(k)
        for i=1,4 do
           c=L:sub(i,i)
           d=L:gsub(c,(tonumber(c)+1)%10)
           e=a[tonumber(d)]
           A[d] = (not e or #e > #v) and v..c or e
        end
        b=k+1
        if k < 9999 then
            e=a[b]
            A[b] = (not e or #e > #v) and v.."C" or e
        end
    end
    a=A
end
print(a[93],a[1000],a[9999])

1

Mathematica,得分512710

Unprotect[StringRepeat]
StringRepeat[x_String, 0]:=""
Protect[StringRepeat]
#<>StringRepeat["C",#3-#2*1111]&[Array[ToString@#&,#,0],##]&[If[#<10^3,0,Quotient[#,1111]],#]&

修复了一个错误StringRepeat(的行为不正确StringRepeat[x_String,0]


是否需要一个空间StringRepeat[x_String, 0]:=""

不,但是我懒得将其删除。那是问题吗?
CalculatorFeline

一点也不:P对我很好奇,除了一个空格之外,其余代码都经过精心设计。

......那 golfed,对不对?还是Mathematica是新的线路噪音?

@cat这不是代码高尔夫球
pppery

1

Pyth,327763步(最佳130字节)

由于在线编译器在处理这些艰巨的任务不称职的,我已经给它较少的工作,所以它只产生011111。但是,它可以从理论上解决问题,因为它使用与顶部Lua相同的算法。

在线尝试!

=Y.d((0k;V53=ZYFGY XZG=k@YG=N%"%04d"GV4=b@NH=di:Nb%"%d"ehibTT XZd.x?>l@Ydlk+kb@Yd+kb)=bhGI<G9999 XZb.x?>l@Yblk+k\C@Yb+k\C))=YZ;@YQ

怎么运行的:

=Y.d((0k;V53=ZYFGY XZG=k@YG=N%"%04d"GV4=b@NH=di:Nb%"%d"ehibTT XZd.x?>l@Ydlk+kb@Yd+kb)=bhGI<G9999 XZb.x?>l@Yblk+k\C@Yb+k\C))=YZ)@YQ
                  assign_copy('Q',eval_input())
=Y.d((0k;         assign_copy('Y',dict(0=k))
V53               for N in range(0,53):
=ZY                   assign_copy('Z',Y)
FGY                   for G in num_to_range(Y):
 XZG=k@YG                 no_print(Z[G] = assign_copy('k',lookup(Y,G)))
=N%"%04d"G                assign_copy('N',format("%04d",G))
V4                        for H in range(0,4):
=b@NH                         assign_copy('b',lookup(N,H))
=di:Nb%"%d"ehibTT             assign_copy('d',base(replace(N,b,format("%d",mod10(increment(base(b,10))))),10))
 XZd.x?>l@Ydlk+kb@Yd+kb       no_print(Z[d]=try_and_catch(greater_than(Plen(lookup(Y,d)),Plen(k)) ? concat(k,b) : lookup(Y,d)), lambda:plus(k,b))
)                         <anti-indent>
=bhG                      assign_copy('b',head(G))
I<G9999                   if less_than(G,9999):
 XZb.x?>l@Yblk+k\C@Yb+k\C     no_print(Z[b]=try_and_catch(greater_than(Plen(lookup(Y,b)),Plen(k)) ? concat(k,"C") : lookup(Y,b)), lambda:plus(k,"C"))
)                         <anti-indent>
)                     <anti-indent>
=YZ                   assign('Y',Z)
)                 <anti-indent>
@YQ               print(lookup(Y,Q))

只是注意:下面是lua。:P但这是惊人的,很好的工作。
Rɪᴋᴇʀ

对我来说仍然如此:o
Leaky Nun

我按积极程度排序,也许您有票数。但这并不重要。
Rɪᴋᴇʀ

哦,它的下面,我现在洛尔
漏嫩

1

JavaScript(ES6),327763步(最佳,184字节)

广度优先搜索,不是那么聪明也不是那么快。

t=>eval("for(k=[],s=[['0000',i='']];[u,p]=s[i++],u-t;k[v=(1+u-~0+'').slice(-4)]=k[v]||s.push([v,p+'C']))[...u].map(x=>k[v=[...u].map(y=>x-y?y:-~x%10).join``]=k[v]||s.push([v,p+x]));p")

少打高尔夫球

t=>{
  k=[]; // mark values already found to reduce search
  for( i=0, s=[['0000','']]; 
       [u,p]=s[i++], // u: current code, p:current steps
       u != t; // exit if target found
     )
  {
     // try all digits present in current code
     [...u].map(x=> {
       v=[...u].map(y=>x-y?y:-~x%10).join`` // apply digit x to u
       if (!k[v]) // check if value v not found already
          k[v] = s.push([v,p+x]));
     })
     v=(1+u-~0+'').slice(-4); // try operator C
     if (!k[v]) // check if value v not found already
       k[v] = s.push([v,p+'C']))
  }
  return p
}

测试

f=t=>eval("for(k=[],s=[['0000',i='']];[u,p]=s[i++],u-t;k[v=(1+u-~0+'').slice(-4)]=k[v]||s.push([v,p+'C']))[...u].map(x=>k[v=[...u].map(y=>x-y?y:-~x%10).join``]=k[v]||s.push([v,p+x]));p")

function SingleTest()
{
  var i=S.value
  if (/^\d{4}$/.test(i)) X.value=f(i)
  else X.value='invalid input'
}  

SingleTest()

function LongTest()
{
  var i=0,v,r,t=0
  
  var step=_=>{ 
    v = ('000'+i).slice(-4);
    r = f(v);
    t+= r.length    
    V.value = v;
    R.value = r;
    T.value = t;
    ++i;
    if(i<10000) setTimeout(step, 0)
  }  
  
  step()
}
#V,#T,#S { width:5em }
#R,#X { width: 25em }
Single Test <input id=S value='0093'><button onclick="SingleTest()">-></button><input readonly id=X><hr>
Long test (0000 ... 9999) <button onclick="LongTest()">Go</button>(i mean <i>long</i>, runtime 1 hour)<br>
<input readonly id=V>
<input readonly id=R> 
Total steps:<input readonly id=T>

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.