Знайдіть найкоротший спосіб просунути лічильник до певної кількості


10

У мене лічильник. Це невеликий пристрій, який виглядає приблизно так:

лічильник

Дисплей переходить від 0000до 9999. У верхній частині є невелика кнопка, що збільшує кількість рахунків на 1, і невелика кнопка праворуч, мета якої - скинути лічильник на 0.

Тепер річ у маленькій ручці полягає в тому, що якщо повернути її назад, ви можете змусити її збільшувати будь-яку цифру, яку ви хочете, як тільки ви знову повернете її вперед. Тож якщо я натискаю кнопку лічильника 10 разів, щоб лічильник показав0010 , я можу повернути ручку назад, поки не почую крихітний клацання, а потім повернути її вперед і змусити перейти прямо до неї 0090.

Але, ручка завжди збільшуватиме всі випадки однієї цифри на 1 кожен раз, коли вона натискає цифри вперед. Так що, якщо лічильник показує 6060, ви можете тільки зробити це , щоб збільшити 7070, а НЕ 6070або 7060. Крім того, ручка перекинеться 9на 0без перенесення, тому 0990перейде до 0000замість 1000або 1100.


Хочу знати найефективніший спосіб встановити лічильник на певну кількість. Ваше завдання - написати програму або функцію, яка визначатиме найкоротшу послідовність натискання кнопок і пересування кнопок, необхідних для цього.

Ваша програма прийме як введення 4-значний номер від 0000до 9999та поверне ряд кроків у наступному форматі:

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

Якщо Cозначає "натиснути кнопку лічильника" і будь-яка цифра Dвід 0 до 9 означає ", використовуйте регулятор, щоб пересувати всі події Dна 1".

Ваша програма повинна створити дійсну послідовність кроків для всіх можливих чотиризначних комбінацій, і вона буде набрана загальною кількістю кроків, необхідних для всіх 10000 випадків. У випадку зв'язання (швидше за все, коли знайдеться оптимальний алгоритм), коротший код виграє.


Що станеться, якщо повернути ручку вперед? Перейдіть 0010в 0020в цьому випадку? Або ви можете лише повернути ручку назад? А також, чи вважає кожен "D" числом "D" кількість просування ручки (наприклад, чи 1234567означає повернути ручку 1 раз, потім 2 рази, потім 3 рази і так далі)? Або це просто означає кожен поворот ручки (наприклад, це 1234567означає просто повернути ручку 7 разів)?
Р. Кап

Схоже, що вище та нижче не пов'язані між собою.
Leaky Nun

Ручка може навіть вибрати цифри внизу.
Leaky Nun

Якщо повернути ручку вперед, ви будете пересуватись уперед від 0010 до 0020 або 1111, залежно від положення, в якому вже знаходиться ручка. Ви повертаєте ручку назад, щоб встановити її положення, а потім вперед для просування цифр.
Джо З.

1
Серйозно, цей хлопець потребує свого лічильника за правильним значенням !!!! ЗАРАЗ !!!
CalculatorFeline

Відповіді:


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

Математика, оцінка 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 Мені було просто цікаво, що решта коду - це гольф, за винятком одного пробілу.
кіт

... це гольф, правда? Або Mathematica - це новий шум лінії?
кіт

@cat Це не код-гольф
pppery

1

Pyth, 327763 кроки (оптимально, 130 байт)

Так як інтернет - компілятор невідповідний при роботі з такою величезною завданням, я дав йому менше роботи, так що це тільки породжує 0, 1і 1111. Однак він теоретично може вирішити проблему, оскільки використовує той же алгоритм, що і Луа вгорі.

Спробуйте в Інтернеті!

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

Тільки зауважимо: Луя одна внизу. : P Але це дивовижна, хороша робота.
Rɪᴋᴇʀ,

Все ще для мене вище: o
Лина монашка

Я сортую за активними, можливо, у вас є голоси. Але це насправді не має значення.
Rɪᴋᴇʀ,

О, це внизу для мене хаха
Leaky черниця

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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.