Crack il codice sul lucchetto a combinazione


22

Dato un lucchetto a combinazione standard come quello nella foto. Il modo per sbloccarlo è allineare i 4 numeri nel codice sulla riga di combinazione. Dopo anni di fedele servizio sei stato licenziato dalla fabbrica di serrature e hai deciso di vendicarti non confondendo le serrature prima di espellerle, lasciando così ogni serratura con la combinazione per sbloccarla sulla linea della combinazione.

Lucchetto a combinazione

Sai anche che guardando l'ordine dei numeri nelle altre righe è possibile capire quali numeri devono essere sulla riga della combinazione (e quindi la combinazione per sbloccarla è).

Se a ogni riga del lucchetto viene assegnato un numero che inizia dalla riga 0 per la riga combinata (la riga che sblocca il blocco) alla riga 9. Ad esempio, se i numeri sulla riga 4 lo sono 5336, allora la combinazione per sbloccarlo sarebbe 1992.

Sfortunatamente i blocchi sono già stati impacchettati e la tua vista di ciascun blocco è oscurata, quindi puoi vedere solo numeri su diverse linee del blocco.

La sfida

Dato 4 coppie di cifre, in cui la prima cifra dell'intero rappresenta il numero di riga e la seconda cifra rappresenta il numero che appare su quella riga, elaborare la combinazione per il blocco. Ad esempio se inserisci:

57 23 99 45

Quindi dovrebbe emettere:

2101

O

25 78 63 15

e

3174

Supponiamo che l'input sia sempre 4 numeri interi positivi nella forma `25 64 72 18.

Questo è , quindi vince il programma più breve in numero di byte.

Anche questa è la mia prima domanda, quindi ogni feedback è apprezzato.


Penso che sia necessario chiarire l'input. Dici " Dato 4 coppie di numeri interi " e poi fai un esempio 57 23 99 45. Non sono quattro coppie di numeri interi: sono quattro numeri interi. E alcune risposte stanno assumendo che lo ottengano come una stringa, mentre altri stanno assumendo che venga pre-analizzato come 4 pollici.
Peter Taylor,

Non sono d'accordo, il fatto che dicesse che quattro coppie di numeri interi hanno reso chiaro il formato dell'input, 57 è la coppia intera 5 e 7, non l'intero 57. La mia prima ipotesi è stata che la linea era 57 e la combinazione era 23.
Qwerty01

1
Che ne dici di "coppie di cifre?" Sarebbe molto più chiaro e preciso (e funziona anche con i principali 0).
soffice

Tecnicamente, il termine corretto sarebbe il blocco della permutazione . La maggior parte dei "blocchi a combinazione" sono in realtà blocchi a permutazione, perché l'ordine delle cifre fa la differenza.
nyuszika7h,

Tecnicamente sì, è corretto, ma non credo sia un titolo accattivante.
Rory McPerlroy,

Risposte:


32

CJam, 9 8 byte

ea9fbAf%

Legge le coppie di cifre come argomenti della riga di comando. Per provare il codice di linea , cambio eaa lS/leggere da STDIN simulato.

Esempio di esecuzione

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

Come funziona

Il codice carattere della cifra d è 48 + d . Pertanto, considerando la stringa di due cifre xy un numero di 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.                                                    ";

Dannazione, non puoi permettere a nessun altro di vincere, no? : P
Ottimizzatore

Non credo che avremo una risposta CJam migliore di questa
Rory McPerlroy,

1
Cosa è appena successo lì?
Guerra,

1
@DigitalTrauma: Certo, vai avanti. La stringa "99"viene in realtà interpretata come l'array [57 57]da b; "xy"9bè implementato come 9 * ord(x) + ord(y). Dovrei aggiungerlo alla mia risposta.
Dennis,

4
10.000 copre a malapena tutti i programmi a 2 caratteri se limitiamo le possibili soluzioni all'ASCII stampabile.
Dennis,

13

CJam, 13 12 11 caratteri

Grazie a user23013, ora è ridotto a 11 caratteri :)

4{Ar:--A%}*

spiegazioni:

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

Provalo online

So che si può giocare a golf di più. Ma questo è il mio primo vero tentativo su CJam e sono limitato dall'esperienza :)


In alternativa, gli altri metodi per fare la stessa cosa con 1 carattere in più:

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

Lo stavo aspettando. Bene, la prossima settimana ...
Soham Chowdhury

I primi tre personaggi potrebbero essere alternativamente l~]. Mi sembra che l'analisi dell'ingresso dovrebbe essere possibile con meno di tre, ma non ho mai usato CJam prima: /
Ingo Bürk

