תרגיל בית מספר 1#

‫אוניברסיטת תל אביב ‪ -‬בית הספר למדעי המחשב‬
‫מבוא מורחב למדעי המחשב‪ ,‬חורף ‪3102‬‬
‫תרגיל בית מספר ‪( 7‬אחרון!) ‪ -‬להגשה עד ‪ 77‬בינואר ‪ 7102‬בשעה ‪72:22‬‬
‫בציון הסופי ישוקללו ‪ ( 5‬ולא ‪ )6‬מתוך ‪ 7‬התרגילים הטובים של כל סטודנט‪.‬‬
‫קיראו בעיון את קובץ הנחיות הגשת תרגילי בית שמופיע באתר‪.‬‬
‫את כל הפונקציות שאתם כותבים הגישו בקובץ ‪ py‬אחד‪ .‬הקפידו על שמות הפונקציות כפי שהן מצוינות‬
‫בשאלות‪ .‬לנוחיותכם‪ ,‬מצורף קובץ ‪ skeleton‬המכיל את חתימות כל הפונקציות שעליכם לממש‪.‬‬
‫בסיום העבודה שנו את שמו ל ‪( 123456789.py -‬עם תעודת הזהות שלכם)‪.‬‬
‫הקפידו לבדוק את תקינות קובץ ה ‪ py -‬שאתם מגישים על ידי הרצה מדוקדקת של הפונקציות‪.‬‬
‫את התשובות ליתר השאלות הגישו בקובץ ‪ doc/docx/pdf‬אחד‪.‬‬
‫בסה"כ מגישים שני קבצים בלבד‪ .‬הקפידו לענות על כל מה שנשאלתם‪.‬‬
‫שאלה ‪0‬‬
‫בשאלה זו נממש ְמאַ יֵּ ת ( ‪ ,(spell-checker‬שישמש לתיקון שגיאות איות (‪ )typos‬בטקסט‪.‬‬
‫יהיה בידנו אוסף של מילים חוקיות‪ ,language ,‬שיוזן מתוך קורפוס כלשהו‪ .‬בהינתן טקסט כלשהו‪ ,‬נמצא‬
‫לכל מילה בטקסט את המילה הקרובה ביותר אליה ב ‪( language -‬ייתכן שזו אותה מילה בעצמה)‪ .‬נממש‬
‫שתי גישות להגדרת מרחק בין מילים‪ hamming :‬ו ‪( qwerty -‬יוסברו מייד)‪.‬‬
‫הגדרת מרחק בין מילים בשיטת ‪hamming‬‬
‫בהינתן ‪ 2‬מילים ‪ ,w1, w2‬המרחק ביניהן יוגדר כך‪ :‬מצמידים את שתי המילים לשמאל זו מעל זו‪ ,‬וסופרים‬
‫את כמות התווים השונים בין שתי המילים‪ ,‬כולל תווים חסרים‪ .‬נתעלם מהבדלי ‪ .case‬למשל‪:‬‬
‫‪hamming("hello", "belL"( = 2‬‬
‫‪o‬‬
‫‪l‬‬
‫‪l‬‬
‫‪e‬‬
‫‪h‬‬
‫‪w1‬‬
‫‪L‬‬
‫‪l‬‬
‫‪e‬‬
‫‪b‬‬
‫‪w2‬‬
‫‪1‬‬
‫‪diff 1‬‬
‫הגדרת מרחק בין מילים בשיטת ‪qwerty‬‬
‫כפי שהוזכר באחת ההרצאות‪ ,‬רוב מקלדות בעולם כיום מסודרות לפי סטנדרט שנקרא ‪( qwerty‬אלו ‪6‬‬
‫האותיות בשורה העליונה משמאל‪ .‬בהרצאה הוזכר גם סידור אלטרנטיבי שנקרא ‪.)Dvorak‬‬
‫ניתן להגדיר מרחק בין כל שתי אותיות באופן יחסי למרחק ביניהן על המקלדת‪ .‬גישה זו מבוססת על ההנחה‬
‫ששגיאות איות מתרחשות בגלל גלישת האצבע למקש אחר‪ ,‬או בגלל הקשה עודפת או חסרה‪.‬‬
‫מרחק בין שני תווים יוגדר כמספר הצעדים שיש לבצע כדי לנוע מאחד לשני‪ ,‬כאשר צעד יכול להתבצע בכיוון‬
‫אופקי או אנכי בלבד‪ .‬לצורך העניין נגדיר את מיקומי התווים כמתואר באיור הבא ‪:‬‬
‫‪11‬‬
‫‪10‬‬
‫‪9‬‬
‫‪8‬‬
‫‪7‬‬
‫‪6‬‬
‫‪5‬‬
‫‪3‬‬
‫‪4‬‬
‫‪1‬‬
‫‪2‬‬
‫‪0‬‬
‫‪del‬‬
‫‪0‬‬
‫‪p‬‬
‫‪o‬‬
‫‪i‬‬
‫‪u‬‬
‫‪y‬‬
‫‪t‬‬
‫‪r‬‬
‫‪e‬‬
‫‪w‬‬
‫‪l‬‬
‫‪k‬‬
‫‪j‬‬
‫‪h‬‬
‫‪g‬‬
‫‪f‬‬
‫‪d‬‬
‫‪s‬‬
‫‪a‬‬
‫‪m‬‬
‫‪n‬‬
‫‪b‬‬
‫‪v‬‬
‫‪c‬‬
‫‪x‬‬
‫‪z‬‬
‫‪q‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫למשל‪ ,‬מרחק ‪ qwerty‬בין '‪ 'q‬לבין '‪ 'a‬הוא ‪ ,2‬ואילו בין '‪ 'a‬לבין '‪ 'y‬הוא ‪.5‬‬
‫בהינתן ‪ 2‬מילים ‪ ,w1, w2‬המרחק ביניהן יוגדר כך‪ :‬מצמידים את שתי המילים לשמאל זו מעל זו‪ ,‬ומסכמים‬
‫את המרחקים בין התווים‪ ,‬בהתאם להגדרה הנ"ל‪ .‬אם אחת המילים קצרה מהשניה‪ ,‬ייחשב הדבר כמרחק‬
‫אל התו ‪ .del‬נתעלם מהבדלי ‪.case‬‬
‫למשל‪:‬‬
‫‪qwerty("hello", "belL"( = 5‬‬
‫‪o‬‬
‫‪4‬‬
‫‪l‬‬
‫‪l‬‬
‫‪e‬‬
‫‪h‬‬
‫‪w1‬‬
‫‪L‬‬
‫‪l‬‬
‫‪e‬‬
‫‪b‬‬
‫‪w2‬‬
‫‪0‬‬
‫‪0‬‬
‫‪0‬‬
‫‪diff 1‬‬
‫סעיף א'‪ :‬כיתבו פונקציה )‪ hamming(w1,w2‬שמקבלת שתי מחרוזות המורכבות מאותיות באנגלית בלבד‬
‫(קטנות או גדולות)‪ ,‬ומחזירה את המרחק ביניהן בשיטת ‪.hamming‬‬
‫סעיף ב'‪ :‬כיתבו פונקציה )‪ qwerty(w1,w2‬שמקבלת שתי מחרוזות המורכבות מאותיות באנגלית בלבד‬
‫(קטנות או גדולות)‪ ,‬ומחזירה את המרחק ביניהן בשיטת ‪.qwerty‬‬
‫לעזרתכם ניתנת הפונקציה הבאה ( לא חובה להשתמש בה‪ ,‬ואפשר גם לשנות אותה)‪ :‬פונקציה זו מייצרת‬
‫מילון שמפתחותיו הם אותיות קטנות באנגלית והערכים הנלווים הם המיקומים על המקלדת‪ ,‬כפי שהוצגה‬
‫לעיל‪ .‬שימו לב שהתו '‪ 'del‬לא מופיע במילון שנוצר‪.‬‬
‫‪def build_qwerty_dict():‬‬
‫[ = ‪keyboard_as_list‬‬
‫‪['q','w','e','r','t','y','u','i','o','p'],‬‬
‫‪[' ','a','s','d','f','g','h','j','k','l'],‬‬
‫] ]'‪[' ',' ','z','x','c','v','b','n','m‬‬
‫}{ = ‪kbrd‬‬
‫‪for i in range(len(keyboard_as_list)):‬‬
‫]‪row = keyboard_as_list[i‬‬
‫‪for j in range(len(row)):‬‬
‫]‪char = row[j‬‬
‫)‪kbrd[char] = (i+1, j‬‬
‫' ' ‪kbrd.pop(' ') # Get rid of filler char‬‬
‫‪return kbrd‬‬
‫עמוד ‪ 2‬מתוך ‪5‬‬
:‫לדוגמה‬
>>> kbrd = build_qwerty_dict()
>>> kbrd['q']
(1, 0)
>>> kbrd['m']
(3, 8)
‫ הפונקציה מקבלת מחרוזת‬.nearest_neighbor(word, language, distFunc) ‫ כיתבו פונקציה‬:'‫סעיף ג‬
‫ (שמקבלת שתי מחרוזות המורכבות‬distFunc ‫ ופונקצית מרחק‬,language ‫ רשימת מילים חוקיות‬,word
‫ מחזירה את המילה הקרובה‬nearest_neighbor .)‫מאותיות באנגלית בלבד ומחזירה את המרחק ביניהן‬
.‫ תחת פונקצית המרחק הנתונה‬language ‫ ברשימה‬word - ‫ביותר ל‬
‫ הפונקציה‬.text - ‫ שתתקן שגיאות איות ב‬,correct(text, language, distFunc) ‫ כיתבו פונקציה‬:'‫סעיף ד‬
,‫ ומחזירה משפט מתוקן‬,distFunc ‫ ופונקצית מרחק‬,language ‫ רשימת מילים חוקיות‬,text ‫מקבלת טקסט‬
.language ‫ אל מול‬text - ‫ על כל אחת מהמילים ב‬nearest_neighbor ‫ע"י הפעלה פשוטה של‬
‫ כלומר כל תו שאיננו‬.‫לצורך כך מילה בטקסט היא רצף מקסימלי של אותיות (קטנות או גדולות) באנגלית‬
.‫כזה מהווה הפרדה בין מילים‬
: ‫" מכיל את המילים‬intro. to Computer-Science with python 3.2" ‫למשל הטקסט‬
intro, to, Computer, Science, with, python
‫ את כל התווים שאינם אותיות‬text ‫ אשר "מנקה" מהמחרוזת‬split(text) ‫ כיתבו פונקצית עזר‬:‫המלצה‬
.‫ ומחזירה את רשימת המילים שבה‬,‫קטנות או גדולות באנגלית‬
:‫למשל‬
>>> split("intro. to Computer-Science with python 3.2")
['intro', 'to', 'Computer', 'Science', 'with', 'python']
:correct ‫דוגמה להרצת‬
>>> text = "inyro. two computre-Science withh pithon 3.2"
>>> language = ["to", "intro", "introduction","computer", "science", "Python", "with", "ourib"]
>>> correct(text, language, hamming)
'intro to computer science with Python
>>> correct(text, language, qwerty)
'intro to computer science with Python
>>> text = "inyro. two computre-Science withh piton 3.2"
#note the 'piton' in the end
>>> correct(text, language, hamming)
'intro to computer science with with'
>>> correct(text, language, qwerty)
'intro to computer science with ourib'
5 ‫ מתוך‬3 ‫עמוד‬
‫שאלה ‪7‬‬
‫להלן קוד לתיקון שגיאות‪ :‬בהינתן הודעה באורך ‪ 2‬ביטים‪ ,‬נשלח כל ביט פעמיים (כמו ב ‪)repetition code -‬‬
‫ונוסיף ביט זוגיות בסוף (כמו ב ‪ )parity check code -‬בסוף ‪ XOR‬בין שני הביטים המקוריים‪ .‬למשל‪ ,‬עבור‬
‫ההודעה ‪ ,01‬ישודר ‪( 00110 00111‬הביטים שנוספו מודגשים בקו)‪.‬‬
‫א‪ .‬מהו המרחק המינימלי ‪ d‬של הקוד (מרחק ‪ Hamming‬המינימלי בין שתי הודעות חוקיות כלשהן) ?‬
‫הסבירו‪.‬‬
‫ב‪ .‬כמה טעויות ניתן לגלות וכמה ניתן לתקן?‬
‫ג‪ .‬מהו כמות ההודעות שמוכלות בספרה (‪ )sphere‬שסביב כל הודעה חוקית ? הכוונה לס פרה שמכילה‬
‫סביב הודעה חוקית‪.‬‬
‫הודעות הניתנות לתיקון‪ ,‬כלומר ספרה ברדיוס‬
‫ד‪ .‬האם קוד זה הוא "קוד מושלם"? הסבירו‪.‬‬
‫שאלה ‪2‬‬
‫בתרגול ראינו את קוד אינדקס לתיקון שגיאות‪ .‬לקוד פרמטר‬
‫נדגים את אופן הקידוד של מילה בקוד אינדקס‪ ,‬עבור‬
‫ביטים של מידע ו ‪-‬‬
‫כזכור‪ ,‬מילת קוד מכילה‬
‫הקובע את אורך המילה‪ .‬לשם תזכורת‪,‬‬
‫‪:‬‬
‫ביטים של תיקון שגיאות (בדוגמא שלנו ‪ 7‬ביטים‬
‫של מידע ו ‪ 6-‬ביטים של תיקון שגיאות‪ .‬בשאלה זו איננו מוסיפים עוד ביט זוגיות כפי שעשינו בתרגול)‪.‬‬
‫הביטים של תיקון השגיאות מכילים את ה ‪ XOR-‬של האינדקסים של הביטים שערכם ‪ 0‬במילת המידע‬
‫(ביטים ‪ 2,3,5,6‬בדוגמא)‪ .‬הביטים של תיקון השגיאות חוזרים על עצמם פעמיים‪ .‬עבור‬
‫כללי‪ ,‬הפרמטרים‬
‫של הקוד הם ‪:‬‬
‫המשקל של מילת קוד ( ‪ )Hamming Weight‬הינו מספר הפעמים שמופיע בה הערך ‪ .0‬למשל‪ ,‬המשקל של‬
‫המילה בדוגמא למעלה הוא ‪ .6‬שימו לב ‪ ,‬שלמעט מילת ה ‪( 1-‬שמכילה אפסים בלבד) כל מילה חוקית בקוד‬
‫אינדקס היא במשקל ‪ 3‬לפחות‪.‬‬
‫עבור קוד אינדקס עם‬
‫(כלומר ‪ 05‬ביטים של מידע ו ‪ 8-‬ביטים של תיקון שגיאות)‪ ,‬רשמו את כל‬
‫המילים החוקיות בקוד אינדקס שמשקלן ‪ .3‬לדוגמא ‪:‬‬
‫כמה מילים כאלו יש? תארו בקצרה מה מאפיין את המילים הללו (כלומר איזו תכונה צריכה להתקיים בהן)‬
‫ומדוע אין מילים נוספות שמשקלן ‪ 3‬מלבד אלו שציינתם‪.‬‬
‫ניתן להיעזר בקוד פייתון על מנת לפתור את השאלה‪ ,‬אך אין חובה כזאת‪ .‬אם השתמשתם בקוד על מנת‬
‫לפתור את השאלה‪ ,‬צרפו אותו לקובץ ה ‪ py -‬שאתם מגישים‪.‬‬
‫עמוד ‪ 4‬מתוך ‪5‬‬
‫ נקודות‬02 ‫ – בונוס‬4 ‫שאלה‬
In class, we saw a proof that the halting problem is not solvable. Assuming the existence of a (high
order) function Halt(func,x), which determines if func halts on input x, we constructed a (high order)
function, modify(f). We saw that when applying modify to itself, modify(modify) halts iff it does not
halt, which is a contradiction (to the existence of such Halt).
Benny claims that not only is it impossible to compute Halt(func,x), but even computing the bounded
halting is impossible. The bounded halting BHalt(s,func,x) determines if func halts on input x within s
seconds. Having heard this claim during the weekly staff meeting, the teaching assistants quickly
produce the piece of code (attached), which, they claim, solves bounded halting.
The code for BHalt(s,func,x) opens a new thread, which executes func on input x. For those unfamiliar
with the notion of threads, you may think of it as another program that runs in parallel to the main
program. Since func itself may invoke BHalt(s,func,x), the code uses a global counter, used to prevent
the opening of more than one thread at a time. If func halted on x within s seconds, a corresponding
message "Execution ended" is printed, and the value True is returned. If func did not halt on x within s
seconds, a corresponding message "Execution did not end" is printed, and the value False is returned.
You are NOT asked to explain the inner working of the threads mechanism.
Benny is not impressed. He wrote down a modified version of modify(f). This version is quite similar to
the one presented in class, only it has an additional parameter s (default set to 10 seconds), and calls
BHalt(s,f,f). In addition, if an infinite loop is entered, successive integers are printed, one per iteration,
starting with 0.
Benny claims that running the new modify on itself will lead to a contradiction, resulting in the
processor melting down, the hard disk going up in flames, or some other disaster along these lines.
YOU be the judges: Load the attached code. Then, in IDLE, execute
>>> modify(modify)
(When re-running the code, don't forget to set the global counter back to 0.)
1. Explain in words what happened (which function called which function? by the printouts, what
does modify(modify) do? Does it halt in s=10 seconds? will anything change if you use s=20
instead?).
2. Does this prove that the bounded halting problem is not solvable as Benny claims? in other words,
is Benny's argument valid for the bounded halting problem (as it was, in class, for the halting
problem)?
3. Is the bounded halting problem solvable or not? explain.
5 ‫ מתוך‬5 ‫עמוד‬