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


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».

Ваша программа должна создать правильную последовательность шагов для всех возможных четырехзначных комбинаций и будет оцениваться по общему количеству шагов, необходимых для всех 10 000 случаев. В случае ничьей (наиболее вероятно, когда найден оптимальный алгоритм), выигрывает более короткий код.


Что произойдет, если вы поверните ручку вперед? Переключитесь 0010в 0020в этом случае? Или вы можете только повернуть ручку назад? А также, считается ли каждая буква «D» числом продвижений ручки «D» (например, 1234567означает ли это поворот ручки 1 раз, затем 2 раза, затем 3 раза и т. Д.)? Или это просто означает каждый отдельный поворот ручки (например, 1234567означает ли это поворот ручки 7 раз)?
Р. Кап

Похоже, что выше и ниже не связаны.
Утренняя монахиня

Ручка может даже выбрать цифры ниже.
Утренняя монахиня

Поворот ручки вперед приведет к перемещению от 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

Mathematica, оценка 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 Мне было просто любопытно, что остальная часть кода выполнена в гольфе, кроме одного пробела.
кот

... что это golfed, верно? Или Mathematica - это шум новой линии?
кот

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

1

Pyth, 327763 шага (оптимальный, 130 байтов)

Так как интернет - компилятор неподходящий при работе с такой огромной задачей, я дал ему меньше работы, так что это только порождает 0, 1и 1111. Тем не менее, он может теоретически решить проблему, потому что он использует тот же алгоритм, что и Lua наверху.

Попробуйте онлайн!

=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
Leaky Nun

Я сортирую по активным, возможно, у вас есть голоса. Но это не имеет значения.
Rɪᴋᴇʀ

О, это ниже для меня сейчас LOL
Leaky Nun

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.