Kilidi aç


34

Bisikletinizi 3 haneli şifreli kilitle kilitlediniz. Şimdi bir gezintiye çıkmak istiyorsunuz ve aşağıdaki programın yardımıyla kilidini açmanız gerekiyor.

Giriş

1. parametre

Kilidinizin rakam kombinasyonu kilitli durumda. 2. parametreden farklı olmalıdır (= kilit açık kombinasyonu durumun ). (Ya da bisikletin çalınmış olabilir!)

Menzil 000..999. Önde gelen sıfırlar ihmal edilmemelidir.

2. parametre

Kilidinizin rakam kombinasyonu açık durumda. Bu değer senin amacın.

Menzil 000..999. Önde gelen sıfırlar ihmal edilmemelidir.

Çıktı

İlk durum (her zaman 1. parametredir) ve son adım (her zaman 2. parametre olan) dahil olmak üzere her "dönme" den sonra her bir kombinasyon kilidinin bir listesi.

Algoritma

Kilitlenmemiş durumda doğru haneye ulaşana kadar ilk haneyi birer birer "döndürmeye" başlarsınız . Ancak, tüm kilit açma kodunu bildiğiniz için, kilitlenmemiş haldeyken haneye ulaşmak için en küçük döndürme miktarına ihtiyaç duyduğunuz yönde döndürün . Beraberlik durumunda, istediğiniz yönü seçebilirsiniz.

Doğru ilk haneye ulaştığınızda, aynı prosedürü 2. ve ardından 3. ile başlatırsınız.

Rakamların sırası, bir daire olarak anlaşılmalıdır:

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

Bunun anlamı, 1'den 9'a kadar olan en küçük dönme miktarının olmadığıdır.

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

fakat

1 -> 0 -> 9 = 2

notlar

Örnekler

Örnek 1, doğru

Input: 999 001

Output:
999
099
009
000
001

2. Örnek, doğru

Input: 000 292

Output:
000
100
200
290
291
292

Örnek 3, yanlış çıktı

Input: 999 121

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

Correct output:
999
099
199
109
119
129
120
121

Örnek 4, yanlış giriş

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

Bu , en kısa cevap kazanır.


İki parametrenin sırasını değiştirebilir miyim?
tsh

Rakamları optimal olduğu sürece herhangi bir sırayla güncelleyebilir miyiz?
Arnauld

@Arnauld Hayır çünkü kilidimi tek tek
açıyorum

2
@ Night2 Hayır, çünkü program bir kombinasyon görünümünün "kilit açma işlemini" simüle etmelidir.
user2190035

Yanıtlar:


12

Python 2 , 113 107 105 99 95 bayt

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

Çevrimiçi deneyin!

Tam sayı listesi olarak girdi alır


Kaydedilen:

  • -6 bayt, Joel sayesinde
  • -4 bayt, Jitse sayesinde

2
99 bayt hesaplamak için farklı bir yol kullanarak.
Joel,

@Joel Teşekkürler! :)
TFeld

2
96 bayt - bonus: Herhangi bir dizi büyüklüğü için çalışır
Jitse

1
95 bayt - Python 2 kullandığınızdan beri, kaybedersiniz//
Jitse

@Jitse Thanks :)
TFeld

6

Jöle , 15 bayt

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

[0,9]

Çevrimiçi deneyin!

Nasıl?

_æ%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 bayt

@Tsh sayesinde 2 bayt kaydedildi

Körili sözdiziminde girdiyi 2 basamak dizisi olarak alır (a)(b). Bir dize döndürür.

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

Çevrimiçi deneyin!

Yorumlananlar

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 bayt

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

Çevrimiçi deneyin!

Joel'e 3 bayt teşekkür ederim .

Girdiyi liste olarak alır.



1
@Joel: Teşekkürler! Aslında, Python 2 //olduğundan, aynı olduğundan, /kazanılan ilave bir bayt var.
Chas Brown

Bu, @ TFeld'in cevabıyla aynı yaklaşıma benziyor , ancak küçük değişikliklerle
Jitse,

@Jitse: İkimiz de cevaplarımızı değiştirdik; örneğin, for x,y,i in zip(a,c,[0,1,2])hatırlarsam ... ile başladı ...
Chas Brown

1

Jöle , 30 bayt

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

Çevrimiçi deneyin!

Her ikisi de tamsayıların listesi olarak sol argüman kilidini açma kodu ve sağındaki geçerli kilitli durumu belirten ikili bir bağlantı.

Bu çok uzun sürüyor!


1

PHP , 114 bayt

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;

Çevrimiçi deneyin!

Çözümüm muhtemelen berbat, ama şimdilik düşünebileceğim en iyisi bu!


1

Kömür , 48 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

θ

İlk pozisyonu yazdırın.

≔EθIιθ

İlk konum dizesini hesaplama amacıyla sayısal rakam dizisine değiştirin.

F³«

Sırayla her rakamın üzerinde döngü.

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

Bu basamağın kilidini açmak için gereken dönüş sayısını hesaplayın. Bu arasında bir sayı olduğu -5için 4burada -5araç 5 aşağı doğru dönme ve4 araçları 4 yukarı doğru dönüşleri.

F↔ζ«

Her dönüş üzerinde döngü.

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

Rakamı, dönme işaretine göre güncelleyin.

⸿⪫θω

Rakamları yeni bir satıra dizge olarak verin.


1

T-SQL 2008, 170 bayt

Okunabilir hale getirmek için bazı satır çizgiler ekledim

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

Çevrimiçi deneyin


Bu çözüm çıktıda lider 0'ları tutmuyor. Örnek: 000-999
Matta

1
@Matthew neredeyse haklısın, bu yapı giriş seçeneği içinde kullanmak umuyordum, ancak girişinde 0 ile başlarsanız, girişden kaldırılacak. Yine de başarısız olan bir çözüm değil
t-clausen.dk

1
@Matthew - şimdi btw olarak düzeltildi. Zaten sql parçası olmayan giriş kutuları kaldırıldı
t-clausen.dk



0

MATLAB, 100 89 bayt

Farklı bir yaklaşım (çıkarma matrisi oluşturmak için örtülü genişleme kullanmak) 11 baytı azaltır:

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

[Orijinal 100 bayt çözüm]

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

Her ikisi de girişleri 3 elemanlı diziler olarak geçirerek çağrılır, örn. f([9 1 1], [2 3 2])


0

Java (JDK) , 139 bayt

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

Çevrimiçi deneyin!

Java'nın System.out.printlnoldukça pahalı olması nedeniyle herkesin aynı algoritması farklı bir şekilde yuvarlandı !



0

Kotlin , 162 bayt

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.