Herkese merhabalar! Bugün 6. gün ile birlikteyiz. Bana önceki güne göre daha kolay gelen bölümün adı ‘Ayarlama Sorunu‘ hakkında. Hikayemiz şu şekilde başlıyor:
Birinci Bölüm:
Hazırlıklar nihayet tamamlandı; siz ve Elfler kamptan yürüyerek ayrıldınız ve yıldız meyvesi korusuna doğru yol almaya başladınız.
Sık çalılıklar arasında ilerlerken Elflerden biri size bir el cihazı veriyor. Birçok süslü özelliği olduğunu, ancak şu anda ayarlanması gereken en önemli özelliğin iletişim sistemi olduğunu söylüyor.
Bununla birlikte, sinyal tabanlı sistemlerle ilgili önemli bir deneyime sahip olduğunuzu duyduğundan, diğer Elfleri arızalı tek cihazlarını size vermenin sorun olmayacağına ikna etti – elbette onu tamir etmekte sorun yaşamazsınız.
Komedi zamanlamasından esinlenilmiş gibi, cihaz birkaç renkli kıvılcım yayıyor.
Elflerle iletişim kurabilmek için cihazın onların sinyaline kilitlenmesi gerekiyor. Sinyal, cihazın her seferinde bir tane aldığı görünüşte rastgele karakterlerden oluşan bir seridir.
İletişim sistemini düzeltmek için, cihaza veri akışında paket başlangıcı işaretini algılayan bir alt program eklemeniz gerekir. Elfler tarafından kullanılan protokolde, bir paketin başlangıcı, hepsi farklı olan dört karakterden oluşan bir dizi ile belirtilir.
Cihaz alt rutininize bir veri akışı tamponu (bulmaca girdiniz) gönderecektir; alt rutininizin en son alınan dört karakterin hepsinin farklı olduğu ilk konumu tanımlaması gerekir. Özellikle, tamponun başından ilk dört karakterlik işaretleyicinin sonuna kadar olan karakter sayısını bildirmesi gerekir.
https://adventofcode.com/2022/day/6
Örneğin, aşağıdaki veri akışı arabelleğini aldığınızı varsayalım:
mjqjpqmgbljsphdztnvjfqwrcgsmlb
İlk üç karakter (mjq) alındıktan sonra, henüz işaretleyiciyi bulmak için yeterli karakter alınmamıştır. Bir işaretleyici ilk kez dördüncü karakter alındıktan sonra ortaya çıkabilir, bu da en son dört karakteri mjqj yapar. j tekrarlandığı için bu bir işaretleyici değildir.
Bir işaretleyici ilk kez yedinci karakter geldikten sonra görünür. Bir kez belirdiğinde, alınan son dört karakter jpqm’dir ve bunların hepsi farklıdır. Bu durumda, alt rutininiz 7 değerini rapor etmelidir, çünkü ilk paket başlangıcı işaretçisi 7 karakter işlendikten sonra tamamlanır.
İşte birkaç örnek daha:
bvwbjplbgvbhsrlpgdmjqwftvncz: karakter 5’ten sonraki ilk işaretleyicinppdvjthqldpwncqszvftbrmjlhg: karakter 6’dan sonraki ilk işaretleyicinznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: karakter 10’dan sonraki ilk işaretleyicizcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: karakter 11’den sonraki ilk işaretleyici
İlk paket başlangıcı işaretçisi algılanmadan önce kaç karakterin işlenmesi gerekir?
Bu problemi çözmek için yazdığım python kodunu aşağıda görebilirsiniz:
with open('buffer.txt', 'r', encoding="utf-8") as f: # Open the file
buffer = f.readlines() # Read the lines of the file
buffer = buffer[0] # Get the actual line
# loop over the each element of the buffer
for i in range(len(buffer)-3): # -3 because the last 3 characters are "end"
# indicate the sequence of four characters that are all different and find its position
if (buffer[i] != buffer[i+1]) and (buffer[i] != buffer[i+2]) and (buffer[i] != buffer[i+3]): # If the three other characters are all different from first character
if (buffer[i+1] != buffer[i+2]) and (buffer[i+1] != buffer[i+3]): # If the two other characters are all different from second character
if (buffer[i+2] != buffer[i+3]): # If the other character is different from third character
print(i+4) # Print the position of the sequence of four characters that are all different
break # Break the loop
Her zamanki gibi bana verilen inputu bir txt dosyasın kaydettim ve ilk satırdaki sinyali okuma işlemini yaptım. Daha sonra, bir döngü başlatır ve bu döngüdeki her bir eleman için bir koşul kontrolü yapar. Koşul, bir dizinin dört karakterinin tümünün farklı olup olmadığını kontrol eder. Eğer dört karakter farklıysa, bu dizinin pozisyonunu ekrana yazdırır ve döngüyü kırar.
İkinci Bölüm:
Buradaki hikayemiz çok değişmiyor. Söylenenler şunlar:
Cihazınızın iletişim sistemi paketleri doğru bir şekilde algılıyor, ancak yine de çalışmıyor. Görünüşe göre mesajları da araması gerekiyor.
Mesaj başlangıcı işaretçisi tıpkı paket başlangıcı işaretçisi gibidir, ancak 4 yerine 14 farklı karakterden oluşur.
Yukarıdaki tüm örnekler için mesaj başlangıcı işaretçilerinin ilk konumları aşağıda verilmiştir:
- mjqjpqmgbljsphdztnvjfqwrcgsmlb: karakter 19’dan sonraki ilk işaretleyici
bvwbjplbgvbhsrlpgdmjqwftvncz: karakter 23’ten sonraki ilk işaretleyicinppdvjthqldpwncqszvftbrmjlhg: karakter 23’ten sonraki ilk işaretleyicinznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: karakter 29’dan sonraki ilk işaretleyicizcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: karakter 26’den sonraki ilk işaretleyici
İlk mesaj başlangıcı işaretçisi algılanmadan önce kaç karakterin işlenmesi gerekir?
Burada farklı olması gereken karakter sayısı 4’ten 14’e çıktığı için az önce yazdığımız kod maalesef hiç efektid olmayacaktır. Bu sebeple biraz düşünüp kodumu optimize etmeye çalıştım ve aşağıdaki kodu yazdım:
with open('buffer.txt', 'r', encoding="utf-8") as f: # Open the file
buffer = f.readlines() # Read the lines of the file
buffer = buffer[0] # Get the actual line
# loop over the each element of the buffer
for i in range(len(buffer)-14): # -14 because the last 14 characters are "end"
s = buffer[i:i+14] # Get the next 14 characters
if len(set(list(s))) == 14: # If there are 14 different characters (set removes duplicates)
print(i + 14) # Print the position of the sequence of 14 characters that are all different
Bu sefer koşul yapısını biraz değiştirdik. Bir dizinin 14 karakterinin tümünün farklı olup olmadığını kontrol set yani küme veri yapısıyla kontrol ediyoruz. Çünkü kümeler bir verinin tekrar etmesini engeller. Eğer 14 karakterden tekrar edenler varsa kümenin uzunluğu azalacağı için if yapısının içine girmeyecektir. Girdiği gibi de break ile döngüyü kesiyoruz ver pozisyon bilgisini yazdırıyoruz.
AoC’un altıncı günü de bu kadardı. Vakit ayırıp okuduğunuz için teşekkür ederim. Eğer yazıyı beğendiyseniz, kodlamaya meraklı arkadaşlarınızla paylaşmayı unutmayın
Herhangi bir sorunuz olursa veya benimle iletişim kurmak isterseniz tüm sosyal medya hesaplarıma bu linke tıklayarak ulaşabilirsiniz. Ayrıca tüm çözümlerimi görebilmeniz için bir github reposu açtım. Bu repoya da bu linkten ulaşabilirsiniz.