Desbloquee su cerradura


34

Has bloqueado tu bicicleta con un candado de combinación de 3 dígitos. Ahora quieres dar un paseo y debes desbloquearlo con la ayuda del siguiente programa.

Entrada

1er parámetro

La combinación de dígitos de su bloqueo en estado bloqueado . Debe ser diferente del segundo parámetro (= la combinación del estado desbloqueado ). (¡De lo contrario, su bicicleta podría ser robada!)

Rango 000..999. Los ceros iniciales no deben omitirse.

2do parámetro

La combinación de dígitos de su bloqueo en estado desbloqueado . Este valor es tu objetivo.

Rango 000..999. Los ceros iniciales no deben omitirse.

Salida

Una lista de cada estado del bloqueo de combinación después de cada "rotación" que incluye el estado inicial (que siempre es el primer parámetro) y el último paso (que siempre es el segundo parámetro).

Algoritmo

Usted comienza a "rotar" el primer dígito uno por uno hasta llegar al dígito correcto en estado desbloqueado . Pero, como conoce el código de desbloqueo completo, gira el dígito en la dirección en la que necesita la menor cantidad de rotaciones para alcanzar el dígito en estado desbloqueado . En caso de empate, puede elegir la dirección que prefiera.

Cuando haya alcanzado el primer dígito correcto, comenzará el mismo procedimiento con el segundo y luego con el tercero.

El orden de los dígitos es entender como un círculo:

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

Esto significa que la menor cantidad de rotaciones de 1 a 9 no es

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

pero

1 -> 0 -> 9 = 2.

Notas

Ejemplos

Ejemplo 1, correcto

Input: 999 001

Output:
999
099
009
000
001

Ejemplo 2, correcto

Input: 000 292

Output:
000
100
200
290
291
292

Ejemplo 3, salida incorrecta

Input: 999 121

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

Correct output:
999
099
199
109
119
129
120
121

Ejemplo 4, entrada incorrecta

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

Este es el gana la respuesta más corta.


¿Puedo cambiar el orden de dos parámetros?
tsh

¿Podemos actualizar los dígitos en cualquier orden siempre que sea óptimo?
Arnauld

@Arnauld No porque desbloqueo mi candado uno por uno :)
user2190035

2
@ Night2 No, ya que el programa debe simular el "proceso de desbloqueo" de una apariencia combinada.
user2190035

Respuestas:


12

Python 2 , 113 107 105 99 95 bytes

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

Pruébalo en línea!

Toma datos como listas de enteros


Salvado:

  • -6 bytes, gracias a Joel
  • -4 bytes, gracias a Jitse

2
99 bytes usando una forma diferente de calcular.
Joel

@ Joel ¡Gracias! :)
TFeld

2
96 bytes - bono: funciona para cualquier tamaño de matriz
Jitse

1
95 bytes , ya que está utilizando Python 2, también podría perder el//
Jitse

@Jitse Gracias :)
TFeld

6

Jalea , 15 bytes

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

[0 0,9 9]

Pruébalo en línea!

¿Cómo?

_æ%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 bytes

Guardado 2 bytes gracias a @tsh

Toma la entrada como 2 matrices de dígitos en sintaxis curry (a)(b). Devuelve una cadena.

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

Pruébalo en línea!

Comentado

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[]

d/6&1^d>0||9->d/5>5/d?9:1
tsh


2

Python 2 , 101 97 bytes

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

Pruébalo en línea!

3 bytes gracias a Joel .

Toma datos como listas de entradas.



1
@ Joel: ¡Gracias! En realidad, dado que es Python 2, //es lo mismo que /, por lo que se obtiene un byte adicional.
Chas Brown

Esto parece exactamente el mismo enfoque que la respuesta de @ TFeld , pero con ligeras modificaciones
Jitse

@Jitse: Bueno, ambos hemos estado modificando nuestras respuestas; por ejemplo, comenzó for x,y,i in zip(a,c,[0,1,2])si recuerdo ...
Chas Brown

1

Jalea , 30 bytes

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

Pruébalo en línea!

Un enlace diádico que toma como argumento izquierdo el código de desbloqueo y a la derecha el estado bloqueado actual, ambos como listas de enteros.

¡Esto se siente demasiado tiempo!


1

PHP , 114 bytes

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;

Pruébalo en línea!

Mi solución probablemente apesta, ¡pero eso es lo mejor que puedo pensar por ahora!


1

Carbón , 48 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

θ

Imprime la posición inicial.

≔EθIιθ

Cambie la cadena de posición inicial en una matriz de dígitos numéricos para fines de cálculo.

F³«

Pase sobre cada dígito a su vez.

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

Calcule la cantidad de rotaciones necesarias para desbloquear ese dígito. Este es un número de -5a 4donde -5significa 5 rotaciones hacia abajo y 4medios 4 rotaciones hacia arriba.

F↔ζ«

Pase sobre cada rotación.

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

Actualice el dígito de acuerdo con el signo de la rotación.

⸿⪫θω

Imprima los dígitos como una cadena en una nueva línea.


1

T-SQL 2008, 170 bytes

Agregué algunos saltos de línea para que sea legible

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

Pruébalo en línea


Esta solución no mantiene los primeros 0 en la salida. Ejemplo: 000-999
Mateo

1
@Matthew tiene casi razón, esperaba usar esta opción de entrada incorporada, sin embargo, si comienza con 0 en la entrada, se eliminará de la entrada. Sin embargo
t-clausen.dk

1
@Matthew - ahora está arreglado por cierto. Se eliminaron los cuadros de entrada que de todos modos no forman parte de SQL
t-clausen.dk



0

MATLAB, 100 89 bytes

Un enfoque diferente (usando la expansión implícita para crear una matriz de resta) reduce 11 bytes:

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

[Solución original de 100 bytes]

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

Ambos llamados pasando las entradas como matrices de 3 elementos, por ejemplo f([9 1 1], [2 3 2])


0

Java (JDK) , 139 bytes

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;}}

Pruébalo en línea!

¡El mismo algoritmo que todos, funcionó de manera diferente porque el de Java System.out.printlnes bastante costoso!



0

Kotlin , 162 bytes

{s:Array<Int>,e:Array<Int>->var i=0
o@while(i<3){println(""+s[0]+s[1]+s[2])
while(s[i]==e[i]){if(i>1)break@o
i++}
s[i]=(s[i]+if((e[i]-s[i]+10)%10>5)9 else 1)%10}}

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.