Pecahkan kode ke kunci kombinasi

22

Diberi kunci kombinasi standar seperti yang ada pada gambar. Cara membuka kuncinya adalah dengan menyelaraskan 4 angka dalam kode pada baris kombinasi. Setelah bertahun-tahun pelayanan yang setia, Anda telah dipecat dari pabrik kunci dan telah memutuskan untuk membalas dendam dengan tidak mengacaukan kunci sebelum Anda mengirimnya, sehingga meninggalkan setiap kunci dengan kombinasi untuk membuka kuncinya pada jalur kombinasi.

Kunci kombinasi

Anda juga tahu bahwa dengan melihat urutan angka di baris lain, Anda dapat menentukan angka apa yang harus ada pada garis kombinasi (dan karenanya kombinasi untuk membuka kuncinya).

Jika setiap baris pada kunci diberi angka mulai dari baris 0 untuk garis kombinasi (garis yang membuka kunci) ke baris 9. Misalnya, jika angka pada baris 4 adalah 5336, maka kombinasi untuk membuka kunci akan menjadi 1992.

Sayangnya kunci sudah dipaket dan pandangan Anda tentang setiap kunci dikaburkan, sehingga Anda hanya dapat melihat angka pada garis kunci yang berbeda.

Tantangan

Diberi 4 pasang digit, di mana digit pertama bilangan bulat mewakili nomor baris dan digit kedua mewakili nomor yang muncul pada garis itu, buat kombinasi ke kunci. Misalnya jika Anda memasukkan:

57 23 99 45

Maka seharusnya output:

2101

Atau

25 78 63 15

dan

3174

