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


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.