Buka Kunci Anda


34

Anda telah mengunci sepeda Anda dengan kunci kombinasi 3 digit. Sekarang Anda ingin naik dan perlu membukanya dengan bantuan program berikut.

Memasukkan

Parameter 1

Kombinasi digit dari kunci Anda dalam keadaan terkunci . Itu harus berbeda dari parameter ke-2 (= kombinasi status tidak terkunci ). (Atau sepeda Anda bisa dicuri!)

Kisaran 000..999. Nol terkemuka tidak boleh dihilangkan.

Parameter ke-2

Kombinasi digit dari kunci Anda dalam keadaan tidak terkunci . Nilai ini adalah tujuan Anda.

Kisaran 000..999. Nol terkemuka tidak boleh dihilangkan.

Keluaran

Daftar setiap keadaan kunci kombinasi setelah setiap "rotasi" termasuk keadaan awal (yang selalu menjadi parameter 1) dan langkah terakhir (yang selalu menjadi paramater ke-2).

Algoritma

Anda mulai "memutar" digit pertama satu per satu hingga Anda mencapai digit yang benar dalam keadaan tidak terkunci . Tetapi, karena Anda mengetahui seluruh kode pembuka kunci, Anda memutar digit ke arah yang Anda perlukan jumlah rotasi terkecil untuk mencapai angka dalam keadaan tidak terkunci . Dalam kasus dasi, Anda dapat memilih arah apa pun yang Anda inginkan.

Ketika Anda telah mencapai angka pertama yang benar, Anda memulai prosedur yang sama dengan tanggal 2 dan kemudian dengan tanggal 3.

Urutan digit adalah dipahami sebagai lingkaran:

... 9 0 1 2 3 4 5 6 7 8 9 0 1 2 ...

Ini berarti, jumlah rotasi terkecil dari 1 hingga 9 tidak

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 = 8

tapi

1 -> 0 -> 9 = 2.

Catatan

Contohnya

Contoh 1, benar

Input: 999 001

Output:
999
099
009
000
001

Contoh 2, benar

Input: 000 292

Output:
000
100
200
290
291
292

Contoh 3, output salah

Input: 999 121

Wrong output:
999
899 // Wrong because wrong rotation direction.
799
699
...

Correct output:
999
099
199
109
119
129
120
121

Contoh 4, input salah

Input: 1 212 // Wrong because no leading zeros.

Ini adalah jawaban tercepat yang menang.


Bolehkah saya mengubah urutan dua parameter?
tsh

Bolehkah kami memperbarui digit dalam urutan apa pun asalkan optimal?
Arnauld

@Arnauld Tidak karena saya membuka kunci saya satu per satu :)
user2190035

2
@ Night2 Tidak, karena program harus mensimulasikan "proses membuka" tampilan kombinasi.
user2190035

Jawaban:


12

Python 2 , 113 107 105 99 95 byte

a,b=input()
i=0
print a
for x in a:
 while x-b[i]:a[i]=x=(x+(x-b[i])%10/5*2-1)%10;print a
 i+=1

Cobalah online!

Mengambil input sebagai daftar bilangan bulat


Disimpan:

  • -6 byte, terima kasih kepada Joel
  • -4 byte, terima kasih kepada Jitse

2
99 byte menggunakan cara berbeda untuk menghitung.
Joel

@ Joel, terima kasih! :)
TFeld

2
96 byte - bonus: bekerja untuk berbagai ukuran array
Jitse

1
95 byte - karena Anda menggunakan Python 2, mungkin akan kehilangan//
Jitse

@Jitse Terima kasih :)
TFeld

6

Jelly , 15 byte

_æ%5ḣT$ṂṠ⁸_%⁵ðƬ

[0,9]

Cobalah online!

Bagaimana?

_æ%5ḣT$ṂṠ⁸_%⁵ðƬ - Link: list of integers, s; list of integers, t
              Ƭ - collect up values until a fixed point is reached applying:
             ð  -   the dyadic chain:  (i.e. f(x, t) where x starts off as s)
_               -     subtract (t from x) (vectorises) - i.e. [ta-xa, tb-xb, tc-xc]
   5            -     literal five
 æ%             -     symmetric modulo (vectorises) - i.e. [[-4..5][ta-xa], [-4..5][tb-xb], [-4..5][tc-xc]]
      $         -     last two links as a monad:
     T          -       truthy indices  - e.g. [0,-4,1]->[2,3]
    ḣ           -       head to index (vectorises)       [[0,-4],[0,-4,1]]
       Ṃ        -     minimum                            [0,-4]
        Ṡ       -     sign (vectorises)                  [0,-1]
         ⁸      -     chain's left argument (x)
          _     -     subtract (vectorises) - i.e. move the single spindle one in the chosen direction
            ⁵   -     literal ten
           %    -     modulo (since 9+1=10 not 0)

4

JavaScript (ES6),  73 72  70 byte

Disimpan 2 byte berkat @tsh

Mengambil input sebagai 2 array digit dalam sintaks curried (a)(b). Mengembalikan string.

a=>g=b=>b.some(x=>d=x-(a[++i]%=10),i=-1)?a+`
`+g(b,a[i]+=d/5<5/d||9):b

Cobalah online!

Berkomentar

