Разблокировать замок

34

Вы заблокировали свой велосипед с кодовым замком из 3 цифр. Теперь вы хотите покататься и разблокировать его с помощью следующей программы.

вход

1-й параметр

Цифровая комбинация вашего замка в заблокированном состоянии. Он должен отличаться от 2-го параметра (= комбинация разблокированного состояния). (Или ваш велосипед может быть украден!)

Диапазон 000 .. 999. Ведущие нули не должны быть опущены.

2-й параметр

Цифровая комбинация вашего замка в разблокированном состоянии. Это значение является вашей целью.

Диапазон 000 .. 999. Ведущие нули не должны быть опущены.

Выход

Список каждого состояния кодовой блокировки после каждого «вращения», включая начальное состояние (которое всегда является первым параметром) и последний шаг (который всегда является вторым параметром).

Алгоритм

Вы начинаете «вращать» первую цифру одну за другой, пока не достигнете правильной цифры в разблокированном состоянии. Но, поскольку вы знаете весь код разблокировки, вы поворачиваете цифру в направлении, в котором вам нужно наименьшее количество вращений, чтобы достичь цифры в разблокированном состоянии . В случае галстука вы можете выбрать любое направление, которое вы предпочитаете.

Когда вы наберете правильную первую цифру, вы начнете ту же процедуру со второго и затем с третьего.

Порядок цифр следует понимать как кружок:

... 9 0 1 2 3 4 5 6 7 8 9 0 1 2 ...

Это означает, что наименьшее количество оборотов от 1 до 9 не

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 = 8

но

1 -> 0 -> 9 = 2

Заметки

Примеры

Пример 1, правильный

Input: 999 001

Output:
999
099
009
000
001

Пример 2, правильный

Input: 000 292

Output:
000
100
200
290
291
292

Пример 3, неправильный вывод

Input: 999 121

Wrong output:
999
899 // Wrong because wrong rotation direction.
799
699
...

Correct output:
999
099
199
109
119
129
120
121

Пример 4, неверный ввод

Input: 1 212 // Wrong because no leading zeros.

Это выигрывает самый короткий ответ.

user2190035
источник
Могу ли я изменить порядок двух параметров?
TSH
Можем ли мы обновить цифры в любом порядке, если это оптимально?
Арно
@Arnauld Нет, потому что я один за другим открываю свой замок :)
user2190035
2
@ Night2 Нет, поскольку программа должна имитировать «процесс разблокировки» комбинированного вида.
user2190035
6
Связанные
Луис Мендо

Ответы:

12

Python 2 , 113 107 105 99 95 байт

a,b=input()
i=0
print a
for x in a:
 while x-b[i]:a[i]=x=(x+(x-b[i])%10/5*2-1)%10;print a
 i+=1

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

Принимает ввод как списки целых чисел


Добавлено:

  • -6 байт, спасибо Джоэлу
  • -4 байта, благодаря Jitse
TFeld
источник
2
99 байтов, используя другой способ вычисления.
Джоэл
@ Джоэл Спасибо! :)
TFeld
2
96 байт - бонус: работает для любого размера массива
Jitse
1
95 байт - поскольку вы используете Python 2, вы можете потерять//
Jitse
@ Jitse Спасибо :)
TFeld
6

Желе , 15 байт

_æ%5ḣT$ṂṠ⁸_%⁵ðƬ

[0,9]

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

Как?

_æ%5ḣT$ṂṠ⁸_%⁵ðƬ - Link: list of integers, s; list of integers, t
              Ƭ - collect up values until a fixed point is reached applying:
             ð  -   the dyadic chain:  (i.e. f(x, t) where x starts off as s)
_               -     subtract (t from x) (vectorises) - i.e. [ta-xa, tb-xb, tc-xc]
   5            -     literal five
 æ%             -     symmetric modulo (vectorises) - i.e. [[-4..5][ta-xa], [-4..5][tb-xb], [-4..5][tc-xc]]
      $         -     last two links as a monad:
     T          -       truthy indices  - e.g. [0,-4,1]->[2,3]
    ḣ           -       head to index (vectorises)       [[0,-4],[0,-4,1]]
       Ṃ        -     minimum                            [0,-4]
        Ṡ       -     sign (vectorises)                  [0,-1]
         ⁸      -     chain's left argument (x)
          _     -     subtract (vectorises) - i.e. move the single spindle one in the chosen direction
            ⁵   -     literal ten
           %    -     modulo (since 9+1=10 not 0)
Джонатан Аллан
источник
4

JavaScript (ES6),  73 72  70 байт

Сохранено 2 байта благодаря @tsh

Принимает ввод как 2 массива цифр в синтаксисе карри (a)(b). Возвращает строку.

a=>g=b=>b.some(x=>d=x-(a[++i]%=10),i=-1)?a+`
`+g(b,a[i]+=d/5<5/d||9):b

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

комментарии

