Piskoposlara Karşı Güçlü Şifreler


13

Şifre Piskopos İyilik ile karıştırılmamalıdır !

Bir dize verildiğinde, piskoposlara karşı güçlü bir parola oluşturuyorsa yanıt (doğru / yanlış veya iki tutarlı değer) .

Parola, her bir karakter çiftinin bir satranç tahtasında kare olarak yorumlanabileceği ve her bir kareye beyaz bir piyon yerleştirdiğiniz takdirde , değişen harflerden (inç ) ve rakamlardan (inç ) oluşan bir dize ise piskoposlara karşı güçlüdür. parolada, beyaz bir piskoposun herhangi bir sayıda ardışık hamlede, ilk ( ) satırdaki herhangi bir kareden son ( ) satırdaki herhangi bir kareye seyahat etmesinin bir yolu yoktur .a-h1-818

Örnekler

Piskoposlara karşı güçlü şifreler

  • a1b1c1d1e1f1g1h1
  • a8b8c8d8e8f8g8h8
  • a1b2c3d4d5f5f4g3g4h2b5
  • h4g4f4e4c4b4a4c3e3
  • a1b1c1d1e1f1g1a8b8c8d8e8f8g8
  • b4b5d4d5f4f5g3h5

Örneğin, a1b1c1d1e1f1g1a8b8c8d8e8f8g8konumuna karşılık gelen foove b4b5d4d5f4f5g3h5pozisyonuna karşılık gelirfoo

