Encontre a maneira mais curta de avançar um contador para um determinado número

10

Eu tenho um balcão. É um pequeno dispositivo que se parece com isso:

contador

O visor passa de 0000para 9999. Possui um pequeno botão na parte superior que aumenta a contagem em 1 e um pequeno botão à direita, cujo objetivo é redefinir o contador de volta para 0.

Agora, o importante sobre o pequeno botão é que, se você o girar para trás, poderá aumentar qualquer dígito que desejar, depois que o girar novamente. Portanto, se eu pressionar o botão do contador 10 vezes para que o contador apareça 0010, posso girar o botão para trás até ouvir um pequeno clique, depois girá-lo para frente novamente e fazê-lo ir direto para 0090.

Porém, o botão sempre aumentará todas as ocorrências do mesmo dígito em 1 sempre que empurrar os números para frente. Portanto, se o contador aparecer 6060, você só poderá aumentar para7070 , não para 6070ou 7060. Além disso, o botão vai rolar 9s sobre a 0sem proceder, assim 0990irá avançar para 0000, em vez de 1000ou 1100.


Quero saber a maneira mais eficiente de definir o contador para um determinado número. Sua tarefa é escrever um programa ou função que determine a menor seqüência de pressionamentos de botões e avanços dos botões necessários para fazê-lo.

Seu programa terá como entrada um número de 4 dígitos de 0000a 9999e retornará uma série de etapas no seguinte formato:

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

Onde Csignifica "pressione o botão do contador" e qualquer dígito Dde 0 a 9 significa "use o botão para avançar todas as ocorrências de D1".

Seu programa deve produzir uma sequência válida de etapas para todas as combinações possíveis de quatro dígitos e será pontuado pelo número total de etapas necessárias para todos os 10.000 casos. No caso de empate (provavelmente quando o algoritmo ideal for encontrado), o código mais curto vencerá.

Joe Z.
fonte
O que acontece se você girar o botão para frente? Será que vai transformar 0010em 0020nesse caso? Ou você só pode girar o botão para trás? E também, cada "D" conta como número "D" de avanços do botão (por exemplo, 1234567significa girar o botão 1 vez, depois 2 vezes, depois 3 vezes, etc.)? Ou significa apenas cada giro do botão separado (por exemplo, significa 1234567apenas girar o botão 7 vezes)?
R. Kap
Parece que o acima e o abaixo não estão relacionados.
Leak Nun #
O botão pode até escolher dígitos abaixo.
Leak Nun #
Girar o botão para a frente avançará 0010 para 0020 ou 1111, dependendo da posição em que o botão já está. Você gira o botão para trás para definir sua posição e depois para a frente para avançar os dígitos.
Joe Z.
11
Sério, esse cara precisa do seu contador no valor correto !!!! AGORA!!!
CalculatorFeline

Respostas:

5

Lua, 327763 etapas (ideal, 276 bytes)

Versão Golfed:

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[(...)])

Versão aprimorada dos exemplos em questão (apenas 1000aprimorada):

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

Versão não destruída:

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])
Freira Furada
fonte
1

Mathematica, pontuação 512710

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

Corrige um erro com StringRepeat(comporta-se incorretamente por StringRepeat[x_String,0])

CalculatorFeline
fonte
Precisa haver um espaço StringRepeat[x_String, 0]:=""?
gato
Não, mas eu estava com preguiça de removê-lo. Isso é um problema?
CalculatorFeline
Nem um pouco: P Foi apenas curioso para mim que o restante do código seja jogado de golfe, exceto por um espaço em branco.
gato
... isso é golfe, certo? Ou o Mathematica é o novo ruído da linha?
gato
@cat Isso não é código-golfe
pppery 07/01
1

Pyth, 327763 etapas (ideal, 130 bytes)

Desde o compilador online é inepto em lidar com tal tarefa enorme, eu ter dado menos trabalho, de modo que só gera 0, 1e 1111. No entanto, teoricamente, ele pode resolver o problema, porque usa o mesmo algoritmo que Lua no topo.

Experimente online!

=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

Como funciona:

=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))
Freira Furada
fonte
Apenas observando: O lua está abaixo. : P Mas isso é incrível, bom trabalho.
Rɪᴋᴇʀ
É ainda acima para mim: o
Leaky Nun
Eu ordeno por ativo, talvez você tenha votos. Mas isso realmente não importa.
Rɪᴋᴇʀ
Ah, é abaixo de mim agora lol
Leaky Nun
1

JavaScript (ES6), 327763 etapas (ideal, 184 bytes)

Uma primeira pesquisa abrangente, nem tão inteligente nem tão rápida.

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")

Menos golfe

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
}

Teste

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>

edc65
fonte