a =>                  // a[] = initial combination
g = b =>              // b[] = target combination
  b.some(x =>         // for each digit x in b[]:
    d =               //   compute the difference d:
      x -             //     between x
      (a[++i] %= 10), //     and the corresponding digit in a[]
                      //     we apply a mod 10, because it may have exceed 9
                      //     during the previous iteration
    i = -1            //   start with i = -1
  ) ?                 // end of some(); if it's truthy:
    a + `\n` +        //   append a[] followed by a line feed
    g(                //   followed by the result of a recursive call:
      b,              //     pass b[] unchanged
      a[i] +=         //     add either 1 or 9 to a[i]:
        d / 5 < 5 / d //       add 1 if d / 5 < 5 / d
        || 9          //       otherwise, add 9
    )                 //   end of recursive call
  :                   // else:
    b                 //   stop recursion and return b[]
Arnauld
источник
d/6&1^d>0||9->d/5>5/d?9:1
TSH
2

Python 2 , 101 97 байт

a,c=input()
print a
for i in 0,1,2:
 while a[i]!=c[i]:a[i]=(a[i]+(a[i]-c[i])%10/5*2-1)%10;print a

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

3 байта спасибо Джоэлу .

Принимает ввод как списки целых.

Час Браун
источник
98 байт
Джоэл
1
@Joel: спасибо! На самом деле, так как это Python 2, //то же самое /, так что получен дополнительный байт.
Час Браун
Это похоже на тот же подход, что и ответ @ TFeld , но с небольшими изменениями
Jitse
@Jitse: Хорошо, мы оба модифицировали наши ответы; например, он начал с того, for x,y,i in zip(a,c,[0,1,2])что я вспомнил ...
Час Браун
1

Желе , 30 байт

_ż+¥⁵AÞḢṠxAƊ×€ʋ"JṬ€$$Ẏ;@W}+\%⁵

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

Диадическая ссылка, принимающая в качестве левого аргумента код разблокировки, а справа - текущее заблокированное состояние, как списки целых чисел.

Это слишком долго!

Ник Кеннеди
источник
1

PHP , 114 байт

for([,$a,$b]=$argv;$i<3;($x=$a[$i]-$b[$i])?(print$a._).$a[$i]=($y=$a[$i]+(5/$x>$x/5?-1:1))<0?9:$y%10:++$i);echo$b;

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

Мое решение, вероятно, отстой, но это лучшее, что я могу придумать на данный момент!

night2
источник
1

Древесный уголь , 48 байтов

θ≔EθIιθF³«≔⁻﹪⁺⁻I§ηι§θι⁵χ⁵ζF↔櫧≔θι﹪⁺§θι÷ζ↔ζχ⸿⪫θω

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

θ

Напечатайте начальную позицию.

≔EθIιθ

Измените начальную строку позиции в массив числовых цифр для целей расчета.

F³«

Обведите каждую цифру по очереди.

≔⁻﹪⁺⁻I§ηι§θι⁵χ⁵ζ

Рассчитайте количество вращений, необходимых для разблокировки этой цифры. Это число от -5до , 4где -5означает 5 нисходящих вращения и 4средство 4 вверх вращений.

F↔ζ«

Зацикливайтесь на каждом повороте.

§≔θι﹪⁺§θι÷ζ↔ζχ

Обновите цифру в соответствии со знаком вращения.

⸿⪫θω

Выведите цифры в виде строки на новой строке.

Нил
источник
1

T-SQL 2008, 170 байт

Я добавил несколько разрывов строк, чтобы сделать его читабельным

DECLARE @1 char(3)='123',@2 char(3)='956'

DECLARE @r int,@s int,@ int=0
g:SET @+=1
h:SELECT @r=substring(@1,@,1)+9,@s=@r-substring(@2+'1',@,1)
IF @s=9GOTO g
PRINT @1
SET @1=stuff(@1,@,1,(@r+@s/5%2*2)%10)
IF @<4GOTO h

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

t-clausen.dk
источник
Это решение не удерживает 0 в выводе. Пример: 000-999
Матфея
1
@ Впрочем, вы почти правы, я надеялся использовать эту опцию ввода во встроенном виде, однако, если вы начнете с ввода 0, он будет удален из ввода. Это не решение, которое терпит неудачу, хотя
t-clausen.dk
1
@ Матфея - это исправлено, кстати. Удалены поля ввода, которые в любом случае не являются частью sql
t-clausen.dk
0

MATLAB, 100 89 байт

Другой подход (использование неявного расширения для создания матрицы вычитания) сокращает 11 байтов:

function f(a,b);c = mod(a-b+5,10)-5;a,mod(a-cumsum(repelem(eye(3).*sign(c),abs(c),1)),10)

[Оригинальное 100-байтовое решение]

function f(a,b);c=mod(a-b+5,10)-5;a,for n=1:3;for r=1:abs(c(n));a(n)=mod(a(n)-sign(c(n)),10),end;end

Оба вызываются путем передачи входных данных как трехэлементных массивов, например f([9 1 1], [2 3 2])

Wolfie
источник
0

Java (JDK) , 139 байт

a->b->{for(int i;;a[i]+=(a[i]-b[i]+10)%10<5?9:1,a[i]%=10){System.out.println(""+a[i=0]+a[1]+a[2]);for(;i<3&&a[i]==b[i];i++);if(i>2)break;}}

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

Тот же алгоритм, что и у всех, по-другому, потому что Java System.out.printlnдовольно дорогой!

Оливье Грегуар
источник