Şifreyi şifreye kilitle


22

Resimdeki gibi standart bir şifreli kilit verilir. Kilidini açmak için yolu koddaki 4 sayıyı birleştirme satırında hizalamaktır. Yıllarca süren sadakat hizmetlerinden sonra kilit fabrikasından kovuldunuz ve kilitleri göndermeden önce kilitleme yapmadan intikam almaya karar verdiniz, böylece her kilidi birleşim hattında kilidini açmak için kombinasyonla birlikte bırakın.

Şifreli kilit

Ayrıca, diğer satırlardaki sayıların sırasına bakarak, kombinasyon satırında hangi sayıların bulunması gerektiğini (ve dolayısıyla kilidi açmak için kullanılan kombinasyonun) hesaplamanın mümkün olduğunu da biliyorsunuz.

Kilit üzerindeki her satıra, kombinasyon hattı için 0 satırından başlayarak (kilidin kilidini açan satır) satır 9'a kadar bir numara verilirse, örneğin, satır 4'teki sayılar varsa, 5336kilidi açmak için kullanılan kombinasyon olacaktır 1992.

Maalesef, kilitler önceden paketlenmiştir ve her bir kilidin görüşünü gizlemektesiniz, böylece sadece kilidin farklı satırlarındaki sayıları görebilirsiniz.

Meydan okuma

Tamsayının ilk basamağının satır numarasını, ikinci basamağın ise o satırda görünen rakamı gösterdiği 4 basamaklı rakamlar göz önüne alındığında, şifreyi kilidin üzerinde çalışın. Örneğin, eğer girdiyseniz:

57 23 99 45

Sonra çıktı gerekir:

2101

Veya

25 78 63 15

ve

3174

Girişin her zaman için 25 64 72 18 biçiminde 4 pozitif tam sayı olacağını varsayalım.

Bu , yani bayt sayısındaki en kısa programlar kazanır.

Ayrıca bu benim ilk sorum, bu nedenle herhangi bir geri bildirim takdir edilmektedir.


Bence girişi netleştirmen gerekiyor. " 4 çift tamsayı verildi " diyor ve bir örnek veriyorsunuz 57 23 99 45. Bu dört çift tamsayı değil: dört tamsayı. Ve bazı cevaplar bunu bir dize olarak aldıklarını varsayıyorlar, bazıları ise 4 inç olarak hazır ayrılmaya başladığını varsayıyor.
Peter Taylor

Ben, bu 57 satır 57 ve kombinasyon 23. olduğuna 57. İlk varsayım oldu tamsayı tamsayı çifti 5 ve 7, değil, tamsayılar dört çift girişinin biçimi temizlemek yaptığını söyledi gerçeğini katılmıyorum
Qwerty01

1
"Rakam çiftleri" nasıl? Bu çok daha net ve kesin olurdu (ve aynı zamanda liderlerle de çalışır 0).
kabarık

Teknik olarak, doğru terim permütasyon kilidi olacaktır . Çoğu "kombinasyon kilitleri" aslında permitasyon kilitleridir, çünkü rakamların sırası fark yaratır.
nyuszika7h

Teknik olarak evet doğru, ama akılda kalıcı bir başlık yapmayı sanmıyorum.
Rory McPerlroy

Yanıtlar:


32

CJam, 9 8 bayt

ea9fbAf%

Rakam çiftlerini komut satırı argümanları olarak okur. İçin çevrimiçi kodu deneyin , değişim eaiçin lS/simüle STDIN'den okumak için.

Örnek çalışma

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

Nasıl çalışır

Haneli bir karakter kodu d olduğunu + d 48 . Böylece, iki basamaklı dize xy baz alındığında, 9 sayı 9 * (48 + x) + (48 + y) = 10 * (48 + x) + y - x ≡ y - x (mod 10) verir .

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

Kahretsin, başkasının kazanmasına izin veremezsin, değil mi? : P
Doktoru

Bundan daha iyi bir CJam cevabı bulacağımızı sanmıyorum
Rory McPerlroy

