Finden Sie den kürzesten Weg, um einen Zähler auf eine bestimmte Zahl zu bringen


10

Ich habe einen Zähler. Es ist ein kleines Gerät, das so aussieht:

Zähler

Die Anzeige geht von 0000bis 9999. Oben befindet sich ein kleiner Druckknopf, der die Anzahl um 1 erhöht, und rechts ein kleiner Knopf, mit dem der Zähler auf 0 zurückgesetzt werden soll.

Das Besondere an dem kleinen Knopf ist, dass Sie ihn, wenn Sie ihn rückwärts drehen, beliebig vergrößern können, sobald Sie ihn wieder vorwärts drehen. Wenn ich also den Zählerknopf 10 Mal drücke, damit der Zähler angezeigt wird 0010, kann ich den Knopf nach hinten drehen, bis ich ein winziges Klicken höre, ihn dann wieder nach vorne drehen und ihn direkt zu bewegen 0090.

Der Knopf erhöht jedoch jedes Mal, wenn er Zahlen nach vorne drückt, alle Vorkommen derselben Ziffer um 1. Wenn der Zähler angezeigt wird 6060, können Sie ihn nur auf 7070, nicht auf 6070oder erhöhen 7060. Außerdem wird der Knopf rollen 9s über 0ohne zu tragen, so 0990wird Voraus 0000statt 1000oder 1100.


Ich möchte wissen, wie der Zähler am effizientesten auf eine bestimmte Zahl eingestellt werden kann. Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die die kürzeste Folge von Tastendrücken und Knopfbewegungen bestimmt, die dazu erforderlich sind.

Ihr Programm nimmt eine 4-stellige Zahl von 0000bis als Eingabe 9999und gibt eine Reihe von Schritten im folgenden Format zurück:

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

Wobei Cfür "Druckknopf drücken" steht und jede Ziffer Dvon 0 bis 9 für "Verwenden Sie den Knopf, um alle Vorkommen Dum 1 vorzuschieben" steht.

Ihr Programm muss eine gültige Abfolge von Schritten für alle möglichen vierstelligen Kombinationen erstellen und wird anhand der Gesamtzahl der Schritte bewertet, die für alle 10.000 Fälle erforderlich sind. Bei einem Gleichstand (höchstwahrscheinlich, wenn der optimale Algorithmus gefunden wurde) gewinnt der kürzere Code.


Was passiert, wenn Sie den Knopf nach vorne drehen? Wird es sich 0010in 0020in diesem Fall? Oder können Sie den Knopf nur rückwärts drehen? Und zählt jedes "D" als "D" Anzahl der Vorschübe des Knopfes (bedeutet zum Beispiel, 1234567den Knopf 1 Mal, dann 2 Mal, dann 3 Mal usw. zu drehen)? Oder bedeutet es nur jede einzelne Knopfdrehung (bedeutet zum Beispiel 1234567nur, den Knopf 7 Mal zu drehen)?
R. Kap

Sieht so aus, als ob oben und unten nichts miteinander zu tun haben.
Undichte Nonne

Der Knopf kann im Folgenden sogar Ziffern auswählen.
Undichte Nonne

Wenn Sie den Knopf nach vorne drehen, wird entweder 0010 auf 0020 oder 1111 vorgeschoben, je nachdem, in welcher Position sich der Knopf bereits befindet. Sie drehen den Knopf nach hinten, um seine Position einzustellen, und dann nach vorne, um die Ziffern vorzurücken.
Joe Z.

1
Im Ernst, dieser Typ braucht seinen Zähler zum richtigen Wert !!!! JETZT!!!
CalculatorFeline

Antworten:


5

Lua, 327763 Schritte (optimal, 276 Bytes)

Golfversion:

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

Verbesserte Version der fraglichen Beispiele (nur 1000verbessert):

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

Ungolfed Version:

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

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

Behebt einen Fehler mit StringRepeat(verhält sich falsch für StringRepeat[x_String,0])


Muss es einen Platz geben StringRepeat[x_String, 0]:=""?
Katze

Nein, aber ich war zu faul, um es zu entfernen. Ist das ein Problem?
CalculatorFeline

Überhaupt nicht: P Es war nur neugierig für mich, dass der Rest des Codes bis auf ein Leerzeichen Golf spielt .
Katze

... das ist Golf, oder? Oder ist Mathematica das neue Leitungsrauschen?
Katze

@cat Dies ist kein Code-Golf
pppery

1

Pyth, 327763 Schritte (optimal, 130 Bytes)

Da die Online - Compiler auf dem Umgang mit solchen enormen Aufgabe unfähiger ist, habe ich ihm weniger Arbeit gegeben, so dass es erzeugt nur 0, 1und 1111. Es kann das Problem jedoch theoretisch lösen, da es denselben Algorithmus wie das Lua oben verwendet.

Probieren Sie es online aus!

=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

Wie es funktioniert:

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

Nur zur Bemerkung: Die Lua ist unten. : P Aber das ist erstaunlich, gute Arbeit.
Rɪᴋᴇʀ

Ist noch oben für mich: o
Leaky Nun

Ich sortiere nach aktiv, vielleicht hast du Stimmen. Aber es spielt keine Rolle.
Rɪᴋᴇʀ

Oh, es ist unten für mich jetzt lol
Leaky Nun

1

JavaScript (ES6), 327763 Schritte (optimal, 184 Byte)

Eine breite erste Suche, nicht so klug und nicht so schnell.

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

Weniger Golf gespielt

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
}

Prüfung

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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.