4{ri_A/-A%}*è più corto di un byte.
Ingo Bürk,

1
Ah, o cosa hai fatto dal mio precedente commento. Bene, ora ci sono due soluzioni da 12 byte! :)
Ingo Bürk,

3
Or 4{Ar:--A%}*.
jimmy23013,

6

Golfscript (14 13 )

Provalo online qui

È praticamente la stessa della soluzione Optimizer , ma in una lingua diversa. È difficile affrontarlo in modo diverso perché il problema è abbastanza semplice , quindi il legame va sicuramente a Optimizer, la cui voce era comunque precedente.

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

Per lo stesso numero di byte che puoi fare

~]{.10/- 10%}/

Nessuna variabile predefinita con valore 10 in Golfscript?
Ottimizzatore

@Optimizer Purtroppo no. Peccato, perché avere già l'input nello stack sarebbe il vantaggio rispetto a CJam.
Ingo Bürk,

Sì, può contenere 10 caratteri in CJam (con input in pila) o 11 in Golfscript (con variabile predefinita)
Optimizer

Potrei averne anche 12 in Golfscript se solo non dovessi lasciare spazio - 10.
Ingo Bürk,

1
eh, anche il più breve dei linguaggi hanno i loro brevi comings: P
Optimizer

6

GNU cc , 14 byte

Prendendo in prestito l'intelligente trucco di base 9 di Dennis :

9i[?A%nd]dxxxx

Numeri interi di input letti da STDIN, uno per riga.

Spiegazione:

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    

Produzione:

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

Risposta precedente, 18 byte:

Perché pensavo di poter avvicinarmi alle lingue del "golf" con questo (ma non l'ho fatto):

[A?A~--A%n]dddxxxx

1
È possibile salvare un byte:9i[?A%nd]dxxxx
Dennis,

@Dennis - Fantastico! Ora sono testa a testa con golfscript e APL!
Trauma digitale,

6

C 64 63 56 o 61

Se l'input può essere reindirizzato dal file

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

Se l'input deve essere digitato su stdin

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

Legge i quattro numeri in un ciclo e quindi li elabora sottraendo la prima cifra dal valore e stampando il risultato modulo 10.

Risparmio grazie ai vari commenti qui sotto e anche usando putchar invece di printf


Freddo. Puoi salvare una virgola mettendo l' scanfesterno in for()questo modoa,i;main(){for(;i++-4;printf("%d",(a-a/10)%10))scanf("%d",&a);}
Level River St

È inoltre possibile salvare 2 byte utilizzando a*.9invece dia-a/10
rev

@steveverrill Mi piace. Così concentrato sul mettere tutto nel ciclo for che mi mancava quello
Alchymist

1
@AcidShout Siamo spiacenti, non funziona. Ad esempio 78 * .9 = 70.2, mentre 78 - 78/10 = 71. Anche l'uso di .9 promuove l'argomento a un doppio, quindi non posso prendere la mod.
Alchymist,

È possibile salvare alcuni byte utilizzando un whileloop e dichiarando acome argomento di main:main(a){while(scanf("%d",&a)>0)printf("%d",(a-a/10)%10);}
Dennis

5

Python 3, 64

Semplice.

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

Può essere più breve se mi è permesso stampare, diciamo, [2, 1, 0, 1]invece ( 46 ):

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

Puoi salvarne alcuni prendendo str((i-i//10)%10)direttamente invece di usare un secondo map(). Ho iniziato con i generatori anche per i miei, ma ho scoperto che un forcircuito reale ha finito per essere più corto.
DLosc,

Sì, grazie per quello!
Soham Chowdhury,

Perché stai usando la comprensione delle liste? Utilizzare genexps per salvare 2 caratteri: print(''.join((i-i//10)%10for i in map(int,input().split()))). Anche se gli spazi sono allowd nell'output si può evitare joine utilizzare tuple-disimballaggio: print(*((i-i//10)%10for i in map(int,input().split()))).
Bakuriu,

Credo tu abbia ragione.
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));}

Input dalla riga di comando. Sottrae il primo codice ASCII di ciascun argomento dal secondo, aggiunge 10 e accetta il modulo 10.

Penso che questa sia la prima volta che scrivo a printfcon quattro se %nessuna virgola (la virgola è nella #define.)


#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)seguito da a,b;main(){f;f;f;f;}sarebbe più breve di 18 byte.
Dennis,

@Dennis è un grande miglioramento, ma è fondamentalmente un programma completamente diverso. Penso che se qualcuno lo pubblica, dovresti essere tu, non io. Non sono sicuro se lo spazio scanfsia necessario, dato che scanfsi suppone che analizzi gli spazi bianchi solo come separatore. Alchymist ha un'idea ancora migliore in C. Ma sembra che tu abbia già vinto con la tua risposta Cjam.
Level River St,

Sì, ho iniziato notando che lo spazio dopo a(n)può essere omesso, quindi ho notato che mettere in printf("%d%,...)giro la tua macro salverebbe alcuni byte e alla fine mi sono lasciato trasportare un po '... - Lo spazio è necessario poiché %clegge un personaggio, qualsiasi carattere, quindi alla seconda esecuzione ne memorizzerebbe 32 in a. - Battere CJam con C dovrebbe rivelarsi difficile. printf()è già fintanto che la mia risposta ...
Dennis,

4

Java - 203 byte

Solo perché ci deve essere una voce Java, ho visto una bella opportunità per dare una possibilità a questo codice di giocare a golf (prima presentazione in assoluto).

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 c'è spazio per alcuni miglioramenti, sarei felice di conoscerli ;-)


Puoi cercare [suggerimenti] e ottenere vari suggerimenti sul golf per iniziare :)
Ottimizzatore,

Figo, grazie! Dare un'occhiata ad alcuni suggerimenti mi ha aiutato a radere 13 byte :)
Sander,

3

Lua - 46 caratteri

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

Legge tre caratteri alla volta (concedimi la piccola misericordia di inserire uno spazio alla fine), e anche se a e b sono string-y ... ba MAGICALUALY consente loro di concepire un intero bambino sano. Esegue il controllo avvolgente durante la stampa.

Come lo eseguo:


1
Potresti fornire un esempio di input / output di dati, non riesco a farlo funzionare su Ideone
Rory McPerlroy

@ Harry12345 Ah, mi dispiace per quello. Anarchy Golf mi sta pensando su come implementare lo stdinput. Probabilmente potrei codificarlo meglio, ma meh, lua è terribile. Ho pubblicato un esempio di me che eseguo il programma.
AndoDaan,

3

JavaScript ES6 - 53 43 byte

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

Funzione abbastanza semplice, usa regex per ottenere i numeri. Provalo su http://jsfiddle.net/efc93986/1/ . Se le funzioni non sono consentite, un programma autonomo a 52 byte:

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

Poiché ES6 attualmente funziona solo su Firefox, il seguente codice funziona su qualsiasi browser moderno, a 70 byte:

alert(prompt().replace(/.. ?/g,function(a){return(1+a[1]-a[0])%10}))

Io amo il tuo 1+.
Neil,

1
La domanda dice di assumere un input valido, quindi puoi usare ...?invece di /\d+ ?. Lo spazio dopo il ritorno può essere omesso. Inoltre, poiché non è stato specificato alcun I / O specifico, dovresti essere in grado di utilizzare una funzione.
Dennis,

1
a-a[0]invece di 1+a[1]-a[0]dovrebbe funzionare pure.
Dennis,

2

Python 2 - 33 byte

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

Accetta input utente delimitato da virgole. Ad esempio input:

29,26, 31, 88

Produzione:

7
4
8
0

Se l'output deve corrispondere esattamente all'esempio, allora è molto più lungo. 47 byte:

print"%d"*4%tuple((i-i/10)%10 for i in input())

input()non funziona nel mio interprete Python 2.
Soham Chowdhury,

@SohamChowdhury hai usato le virgole?
feersum

2
Oh no, non l'ho fatto. Ora funziona. In una nota a margine, penso che devi prendere input delimitati da spazi per le specifiche.
Soham Chowdhury,

3
Sono d'accordo, l'input dovrebbe essere limitato
dallo

2

APL, 14

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

La spiegazione
prende input dallo schermo. I valori separati da spazio vengono analizzati come una matrice.
{...}¨per ogni numero, inseriscilo in funzione.
⍎¨⍕⍵accetta l'argomento, crea una matrice delle sue cifre.
--/calcola le unità meno le decine.
10|mod 10.


1
Può contenere 14 caratteri, ma è di 24 byte .
Ingo Bürk,


ma per il golf del codice contiamo in UTF-8, non un set di caratteri speciale. Sarebbe solo una scappatoia e potrebbe essere abusata molto facilmente.
Ingo Bürk,

1
@ IngoBürk Secondo meta.codegolf.stackexchange.com/a/961/6972 le risposte possono essere codificate in qualsiasi codifica, a meno che l'OP non specifichi diversamente. Esiste davvero una tabella codici IBM per i caratteri APL che è una mappatura a byte singolo, che era esattamente ciò che Dyalog usava prima di Unicode 3.0. Se insisti su Unicode, cosa succede se invento una nuova lingua che utilizza caratteri non Unicode? Come valuteresti i byte per questo?
TwiNight

Avrei potuto giurare che il valore predefinito era UTF-8. 14 byte, quindi.
Ingo Bürk,

2

J - 20 15

La forma non verbale (come istruzione anziché definizione della funzione) è più corta di 5 caratteri:

10|-~/|:10#.inv

La forma del verbo che è un bel treno :

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

Questo verbo utilizzato sugli input di esempio:

   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

Cifre a carattere singolo, una vera nemesi nel golf di Haskell.


2

Perl: 38 40

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

Produzione:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174

1
1. I caratteri di sottolineatura sono sintassi di markdown, quindi il codice è stato un po 'incasinato. Per evitare ciò, indentare il codice con quattro spazi. 2. absnon è necessario; x - x/10non può essere negativo. 3. Se si utilizzano i flag -040pe(generalmente conteggiati come 5 byte) per scorrere su input delimitati da spazi, è possibile abbreviare il codice $_=($_-int$_/10)%10. 4. Se si preferisce evitare i flag della riga di comando, è comunque possibile salvare alcuni byte impostando $/=$;e rimuovendo la chiamata a split.
Dennis,

1

Rubino, 35 byte

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

Spiegazione

L'input viene considerato come argomento della riga di comando. String#bytesrestituisce una matrice di numeri interi (codici di caratteri ASCII). È importante solo la differenza tra il codice dell'ultimo e del primo carattere, non gli interi.


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. Non sono sicuro di altri compilatori, ma GCC richiede #include<iostream>e std::prima cine cout. 2. Non è necessario il condizionale se si omette a=a%10. 3. Non sono necessarie le variabili be c, i linefeed e (con alcune modifiche) le parentesi attorno al ciclo for.
Dennis,

1
@SeanD: non approvare le modifiche che modificano il codice. In questo caso particolare, la modifica ha reso la risposta non valida. Ha anche rimosso la prima riga, che dovrebbe essere presente in tutte le risposte.
Dennis,

1
(CC @TeunPronk)
Dennis,

@Dennis di solito le risposte su questo sito non includono le linee del preprocessore. Ho omesso le righe #include<iostream>eusing namespace std;
bacchusbeale il

So che di solito non sono inclusi nel conteggio dei byte, ma penso che dovrebbero essere presenti nella risposta.
Dennis,

1

PHP - 90 caratteri

Ho pensato di provare il codice golf, quindi eccolo qui, il mio primo tentativo - probabilmente può essere giocato a golf di più.

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

58 personaggi (per gentile concessione di Ismael Miguel)

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

Accedi al file usando

file.php?n=57239945

Prova questo codice: <? for($i=0;$i<4;)echo abs($_GET[n][$i]%10);è lungo 44 caratteri. Accesso da un browser tramite file.php?n[]=xx&n[]=yy&n[]=xy&n[]=yx. (codice non testato)
Ismael Miguel,

Buona idea usando $_GETma mostra 57% 10 e ho bisogno (5-7)% 10
Rory McPerlroy

Prova questo: <? for($i=0,$a=$_GET[n];$i<4;++$i)echo abs($a[$i][0]-$a[$i++][1]%10);. Purtroppo, è lungo 65 byte. (dimenticato l' $iincremento sull'ultimo) Oppure potresti provare ad <? for($i=0;$i<8;)echo abs($_GET[n][$i++]-$_GET[n][$i++]%10);accedere al browser usando file.php?n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y, essendo lungo 61 byte.
Ismael Miguel,

Sì, i secondi funzionano, è necessario farlo $_GET['n']. Ho modificato la mia risposta.
Rory McPerlroy,

Bene, non è richiesto. Emette semplicemente un avvertimento. Questo va bene per questo sito web. Ma provate questo: <? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);. Il %10è inutile e questo semplicemente un aspetto migliore. Inoltre, puoi accedervi usando file.php?n[]=xyxyxyxy. Questa soluzione è lunga 58 byte.
Ismael Miguel,

0

Python 3, 60

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

Input e output esattamente come specificato, anche se non stampa una nuova riga finale. Due trucchi interessanti qui: 1) sostituendo due chiamate a int()con una chiamata a eval(), e 2) usando join()per ottenere a-b, quindi annullandolo b-acome richiesto. Fortunatamente l'operatore modulo di Python fornisce valori positivi anche se il primo argomento è negativo!


Perché questo è stato downvoted? Funziona perfettamente. (A proposito, il eval('-'.join(x))trucco è geniale.)
terremoto del

@flornquake Grazie!
DLosc,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.