1
Orada ne oldu?
Savaş

1
@ DigitalTrauma: Tabii, devam et. Dize "99"aslında dizi olarak yorumlanır [57 57]tarafından b; "xy"9bolarak uygulanmaktadır 9 * ord(x) + ord(y). Bunu cevabıma eklemeliyim.
Dennis,

4
Olası çözümleri yazdırılabilir ASCII ile sınırlandırırsak 10.000, tüm 2 karakter programlarını bile kapsar .
Dennis,

13

CJam, 13 12 11 karakter

User23013 sayesinde 11 karaktere düştü :)

4{Ar:--A%}*

açıklamalar:

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

Çevrimiçi deneyin

Daha çok golf oynayabileceğini biliyorum. Ama bu benim CJam'daki ilk gerçek girişimim ve deneyimle sınırlıyım :)


Alternatif olarak, aynı şeyi 1 ekstra karakterde yapan diğer yöntemler:

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

veya

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

veya

ea{i_A/-A%}/     // If input is passed through command line

bunun için bekliyordum. Şey, gelecek hafta ...
Soham Chowdhury

İlk üç karakter alternatif olarak olabilir l~]. Girdiyi üçten daha azıyla mümkün olmalıdır, ancak CJam'ı daha önce hiç kullanmadım: /
Ingo Bürk

4{ri_A/-A%}*bir bayt daha kısa.
Ingo Bürk

1
Ah, ya da önceki yorumumdan ne yaptın. Peki şimdi iki 12 byte çözüm var! :)
Ingo Bürk

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

6

Golf Yazısı (14 13 )

Burada çevrimiçi deneyin

Optimizer’ın çözümü ile hemen hemen aynı , ancak farklı bir dilde. Farklı bir şekilde yaklaşmak zor, çünkü sorun oldukça basit , bu nedenle bağ, kesinlikle daha önce girişi daha iyisi olan Optimizer’a gidiyor.

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

Aynı sayıda bayt için

~]{.10/- 10%}/

Golfscript'te önceden tanımlanmış 10 değeri yok mu?
Doktor

@Optimizer Maalesef hayır. Çok kötü, çünkü yığında girdi olması zaten CJam'a göre bir avantaj olurdu.
Ingo Bürk

Evet, CJam'de (yığın üzerinde girişle) 10 karakter veya Golfscript'te 11 (önceden tanımlanmış değişkenlerle) olabilir
Optimizer

12 tane de Golfscript'e sahip olabilirdim, eğer sadece alanı bırakmak zorunda olmasaydım - 10.
Ingo Bürk

1
heh, hatta dillerin en kısa onların sahip kısa geliş: P
Doktoru

6

GNU dc , 14 bayt

Borçlanma Dennis'in akıllı taban 9 numara @ :

9i[?A%nd]dxxxx

Giriş tamsayıları her satırda bir tane olmak üzere STDIN'den okunur.

Açıklama:

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    

Çıktı:

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

Önceki Cevap, 18 bayt:

Çünkü bununla "golf" dillerine daha yakın olabileceğimi düşündüm (ama yapmadım):

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

1
Bir bayt kaydedebilirsiniz:9i[?A%nd]dxxxx
Dennis

@Dennis - Harika! Şimdi ben golfscript ve APL ile boyun boyun!
Dijital Travma,

6

C 64 63 56 veya 61

Giriş dosyadan borulanabilir ise

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

Girdi stdin'e yazılmalıdır.

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

Döngüdeki dört sayıyı okur ve sonra her birini değerden ilk basamağı çıkararak ve sonuç modulosu 10 yazdırarak işler.

Aşağıdaki çeşitli yorumlar sayesinde ve ayrıca printf yerine putchar kullanarak tasarruf


Güzel. Sen koyarak bir virgül kaydedebilirsiniz scanfdışında for()böylea,i;main(){for(;i++-4;printf("%d",(a-a/10)%10))scanf("%d",&a);}
Seviye Nehri St

Ayrıca 11: a*.9a-a/10
rev

