Descifrar el código a la cerradura de combinación

22

Dado un bloqueo de combinación estándar como el de la imagen. La forma de desbloquearlo es alinear los 4 números en el código en la línea de combinación. Después de años de servicio leal, ha sido despedido de la fábrica de cerraduras y ha decidido vengarse al no mezclar las cerraduras antes de enviarlas, dejando así cada cerradura con la combinación para desbloquearla en la línea de combinación.

Cerradura de combinación

También sabe que al observar el orden de los números en las otras líneas, es posible determinar qué números deben estar en la línea de combinación (y, por lo tanto, la combinación para desbloquearla es).

Si a cada línea de la cerradura se le asigna un número que comienza desde la línea 0 para la línea de combinación (la línea que desbloquea la cerradura) hasta la línea 9. Por ejemplo, si los números de la línea 4 son 5336, entonces la combinación para desbloquearlo sería 1992.

Desafortunadamente, las cerraduras ya se han empaquetado y su vista de cada cerradura está oculta, por lo que solo puede ver números en diferentes líneas de la cerradura.

El reto

Dados 4 pares de dígitos, donde el primer dígito del número entero representa el número de línea y el segundo dígito representa el número que aparece en esa línea, calcule la combinación de la cerradura. Por ejemplo, si ingresa:

57 23 99 45

Entonces debería generar:

2101

O

25 78 63 15

y

3174

