Sayacı belirli bir sayıya ilerletmenin en kısa yolunu bulun


10

Bir sayacım var. Şuna benzeyen küçük bir cihaz:

sayaç

Ekran gider 0000için 9999. Üstte sayıyı 1 artıran küçük bir basma düğmesi ve sağda, sayacı 0'a sıfırlamak olan küçük bir düğme vardır.

Şimdi, küçük düğme ile ilgili şey, geriye doğru çevirirseniz, tekrar ileri doğru çevirdiğinizde istediğiniz herhangi bir rakamı artırabilmenizdir. Sayaç düğmesini gösterecek şekilde sayaç düğmesine 10 kez basarsam, 0010küçük bir klik sesi duyana kadar düğmeyi geriye doğru döndürebilirim, sonra tekrar ileri doğru çevirip düz konuma getirebilirim 0090.

Ancak, düğme, sayıları her ileri ittiğinde aynı basamağın tüm oluşumlarını her zaman 1 artırır. Yani sayaç gösterileri ise 6060, sadece o yükselmesi yapabilir 7070değil, 6070ya da 7060. Ayrıca, düğme yuvarlanacak 9için s üzerinde 0taşıyan olmadan 0990ilerlemek olacaktır 0000yerine 1000ya 1100.


Sayacı belirli bir sayıya ayarlamanın en etkili yolunu bilmek istiyorum. Göreviniz, düğme basma ve düğme ilerlemelerinin en kısa sırasını belirleyecek bir program veya işlev yazmaktır.

Programınız girdi olarak 4 basamaklı bir sayı alacak 0000için 9999ve aşağıdaki biçimde bir dizi adım döndürür:

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

Nerede Canlamına gelir ve herhangi bir rakamla "Karşı düğmeye basmak" D"tüm tekrarlarını ilerlemek için düğmeyi kullanmak için 0 ila 9 tribünden D1 ile".

Programınız tüm olası dört basamaklı kombinasyonlar için geçerli bir adım dizisi üretmelidir ve tüm 10.000 vaka için gereken toplam adım sayısına göre puanlanır. Beraberlik durumunda (muhtemelen en uygun algoritma bulunduğunda), daha kısa kod kazanacaktır.


Düğmeyi ileri doğru çevirirseniz ne olur? O dönecek 0010içine 0020bu durumda? Ya da sadece düğmeyi geriye çevirebilir misiniz? Ve ayrıca, her "D" düğmenin "D" sayısı olarak sayılır mı (örneğin, 1234567düğmeyi 1 kez, sonra 2 kez, sonra 3 kez, yani böyle çevirmek anlamına gelir)? Yoksa her bir ayrı düğme dönüşünü 1234567ifade ediyor mu?
R. Kap

Yukarıdaki gibi ve aşağıda ilgisiz gibi görünüyor.
Leaky Nun

Düğme aşağıdaki rakamları bile seçebilir.
Leaky Nun

Düğmeyi ileri doğru çevirmek, düğmenin bulunduğu konuma bağlı olarak 0010 ila 0020 veya 1111'i ilerletir. Konumunu ayarlamak için düğmeyi geriye doğru, sonra basamakları ilerletmek için ileri doğru çevirirsiniz.
Joe Z.

1
Cidden, bu adam ihtiyacı doğru değerde onun sayaç !!!! ŞİMDİ !!!
CalculatorFeline

Yanıtlar:


5

Lua, 327763 adım (optimum, 276 bayt)

Golf versiyonu:

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

Söz konusu örneklerin geliştirilmiş sürümü (yalnızca 1000geliştirildi):

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

Ungolfed sürümü:

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, skor 512710

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

İle ilgili bir hatayı düzeltir StringRepeat(için yanlış davranır StringRepeat[x_String,0])


İçinde boşluk olması gerekiyor mu StringRepeat[x_String, 0]:=""?
kedi

Hayır, ama onu kaldırmak için çok tembeltim. Bu bir problem mi?
CalculatorFeline

Hiç de değil: P Kodun geri kalanının bir boşluk dışında golf oynadığını merak ediyordum .
kedi

... bu edilmektedir golfed, doğru mu? Yoksa Mathematica yeni hat gürültüsü mü?
kedi

@cat Bu kod golf
pppery

1

Pyth, 327763 adım (optimum, 130 bayt)

Online derleyici böyle muazzam bir görev ile uğraşan beceriksiz olduğundan, yalnızca oluşturur böylece, o daha az iş verdik 0, 1ve 1111. Ancak, teorik olarak sorunu çözebilir, çünkü üstteki Lua ile aynı algoritmayı kullanır.

Çevrimiçi deneyin!

=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

Nasıl çalışır:

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

Sadece dikkat: lua biri aşağıda. : P Ama bu inanılmaz, iyi iş.
Rɪᴋᴇʀ

Hala benim için yukarıda: o
Leaky Nun

Aktif olarak sıralıyorum, belki oylarınız var. Ama önemli değil.
Rɪᴋᴇʀ

Oh şimdi benim için aşağıda lol
Leaky Nun

1

JavaScript (ES6), 327763 adım (optimum, 184 bayt)

Bir Genişlik İlk Arama, çok akıllı ve çok hızlı değil.

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

Daha az golf

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
}

Ölçek

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.