@steveverrill Beğen. Bu yüzden özlediğim her şeyi for döngüsüne koymaya odaklandım
Alchymist

1
@AcidShout Üzgünüz - çalışmıyor. Mesela 78 * .9 = 70.2, 78 - 78/10 = 71. Ayrıca .9 kullanımı argümanı iki katına çıkardığından mod alamıyorum.
Simyacı

Bir whiledöngü kullanarak ve aargümanı olarak ilan ederek birkaç bayttan tasarruf edebilirsiniz main:main(a){while(scanf("%d",&a)>0)printf("%d",(a-a/10)%10);}
Dennis

5

Python 3, 64

Basit.

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

Bunun [2, 1, 0, 1]yerine yazdırmama izin verilirse daha kısa olabilir ( 46 ):

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

str((i-i//10)%10)Bir saniye kullanmak yerine doğrudan alarak bir miktar tasarruf edebilirsiniz map(). Ben de benim için jeneratörlerle başladım, ancak gerçek bir fordöngünün daha kısa olduğunu gördüm .
DLosc

Evet, bunun için teşekkürler!
Soham Chowdhury

Neden liste-anlama kullanıyorsunuz? 2 karakter kurtarmak için genexps kullanın: print(''.join((i-i//10)%10for i in map(int,input().split()))). Alanlarda çıktıda allowd edilir Ayrıca, kurtulabilirsiniz joinve kullanım tuple-açma: print(*((i-i//10)%10for i in map(int,input().split()))).
Bakuriu,

Sanırım haklısın.
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));}

Komut satırından giriş. Her argümanın ilk ASCII kodunu ikinciden çıkarır, 10 ekler ve modulo 10 alır.

Sanırım ilk defa printfdört %s ile yazdım ve virgül yok (virgül içinde #define.)


#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)ardından a,b;main(){f;f;f;f;}18 bayt daha kısa olur.
Dennis,

@Dennis bu harika bir gelişme, ancak temelde tamamen farklı bir program. Sanırım biri gönderirse, sen olmalısın, ben değil. Boşluğun scanfgerekli olup olmadığını bilmiyorum , bununla birlikte scanfboşlukları yalnızca ayırıcı olarak ayrıştırması gerekiyor. Simyacıların C'de daha iyi bir fikirleri var. Fakat Cjam cevabınızla zaten kazanmışsınız gibi görünüyor.
Level River St

Evet, uzay sonra o fark tarafından başlatılmış a(n)atlanabilir, sonra ben koyarak fark printf("%d%,...)sizin makro etrafında birkaç byte kurtaracak ve nihayet ... biraz götürdü var - beri uzay tabi %cbir karakter okur, herhangi karakter, yani ikinci çalışmada 32 inç saklardı a. - CJam'i C ile yenmek zor olmalı. printf()zaten benim cevabım kadar ...
Dennis

4

Java - 203 bayt

Orada Çünkü sahip bir Java girişi olmak gerekirse, ben bir şans (şimdiye kadar ilk teslim) golf bu kodu vermek için güzel bir fırsat gördü.

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

Bazı iyileştirmeler için yer varsa, onlar hakkında bilmek sevinirim ;-)


[İpuçlarını] arayabilir ve golf oynamaya başlamak için çeşitli ipuçları alabilirsiniz :)
Doktor

Harika, teşekkürler! Bazı ipuçlarını incelemek 13 byte'ı tıraş etmeme yardımcı oldu :)
Sander

3

Lua - 46 karakter

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

Bir kerede üç karakter okur (sonunda bir boşluk girme konusunda bana küçük bir merhamet göster) ve a ve b string-y olsa bile ... Etrafı yazdırırken kontrol eder.

Nasıl çalıştırırım:


1
Bir örnek veri girişi / çıkışı sağlayabilir misiniz, bunu Ideone'da
Rory McPerlroy

@ Harry12345 Ah, bunun için üzgünüm. Anarşi Golf aklımı başıma nasıl soktuğuma karar veriyor. Muhtemelen daha iyi kodlayabilirdim, ama meh, Lua korkunç. Programı çalıştırmam için bir örnek yolladım.
AndoDaan

3

JavaScript ES6 - 53 43 bayt

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

Oldukça basit işlevi, sayıları almak için regex kullanır. Http://jsfiddle.net/efc93986/1/ adresinde deneyin . İşlevlere izin verilmezse, 52 bayt'ta bağımsız bir program:

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

ES6 şu anda yalnızca Firefox'ta çalıştığından, aşağıdaki kod herhangi bir modern tarayıcıda, 70 baytta çalışır:

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

Aşkını 1+.
Neil

1
Soru, geçerli girdiler aldığını söylüyor, ...?bunun yerine kullanabilirsiniz /\d+ ?. Döndükten sonra boşluk atlanabilir. Ayrıca, belirli bir G / Ç belirtilmediğinden, bir işlev kullanabilmelisiniz.
Dennis,

1
a-a[0]yerine de 1+a[1]-a[0]çalışması gerekir.
Dennis,

2

Python 2 - 33 bayt

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

Virgülle ayrılmış kullanıcı girişini kabul eder. Örneğin, Giriş:

29,26, 31, 88

Çıktı:

7
4
8
0

Çıktı örneğe tam olarak uyması gerekiyorsa, çok daha uzundur. 47 bayt:

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

input()Python 2 tercümanımda çalışmıyor.
Soham Chowdhury

@SohamChowdhury virgül kullandınız mı?
feersum

2
Hayır yapmadım. Şuan çalışıyor. Bir yandan notta, spesifikasyon başına alanla sınırlı girdi almanız gerektiğini düşünüyorum .
Soham Chowdhury

3
Sınırlı de-I girişi alanını olmalıdır katılıyorum
Rory McPerlroy

2

APL, 14

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

Açıklama
ekrandan girdi alır. Boşluk ile ayrılmış değerler bir dizi olarak ayrıştırılır.
{...}¨Her numara için, işlevine besleyin.
⍎¨⍕⍵argümanı alır, rakamlarından oluşan bir dizi oluşturur.
--/eksi onlarca birimi hesaplar.
10|10 numara.


1
Bu 14 karakter olabilir, ancak 24 bayttır .
Ingo Bürk


ancak kod golf için bazı özel karakter kümesi değil, UTF-8'e güveniyoruz. Bu sadece bir kaçamak olur ve çok kolay bir şekilde kötüye kullanılabilir.
Ingo Bürk

1
@ IngoBürk meta.codegolf.stackexchange.com/a/961/6972 uyarınca cevaplar, OP aksi belirtilmediği sürece herhangi bir kodlamada kodlanabilir. Gerçekten de tek baytlık bir haritalama olan APL karakterleri için bir IBM kod sayfası var, bu tam olarak Dyalog'un Unicode 3.0'dan önce kullandığı şeydi. Unicode konusunda ısrar ediyorsanız, Unicode olmayan karakterler kullanan yeni bir dil icat edersem ne olur? Bunun için baytları nasıl sayarsınız?
TwiNight

Varsayılan UTF-8 olduğuna yemin edebilirdim. 14 bayt, öyleyse.
Ingo Bürk

2

J - 20 15

Fiil olmayan form (işlev tanımı yerine ifade olarak) 5 karakterden kısadır:

10|-~/|:10#.inv

Güzel bir tren olan fiil formu :

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

Örnek girdilerde kullanılan bu fiil:

   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

Tek karakterli rakamlar, Haskell golf oyununda gerçek bir nemesis.


2

Perl: 38 40

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

Çıktı:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174

1
1. Alt çizgiler işaretleme sözdizimidir, bu yüzden kodunuz biraz dağıldı. Bunu önlemek için kodu dört boşlukla girin. 2. absgerekli değildir; x - x/10olumsuz olamaz. 3. -040peBoşluk ile sınırlandırılmış girdiyi yinelemek için bayrakları (genellikle 5 bayt sayılır) kullanırsanız, kodunuzu kısaltabilirsiniz $_=($_-int$_/10)%10. 4. Komut satırı bayraklarından kaçınmayı tercih ederseniz $/=$;, aramayı ayarlayıp kaldırarak hala birkaç bayt kaydedebilirsiniz split.
Dennis,

1

Ruby, 35 bayt

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

açıklama

Giriş, komut satırı argümanları olarak alınır. String#bytesbir Tam Sayı Dizisi (ASCII karakter kodları) döndürür. Yalnızca son ve ilk karakter kodu arasındaki fark, Integer'in kendileri için değil, önemlidir.


1

C # ve 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. Diğer derleyiciler hakkında emin değilim, ancak GCC #include<iostream>ve std::öncesi cinve gerektiriyor cout. 2. İhmal ederseniz şartlıya ihtiyacınız yoktur a=a%10. 3. Değişkenlere bve csatır beslemelerine ve (birkaç değişiklikle) for döngüsünün etrafındaki parantezlere ihtiyacınız yoktur.
Dennis

1
@SeanD: Lütfen kodu değiştiren düzenlemeleri onaylamayın. Bu özel durumda, düzenleme cevabı geçersiz kıldı. Ayrıca tüm cevaplarda bulunması gereken ilk satırı da kaldırmıştır.
Dennis,

1
(CC @TeunPronk)
Dennis,

@Dennis genellikle bu sitedeki cevaplarda önişlemci satırları içermez. Satırları #include<iostream>using namespace std;
atladım

Genelde bayt sayısına dahil olmadığını biliyorum, ancak cevapta bulunmaları gerektiğini düşünüyorum.
Dennis,

1

PHP - 90 karakter

Kod golfü bir deneyeyim dedim, işte burada, ilk girişimim - muhtemelen daha fazla golf olabilir.

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

58 karakter (Ismael Miguel'in izniyle)

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

Kullanarak erişim dosyası

file.php?n=57239945

Bu kodu deneyin: <? for($i=0;$i<4;)echo abs($_GET[n][$i]%10);44 karakter uzunluğunda. Kullanarak bir tarayıcıdan erişin file.php?n[]=xx&n[]=yy&n[]=xy&n[]=yx. (denenmemiş kod)
Ismael Miguel

Kullanması iyi bir fikir $_GETancak%
57'yi gösteriyor ve

Bunu dene: <? for($i=0,$a=$_GET[n];$i<4;++$i)echo abs($a[$i][0]-$a[$i++][1]%10);. Ne yazık ki, 65 bayt uzunluğunda. (sonuncunun $iartımını unuttum ) Ya da 61 bayt uzunluğunda <? for($i=0;$i<8;)echo abs($_GET[n][$i++]-$_GET[n][$i++]%10);tarayıcı kullanarak erişmeyi deneyebilirsiniz file.php?n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y.
Ismael Miguel

Evet, ikincisi işe yarıyor, $_GET['n']tho yapmalı . Cevabımı değiştirdim.
Rory McPerlroy 16:14

Eh, gerekli değil. Bu sadece bir uyarı verir. Bu web sitesi için sorun değil. Ama bu bir deneyin: <? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);. %10Faydasız ve bu sadece iyi görünüyor. Ayrıca, kullanarak erişebilirsiniz file.php?n[]=xyxyxyxy. Bu çözüm 58 bayttır.
Ismael Miguel

0

Python 3, 60

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

Tam olarak belirtildiği gibi giriş ve çıkış yapın, ancak takip eden bir yeni satır yazdırmaz. Burada iki ilginç numara: 1) iki çağrıyı int()bir çağrı ile değiştirmek eval(), ve 2) kullanmajoin() almak içina-b , sonra gerektiğinde olumsuzlamak b-a. Neyse ki Python'un modulo operatörü, ilk argüman negatif olsa bile pozitif değerler veriyor!


Bu neden indirildi? Mükemmel çalışıyor. ( eval('-'.join(x))
BT

@flornquake Teşekkürler!
DLosc
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.