מבוא לתכנות ב-,JAVA סמסטר עבודת בית מספר 4: רקורסיה ב' תשע"ט מתרגל אחראי: אבי יצחקוב שעות קבלה: ימי שלישי, 10-12, בניין 37 חדר 111- תאריך פרסום: 21/05/19 מועד אחרון להגשה: 04/06/19 בשעה 23:55 הנחיות נוספות להגשה: יש לפתור ולהגיש את העבודות בזוגות בלבד )אין להגיש ביחידים(. בהגשת העבודה עליכם לפתוח קבוצת הגשה משותפת הכוללת את שני המגישים ב-.submission system תיאור המטלה: מטלה זו מורכבת ממשימות בלתי תלויות, בכל משימה עליכם לכתוב פונקציה רקורסיבית אחת או יותר לביצוע המשימה. לא יתקבלו פתרונות לא רקורסיביים עבור פונקציות שנדרשתם לכתוב עבורן פתרון רקורסיבי. הצגת תפריט למשתמש עליכם להציג למשתמש את התפריט הבא בתחילת התוכנית ובסיום כל טיפול בסעיף, עד אשר המשתמש יבחר באפשרות 0. אם המשתמש בחר באפשרות שאינה בתפריט, תודפס הודעת שגיאה option Error: invalid והתפריט יודפס שו אפשרות 0 בתפריט יציאה מהתוכנית בבחירת אפשרות זו, תוצג למשתמש ההודעה Exiting. והתוכנית תסתיים. דוגמת ריצה:
0 Exiting. אפשרות 1 בתפריט מספר הדרכים להצגת מספר כסכום חזקות בבחירת אפשרות זו, המשתמש נדרש להזין שני מספרים חיוביים ושלמים sum ו- n. התוכנית תמצא את מספר הדרכים להביע את num כסכום חזקות n -יות של מספרים טבעיים שונים. דוגמאות: עבור = 100 num ו- = 2 n הפלט יהיה 3 כי 100 ניתן להצגה כסכום של חזקות 2 בשלושה דרכים: 1 2 + 3 2 + 5 2 + 7 2 10 2 8 2 + 6 2 לעומת זאת עבור = 100 num ו - 3 = n הפלט יהיה 1 מכיוון שהדרך היחידה להציג את 100 כסכום של חזקות 3 היא: 1 3 + 2 3 + 3 3 + 4 3 השלימו את הפונקציה הרקורסיבית public static int countways(int num, int n, int i) שמקבלת שלושה מספרים חיוביים.num,,n i הפונקציה תחזיר את מספר הדרכים שבהן ניתן להציג את num כסכום חזקות n -יות של מספרים טבעיים שונים הגדולים שווים ל i. ניתן להשתמש בסעיף זה בפונקציה Math.pow(a,b) לצורך חישוב a. b השלימו את הפונקציה public static int countways(int num, int n) שמקבלת שני מספרים חיוביים.num, n הפונקציה תחזיר את מספר הדרכים שבהן ניתן להציג את num כסכום חזקות n -יות של מספרים טבעיים שונים. שימו לב, על הפונקציה בסעיף זה לבצע קריאה בודדת לפונקציה הרקורסיבית מסעיף א' )ללא קוד נוסף(. ג. הוסיפו קוד בפונקציה main המבצע את הפעולות הנדרשות באפשרות 1: התוכנית תקלוט מהמשתמש שני מספרים num, n - התוכנית תדפיס את מספר הדרכים להצגת num כסכום חזקות n -יות - דוגמת הרצה:
1 Enter a number: 100 Enter a power: 2 Number of ways is 3 אפשרות 2 בתפריט הסרת כפילויות עוקבות במחרוזת בבחירת אפשרות זו, המשתמש נדרש להזין מחרוזת. התוכנית תחפש במחרוזת הקלט רצפים המורכבים מאותו תו, ותחזיר מחרוזת חדשה המכילה תו אחד מכל רצף. דוגמאות: עבור הקלט: aaaaabcbcdd יודפס.abcbcd עבור aaaaaaa יודפס a. עבור aabbaabb יודפס abab השלימו את הפונקציה הרקורסיבית public static String removeduplicates(string str) שמקבלת כקלט מחרוזת str ומחזירה מחרוזת ללא כפילויות עוקבות. השלימו את הקוד בפונקציה main שמבצע את הנדרש באפשרות זו. התוכנית תקלוט מהמשתמש מחרוזת ותדפיס את המחרוזת ללא כפילויות. דוגמת ריצה:
2 Enter a string: aabbcc abc אפשרות 3 בתפריט מהלך מנצח במשחק "נים" רקע: "נים" הוא משחק אסטרטגיה לשני שחקנים שבו נתונה ערימה של גפרורים. בכל תור יכול שחקן לקחת 1 או 2 גפרורים מהערימה. המנצח במשחק הוא מי שלקח את הגפרור האחרון. דוגמא למשחק: עבור ערימה עם 5 גפרורים ושני שחקנים a,b שחקן a לוקח גפרור אחד )מצב הערימה: 4( שחקן b לוקח גפרור אחד )מצב הערימה: 3( )זהו מהלך מנצח של b כיוון שלא משנה מה שחקן a יעשה בתורו, שחקן b יכול לבצע מהלך נגדי שיגרום לו לנצח( שחקן a לוקח שני גפרורים )מצב הערימה: 1( שחקן b לוקח גפרור ומנצח. מהלך מנצח של שחקן א' הוא מהלך שמוביל למצב משחק שבו לכל בחירה של השחקן היריב ב' בתורות הבאים, יש לשחקן א' מהלך בתגובה שמוביל לכך שהוא ינצח תמיד. נבחן את הדוגמ כאשר b שיחק בפעם הראשונה היה לו מהלך מנצח )לקחת גפרור אחד( כיוון שזה הוביל למצב שבו לא משנה מה שחקן a יעשה בתורות הבאים, שחקן b תמיד יוכל לנצח. תיאור המשימה: בבחירת אפשרות זו, המשתמש יזין את גודל ערימת הגפרורים ונבדוק האם לשחקן הנוכחי )שזה התור שלו( יש מהלך שמוביל בוודאות לניצחון. השלימו את הפונקציה הרקורסיבית public static boolean haswinningmovenim(int n) שמקבלת את גודל הערימה n ומחזירה true אם ורק אם לשחקן הנוכחי )שזהו תורו( יש מהלך מנצח. השלימו את הקוד בפונקציה main שמבצע את הנדרש באפשרות זו: התוכנית תקלוט מהמשתמש את גודל הערימה - התוכנית תבדוק האם לשחקן הנוכחי יש מהלך מנצח ותדפיס פלט בהתאם: אם יש מהלך מנצח התוכנית - move!.has winning אחרת יודפס: move! No winning תדפיס דוגמת ריצה:
3 Enter size of heap: 4 Has winning move! אפשרות 4 בתפריט בעיית המשקולות עם בחירה מרובה של משקולות בבחירת אפשרות זו, המשתמש יזין מערך של משקולות, weights סכום sum ומספר k. התוכנית תבדוק האם ניתן להרכיב את sum בעזרת המשקולות במערך, weights כאשר ניתן להשתמש בכל משקולת 0 עד k )כולל( פעמים. בעיה זו דומה לדוגמא שראיתם בתרגול אך שונה ממנה. בבעיה שמוצגת בעבודה זו ניתן להשתמש בכל משקולת יותר מפעם אחת ואלו בבעיה שראיתם בתרגול ניתן להשתמש בכל משקולת לכל היותר פעם אחת )זהו מקרה פרטי של הבעיה המוצגת(. לדוגמא: עבור מערך משקולות {3,5,7}, סכום 13, ו -2=k התשובה היא כן וזאת מכיוון שניתן להרכיב את 13 בעזרת המשקולות 3,3,7. השלימו את הפונקציה הרקורסיבית: public static boolean calcweights(int[] weights, int sum, int k, int index) שמקבלת מערך של משקולות,weights מספר שלם חיובי,sum מספר שלם אי-שלילי k ואינדקס.index הפונקציה תחזיר true אם ורק אם ניתן להרכיב את הסכום sum מהמשקולות בתת-המערך weights[index weights.length-1] כך שכל משקולת מופיעה 0 עד k פעמים. השלימו את הפונקציה: public static boolean calcweights(int[] weights, int sum, int k) שמקבלת מערך של משקולות,weights מספר שלם חיובי,sum ומספר שלם אי-שלילי k. הפונקציה תחזיר true אם ורק אם ניתן להרכיב את הסכום sum מהמשקולות במערך weights כך שכל משקולת מופיעה 0 עד k פעמים.. שימו לב, על הפונקציה בסעיף זה לבצע קריאה בודדת לפונקציה הרקורסיבית מסעיף א' )ללא קוד נוסף(. הוסיפו קוד בפונקציה main שמבצע את הנדרש באפשרות זו: התוכנית תקלוט מהמשתמש מערך של משקולות,weights סכום,sum ומספר k. - התוכנית תבדוק האם ניתן להרכיב את sum מהמשקולות ב.weights - אם ניתן להרכיב את הסכום התוכנית תדפיס.true אחרת יודפס.false - דוגמת ריצה:
4 Enter weights array size: 3 Enter weights: 3 5 7 Enter sum: 13 Enter k: 2 true אפשרות 5 בתפריט מספר הדרכים לתשלום במכונת משקאות בסעיף זה נפתור את הבעיה הבאה: נתונה מכונת משקאות שמקבלת מטבעות מסוג שקל, 2 שקלים ו- 5 שקלים. נרצה לחשב את מספר הדרכים בהן ניתן לשלם סכום נתון כשבכל שלב מכניסים למכונה מטבע אחד מסוג כלשהו עד לתשלום כל הסכום. אולם, למכונה יש אילוץ: ברגע שהוכנס מטבע של 5, לא ניתן להכניסה מטבעות נוספים מסוג 5. במילים אחרות, ברגע שהוכנס מטבע מסוג, 5 ניתן לשלם את ההפרש שנותר אך ורק בעזרת מטבעות של 1 ו- 2. דוגמאות: את הסכום 5 ניתן לשלם ב 9 דרכים: 1,1,1,1,1 1,1,1,2 1,1,2,1 1,2,1,1 2,1,1,1 2,2,1 2,1,2 1,2,2 5 את הסכום 10 ניתן לשלם ב 127 אופנים. מספר אפשרויות זה אינו כולל תשלום בעזרת שני מטבעות של 5. ממשו את הפונקציה הרקורסיבית public static int paywithshekelandshnekel(int n) שמקבלת מספר טבעי n המייצג סכום, ומחזירה את מספר הדרכים לשלם סכום זה במכונת המשקאות בעזרת מטבעות של 1,2
ממשו את הפונקציה הרקורסיבית public static int pay(int n) שמקבלת מספר טבעי n המייצג סכום, ומחזירה את מספר הדרכים לשלם סכום זה במכונת המשקאות בעזרת מטבעות של 1,2,5 )תחת האילוץ שהוצג( ג. הוסיפו קוד בפונקציה main שמבצע את הנדרש באפשרות זו: התוכנית תקלוט מהמשתמש סכום ותחזיר את מספר הדרכים שניתן לשלם סכום זה בעזרת מטבעות של 1,2,5 תחת האילוץ: ברגע שהוכנס מטבע מסוג, 5 ניתן לשלם את ההפרש שנותר אך ורק בעזרת מטבעות של 1 ו- 2. 5 Enter sum: 5 Number of combinations is 9 דוגמת הרצה: אפשרות 6 בתפריט סכום טוטאלי של מספר בבחירת אפשרות זו, המשתמש יזין מספר טבעי והתוכנית תחשב את 'הסכום הטוטאלי' שלו. הגדרה: סכום טוטאלי של מספר נתון הוא מספר בין 1 ל- 9 שמתקבל ע"י סכימה רפטטיבית של הספרות עד שמתקבל מספר המורכב מספרה אחת. דוגמא: הסכום הטוטאלי של 1234567 הוא 1 כי: 1+2+3+4+5+6+7 =28 2+8=10 1+0=1 ממשו את הפונקציה הרקורסיבית public static int totalsum(long n) שמקבלת מספר טבעי n, ומחזירה את הסכום הטוטאלי שלו.
הוסיפו קוד בפונקציה main שמבצע את הנדרש באפשרות זו: התוכנית תקלוט מהמשתמש מספר טבעי ותחזיר את הסכום הטוטאלי שלו. שימו לב, עליכם לקלוט מספר מטיפוס long מהמשתמש. ניתן לבצע זאת ע"י קריאה ל- sc.nextlong() 6 Enter a number: 1234567 The total sum is 1 דוגמת ריצה: הערות 1. העבודות יוגשו בזוגות בלבד!. 2. פתרונות לא רקורסיביים עבור פונקציות שנדרשתם לספק עבורן פתרון רקורסיבי לא יתקבלו )ציון 0 למשימה המתאימה(. 3. כל יום איחור או חלק ממנו יהיה במחיר 10 נקודות, לדוגמא איחור ב 27 שעות יקנה ציון מקסימאלי של 80 לעבודה. 4. יש להגיש קובץ zip בשם zip.>id< כאשר >id< הוא מספר תעודת הזהות שלכם. בתוך הקובץ הנ"ל יהיה קובץ java בודד )ללא תיקיות( בשם Assignment4.java בדיוק. 5. ניתן להניח שבסוף הזנת הקלט המשתמש יקליד enter ולא כל כפתור אחר. 6. ניתן להניח שהמשתמש תמיד יקליד קלט חוקי, אלא אם כן צוין אחרת. 7. במטלה זו ניתן להשתמש אך ורק בפונקציות,לולאות, משפטי תנאי, מערכים )גם דו מימדיים( ומחרוזות. אין להשתמש בכל מבנה נתונים אחר וכל נושא שטרם נלמד. 8. העבודה צריכה להיות מוכלת בחבילת ברירת המחדל. כלומר בתחילת הקובץ שלכם לא אמור להופיע המשפט: package <name>; 9. באחריות כל סטודנט להתעדכן בשינויים/עדכונים באתר הקורס. 10. יש לשמור על הקוד במקום שנגיש אך ורק לכם, סיבות כגון מחשב שניזוק או דיסק און קי שנשרף לא יתקבלו כסיבות מוצדקות להגשת עבודה באיחור. 11. יש לתת שמות משמעותיים למשתנים, יש להעיר הערות ברורות ומבארות על העבודה, מרכיבים אלו הינם חלק מהניקוד על העבודה. 12. על ההערות להיות כתובות באנגלית בלבד מתומצתות ובשיקול דעת. 13. יש להקפיד שהעבודה תהיה קריאה. אין לכתוב שורות קוד ארוכות מאוד ויש להקפיד על הזחה )אינדנטציה(: על קטעי הקוד הנמצאים בתוך לולאה או if להיות מוזזים ימינה בtab. למידע נוסף על אינדנטציה ראה ערך https://en.wikipedia.org/wiki/indent_style 14. אין להשתמש בחומר שאינו נלמד בכיתה עד רגע פרסום התרגיל. בפרט אין להשתמש בכל ספריה, פונקציה, או כל קטע קוד אחר שלא הועבר בשיעור / תרגול עד לרגע הפרסום.
15. מומלץ לא לכתוב את כל הקוד ורק אז לקמפל ולדבג, אלא לכתוב חלק אחד ורק לאחר שחלק זה מקומפל ומדובג היטב להמשיך הלאה. 16. מומלץ לא לחכות לרגע האחרון ולהתחיל את העבודה בהקדם האפשרי. 17. שאלות בנוגע לעבודה יש לפרסם בפורום העבודה הנמצא באתר הקורס.לפני פרסום שאלה, יש לעבור על השאלות שכבר נענו בפורום ולוודא שהשאלה לא נשאלה כבר וקיבלה מענה.שאלות שישלחו למיילים של צוות הקורס או שאלות חוזרות לא יקבלו מענה.כמו כן, אין לשאול שאלות בנוגע לעבודה במהלך התרגול או בהפסקות.