פקודת Bash קצרה לפתרון Spelling Bee
דבורת האיות הוא משחק חמוד המכיל אות אחת באמצע ועוד 6 אותיות מסביב והמשימה שלנו היא למצוא כמה שיותר מילים מהאותיות האלה עם הכללים:
האות שבאמצע חייבת להופיע.
אורך המילה לפחות 4 אותיות.
אפשר לשחק בו כאן: https://6mal5.com/wortendo/
ובטח בעוד המון מקומות ברשת.
המשחק כיפי וביום רגיל כשנתקעים אפשר לבקש עזרה מחברים אבל אם במקרה אין לכם חברים שאוהבים משחקי מילים או שגם הם לא יודעים להרכיב מילים עם U נוכל לקבל גם טיפים מהמחשב בעזרת סקריפט Bash קצר. אני אראה את הסקריפט בגירסה שלי קודם ואחרי זה בגירסה של קלוד ודרך זה גם נלמד משהו על הבדלי הגישות בין אנשים לבינה מלאכותית.
אתחיל עם הפיתרון שלי והוא נראה כך:
#!/bin/bash -e
center=$1
rest=$2
cat /usr/share/dict/words | grep $center | grep .... | egrep "^[${rest}{$center}]+$" | awk '{ print length "\t" $0 }' | sort -n | cut -f2-
וכן זה שורה אחת:
- לוקחים קובץ מילים.
- משאירים רק את המילים עם האות שבאמצע.
- משאירים רק מילים עם 4 אותיות.
- משאירים רק מילים שמורכבות אך ורק מהאותיות של המשחק.
- מסדרים את הכל לפי האורך כך שמילים ארוכות יופיעו בתחתית הרשימה (שיהיה קל לראות אותן).
מיטיבי לכת יכולים להוסיף שם head -1
כדי לקבל רק רמז אחד.
ועכשיו למימוש של קלוד:
#!/bin/bash -e
center=$1
rest=$2
# Check if arguments are provided
if [ -z "$center" ] || [ -z "$rest" ]; then
echo "Usage: $0 <center_letter> <other_letters>"
echo "Example: $0 a bcdefg"
exit 1
fi
# Combine all available letters
all_letters="${center}${rest}"
# Convert to lowercase for consistency
center=$(echo "$center" | tr '[:upper:]' '[:lower:]')
rest=$(echo "$rest" | tr '[:upper:]' '[:lower:]')
all_letters=$(echo "$all_letters" | tr '[:upper:]' '[:lower:]')
# Word list file (common locations)
word_files=(
"/usr/share/dict/words"
"/usr/dict/words"
"/usr/share/dict/american-english"
"/usr/share/dict/web2"
)
word_file=""
for file in "${word_files[@]}"; do
if [ -f "$file" ]; then
word_file="$file"
break
fi
done
if [ -z "$word_file" ]; then
echo "Error: No word dictionary found. Please install a word list."
echo "On Ubuntu/Debian: sudo apt-get install wamerican"
echo "On macOS: Word lists are usually in /usr/share/dict/"
exit 1
fi
echo "Solving Spelling Bee with center letter: $center"
echo "Available letters: $all_letters"
echo "Using word list: $word_file"
echo "----------------------------------------"
# Find valid words
valid_words=()
total_score=0
while IFS= read -r word; do
# Convert word to lowercase and remove any non-alphabetic characters
clean_word=$(echo "$word" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z]//g')
# Skip if word is less than 4 letters
if [ ${#clean_word} -lt 4 ]; then
continue
fi
# Check if word contains the center letter
if [[ "$clean_word" != *"$center"* ]]; then
continue
fi
# Check if word only uses available letters
valid=true
for ((i=0; i<${#clean_word}; i++)); do
letter="${clean_word:$i:1}"
if [[ "$all_letters" != *"$letter"* ]]; then
valid=false
break
fi
done
if [ "$valid" = true ]; then
# Calculate score
word_length=${#clean_word}
if [ $word_length -eq 4 ]; then
score=1
else
score=$word_length
fi
# Check if it's a pangram (uses all letters)
is_pangram=true
for ((i=0; i<${#all_letters}; i++)); do
letter="${all_letters:$i:1}"
if [[ "$clean_word" != *"$letter"* ]]; then
is_pangram=false
break
fi
done
if [ "$is_pangram" = true ]; then
score=$((score + 7))
echo "$clean_word ($score points) - PANGRAM!"
else
echo "$clean_word ($score points)"
fi
valid_words+=("$clean_word")
total_score=$((total_score + score))
fi
done < "$word_file"
echo "----------------------------------------"
echo "Found ${#valid_words[@]} valid words"
echo "Total score: $total_score points"
נשים לב להמון דברים כאן:
קלוד חישב ניקוד של כל המילים שהוא מצא. זה מאוד סיבך לו את המימוש.
קלוד השתמש רק בפקודות bash לסינונים בעוד שאני שמחתי להשתמש ב grep.
קלוד "ניקה" את המילים לפני הבדיקה, כלומר מחק תווים שאינם אותיות באנגלית. זאת בחירה מוזרה כי אם בקובץ המילים יש מילה שמכילה מספר הגיוני יותר לדלג על השורה שלה. רוב הסיכויים שבלי המספר זאת לא תהיה מילה תקינה באנגלית.
השוואה יותר מעניינת מתקבלת כשאני מעדכן את הפרומפט ומוסיף את המשפט:
Use a one line pipeline giving just word suggestions (without score)
עכשיו אני מקבל מקלוד את הסקריפט:
#!/bin/bash -e
center=$1
rest=$2
grep -E "^[${center}${rest}]+$" /usr/share/dict/words | grep "$center" | awk 'length >= 4' | sort -u
שכבר מאוד דומה לפיתרון שלי מלבד סדר הפעולות, המיון בסוף, והבחירה להשתמש ב awk במקום ב grep כדי לבדוק אורך.