Piskoposlara karşı zayıf şifreler

  • a4c4e4g4g5d6f6e3d2b2 (iyi biçimlendirilmiş ancak güçlü değil - bu örnek için Jo King'e teşekkürler!)
  • b1c1d1e1f1g1h1a8b8c8d8e8f8g8 (iyi biçimlendirilmiş ancak güçlü değil)
  • h4g4f4e4c4b4a4c3 (iyi biçimlendirilmiş ancak güçlü değil)
  • d4 (iyi biçimlendirilmiş ancak güçlü değil)
  • b4b5d4d5f4f5g2h5 (iyi biçimlendirilmiş ancak güçlü değil)
  • correct horse battery staple (Kötü şekillendirilmiş)
  • 1a1b1c1d1e1f1g8a8b8c8d8e8f8g (Kötü şekillendirilmiş)
  • a (Kötü şekillendirilmiş)
  • aa (Kötü şekillendirilmiş)

1
Piskopos hangi renk karelerine gidiyor?
Cehalet

2
Son test durumunuz spesifikasyonlarınızla çelişiyor. Ayrıca açıklamak gerekir nasıl " karakter çiftlerinin bir tahta üzerinde bir kare olarak yorumlanabilir ".
Shaggy

1
Bir piskopos sonra, h5 almak d1 inmek beri a1b2c3d4d5f5f4g3g4h2b5, piskoposları karşı güçlü değil
Cehalet şekillenme

2
@TRITICIMAGVS, Ourous: Hem piyonların hem de piskoposun beyaz olduğunu açıklığa kavuştum, bu yüzden ikisinin de diğerini yakalamasına (veya inmesine, üzerinden geçmesine veya üzerinden atlamasına) izin verilmiyor.
Quuxplusone

1
Ayrıca, doğru test durumlarından birine bir örnek verebilir misiniz? Çünkü şifrenin karelerinin beyaz piyonlarla dolu olduğunu anlıyorum, ancak beyaz filin nereye yerleştirildiğini anlamıyorum. Herhangi bir yerde gayet Ve eğer, neden her satır için seyahat edemez 1aracılığıyla 8ilk test durumunda? Her sütuna gidemez, çünkü asütun tamamen piyonlarla doldurulur, ancak her satıra sorunsuz bir şekilde seyahat edebilir, değil mi? Bir şeyleri özlediğimi hissediyorum ..: S
Kevin Cruijssen

Yanıtlar:


4

Yakut, 115 182 163 bayt

->s{z=('00'..'99').map{|x|x=~/[09]/||s[(x[1].ord+48).chr+x[0]]};(11..18).map &g=->x{z[x]||[x-11,x-9,x+z[x]=9,x+11].map(&g)};s=~/^([a-h][1-8])*$/&&(z[81,9]-[9])[8]}

Çevrimiçi deneyin!

İade 1güçlü ve nilzayıf için. (+67 bayt "geri izleme" yi hesaba katmak içindir.)

->s{
 z=                             # this is the board
 ('00'..'99').map{|x|           # coordinates are described as y*10 + x
  x=~/[09]/||                   # truthy if out of bounds...
  s[(x[1].ord+48).chr+x[0]]     # ...or impassable
 }                              # now only the passable squares are falsey
 (11..18).map                   # for each x position at y=1,
  &g=->x{                       # call helper function on that square
   z[x]||                       # if the square is passable (i.e. falsey),
    [x-11,x-9,x+z[x]=9,x+11]    # mark it impassable by setting to 9 (truthy)
     .map(&g)                   # call helper recursively for each neighbor
  }
 s=~/^([a-h][1-8])*$/           # make sure the input was valid,
 &&(z[81,9]-[9])[8]             # and check that the last row was never reached
}

Kullanılan birkaç püf noktası:

  • Sayısal aralık yerine dize aralığını 0..99kullanırız, böylece sayı otomatik olarak 2 basamağa bırakılır ve dizilir. Bu regex ile çok kısa - maç kontrol sınırlarını yapar .'00'..'99'/[09]/

  • Yardımcı Fonksiyonun içerisinde yeni koordinatlar listesini oluştururken [x-11, x-9, x+9, x+11], biz aynı anda atamak z[x]için 9bir truthy değeri olur süreçte, (ziyaret kare işaretleme).

  • Son satırda, dizinin z[81,9]bulunmadığını kontrol etmek istiyoruz 9. Bunu, 9( z[81,9]-[9]) öğesinin tüm örneklerini kaldırarak ve sonuçta elde edilen dizinin ( [8]) 9. elemanını sorarak yaparız . Dizinin başlangıçta 9 elementi olduğunu bildiğimizden, varsa kaldırıldı, alırsak nil, hepsi kalırsa, dizinin son öğesini alırız (her zaman olur 1).


2

Piton 2 , 330 318 313 309 370 bayt

import numpy as n
b=n.ones([8,8])
q=r=1
s=input()
l=len(s)
def g(x,y=0,p=0):
    if b[y,x]and p<32:
        if y<7:
            if x<7:
                g(x+1,y+1,p+1)
                if y:g(x+1,y-1,p+1)
            if x:
                g(x-1,y+1,p+1)
                if y:g(x-1,y-1,p+1)
        else:global q;q=0
for i in range(l/2):
    x=ord(s[2*i])-97;y=ord(s[2*i+1])-49
    if y>8or y<0 or l%2or x>8or x<0:r=0
    if r:b[7-y,x]=0
map(g,range(8))
print q&r

Çevrimiçi deneyin!

Pratik sürümü çevrimiçi deneyin! (Orijinal tamamen kontrol etmek için 4 ^ 32 işlem alabilir, bunu bir - bayt sayısı kadar kullanmanızı öneririm)

Süper kısa bir çözüm değil - g'nin lambda işlevinin g'den daha kısa bir versiyonunun nasıl yapılacağını anlayamadım.

Quuxplusone sayesinde -4 bayt

Geri izleme için +61 bayt muhasebe (Jo King'i ve golf ipuçlarını işaret ettiğiniz için teşekkürler)


Güzel. q=r=1daha kısa olurdu q=1 r=1, değil mi? Ve if r:daha kısa if r>0:.
Quuxplusone

2

Python 2 , 490 476 474

def f(p):
 a=[set(ord(c)-33 for c in s)for s in"* )+ *, +- ,. -/ .0 / \"2 !#13 \"$24 #%35 $&46 %'57 &(68 '7 *: )+9; *,:< +-;= ,.<> -/=? .0>@ /? 2B 13AC 24BD 35CE 46DF 57EG 68FH 7G :J 9;IK :<JL ;=KM <>LN =?MO >@NP ?O BR ACQS BDRT CESU DFTV EGUW FHVX GW JZ IKY[ JLZ\\ KM[] LN\\^ MO]_ NP^` O_ R QS RT SU TV UW VX W".split()];x=set((ord(p[i+1])-49)*8+ord(p[i])-97 for i in range(0,len(p),2))
 r=set(range(8))-x
 for i in range(99):r=set().union(*[a[c]for c in r])-x
 return all(c<56 for c in r)

Çevrimiçi deneyin!

Bu "taşkın dolgu" ile çalışır. İlk önce a, hangi karelerin diğer karelere bitişik olduğunu, bishopwise bir liste oluştururuz . Ardından bir dizi xistisna oluştururuz (şifreye göre). Daha sonra r, sadece ilk satır (eksi herhangi bir istisna hariç) olarak başlayan ve oradan 99 kez fazladan gelmesi gereken art arda dışarıya "sel" olan bir dizi ulaşılabilir kareyi başlatırız. Son olarak, son sıradaki karelerden herhangi birinin ulaşılabilir setimizde sonlanıp sonlanmadığını test ediyoruz. Eğer öyleyse, zayıf bir şifremiz var! Değilse, güçlü bir şifremiz var.

Dezavantaj, belki de diskalifiye edici (Burada olağan kuralı bilmiyorum): Parola yanlış biçimlendirilmişse ("doğru at pili zımbası" gibi), o zaman geri dönmek yerine bir istisna atarız False. Ancak Trueparola güçlü olursa her zaman geri döneriz!

Jo King sayesinde eksi 16 bayt. aKullanıldığı tek yerde satır içi ve biraz matematik katlıyoruz.

def f(p):
 x=set(ord(p[i])-489+8*ord(p[i+1])for i in range(0,len(p),2));r=set(range(8))-x
 for i in[1]*99:r=set().union(*[[set(ord(k)-33for k in s)for s in"* )+ *, +- ,. -/ .0 / \"2 !#13 \"$24 #%35 $&46 %'57 &(68 '7 *: )+9; *,:< +-;= ,.<> -/=? .0>@ /? 2B 13AC 24BD 35CE 46DF 57EG 68FH 7G :J 9;IK :<JL ;=KM <>LN =?MO >@NP ?O BR ACQS BDRT CESU DFTV EGUW FHVX GW JZ IKY[ JLZ\\ KM[] LN\\^ MO]_ NP^` O_ R QS RT SU TV UW VX W".split()][c]for c in r])-x
 return all(c<56for c in r)

@ Teşekkürler teşekkürler! forNasıl kaldırılacağını göremediğim iki s'den önce hala boşluk var . Ben yerine bulundu range(99)ile repr(f)benim yerel makinede işler değil tio.run en tercüman üzerinde ... ama sonra bulundu [1]*99zaten kısaydı! Böylece 4 bayt daha tasarruf etti.
Quuxplusone

iki fors önce boşluk kaldırmak nasıl göremedim - Oh! Görünüşe göre Python 33foriki jeton gibi davranıyor (oysa for33bir jeton olurdu). Bugün öğrendim. Eksi 2 bayt daha.
Quuxplusone

1

Temiz , 285 bayt

import StdEnv,Data.List
$_[_]=1<0
$a[x,y:l]=case[[u,v]\\u<-[0..7],v<-[0..7]|u==toInt x-97&&v==toInt y-49]of[p]= $[p:a]l;_=1<0
$a _=all(\[_,y]=y<7)(iter 64(nub o\e=e++[k\\[u,v]<-e,p<-[-1,1],q<-[-1,1],k<-[[abs(u+p),abs(v+q)]]|all((<>)k)a&&all((>)8)k])(difference[[e,0]\\e<-[0..7]]a))

$[]

Çevrimiçi deneyin!

$[]olduğu $ :: [[Int]] [Char] -> Boolveren ilk bağımsız değişken ile oluşan \ [Char] -> Bool.

İşlev, dizeyi bir seferde iki karakter tüketerek çalışır ve dize geçersiz parçayı görür görmez geçersiz bir biçimde ise hemen false değerini döndürür. Dize işlendikten sonra, panonun bir tarafındaki her boş kareye bir piskopos yerleştirir ve bunları 64 kez mümkün olan her şekilde hareket ettirir ve bitiş konumlarından herhangi birinin hedef satırda olup olmadığını kontrol eder.


Yanlış dönmek gibi görünüyor Trueiçin a1b1c1d1e1f1g1? Nasıl çalıştığı hakkında bir şey anladığımdan değil. :)
Quuxplusone

2
@Quuxplusone Beyin osuruydum ve beyaz piskoposların sadece beyaz kareler kullandığını düşündüm. Ayrıca bir açıklama ekledim.
Οurous

1

Wolfram Dili (Mathematica) , 339 316 358 353 345 bayt

@Doorknob sayesinde -23 bayt.

Geri izleme için +42 bayt muhasebe.

p[m_]:=StringPartition[#,m]&;l=Range@8;f[n_]:=Check[w=(8#2+#1-8)&@@@({LetterNumber@#,FromDigits@#2}&@@@(p@1/@p[UpTo@2]@n));g=Graph[Sort/@UndirectedEdge@@@Position[Outer[EuclideanDistance@##&,#,#,1],N@Sqrt@2]&@GraphEmbedding@GridGraph@{8,8}//Union]~VertexDelete~w;c:=#~Complement~w&;m=0;Do[m+=Length@FindPath[g,i,j],{i,c@l},{j,c[l+56]}];m==0,0>1]

Çevrimiçi deneyin!

Geri izlemeyi açıklamak için bunların çoğunu yeniden yazdım, grafiği tanımlamanın daha kolay bir yolu olabileceğini düşünüyorum g, Mathematica, GraphData[{"bishop",{8,8}}]bir piskoposun satranç tahtasında yapabileceği tüm hareketlerin grafiği ( Bishop Grafiği ), ancak bu grafik daha fazla bağlantı içeriyor en yakın diyagonal komşuya göre. Eğer bunu yapmanın daha kısa bir yolunu bilen biri varsa bana bildirin. Grafik oluşturma kredisi bu MathematicaSE cevabına gider .

Zayıf / kötü biçimlendirilmiş parolalar Trueiçin güçlü parolaları döndürür False. Hatalı oluşturulmuş şifrelerin çoğu için bir grup hata mesajı üreteceğini ve sonra geri döneceğini unutmayın False. Bu kurallar doğrultusunda değilse o zaman değiştirerek bastırılabilir f[n_]:=...için f[n_]:=Quiet@...6 bayt malolan.

Ungolfed:

p[m_] := StringPartition[#, m] &;

f[n_] :=
 Check[
  w = (8 #2 + #1 - 
       8) & @@@ ({LetterNumber@#, FromDigits@#2} & @@@ (p@1 /@ 
        p[UpTo@2]@n));
  r = GridGraph[{8, 8}];
  g = Graph[Sort /@ UndirectedEdge @@@
             Position[Outer[EuclideanDistance@## &, #, #, 1],N@Sqrt@2] &@
              GraphEmbedding@r // Union]~VertexDelete~w;
  s = Complement[{1,2,3,4,5,6,7,8},w];
  e = Complement[{57,58,59,60,61,62,63,64},w];
  m = 0;
  Do[m += Length@FindPath[g, i, j], {i, s}, {j, e}];
  If[m == 0,True,False]
  , False]

Yıkmak:

p[m_]:=StringPartition[#,m]& 

Bir dize argümanı alır ve her biri uzunluktaki bir dize listesine böler m.

Check[...,False]

FalseHerhangi bir hata mesajı üretilirse, yani hatalı biçimlendirilmiş dizeleri nasıl yakaladığımızı döndürür (yani iyi biçimlendirildiklerini, kaçınılmaz olarak satırda bir hata oluşturduğunu varsayalım).

(8*#2 + #1 - 8) & @@@ ({LetterNumber@#, FromDigits@#2} & @@@ (p@1 /@ 
        p[UpTo@2]@n));

Piyon pozisyonların dizeyi alır ve bu tür böler "a2h5b"olur {{"a","2"},{"h","5"},{"b"}}, daha sonra LetterNumberbir dizi (mektup dönüştürür a -> 1, vs) ve FromDigitsbir tamsayı içine dönüştürür rakamı. Dize de kurulmadığı takdirde, bu adım ile yakalanacak bir hata üretecektir Checkdönen, False. Bu iki sayı daha sonra karttaki bir kareye karşılık gelen bir tam sayıya dönüştürülür.

r = GridGraph[{8, 8}];
g = Graph[
     Sort /@ UndirectedEdge @@@ 
          Position[Outer[EuclideanDistance@## &, #, #, 1], 
           N@Sqrt@2] &@GraphEmbedding@r // Union]~VertexDelete~w;

Piyon konumları silinmiş olarak en yakın komşu diyagonal kenarların grafiğini oluşturur.

s = Complement[{1,2,3,4,5,6,7,8},w];
e = Complement[{57,58,59,60,61,62,63,64},w];

Bunlar sırasıyla boş başlangıç ​​ve bitiş köşelerinin listeleridir

m=0
Do[m += Length@FindPath[g, i, j], {i, s}, {j, e}];
If[m == 0,True,False]

Her çift için başlangıç ​​ve bitiş köşeleri üzerindeki döngüler, FindPatharalarındaki yolların bir listesi olacaktır. Aralarında hiçbir yol yoksa, boş bir liste olacaktır, bu yüzden Length@geri döner 0. Hiç yol yoksa, msıfır olur ve geri döneriz True, aksi takdirde geri döneriz False.


Birkaç ipucu: Trueve Falseolabilir 1>0ve 0>1sırasıyla. p[1]@#&/@eşittir p@1/@. Sequence@@ile değiştirilebilir ##&@@. Bunun yerine {LetterNumber[#[[1]]],FromDigits[#[[2]]]}&/@kullanabilirsiniz {LetterNumber@#,FromDigits@#2}&@@@.
Kapı Tokmağı

@ Doonono teşekkürler! Kod golf bana Mathematica hakkında her türlü yeni şeyleri öğretiyor. Hala% 100 anlamıyorum p@1/@ama genel fikri görüyorum. Sanırım p@1 = StringPartition[#,1]&biraz kafa karıştırıcı sanırım çünkü piki argümanı iki farklı yoldan alıyor, biri m_diğeri gibi #...&, sanırım bu sadece bir öncelik meselesi. Yine de mantıklı p@m = p[m].
Kai

Benim için de var! Ana değişiklik, ftek bir argüman alan herhangi bir işlev için f@#&, sadece fburada olduğu gibi aynı davranışa sahip folmasıdır p[1]. (Sonra []gösterimi @, öncelik dışında her zaman aynı olan olarak değiştirdim .)
Kapı tokmağı

@Bu saçma, bu ilk düşündüğümden daha karmaşık, geriye doğru hareketleri de düşünmek zorunda. Teşekkürler
Kai

@JoKing geri izleme için yeni bir tane yazdı.
Kai
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.