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.


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

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

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%}/

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

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


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())])

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


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


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:


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

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())

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.


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

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.


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

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.


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

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

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

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!


Por que isso foi prejudicado? Funciona perfeitamente bem. (A propósito, o eval('-'.join(x))truque é brilhante.)
— flornquake

@flornquake Thanks!
— DLosc 22/09/14
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.