Şifreli Kicker //


12

Şifreli Kicker

Metni şifrelemenin yaygın ancak güvensiz bir yöntemi, alfabenin harflerine izin vermektir. Başka bir deyişle, alfabedeki her harf metinde sürekli olarak başka bir harfle değiştirilir. Şifrelemenin tersine çevrilebilir olduğundan emin olmak için, iki harf aynı harfle değiştirilmez. Göreviniz, her satırın farklı bir dizi değiştirme kullandığını ve şifresi çözülen metindeki tüm kelimelerin bilinen kelimelerin sözlüğünden olduğunu varsayarak, kodlanmış birkaç metin satırının şifresini çözmek.

Giriş

Girdi alfabetik sırada küçük harflerden oluşuyor. Bu kelimeler, şifresi çözülen metinde görünebilecek sözcüklerin sözlüğünü oluşturur. Sözlüğü takip eden birkaç girdi satırı vardır. Her satır yukarıda açıklandığı gibi şifrelenir.

Sözlükte 1000'den fazla kelime yok. Hiçbir kelime 16 harfi aşamaz. Şifrelenmiş satırlar yalnızca küçük harfler ve boşluklar içerir ve 80 karakteri geçmez.

Çıktı

Her satırın şifresini çözün ve standart çıkışa yazdırın. Birden fazla çözüm varsa, herhangi biri yapacak. Çözüm yoksa, alfabenin her harfini yıldız işareti ile değiştirin.

Örnek Giriş

and dick jane puff spot yertle

bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd

Örnek Çıktı

dick and jane and puff and spot and yertle
**** *** **** *** **** *** **** *** ******

İşte çözüm. En kısa bayt / Rekabetçi programcı için yarışta koşan bir at olmadığımı lütfen unutmayın . Ben sadece bulmaca severim!

( Kaynak )


1
Lütfen her giriş için geçerli olan> giriş <kısıtlamalarınızı gevşetin. Örneğin, birçok dil nefret edecek ve formatın 6 ile başladığını takdir etmeyecek. Formatı tamamen belirtmeden bırakmanızı öneririm ve sadece girişin bir kelime listesi ve şifrelenecek satır listesi olduğunu söyleyebilirim.
orlp

Tamam, işte böyle!
Dhruv Ramani

1
Bunun için çalışma zamanı kısıtlamaları var mı? Biri çalışana kadar (muhtemelen yıllarca sürebilir) mümkün olan her değiştirme kombinasyonunu tekrarlayabilir miyim?
Nathan Merrill

@NathanMerrill Bunu yapın ve yıllar alacaksa, yıldız formunda yazdırın. Vihan, Bu bir kopya değil, lütfen soruyu doğru okuyun.
Dhruv Ramani

Sadece kelimeleri çıkarabilir miyiz yoksa onlara katılmak zorunda mıyız?
Downgoat

Yanıtlar:


3

Python 3, 423 bayt

import sys,re
S=re.sub
D,*L=sys.stdin.read().split('\n')
def f(W,M=[],V="",r=0):
 if len({d for(s,d)in M})==len(M):
  if[]==W:return V.lower()
  for d in D.split():p='([a-z])(?%s.*\\1)';m=re.match(S(p%'=',')\\1=P?(',S(p%'!',').>\\1<P?(',W[0].translate(dict(M))[::-1]))[::-1]+'$',d.upper());r=r or m and f(W[1:],M+[(ord(s),m.group(s))for s in m.groupdict()],V+d+" ")
  return r
for l in L:print(f(l.split())or S('\w','*',l))

STDIN'den girişi okur ve örnek giriş / çıkışıyla aynı formatı kullanarak çıktıyı STDOUT'a yazar.

açıklama

Her şifre metni satırı için aşağıdaki prosedürü gerçekleştiririz:

Daha önce kurduğumuz (başlangıçta boş olan) tüm harf dönüşümlerinin bir haritasını ( M) tutarız . Bunu, kaynak harflerin tümü küçük ve hedef harflerin tamamı büyük olacak şekilde yaparız.

Şifrelemedeki kelimeleri sırayla işleriz. Her kelime için, sözlükteki eşleşebileceği tüm kelimeleri aşağıdaki gibi buluruz:

Diyelim ki, w , kelimemiz glpplppljjlve M'nin kuralı içerdiğini varsayalım j -> P. Biz ilk dönüşümü w mevcut kurallarını kullanarak M alma, glpplpplPPl. Sonra dönüşümü w aşağıdaki piton aromalı regex:

(?P<g>.)(?P<l>.)(?P<p>.)(?P=p)(?P=l)(?P=p)(?P=p)(?P=l)PP(?P=l)

Dönüşümün kuralları aşağıdaki gibidir:

  • Her küçük harfin ilk oluşumu x, ile değiştirilir . Bu, tek bir karakterle eşleşen adlandırılmış bir yakalama grubunu tanımlar .(?P<x>.)x
  • Sonraki her olayda, her küçük harf x, ile değiştirilir . Bu, önceden adlandırılmış grup tarafından önceden yakalanan karakterin bir geri başvurusudur .(?P=x)x

Bu ters bu dönüşümü gerçekleştirmek ağırlık daha sonra aşağıdaki iki normal ifade ikameleri uygulanması:

s/([a-z])(?!.*\1)/)>\1<P?(/
s/([a-z])(?=.*\1)/)\1=P?(/

ve ardından sonucu tersine çevirir. Daha önce M tarafından dönüştürülen karakterlerin büyük harf olarak göründüğünü ve bu nedenle değişmeden kaldığını unutmayın.

Ortaya çıkan normal ifadeyi, sözlük kelimelerinin büyük harf olarak göründüğü sözlük kelimelerinin her biriyle eşleştiriyoruz. Örneğin, yukarıdaki normal ifade kelimeyle eşleşir MISSISSIPPI. Bir eşleşme bulursak, yeni dönüşüm kurallarını çıkarır ve M'ye ekleriz . Yeni dönüşüm kuralları, yakalama gruplarının her biri tarafından yakalanan karakterlerdir. Yukarıdaki regex, grup gmaçları M, grup lmaçı Ive grup pmaçları Sbize kurallarını vererek g -> M, l -> I, p -> S. Ortaya çıkan kuralların tutarlı olduğundan, yani iki kaynak harfin aynı hedef harfle eşleşmediğinden emin olmalıyız; aksi takdirde maçı reddederiz.

Ardından, artırılmış dönüşüm kurallarını kullanarak bir sonraki kelimeye geçiyoruz. Bu işlemi kullanarak tüm şifre metni sözcükleriyle eşleşebilirsek, metnin şifresini çözdük. Bir kelimeyi sözlük kelimelerinin hiçbiriyle eşleştiremezsek, önceki kelimeleri farklı sözlük kelimelerine karşı izler ve eşleştirmeye çalışırız. Bu işlem başarısız olursa, çözüm yoktur ve bir satır yıldız yazdırırız.


2

CJam, 62 56 bayt

qN%Sf/(f{\:C,m*{C..+`Sa`m2/Q|z_''f-Qf|=},C:,'*f*a+0=S*N}

Oldukça yavaş ve bellek aç, ancak Java yorumlayıcısı ile test durumda çalışır.

Örnek çalışma

$ cat input; echo
and dick jane puff spot yertle

bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd
$ time cjam kicker.cjam < input
dick and jane and puff and spot and yertle
**** *** **** *** **** *** **** *** ******

real    5m19.817s
user    6m41.740s
sys     0m1.611s
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.