Asumsikan input akan selalu menjadi 4 bilangan bulat positif dalam bentuk `25 64 72 18.

Ini adalah , sehingga program terpendek dalam jumlah byte menang.

Ini juga pertanyaan pertama saya, jadi setiap umpan balik sangat dihargai.

Rory McPerlroy
sumber
Saya pikir Anda perlu mengklarifikasi input. Anda mengatakan " Diberikan 4 pasang bilangan bulat " dan kemudian memberikan contoh 57 23 99 45. Itu bukan empat pasang bilangan bulat: itu empat bilangan bulat. Dan beberapa jawaban mengasumsikan mereka mendapatkan itu sebagai string, sedangkan yang lain menganggap bahwa itu sudah siap diurai sebagai 4 int.
Peter Taylor
Saya tidak setuju, fakta bahwa dikatakan empat pasang bilangan bulat membuat format input menjadi jelas, 57 adalah pasangan integer 5 dan 7, bukan bilangan bulat 57. Asumsi pertama saya adalah bahwa garisnya adalah 57 dan kombinasinya adalah 23.
Qwerty01
1
Bagaimana dengan "pasangan digit?" Itu akan jauh lebih jelas dan tepat (dan juga bekerja dengan 0s terkemuka ).
halus
Secara teknis, istilah yang benar adalah kunci permutasi . Kebanyakan "kunci kombinasi" sebenarnya adalah kunci permutasi, karena urutan angka membuat perbedaan.
nyuszika7h
Secara teknis ya itu benar, tetapi saya tidak berpikir untuk membuat judul yang menarik.
Rory McPerlroy

Jawaban:

32

CJam, 9 8 byte

ea9fbAf%

Membaca pasangan digit sebagai argumen baris perintah. Untuk mencoba kode online , perubahan eauntuk lS/membaca dari STDIN simulasi.

Contoh dijalankan

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

Bagaimana itu bekerja

Kode karakter digit d adalah 48 + d . Dengan demikian, mengingat string dua digit xy basa 9 angka menghasilkan 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
sumber
Sial, Anda tidak bisa membiarkan orang lain menang, bukan? : P
Optimizer
Saya tidak berpikir kita akan mendapatkan jawaban CJam yang lebih baik dari ini
Rory McPerlroy
1
Apa yang terjadi di sana?
Perang
1
@DigitalTrauma: Tentu, silakan. String "99"sebenarnya ditafsirkan sebagai array [57 57]oleh b; "xy"9bdiimplementasikan sebagai 9 * ord(x) + ord(y). Saya harus menambahkan itu ke jawaban saya.
Dennis
4
10.000 hampir tidak mencakup semua program 2-karakter jika kita membatasi solusi yang mungkin untuk ASCII yang dapat dicetak.
Dennis
13

CJam, 13 12 11 karakter

Terima kasih kepada user23013, sekarang menjadi 11 karakter :)

4{Ar:--A%}*

Penjelasan:

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

Cobalah online

Saya tahu ini bisa lebih banyak golf. Tapi ini adalah upaya nyata pertama saya di CJam dan saya dibatasi oleh pengalaman :)


Atau, metode lain untuk melakukan hal yang sama dalam 1 karakter tambahan:

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

atau

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

atau

ea{i_A/-A%}/     // If input is passed through command line
Pengoptimal
sumber
Saya sedang menunggu ini. Nah, minggu depan ...
Soham Chowdhury
Tiga karakter pertama bisa menjadi alternatif l~]. Saya merasa seperti mengurai input harus mungkin dengan kurang dari tiga, tapi saya belum pernah menggunakan CJam sebelumnya: /
Ingo Bürk
4{ri_A/-A%}*lebih pendek satu byte.
Ingo Bürk
1
Ah, atau apa yang Anda buat dari komentar saya sebelumnya. Nah sekarang ada dua solusi 12 byte! :)
Ingo Bürk
3
Atau 4{Ar:--A%}*.
jimmy23013
6

Golfscript (14 13 )

Cobalah online di sini

Ini hampir sama dengan solusi Pengoptimal , tetapi dalam bahasa yang berbeda. Sulit untuk mendekatinya dengan cara yang berbeda karena masalahnya cukup sederhana , jadi ikatannya pasti masuk ke Pengoptimal, yang entri sebelumnya.

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

Untuk jumlah byte yang sama bisa Anda lakukan

~]{.10/- 10%}/
Ingo Bürk
sumber
Tidak ada variabel yang ditentukan sebelumnya dengan nilai 10 di Golfscript?
Pengoptimal
@Optimizer Sayangnya, tidak. Sayang sekali, karena memiliki input pada stack sudah akan menjadi keunggulan dibandingkan CJam.
Ingo Bürk
Ya, itu bisa 10 karakter dalam CJam (dengan input pada stack) atau 11 dalam Golfscript (dengan variabel yang ditentukan sebelumnya)
Pengoptimal
Saya bisa mendapatkan 12 di Golfscript juga kalau saja saya tidak harus meninggalkan ruang dalam - 10.
Ingo Bürk
1
heh, bahkan bahasa yang terpendek pun memiliki kedatangan singkat : P
Optimizer
6

GNU dc , 14 byte

Pinjam 9 trik pintar base 9 dari Dennis :

9i[?A%nd]dxxxx

Bilangan bulat input dibaca dari STDIN, satu per baris.

Penjelasan:

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    

Keluaran:

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

Jawaban Sebelumnya, 18 byte:

Karena saya pikir saya bisa lebih dekat ke bahasa "golf" dengan ini (tetapi tidak):

[A?A~--A%n]dddxxxx
Trauma Digital
sumber
1
Anda dapat menyimpan byte:9i[?A%nd]dxxxx
Dennis
@ Dennis - Fantastis! Sekarang saya leher-dan-leher dengan skrip golf dan APL!
Digital Trauma
6

C 64 63 56 atau 61

Jika input dapat disalurkan dari file

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

Jika input harus diketik ke stdin

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

Membaca empat angka dalam satu lingkaran dan kemudian memproses masing-masing dengan mengurangi digit pertama dari nilai dan mencetak hasilnya modulo 10.

Penghematan berkat berbagai komentar di bawah ini dan juga menggunakan putchar bukan printf

Ahli alkimia
sumber
Keren. Anda dapat menyimpan koma dengan meletakkan bagian scanfluar for()seperti inia,i;main(){for(;i++-4;printf("%d",(a-a/10)%10))scanf("%d",&a);}
Level River St
Anda juga dapat menyimpan 2 byte dengan menggunakan a*.9bukannyaa-a/10
rev
@steveverrill Suka itu. Jadi fokus pada meletakkan segala sesuatu di dalam for loop yang saya lewatkan itu
Alchymist
1
@AcidShout Maaf - tidak berfungsi. Misalnya 78 * .9 = 70.2, sementara 78 - 78/10 = 71. Juga menggunakan .9 mempromosikan argumen menjadi dobel jadi saya tidak bisa menggunakan mod.
Alchymist
Anda dapat menyimpan beberapa byte dengan menggunakan whileloop dan mendeklarasikan asebagai argumen main:main(a){while(scanf("%d",&a)>0)printf("%d",(a-a/10)%10);}
Dennis
5

Python 3, 64

Mudah.

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

Bisa lebih pendek jika saya diizinkan mencetak, misalnya, [2, 1, 0, 1]( 46 ):

print([i%10-i//10 for i in map(int,input().split())])
Soham Chowdhury
sumber
Anda dapat menyimpan beberapa dengan mengambil str((i-i//10)%10)langsung alih-alih menggunakan sedetik map(). Saya mulai dengan generator juga untuk saya, tetapi menemukan bahwa forloop sebenarnya berakhir menjadi lebih pendek.
DLosc
Yup, terima kasih untuk itu!
Soham Chowdhury
Mengapa Anda menggunakan daftar-pemahaman? Gunakan genexps untuk menyimpan 2 karakter: print(''.join((i-i//10)%10for i in map(int,input().split()))). Juga jika ruang yang allowd dalam output Anda dapat menghindari joindan menggunakan tuple-membongkar: print(*((i-i//10)%10for i in map(int,input().split()))).
Bakuriu
Saya kira Anda benar.
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 dari commandline. Kurangi kode ASCII pertama dari setiap argumen dari argumen kedua, tambahkan 10 dan ambil modulo 10.

Saya pikir ini adalah pertama kalinya saya menulis printfdengan empat %s dan tanpa koma (koma ada di #define.)

Level River St
sumber
#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)diikuti oleh a,b;main(){f;f;f;f;}akan lebih pendek 18 byte.
Dennis
@ Dennis itu perbaikan besar, tetapi pada dasarnya program yang sama sekali berbeda. Saya pikir jika ada yang mempostingnya, itu harus Anda, bukan saya. Saya tidak yakin apakah ruang dalam scanfdiperlukan, mengingat bahwa scanfseharusnya mengurai spasi putih hanya sebagai pemisah. Alchymist memiliki ide yang lebih baik di C. Tapi sepertinya Anda sudah memenangkannya dengan jawaban Cjam Anda.
Level River St
Ya, saya mulai dengan memperhatikan bahwa spasi setelahnya a(n)dapat dihilangkan, kemudian saya perhatikan bahwa meletakkan printf("%d%,...)makro Anda akan menghemat beberapa byte dan akhirnya saya sedikit terbawa ... - Ruang diperlukan karena %cmembaca karakter, apa pun karakter, jadi pada menjalankan kedua itu akan menyimpan 32 in a. - Mengalahkan CJam dengan C harus terbukti sulit. printf()sudah selama jawabanku ...
Dennis
4

Java - 203 byte

Hanya karena ada memiliki untuk menjadi entri Java, saya melihat kesempatan bagus untuk memberikan kode ini bermain golf kesempatan (penyerahan pertama).

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

Jika ada ruang untuk beberapa perbaikan, saya senang mengetahui tentang mereka ;-)

Sander
sumber
Anda dapat mencari [tips] dan mendapatkan berbagai tips tentang golf untuk memulai :) :)
Pengoptimal
Keren Terimakasih! Memeriksa beberapa tips membantu saya mencukur 13 byte :)
Sander
3

Lua - 46 karakter

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

Membaca tiga karakter sekaligus (beri saya sedikit belas kasihan memasukkan spasi di akhir), dan meskipun a dan b adalah string-y ... ba MAGICALUALY memungkinkan mereka untuk menyusun bilangan bulat bayi yang sehat. Apakah lilitan memeriksa saat mencetak.

Bagaimana saya menjalankannya:

AndoDaan
sumber
1
Bisakah Anda memberikan contoh input / output data, sepertinya tidak bisa menjalankannya di Ideone
Rory McPerlroy
@ Harry12345 Ah, maaf soal itu. Anarchy Golf menetapkan pikiran saya tentang bagaimana saya menerapkan stdinput. Saya mungkin bisa mengkodekannya lebih baik, tapi meh, lua mengerikan. Saya memposting contoh saya menjalankan program.
AndoDaan
3

JavaScript ES6 - 53 43 byte

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

Fungsi yang cukup mudah, menggunakan regex untuk mendapatkan angka. Cobalah di http://jsfiddle.net/efc93986/1/ . Jika fungsi tidak diizinkan, program mandiri berukuran 52 byte:

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

Karena ES6 saat ini hanya berfungsi di Firefox, kode berikut ini berfungsi pada browser modern apa pun, pada 70 byte

alert(prompt().replace(/.. ?/g,function(a){return(1+a[1]-a[0])%10}))
NinjaBearMonkey
sumber
Saya suka Anda 1+.
Neil
1
Pertanyaannya mengatakan untuk menerima input yang valid, sehingga Anda dapat menggunakannya ...?sebagai gantinya /\d+ ?. Ruang setelah kembali dapat dihilangkan. Juga, karena tidak ada I / O khusus yang ditentukan, Anda harus dapat menggunakan suatu fungsi.
Dennis
1
a-a[0]alih-alih 1+a[1]-a[0]harus bekerja juga.
Dennis
2

Python 2 - 33 byte

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

Menerima input pengguna yang dibatasi koma. Misalnya Input:

29,26, 31, 88

Keluaran:

7
4
8
0

Jika output diperlukan untuk sama persis dengan contoh maka itu jauh lebih lama. 47 byte:

print"%d"*4%tuple((i-i/10)%10 for i in input())
feersum
sumber
input()tidak berfungsi pada juru bahasa Python 2 saya.
Soham Chowdhury
@SohamChowdhury apakah Anda menggunakan koma?
feersum
2
Oh, tidak, tidak. Ini berfungsi sekarang. Sebagai catatan, saya pikir Anda perlu mengambil input yang dibatasi ruang per spec.
Soham Chowdhury
3
Saya setuju, input harus dibatasi ruang
Rory McPerlroy
2

APL, 14

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

Penjelasan
mengambil input dari layar. Nilai yang dipisahkan oleh ruang diuraikan sebagai array.
{...}¨untuk setiap nomor, masukkan ke dalam fungsi.
⍎¨⍕⍵mengambil argumen, buat array dari digit-digitnya.
--/menghitung satuan minus puluhan.
10|mod 10.

TwiNight
sumber
1
Ini mungkin 14 karakter, tetapi 24 byte .
Ingo Bürk
tetapi untuk kode golf kita hitung dalam UTF-8, bukan charset khusus. Itu hanya akan menjadi celah dan bisa disalahgunakan dengan sangat mudah.
Ingo Bürk
1
@ IngoBürk Sesuai meta.codegolf.stackexchange.com/a/961/6972 jawaban dapat dikodekan dalam penyandian apa pun kecuali jika OP menyatakan sebaliknya. Memang ada codepage IBM untuk karakter APL yang merupakan pemetaan byte tunggal, yang persis seperti yang digunakan Dyalog sebelum Unicode 3.0. Jika Anda bersikeras tentang Unicode, bagaimana jika saya menciptakan bahasa baru yang menggunakan karakter non-Unicode? Bagaimana Anda menghitung byte untuk itu?
TwiNight
Saya bisa bersumpah defaultnya adalah UTF-8. 14 byte itu, lalu.
Ingo Bürk
2

J - 20 15

Bentuk non-kata kerja (sebagai pernyataan alih-alih definisi fungsi) lebih pendek 5 karakter:

10|-~/|:10#.inv

Bentuk kata kerja yang merupakan kereta yang bagus :

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

Kata kerja ini digunakan pada contoh input:

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

Haskell 60 58

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

Digit karakter tunggal, musuh bebuyutan di golf Haskell.

Zeta
sumber
2

Perl: 38 40

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

Keluaran:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174
Riymus
sumber
1
1. Garis bawah adalah sintaks penurunan harga, jadi kode Anda menjadi sedikit kacau. Untuk mencegah hal ini, indentasikan kode dengan empat spasi. 2. abstidak perlu; x - x/10tidak boleh negatif. 3. Jika Anda menggunakan flag -040pe(biasanya dihitung sebagai 5 byte) untuk beralih dari input yang dibatasi ruang, Anda dapat mempersingkat kode Anda menjadi $_=($_-int$_/10)%10. 4. Jika Anda lebih suka menghindari flag-command-line, Anda masih dapat menyimpan beberapa byte dengan mengatur $/=$;dan menghapus panggilan split.
Dennis
1

Ruby, 35 byte

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

Penjelasan

Input diambil sebagai argumen baris perintah. String#bytesmengembalikan Array of Integers (kode karakter ASCII). Hanya perbedaan antara kode karakter terakhir dan pertama yang penting, bukan bilangan bulat itu sendiri.

britishtea
sumber
1

C # & LinqPad: 104

Util.ReadLine<string>("").Split(' ').Select(s =>(s[1]-s[0])).Aggregate("",(r,a)=>r+(a<0?10+a:a)).Dump();
EvilFonti
sumber
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
sumber
1. Tidak yakin tentang kompiler lain, tetapi GCC membutuhkan #include<iostream>dan std::sebelum cindan cout. 2. Anda tidak perlu bersyarat jika dihilangkan a=a%10. 3. Anda tidak memerlukan variabel bdan c, baris baris dan (dengan sedikit modifikasi) tanda kurung di sekitar for loop.
Dennis
1
@SeanD: Tolong jangan setujui editan yang memodifikasi kode. Dalam kasus khusus ini, hasil edit membuat jawaban tidak valid. Itu juga menghapus baris pertama, yang harus ada di semua jawaban.
Dennis
1
(CC @TeunPronk)
Dennis
@Dennis biasanya menjawab di situs ini tidak termasuk garis preprosesor. Saya menghilangkan garis #include<iostream>danusing namespace std;
bacchusbeale
Saya tahu di sana biasanya tidak termasuk dalam hitungan byte, tapi saya pikir mereka harus hadir dalam jawabannya.
Dennis
1

PHP - 90 karakter

Pikir saya akan mencoba kode golf jadi ini dia, usaha pertama saya - mungkin bisa golf lebih.

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

58 karakter (milik Ismael Miguel)

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

Akses file menggunakan

file.php?n=57239945
Rory McPerlroy
sumber
Coba kode ini: <? for($i=0;$i<4;)echo abs($_GET[n][$i]%10);yang panjangnya 44 karakter. Akses dari browser menggunakan file.php?n[]=xx&n[]=yy&n[]=xy&n[]=yx. (kode yang belum diuji)
Ismael Miguel
Ide bagus menggunakan $_GETtetapi menampilkan 57% 10 dan saya perlu (5-7)% 10
Rory McPerlroy
Coba yang satu ini: <? for($i=0,$a=$_GET[n];$i<4;++$i)echo abs($a[$i][0]-$a[$i++][1]%10);. Sayangnya, panjangnya 65 byte. (lupa $ikenaikan yang terakhir) Atau Anda bisa mencoba <? for($i=0;$i<8;)echo abs($_GET[n][$i++]-$_GET[n][$i++]%10);dan mengakses browser menggunakan file.php?n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y, menjadi 61 byte.
Ismael Miguel
Ya yang kedua berfungsi, perlu lakukan itu $_GET['n']. Telah mengedit jawaban saya.
Rory McPerlroy
Yah, itu tidak wajib. Itu hanya mengeluarkan peringatan. Itu bagus untuk situs web ini. Tapi mencoba yang satu ini: <? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);. Tidak %10ada gunanya dan ini hanya terlihat lebih baik. Anda juga dapat mengaksesnya menggunakan file.php?n[]=xyxyxyxy. Solusi ini panjangnya 58 byte.
Ismael Miguel
0

Python 3, 60

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

Input dan output persis seperti yang ditentukan, meskipun tidak mencetak baris tambahan. Dua trik menarik di sini: 1) mengganti dua panggilan menjadi int()dengan satu panggilan keeval() , dan 2) menggunakan join()untuk mendapatkan a-b, kemudian meniadakannya b-asesuai kebutuhan. Untungnya operator modulo Python memberikan nilai-nilai positif bahkan jika argumen pertama negatif!

DLosc
sumber
Mengapa ini diturunkan? Ini bekerja dengan sangat baik. (Btw, eval('-'.join(x))triknya brilian.)
flornquake
@flake, terima kasih!
DLosc