Quebrar o código para o bloqueio de combinação

22

Dada uma trava de combinação padrão como a da foto. A maneira de desbloqueá-lo é alinhar os 4 números no código na linha de combinação. Depois de anos de serviço leal, você foi demitido da fábrica de fechaduras e decidiu se vingar não estragando as fechaduras antes de enviá-las, deixando assim cada fechadura com a combinação para desbloqueá-la na linha de combinação.

Fechadura de combinação

Você também sabe que, observando a ordem dos números nas outras linhas, é possível determinar quais números devem estar na linha de combinação (e, portanto, a combinação para desbloqueá-lo).

Se cada linha do bloqueio receber um número começando da linha 0 da linha de combinação (a linha que desbloqueia o bloqueio) até a linha 9. Por exemplo, se os números da linha 4 forem 5336, então a combinação para desbloqueá-lo seria 1992.

Infelizmente, os bloqueios já foram empacotados e sua visão de cada bloqueio é obscurecida, portanto, você só pode ver números em diferentes linhas do bloqueio.

O desafio

Dados 4 pares de dígitos, em que o primeiro dígito do número inteiro representa o número da linha e o segundo dígito representa o número que aparece nessa linha, calcule a combinação da fechadura. Por exemplo, se você digitar:

57 23 99 45

Então ele deve gerar:

2101

Ou

25 78 63 15

e

3174