a =>                  // a[] = initial combination
g = b =>              // b[] = target combination
  b.some(x =>         // for each digit x in b[]:
    d =               //   compute the difference d:
      x -             //     between x
      (a[++i] %= 10), //     and the corresponding digit in a[]
                      //     we apply a mod 10, because it may have exceed 9
                      //     during the previous iteration
    i = -1            //   start with i = -1
  ) ?                 // end of some(); if it's truthy:
    a + `\n` +        //   append a[] followed by a line feed
    g(                //   followed by the result of a recursive call:
      b,              //     pass b[] unchanged
      a[i] +=         //     add either 1 or 9 to a[i]:
        d / 5 < 5 / d //       add 1 if d / 5 < 5 / d
        || 9          //       otherwise, add 9
    )                 //   end of recursive call
  :                   // else:
    b                 //   stop recursion and return b[]

d/6&1^d>0||9->d/5>5/d?9:1
tsh


2

Python 2 , 101 97 byte

a,c=input()
print a
for i in 0,1,2:
 while a[i]!=c[i]:a[i]=(a[i]+(a[i]-c[i])%10/5*2-1)%10;print a

Cobalah online!

3 byte thx ke Joel .

Mengambil input sebagai daftar int.



1
@ Joel: Terima kasih! Sebenarnya, karena Python 2, //sama dengan /, jadi ada byte tambahan yang didapat.
Chas Brown

Ini terlihat seperti pendekatan yang sama persis dengan jawaban @ TFeld , tetapi dengan sedikit modifikasi
Jitse

@Jitse: Ya, kami berdua memodifikasi jawaban kami; misalnya, ia mulai dengan for x,y,i in zip(a,c,[0,1,2])jika saya ingat ...
Chas Brown

1

Jeli , 30 byte

_ż+¥⁵AÞḢṠxAƊ×€ʋ"JṬ€$$Ẏ;@W}+\%⁵

Cobalah online!

Diad kiri mengambil argumen kuncinya sebagai kode pembuka dan kanannya keadaan terkunci saat ini, keduanya sebagai daftar bilangan bulat.

Ini terasa terlalu lama!


1

PHP , 114 byte

for([,$a,$b]=$argv;$i<3;($x=$a[$i]-$b[$i])?(print$a._).$a[$i]=($y=$a[$i]+(5/$x>$x/5?-1:1))<0?9:$y%10:++$i);echo$b;

Cobalah online!

Solusi saya mungkin payah, tapi itu yang terbaik yang bisa saya pikirkan untuk saat ini!


1

Arang , 48 byte

θ≔EθIιθF³«≔⁻﹪⁺⁻I§ηι§θι⁵χ⁵ζF↔櫧≔θι﹪⁺§θι÷ζ↔ζχ⸿⪫θω

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

θ

Cetak posisi awal.

≔EθIιθ

Ubah string posisi awal menjadi array angka numerik untuk keperluan perhitungan.

F³«

Lingkari setiap digit secara bergantian.

≔⁻﹪⁺⁻I§ηι§θι⁵χ⁵ζ

Hitung jumlah rotasi yang diperlukan untuk membuka kunci angka itu. Ini adalah nomor dari -5ke 4mana -5berarti 5 rotasi ke bawah dan 4sarana 4 rotasi ke atas.

F↔ζ«

Ulangi setiap rotasi.

§≔θι﹪⁺§θι÷ζ↔ζχ

Perbarui digit sesuai dengan tanda rotasi.

⸿⪫θω

Keluarkan digit sebagai string pada baris baru.


1

T-SQL 2008, 170 byte

Saya menambahkan beberapa linebreak agar dapat dibaca

DECLARE @1 char(3)='123',@2 char(3)='956'

DECLARE @r int,@s int,@ int=0
g:SET @+=1
h:SELECT @r=substring(@1,@,1)+9,@s=@r-substring(@2+'1',@,1)
IF @s=9GOTO g
PRINT @1
SET @1=stuff(@1,@,1,(@r+@s/5%2*2)%10)
IF @<4GOTO h

Cobalah online


Solusi ini tidak terus memimpin 0 dalam output. Contoh: 000-999
Matius

1
@ Matius Anda hampir benar, saya berharap untuk menggunakan opsi input build in ini, namun, jika Anda mulai dengan 0 input maka akan dihapus dari input. Ini bukan solusi yang gagal
t-clausen.dk

1
@ Matius - sudah diperbaiki sekarang btw. Dihapus kotak input yang bukan bagian dari sql
t-clausen.dk



0

MATLAB, 100 89 byte

Pendekatan yang berbeda (menggunakan ekspansi implisit untuk membuat matriks pengurangan) mengurangi 11 byte:

function f(a,b);c = mod(a-b+5,10)-5;a,mod(a-cumsum(repelem(eye(3).*sign(c),abs(c),1)),10)

[Solusi 100 byte asli]

function f(a,b);c=mod(a-b+5,10)-5;a,for n=1:3;for r=1:abs(c(n));a(n)=mod(a(n)-sign(c(n)),10),end;end

Keduanya dipanggil dengan melewatkan input sebagai array 3 elemen, mis f([9 1 1], [2 3 2])


0

Java (JDK) , 139 byte

a->b->{for(int i;;a[i]+=(a[i]-b[i]+10)%10<5?9:1,a[i]%=10){System.out.println(""+a[i=0]+a[1]+a[2]);for(;i<3&&a[i]==b[i];i++);if(i>2)break;}}

Cobalah online!

Algoritma yang sama seperti semua orang, digulir berbeda karena Java System.out.printlncukup mahal!



0

Kotlin , 162 byte

{s:Array<Int>,e:Array<Int>->var i=0
o@while(i<3){println(""+s[0]+s[1]+s[2])
while(s[i]==e[i]){if(i>1)break@o
i++}
s[i]=(s[i]+if((e[i]-s[i]+10)%10>5)9 else 1)%10}}

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.