פיתרון Advent Of Code 2022 יום 6 ביוניקס

11/12/2022

אחרי שאלה קצת מעייפת על מגדלים חזרנו לשאלות שאפשר לפתור בשורה אחת של יוניקס, והשאלה של יום 6 היתה הזדמנות מצוינת להיזכר בלולאות ומשתנים של Bash. המשימה הפעם היא לקחת מחרוזת תווים ולמצוא את האינדקס של התו הראשון שארבעת התווים שלפניו שונים אחד מהשני. הדוגמה היתה המחרוזת הזו:

mjqjpqmgbljsphdztnvjfqwrcgsmlb

ואנחנו רואים שבקריאה משמאל לימין הפעם הראשונה שמופיעים 4 תווים שונים היא התווים jqpm ולכן האינדקס של התו שאחריהם (האות g) הוא 7.

בשביל למצוא אותו אפשר לתת ל bash לעבוד:

  1. נרוץ בלולאה עם משתנה לולאה i שמתחיל מ-1.
  2. לכל ערך של i נחתוך מהמחרוזת את 4 התווים החל מהמקום ה i בעזרת cut.
  3. נשלח את egrep לחפש תו כפול במחרוזת. אם הוא לא מצא אפשר לצאת מהלולאה ולהדפיס את i+4-1

בהנחה שהקלט נשמר בקובץ input.txt תוכנית ה bash המתאימה היא:

#!/bin/bash

i=1
while cat input.txt | cut -c $i- | cut -c -4 | egrep '(\w).*\1' >& /dev/null
do
    (( i++ ))
done

echo $(( i + 4 - 1))

או בשורה אחת:

i=1; while cat input.txt| cut -c $i- | cut -c -4 | egrep  '(\w).*\1' >& /dev/null ; do; (( i ++ )); done; echo $(( i + 4 - 1))

שלוש נקודות לקחת מהתוכנית:

  1. הרבה פעמים נוח לפצל תנאי לכמה תנאים ב Pipeline. במקרה שלנו בשביל לחתוך 4 תווים החל ממקום i אפשר לשבור את השיניים בשביל ליצור פקודת cut אחת, אבל יותר קל לפצל את זה לשתי פקודות cut אחת אחרי השניה, אחת מתחילה מהמקום ה i והשניה חותכת 4 תווים.

  2. מאוד נוח שב bash פקודת while מבצעת פקודה שהיא מקבלת שוב ושוב כל עוד הפקודה מצליחה.

  3. סוגריים עגולים כפולים ב bash "בורחים" מהעולם של bash לעולם חשבוני רגיל, ובגלל זה עדיף להשתמש בהם כשרוצים לבצע פעולות אריתמטיות על משתנים.

למרות שלסקריפטים יש בעיית תחזוקה וברוב המקרים יותר קל לכתוב חדש מאשר לעדכן קיים, הם עדיין כלי עבודה עוצמתי במיוחד למשימות קטנות, בזכות הפורטביליות, קלות הכתיבה והיכולת להשתמש בקלות בכל הכלים הקיימים ביוניקס.