Suponga que la entrada siempre será 4 enteros positivos en la forma `25 64 72 18.

Este es el , por lo que gana el programa más corto en número de bytes.

También esta es mi primera pregunta, por lo que cualquier comentario es apreciado.

Rory McPerlroy
fuente
Creo que necesitas aclarar la entrada. Usted dice " Dados 4 pares de enteros " y luego da un ejemplo 57 23 99 45. Eso no son cuatro pares de enteros: son cuatro enteros. Y algunas respuestas suponen que lo obtienen como una cadena, mientras que otras suponen que viene analizado como 4 ints.
Peter Taylor
No estoy de acuerdo, el hecho de que decía que cuatro pares de enteros dejaban claro el formato de la entrada, 57 es el par entero 5 y 7, no el entero 57. Mi primera suposición fue que la línea era 57 y la combinación era 23.
Qwerty01
1
¿Qué tal "pares de dígitos"? Eso sería mucho más claro y preciso (y también funciona con 0s principales ).
esponjoso
Técnicamente, el término correcto sería bloqueo de permutación . La mayoría de los "bloqueos de combinación" son en realidad bloqueos de permutación, porque el orden de los dígitos hace la diferencia.
nyuszika7h
Técnicamente sí, es correcto, pero no creo que sea un título atractivo.
Rory McPerlroy

Respuestas:

32

CJam, 9 8 bytes

ea9fbAf%

Lee los pares de dígitos como argumentos de línea de comandos. Para probar el código en línea , el cambio eaa lS/leer de STDIN simulado.

Ejecución de ejemplo

$ cjam <(echo ea9fbAf%) 57 23 99 45; echo
2101
$ cjam <(echo ea9fbAf%) 25 78 63 15; echo
3174

Cómo funciona

El código de caracteres del dígito d es 48 + d . Por lo tanto, considerando la cadena de dos dígitos xy, un número base 9 produce 9 * (48 + x) + (48 + y) = 10 * (48 + x) + y - x ≡ y - x (mod 10) .

ea       " Push the array of command-line arguments.                                      ";
  9fb    " Mapped base 9 conversion; replace each string 'xy' with (9 * ord(x) + ord(y)). ";
     Af% " Take the results modulo 10.                                                    ";
Dennis
fuente
Maldición, no puedes dejar que nadie más gane, ¿no? : P
Optimizer
No creo que obtengamos una mejor respuesta de CJam que esta
Rory McPerlroy
1
¿Qué acaba de pasar allí?
Guerra
1
@ Digital Trauma: Claro, adelante. La cadena "99"se interpreta realmente como la matriz [57 57]por b; "xy"9bse implementa como 9 * ord(x) + ord(y). Debo agregar eso a mi respuesta.
Dennis
44
10,000 apenas cubre todos los programas de 2 caracteres si restringimos las posibles soluciones a ASCII imprimible.
Dennis
13

CJam, 13 12 11 caracteres

Gracias a user23013, ahora tiene solo 11 caracteres :)

4{Ar:--A%}*

Explicaciones:

4{       }*     "Run the code block 4 times";
   r            "Read the next input token (whitespace separated)";
    :-          "Subtract 2nd number from the first treating r as a 2 numbered string";
  A   -         "Subtract the result of above from 10";
       A%       "Take modulus of 10 and store it on stack";

Pruébalo en línea

Sé que se puede jugar más al golf. Pero este es mi primer intento real en CJam y estoy limitado por la experiencia :)


Alternativamente, los otros métodos para hacer lo mismo en 1 carácter adicional:

l~]{_A/-A%}/     // My previous solution

o

4{ri_A/-A%}*     // As pointed out by Ingo

o

ea{i_A/-A%}/     // If input is passed through command line
Optimizador
fuente
Estaba esperando esto. Bueno, la próxima semana ...
Soham Chowdhury
Los primeros tres personajes podrían ser alternativamente l~]. Siento que analizar la entrada debería ser posible con menos de tres, pero nunca he usado CJam antes: /
Ingo Bürk
4{ri_A/-A%}*es un byte más corto.
Ingo Bürk
1
Ah, o lo que hiciste de mi comentario anterior. Bueno, ahora hay dos soluciones de 12 bytes. :)
Ingo Bürk
3
O 4{Ar:--A%}*.
jimmy23013
6

Golfscript (14 13 )

Pruébalo en línea aquí

Es casi lo mismo que la solución de Optimizer , pero en un idioma diferente. Es difícil abordarlo de una manera diferente porque el problema es bastante simple , por lo que el empate definitivamente va a Optimizer, cuya entrada fue anterior de todos modos.

~]{.10:^/-^%}/

Para la misma cantidad de bytes que puedes hacer

~]{.10/- 10%}/
Ingo Bürk
fuente
¿Ninguna variable predefinida con valor 10 en Golfscript?
Optimizador
@Optimizer Desafortunadamente, no. Lástima, porque tener la entrada en la pila ya sería la ventaja sobre CJam.
Ingo Bürk
Sí, pueden ser 10 caracteres en CJam (con entrada en la pila) u 11 en Golfscript (con variable predefinida)
Optimizer
También podría tener 12 en Golfscript si no tuviera que dejar el espacio adentro - 10.
Ingo Bürk
1
je, incluso la más corta de las lenguas tienen sus cortos idas: P
Optimizador
6

GNU dc , 14 bytes

Pedir prestado el truco inteligente de base 9 de Dennis :

9i[?A%nd]dxxxx

Enteros de entrada leídos de STDIN, uno por línea.

Explicación:

9i                # Set input radix to 9
  [     ]         # push a macro, defined thus:
   ?              #   read number from STDIN and push
    A             #   push literal 10
     %            #   calculate number mod 10
      n           #   print, with no newline
       d          #   duplicate macro
         d        # duplicate macro
          xxxx    # execute the macro 4 times    

Salida:

$ for i in 57 23 99 45; do echo $i; done | dc ./combolock.dc
2101$ 
$ for i in 25 78 63 15; do echo $i; done | dc ./combolock.dc
3174$ 
$ 

Respuesta anterior, 18 bytes:

Porque pensé que podría acercarme a los idiomas de "golf" con esto (pero no lo hice):

[A?A~--A%n]dddxxxx
Trauma digital
fuente
1
Puede guardar un byte:9i[?A%nd]dxxxx
Dennis
@ Dennis - ¡Fantástico! ¡Ahora estoy codo a codo con golfscript y APL!
Digital Trauma
6

C 64 63 56 o 61

Si la entrada se puede canalizar desde el archivo

main(a){while(scanf("%d",&a)>0)putchar(48+(a-a/10)%10);}

Si la entrada debe escribirse en stdin

i;main(a){for(;i++-4;putchar(48+(a-a/10)%10))scanf("%d",&a);}

Lee los cuatro números en un bucle y luego procesa cada uno restando el primer dígito del valor e imprimiendo el módulo de resultado 10.

Ahorro gracias a varios comentarios a continuación y también al uso de putchar en lugar de printf

Alquimista
fuente
Guay. Puede guardar una coma poniendo el scanfexterior for()asía,i;main(){for(;i++-4;printf("%d",(a-a/10)%10))scanf("%d",&a);}
Level River St
También puede guardar 2 bytes usando en a*.9lugar dea-a/10
rev
@steveverrill Me gusta. Tan concentrado en poner todo en el ciclo for que me perdí eso
Alchymist
1
@AcidShout Lo siento, no funciona. Por ejemplo, 78 * .9 = 70.2, mientras que 78 - 78/10 = 71. También usar .9 promueve el argumento a un doble, así que no puedo tomar el mod.
Alchymist
Puede guardar algunos bytes utilizando un whilebucle y declarando acomo argumento de main:main(a){while(scanf("%d",&a)>0)printf("%d",(a-a/10)%10);}
Dennis
5

Pitón 3, 64

Sencillo.

print(''.join([(i-i//10)%10 for i in map(int,input().split())]))

Puede ser más corto si se me permite imprimir, por ejemplo, [2, 1, 0, 1]( 46 ):

print([i%10-i//10 for i in map(int,input().split())])
Soham Chowdhury
fuente
Puede guardar algunos tomando str((i-i//10)%10)directamente en lugar de usar un segundo map(). También comencé con generadores para el mío, pero descubrí que un forciclo real terminó siendo más corto.
DLosc
Sí, gracias por eso!
Soham Chowdhury
¿Por qué estás usando listas de comprensión? Utilice genexps para salvar 2 caracteres: print(''.join((i-i//10)%10for i in map(int,input().split()))). Además, si los espacios son allowd en la salida se puede evitar joiny el uso tupla-desembalaje: print(*((i-i//10)%10for i in map(int,input().split()))).
Bakuriu
Supongo que estas en lo correcto.
Soham Chowdhury
4

C, 92

#define a(n) ,(10+v[n][1]-*v[n])%10
main(int c,char**v){printf("%d%d%d%d"a(1)a(2)a(3)a(4));}

Entrada desde la línea de comandos. Resta el primer código ASCII de cada argumento del segundo, agrega 10 y toma el módulo 10.

Creo que esta es la primera vez que escribo un printfcon cuatro %sy sin coma (la coma está en el #define.)

Level River St
fuente
#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)seguido a,b;main(){f;f;f;f;}sería 18 bytes más corto.
Dennis
@Dennis es una gran mejora, pero es básicamente un programa completamente diferente. Creo que si alguien lo publica, deberías ser tú, no yo. No estoy seguro de si el espacio scanfes necesario, dado que scanfse supone que analiza el espacio en blanco solo como un separador. Alchymist tiene una idea aún mejor en C. Pero parece que ya la ganó con su respuesta de Cjam.
Level River St
Sí, comencé notando que el espacio después a(n)se puede omitir, luego noté que colocar printf("%d%,...)tu macro ahorraría unos pocos bytes y finalmente me dejé llevar un poco ... - El espacio es necesario ya que %clee un personaje, cualquier carácter, por lo que en la segunda ejecución almacenaría 32 pulgadas a. - Vencer a CJam con C debería ser difícil. printf()ya es mi respuesta ...
Dennis
4

Java - 203 bytes

Solo porque tiene que haber una entrada en Java, vi una buena oportunidad para darle una oportunidad a este código de golf (primer envío).

class M{public static void main(String[] a){String r="";for(int i=0;i<4;i++){int l=Byte.valueOf(a[i].substring(1));int f=Byte.valueOf(a[i].substring(0,1));r+=(l-f<0)?l-f+10:l-f;}System.out.print(r);}}

Si hay espacio para algunas mejoras, me alegraría saber sobre ellas ;-)

Lijadora
fuente
Puede buscar [consejos] y obtener varios consejos sobre golf para comenzar :)
Optimizer
¡Genial, gracias! Ver algunos consejos me ayudó a reducir 13 bytes :)
Sander
3

Lua - 46 caracteres

while''do a,b=io.read(1,1,1)print((b-a)%10)end

Lee tres caracteres a la vez (concédeme la pequeña misericordia de ingresar un espacio al final), y aunque a y b son cadenas y ... ba MÁGICAMENTE les permite concebir un bebé entero sano. Realiza la verificación envolvente durante la impresión.

Cómo lo ejecuto:

AndoDaan
fuente
1
¿Podría proporcionar un ejemplo de entrada / salida de datos, parece que no puede ejecutarse en Ideone
Rory McPerlroy
@ Harry12345 Ah, perdón por eso. Anarchy Golf está decidiendo cómo implemento stdinput. Probablemente podría codificarlo mejor, pero meh, lua es terrible. Publiqué un ejemplo de mí ejecutando el programa.
AndoDaan
3

JavaScript ES6 - 53 43 bytes

f=n=>n.replace(/.. ?/g,a=>(1+a[1]-a[0])%10)

Función bastante sencilla, utiliza expresiones regulares para obtener los números. Pruébelo en http://jsfiddle.net/efc93986/1/ . Si no se permiten funciones, un programa independiente de 52 bytes:

alert(prompt().replace(/.. ?/g,a=>(1+a[1]-a[0])%10))

Como ES6 actualmente solo funciona en Firefox, el siguiente código funciona en cualquier navegador moderno, a 70 bytes:

alert(prompt().replace(/.. ?/g,function(a){return(1+a[1]-a[0])%10}))
NinjaOsoMono
fuente
Me encanta tu 1+.
Neil
1
La pregunta dice asumir una entrada válida, por lo que puede usar en ...?lugar de /\d+ ?. El espacio después del retorno puede omitirse. Además, como no se especificó ninguna E / S específica, debería poder usar una función.
Dennis
1
a-a[0]en lugar de 1+a[1]-a[0]debería funcionar también.
Dennis
2

Python 2 - 33 bytes

for i in input():print(i-i/10)%10

Acepta entradas de usuario delimitadas por comas. Por ejemplo, entrada:

29,26, 31, 88

Salida:

7
4
8
0

Si se requiere un resultado que coincida exactamente con el ejemplo, entonces es mucho más largo. 47 bytes:

print"%d"*4%tuple((i-i/10)%10 for i in input())
Feersum
fuente
input()no funciona en mi intérprete de Python 2.
Soham Chowdhury
@SohamChowdhury, ¿usaste comas?
fiesta del
2
Oh no, no lo hice. Ahora funciona. En una nota al margen, creo que debe tomar una entrada delimitada por espacios según la especificación.
Soham Chowdhury
3
Estoy de acuerdo, la entrada debe tener espacio limitado
Rory McPerlroy
2

APL, 14

10|{--/⍎¨⍕⍵}¨⎕

La explicación
toma la entrada de la pantalla. Los valores separados por espacios se analizan como una matriz.
{...}¨para cada número, aliméntelo en función.
⍎¨⍕⍵toma el argumento, crea una matriz de sus dígitos.
--/calcula unidades menos decenas.
10|mod 10.

TwiNight
fuente
1
Puede tener 14 caracteres, pero tiene 24 bytes .
Ingo Bürk
pero para el código de golf contamos en UTF-8, no en un juego de caracteres especial. Eso sería un vacío legal y podría ser abusado muy fácilmente.
Ingo Bürk
1
@ IngoBürk Según meta.codegolf.stackexchange.com/a/961/6972 las respuestas se pueden codificar en cualquier codificación a menos que el OP indique lo contrario. De hecho, hay una página de códigos de IBM para caracteres APL que es un mapeo de un solo byte, que es exactamente lo que Dyalog solía usar antes de Unicode 3.0. Si insiste en Unicode, ¿qué pasa si invento un nuevo lenguaje que use caracteres que no sean Unicode? ¿Cómo contarías bytes para eso?
TwiNight
Podría haber jurado que el valor predeterminado era UTF-8. 14 bytes es, entonces.
Ingo Bürk
2

J - 20 15

La forma no verbal (como declaración en lugar de definición de función) es 5 caracteres más corta:

10|-~/|:10#.inv

La forma verbal que es un buen tren :

10|[:-~/[:|:10#.inv]

Este verbo usado en las entradas de ejemplo:

   10|-~/|:10#.inv 57 23 99 45
2 1 0 1
   10|-~/|:10#.inv 25 78 63 15
3 1 7 4

rotd =: 10|[:-~/[:|:10#.inv] NB. verb form

   rotd 25 78 63 15
3 1 7 4
   rotd 57 23 99 45
2 1 0 1
jpjacobs
fuente
2

Haskell 60 58

main=interact$show.map((\x->mod(x-x`div`10)10).read).words

Dígitos de un solo personaje, una verdadera némesis en el golf de Haskell.

Zeta
fuente
2

Perl: 38 40

print abs($_-int$_/10)%10for split" ",<>

Salida:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174
Riymus
fuente
1
1. Los guiones bajos son una sintaxis de rebajas, por lo que su código se estropeó un poco. Para evitar esto, sangra el código con cuatro espacios. 2. absno es necesario; x - x/10No puede ser negativo. 3. Si usa las banderas -040pe(generalmente contadas como 5 bytes) para iterar sobre la entrada delimitada por espacios, puede acortar su código a $_=($_-int$_/10)%10. 4. Si prefiere evitar las banderas de línea de comandos, aún puede guardar algunos bytes configurando $/=$;y eliminando la llamada a split.
Dennis
1

Ruby, 35 bytes

$*.map{|n|a,b=n.bytes;$><<(b-a)%10}

Explicación

La entrada se toma como argumentos de línea de comando. String#bytesdevuelve una matriz de enteros (códigos de caracteres ASCII). Solo la diferencia entre el último y el primer código de caracteres es importante, no los enteros mismos.

britishtea
fuente
1

C # y LinqPad: 104

Util.ReadLine<string>("").Split(' ').Select(s =>(s[1]-s[0])).Aggregate("",(r,a)=>r+(a<0?10+a:a)).Dump();
EvilFonti
fuente
1

C ++ 118

int main()
{
int a,b,c;
for(int i=0; i<4; i++)
{
cin>>a;
b=a/10;
a=a%10;
c=a-b;
if(c<0)c+=10;
cout<<c;
}
}
bacchusbeale
fuente
1. No estoy seguro acerca de otros compiladores, pero GCC requiere #include<iostream>y std::antes ciny cout. 2. No necesita el condicional si lo omite a=a%10. 3. No necesita las variables by c, los avances de línea y (con algunas modificaciones) los corchetes alrededor del bucle for.
Dennis
1
@SeanD: no apruebe ediciones que modifiquen el código. En este caso particular, la edición hizo que la respuesta no sea válida. También eliminó la primera línea, que debería estar presente en todas las respuestas.
Dennis
1
(CC @TeunPronk)
Dennis
@Dennis generalmente las respuestas en este sitio no incluyen líneas de preprocesador. #include<iostream>using namespace std;
Omití
Sé que generalmente no se incluyen en el recuento de bytes, pero creo que deberían estar presentes en la respuesta.
Dennis
1

PHP - 90 caracteres

Pensé en probar el código de golf, así que aquí está, mi primer intento, probablemente se pueda jugar más.

<?php $a=array(57,23,99,45);foreach($a as$b){echo abs(substr($b,0,1)-substr($b,1,1)%10);}

58 caracteres (cortesía de Ismael Miguel)

for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);

Acceda al archivo usando

file.php?n=57239945
Rory McPerlroy
fuente
Pruebe este código: <? for($i=0;$i<4;)echo abs($_GET[n][$i]%10);que tiene 44 caracteres de longitud. Acceso desde un navegador usando file.php?n[]=xx&n[]=yy&n[]=xy&n[]=yx. (código no probado)
Ismael Miguel
Es una buena idea usar $_GETpero muestra 57% 10 y necesito (5-7)% 10
Rory McPerlroy
Prueba con esto: <? for($i=0,$a=$_GET[n];$i<4;++$i)echo abs($a[$i][0]-$a[$i++][1]%10);. Lamentablemente, tiene 65 bytes de longitud. (olvidé el $iincremento en el último) O podría intentar <? for($i=0;$i<8;)echo abs($_GET[n][$i++]-$_GET[n][$i++]%10);acceder al navegador usando file.php?n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y61 bytes de longitud.
Ismael Miguel
Sí, el segundo funciona, necesito hacer eso $_GET['n']. Han editado mi respuesta.
Rory McPerlroy
Bueno, no es obligatorio. Simplemente emite una advertencia. Eso está bien para este sitio web. Pero probar esto: <? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);. El %10es inútil y este simplemente se ve mejor. Además, puede acceder usando file.php?n[]=xyxyxyxy. Esta solución tiene 58 bytes de longitud.
Ismael Miguel
0

Pitón 3, 60

for x in input().split():print(-eval('-'.join(x))%10,end='')

Entrada y salida exactamente como se especifica, aunque no imprime una nueva línea final. Aquí hay dos trucos interesantes: 1) reemplazar dos llamadas a int()por una llamada a eval(), y 2) usar join()para obtener a-b, luego negarlo b-asegún sea necesario. Afortunadamente, el operador de módulo de Python da valores positivos incluso si el primer argumento es negativo.

DLosc
fuente
¿Por qué se rechazó esto? Funciona perfectamente bien. (Por cierto, el eval('-'.join(x))truco es brillante.)
flornquake
@flornquake ¡Gracias!
DLosc