Suponha que a entrada sempre terá 4 números inteiros positivos na forma `25 64 72 18.

Isso é , então os programas mais curtos em número de bytes vencem.

Além disso, esta é minha primeira pergunta, portanto qualquer feedback é apreciado.

Rory McPerlroy
fonte
Eu acho que você precisa esclarecer a entrada. Você diz " Dados 4 pares de números inteiros " e depois dá um exemplo 57 23 99 45. Não são quatro pares de números inteiros: são quatro números inteiros. E algumas respostas estão assumindo que elas entendem isso como uma string, enquanto outras estão assumindo que ela vem pronta como 4 ints.
Peter Taylor
Discordo do fato de que quatro pares de números inteiros tornaram claro o formato da entrada, 57 é o par inteiro 5 e 7, e não o número inteiro 57. Minha primeira suposição foi que a linha era 57 e a combinação era 23
Qwerty01
1
Que tal "pares de dígitos?" Isso seria muito mais claro e preciso (e também funciona com os principais 0).
macio
Tecnicamente, o termo correto seria bloqueio de permutação . A maioria dos "bloqueios de combinação" são na verdade bloqueios de permutação, porque a ordem dos dígitos faz a diferença.
precisa saber é o seguinte
Tecnicamente sim, está correto, mas acho que não é um título atraente.
Rory McPerlroy

Respostas:

32

CJam, 9 8 bytes

ea9fbAf%

Lê os pares de dígitos como argumentos da linha de comando. Para experimentar o código online , mude eapara lS/para ler a partir de STDIN simulado.

Exemplo de execução

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

Como funciona

O código de caractere do dígito d é 48 + d . Assim, considerando a sequência de dois dígitos xy, um número base 9 produz 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
fonte
Droga, você não pode deixar ninguém mais vencer, não? : P
Otimizador
Acho que não teremos uma resposta CJam melhor do que essa #
Rory McPerlroy 15/09/14
1
O que aconteceu lá?
War
1
@DigitalTrauma: Claro, vá em frente. A cadeia "99"é realmente interpretada como a matriz [57 57]por b; "xy"9bé implementado como 9 * ord(x) + ord(y). Devo acrescentar isso à minha resposta.
Dennis
4
10.000 mal cobrem todos os programas de 2 caracteres se restringirmos as possíveis soluções ao ASCII imprimível.
Dennis
13

CJam, 13 12 11 caracteres

Graças ao user23013, agora ele tem 11 caracteres :)

4{Ar:--A%}*

Explicações:

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

Experimente online

Eu sei que pode ser jogado mais. Mas esta é a minha primeira tentativa real no CJam e estou limitado pela experiência :)


Como alternativa, os outros métodos para fazer a mesma coisa em 1 caractere extra:

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

ou

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

ou

ea{i_A/-A%}/     // If input is passed through command line
Optimizer
fonte
Eu estava esperando por isso. Bem, na próxima semana ...
Soham Chowdhury
Os três primeiros caracteres podem ser alternativamente l~]. Eu me sinto como analisar a entrada deve ser possível com menos de três anos, mas eu nunca usei CJam antes: /
Ingo Bürk
4{ri_A/-A%}*é um byte mais curto.
Ingo Bürk 14/09/14
1
Ah, ou o que você fez do meu comentário anterior. Bem, agora existem duas soluções de 12 bytes! :)
Ingo Bürk
3
Or 4{Ar:--A%}*.
precisa saber é o seguinte
6

Golfe (14 13 )

Experimente online aqui

É praticamente o mesmo que a solução Optimizer , mas em um idioma diferente. É difícil abordá-lo de uma maneira diferente, porque o problema é bastante simples , então o empate definitivamente vai para o Optimizer, cuja entrada era anterior de qualquer maneira.

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

Para o mesmo número de bytes, você pode fazer

~]{.10/- 10%}/
Ingo Bürk
fonte
Nenhuma variável pré-definida com o valor 10 em Golfscript?
Optimizer
@ Optimizer Infelizmente, não. Pena, porque ter a entrada na pilha já seria a vantagem sobre o CJam.
Ingo Bürk
Sim, ele pode ser de 10 caracteres na CJam (com entrada em pilha) ou 11 em Golfscript (com pré variável definida)
Optimizer
Eu também poderia ter 12 no Golfscript se não tivesse que deixar o espaço - 10.
Ingo Bürk 14/09/14
1
heh, mesmo o mais curto de línguas têm as suas curtas idas: P
Optimizer
6

GNU dc , 14 bytes

Usando o truque inteligente da base 9 de Dennis :

9i[?A%nd]dxxxx

Inteiros de entrada lidos em STDIN, um por linha.

Explicação:

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    

Saída:

$ 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$ 
$ 

Resposta anterior, 18 bytes:

Porque eu pensei que poderia me aproximar dos idiomas "golfe" com isso (mas não o fiz):

[A?A~--A%n]dddxxxx
Trauma Digital
fonte
1
Você pode salvar um byte:9i[?A%nd]dxxxx
Dennis
@Dennis - Fantástico! Agora eu estou com o golfscript e com o APL!
Digital Trauma
6

C 64 63 56 ou 61

Se a entrada puder ser canalizada do arquivo

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

Se a entrada deve ser digitada como stdin

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

Lê os quatro números em um loop e depois processa cada um subtraindo o primeiro dígito do valor e imprimindo o módulo de resultado 10.

Economia graças a vários comentários abaixo e também usando putchar em vez de printf

Alquimista
fonte
Legal. Você pode salvar uma vírgula colocando do scanflado de fora o for()seguinte:a,i;main(){for(;i++-4;printf("%d",(a-a/10)%10))scanf("%d",&a);}
Level River St
Você também pode salvar 2 bytes usando em a*.9vez dea-a/10
rev
@steveverrill Gostou. Então focado em colocar tudo no loop for que eu perdi isso
Alchymist
1
@AcidShout Desculpe - não funciona. Por exemplo 78 * .9 = 70.2, enquanto 78 - 78/10 = 71. O uso de .9 também promove o argumento para um dobro, então não posso usar o mod.
Savic
Você pode salvar alguns bytes usando um whileloop e declarando acomo argumento main:main(a){while(scanf("%d",&a)>0)printf("%d",(a-a/10)%10);}
Dennis
5

Python 3, 64

Direto.

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

Pode ser mais curto se eu puder imprimir, por exemplo [2, 1, 0, 1]( 46 ):

print([i%10-i//10 for i in map(int,input().split())])
Soham Chowdhury
fonte
Você pode salvar alguns pegando str((i-i//10)%10)diretamente, em vez de usar um segundo map(). Comecei com geradores também para os meus, mas descobri que um forloop real acabou sendo mais curto.
DLosc
Sim, obrigado por isso!
Soham Chowdhury
Por que você está usando lista-compreensões? Use genexps para salvar 2 caracteres: print(''.join((i-i//10)%10for i in map(int,input().split()))). Além disso, se os espaços são allowd na saída você pode evitar joine uso tupla-desembalar: print(*((i-i//10)%10for i in map(int,input().split()))).
Bakuriu 15/09/14
Eu acho que você está certo.
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 da linha de comando. Subtrai o primeiro código ASCII de cada argumento do segundo, adiciona 10 e pega o módulo 10.

Acho que é a primeira vez que escrevo um printfcom quatro se %nenhuma vírgula (a vírgula está na #define.)

Level River St
fonte
#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)seguido por a,b;main(){f;f;f;f;}seria 18 bytes mais curto.
Dennis
@ Dennis, é uma grande melhoria, mas é basicamente um programa completamente diferente. Eu acho que se alguém postar, deveria ser você, não eu. Não tenho certeza se o espaço scanfé necessário, considerando que ele scanfdeve analisar o espaço em branco apenas como um separador. Alquimista tem uma idéia ainda melhor em C. Mas parece que você já ganhou com a sua resposta Cjam.
Level River St
Sim, comecei percebendo que o espaço a seguir a(n)pode ser omitido, então notei que colocar printf("%d%,...)sua macro economizaria alguns bytes e, finalmente, me empolguei um pouco ... - O espaço é necessário, pois %clê um caractere, qualquer caractere, portanto, na segunda execução, ele armazenaria 32 pol a. - Bater CJam com C deve ser difícil. printf()já é tão longa como a minha resposta ...
Dennis
4

Java - 203 bytes

Só porque tem que haver uma entrada Java, eu vi uma boa oportunidade para dar a esse código a chance de jogar golfe (a primeira submissão de todos os tempos).

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

Se houver espaço para algumas melhorias, eu ficaria feliz em saber sobre elas ;-)

Sander
fonte
Você pode pesquisar [dicas] e obter várias dicas sobre golfe para começar :) #
Optimizer
Legal, obrigado! Verificando algumas dicas me ajudaram a raspar 13 bytes :)
Sander
3

Lua - 46 caracteres

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

Lê três caracteres por vez (conceda-me a pequena misericórdia de inserir um espaço no final), e mesmo que aeb sejam string y ... ba MAGICALUALY permite que eles concebam um bebê inteiro saudável. O wrap-around verifica durante a impressão.

Como eu o executo:

AndoDaan
fonte
1
Você poderia fornecer um exemplo de entrada / saída de dados, parece que não consegue executá- lo
Rory McPerlroy 14/14
@ Harry12345 Ah, desculpe por isso. Anarchy Golf está pensando em como eu implemento o stdinput. Eu provavelmente poderia codificá-lo melhor, mas meh, lua é terrível. Postei um exemplo de mim executando o programa.
AndoDaan
3

JavaScript ES6 - 53 43 bytes

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

Função bastante direta, usa regex para obter os números. Experimente em http://jsfiddle.net/efc93986/1/ . Se funções não forem permitidas, um programa independente de 52 bytes:

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

Como o ES6 atualmente funciona apenas no Firefox, o código a seguir funciona em qualquer navegador moderno, com 70 bytes:

alert(prompt().replace(/.. ?/g,function(a){return(1+a[1]-a[0])%10}))
NinjaBearMonkey
fonte
Eu amo o seu 1+.
Neil
1
A pergunta diz para assumir entrada válida, para que você possa usar em ...?vez de /\d+ ?. O espaço após o retorno pode ser omitido. Além disso, como nenhuma E / S específica foi especificada, você poderá usar uma função.
Dennis
1
a-a[0]em vez de 1+a[1]-a[0]deve funcionar também.
Dennis
2

Python 2 - 33 bytes

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

Aceita entrada de usuário delimitada por vírgula. Por exemplo, Entrada:

29,26, 31, 88

Saída:

7
4
8
0

Se a saída for necessária para corresponder exatamente ao exemplo, será muito mais longo. 47 bytes:

print"%d"*4%tuple((i-i/10)%10 for i in input())
feersum
fonte
input()não funciona no meu intérprete Python 2.
Soham Chowdhury
@SohamChowdhury você usou vírgulas?
feersum 14/09/14
2
Oh, não, eu não fiz. Funciona agora. Em uma nota lateral, acho que você precisa aceitar entradas delimitadas por espaço de acordo com as especificações.
Soham Chowdhury
3
Concordo, a entrada deve ser de espaço limitado
Rory McPerlroy 14/14
2

APL, 14

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

A explicação
recebe as informações da tela. Valores separados por espaço são analisados ​​como uma matriz.
{...}¨para cada número, alimente-o na função.
⍎¨⍕⍵pega o argumento, cria uma matriz de seus dígitos.
--/calcula unidades menos dezenas.
10|mod 10.

TwiNight
fonte
1
Pode ter 14 caracteres, mas tem 24 bytes .
Ingo Bürk 14/09/14
mas para o código de golfe contamos em UTF-8, não em um conjunto de caracteres especial. Isso seria apenas uma brecha e poderia ser abusada com muita facilidade.
Ingo Bürk 14/09/14
1
@ IngoBürk Conforme meta.codegolf.stackexchange.com/a/961/6972, as respostas podem ser codificadas em qualquer codificação, a menos que o OP indique o contrário. De fato, existe uma página de código da IBM para caracteres APL, que é um mapeamento de byte único, exatamente o que o Dyalog costumava usar antes do Unicode 3.0. Se você insistir no Unicode, e se eu inventar um novo idioma que use caracteres não Unicode? Como você contaria bytes para isso?
TwiNight 14/09/14
Eu poderia jurar que o padrão era UTF-8. 14 bytes, então.
Ingo Bürk 15/09/14
2

J - 20 15

A forma não-verbal (como instrução em vez de definição de função) é 5 caracteres mais curta:

10|-~/|:10#.inv

A forma verbal que é um bom trem :

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

Este verbo usado nas entradas de exemplo:

   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
fonte
2

Haskell 60 58

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

Dígitos de caracteres únicos, um verdadeiro inimigo no golfe Haskell.

Zeta
fonte
2

Perl: 38 40

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

Saída:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174
Riymus
fonte
1
1. Os sublinhados são sintaxe de remarcação; portanto, seu código ficou um pouco confuso. Para evitar isso, indente o código com quatro espaços. 2. absnão é necessário; x - x/10não pode ser negativo. 3. Se você usar os sinalizadores -040pe(normalmente contados como 5 bytes) para iterar sobre a entrada delimitada por espaço, poderá reduzir o seu código para $_=($_-int$_/10)%10. 4. Se você preferir evitar os sinalizadores da linha de comando, ainda poderá salvar alguns bytes configurando $/=$;e removendo a chamada para split.
Dennis
1

Ruby, 35 bytes

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

Explicação

A entrada é aceita como argumentos de linha de comando. String#bytesretorna uma matriz de números inteiros (códigos de caracteres ASCII). Somente a diferença entre o código do último e do primeiro caractere é importante, não os números inteiros.

britishtea
fonte
1

C # e LinqPad: 104

Util.ReadLine<string>("").Split(' ').Select(s =>(s[1]-s[0])).Aggregate("",(r,a)=>r+(a<0?10+a:a)).Dump();
EvilFonti
fonte
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
fonte
1. Não tenho certeza sobre outros compiladores, mas o GCC exige #include<iostream>e std::antes cine cout. 2. Você não precisa do condicional se omitir a=a%10. 3. Você não precisa das variáveis be cdos feeds de linha e (com algumas modificações) dos colchetes ao redor do loop for.
Dennis
1
@SeanD: Por favor, não aprove edições que modifiquem o código. Nesse caso específico, a edição tornou a resposta inválida. Também removeu a primeira linha, que deve estar presente em todas as respostas.
Dennis
1
(CC @TeunPronk)
Dennis
As respostas @Dennis normalmente neste site não incluem linhas de pré-processador. Eu omiti as linhas #include<iostream>eusing namespace std;
bacchusbeale 16/09
Sei que geralmente não estão incluídos na contagem de bytes, mas acho que eles devem estar presentes na resposta.
Dennis
1

PHP - 90 caracteres

Pensei em tentar o código de golfe, então aqui está, minha primeira tentativa - provavelmente pode ser mais um jogo de golfe.

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

58 caracteres (cortesia de Ismael Miguel)

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

Acesse o arquivo usando

file.php?n=57239945
Rory McPerlroy
fonte
Experimente este código: <? for($i=0;$i<4;)echo abs($_GET[n][$i]%10);que tem 44 caracteres. Acesse a partir de um navegador usando file.php?n[]=xx&n[]=yy&n[]=xy&n[]=yx. (código não testado)
Ismael Miguel
Boa ideia usar, $_GETmas exibe 57% 10 e eu preciso (5-7)% 10 #
Rory McPerlroy
Tente esta: <? for($i=0,$a=$_GET[n];$i<4;++$i)echo abs($a[$i][0]-$a[$i++][1]%10);. Infelizmente, tem 65 bytes de comprimento. (esqueceu o $iincremento no último) Ou você pode tentar <? for($i=0;$i<8;)echo abs($_GET[n][$i++]-$_GET[n][$i++]%10);acessar o navegador usando file.php?n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y, com 61 bytes de comprimento.
Ismael Miguel
Sim, o segundo funciona, precisa fazer $_GET['n']tho. Editei minha resposta.
Rory McPerlroy
Bem, não é necessário. Simplesmente emite um aviso. Isso é bom para este site. Mas tente este: <? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);. O %10é inútil e este simplesmente parece melhor. Além disso, você pode acessá-lo usando file.php?n[]=xyxyxyxy. Esta solução tem 58 bytes.
Ismael Miguel
0

Python 3, 60

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

Entrada e saída exatamente como especificado, embora não imprima uma nova linha à direita. Dois truques interessantes aqui: 1) substituindo duas chamadas int()por uma chamada para eval()e 2) usando join()para obter e a-b, em seguida, negando-o b-aconforme necessário. Felizmente, o operador de módulo do Python fornece valores positivos, mesmo que o primeiro argumento seja negativo!

DLosc
fonte
Por que isso foi prejudicado? Funciona perfeitamente bem. (A propósito, o eval('-'.join(x))truque é brilhante.)
flornquake
@flornquake Thanks!
DLosc 22/09/14