בכמה דרכים ניתן לשלם על הנסיעה במונית השירות?

10/07/2013

אין תגובות

בשלוש דרכים אישה נקנית – כך פסקו חז"ל, אך מה בדבר נסיעה במונית שירות?
מדי יום אני נוסע הלוך ושוב, מחיר הנסיעה הסטנדרטי הוא 6 ₪, חלק מהנוסעים משלמים בשני מטבעות – של 5 ₪ ושל 1 ₪, אחרים בשישה מטבעות של 1 ₪, ויש כמובן עוד אפשרויות.
ננסה למצוא את כולן:

Declare @N Int=600;

With Mt As

(Select 10 V Union All

Select 50 V Union All

Select 100 V Union All

Select 200 V Union All

Select 500 V Union All

Select 1000 V),

T as

(Select V,

        Cast(V As Varchar(Max)) Vs,

        @N-V V1

From    Mt

Where   V<=@N

Union All

Select  Mt.V,

        T.Vs+','+Cast(Mt.V As Varchar(Max)) Vs,

        T.V1-Mt.V V1

From    T

Inner Join Mt

        On T.V1>=Mt.V

        And T.V>=Mt.V)

Select  *

From    T

Where   V1=0

option (MaxRecursion 0);

clip_image002

האפשרות הראשונה היא כאמור לשלם בשני מטבעות של 5 ₪ ו-1 ₪,

השניה – בשלושה מטבעות: אחד של 5 ₪ ושניים של 50 אגורות,

וכך הלאה – 88 אפשרויות כשהאחרונה והמעט משעשעת היא ב-60 מטבעות של 10 אגורות..

השליפה כוללת את הסט Mt של המטבעות והשטרות השונים המקובילים כיום בארץ – ממטבע בן 10 אגורות וכלה בשטר בן 200 ₪ (נכון לקיץ 2013), ואחריו ה-CTE הרקורסיבי T בו מחפשים מטבעות שאינם גדולים בערכם ממה שנותר עדיין לשלם (T.V1>=Mt.V), ולמען הסדר הטוב ומניעת כפילויות – המטבעות יהיו בסדר יורד של ערכים (T.V>=Mt.V) וכך לא נקבל גם 5+1 וגם 1+5..

עד כאן לגבי מי שיש לו סכום מדוייק ולא צריך לתת לו עודף (V1=0).

מה קורה עם מי שאין לו כסף קטן? הלוא יש מי שמשלמים במטבע של 10 ₪ ואפילו שטר בן 200 ₪ ומקבלים עודף..

זה קצת מסבך את הסיפור: יש לאפשר לשלם יותר ממה שנותר לשלם, אך רק בתנאי שמה שנותר לשלם הוא מספר חיובי. כלומר- למטבע בן 5 ₪ (עדיין חסר כסף..) ניתן להוסיף מטבע נוסף בן 5 ₪ ולצפות לעודף, אך למטבע בן 10 ₪ (כבר עברנו את מחיר הכרטיס) לא ניתן להוסיף עוד מטבע בן 5 ₪ (נניח) מכיוון שהמטבע הזה מיותר.

Declare @N Int=600;

With    Mt As

(Select 10 V Union All

Select  50 V Union All

Select  100 V Union All

Select  200 V Union All

Select  500 V Union All

Select  1000 V Union All

Select  2000 V Union All

Select  5000 V Union All

Select  10000 V Union All

Select  20000 V),

T as

(Select V,

        Cast(V As Varchar(Max)) Vs,

        @N-V V1

From    Mt

Union All

Select  Mt.V,

        T.Vs+','+Cast(Mt.V As Varchar(Max)) Vs,

        T.V1-Mt.V V1

From    T

Inner Join Mt

        On T.V>=Mt.V

        And T.V1>0)

Select  *

From    T

Where   V1<=0

option  (MaxRecursion 0);

clip_image004

הפעם יש 95 אפשרויות, כש-7 האפשרויות שהתווספו ל-88 הקודמות מופיעות בצילום המסך המצורף, ועמודה 1V לנוחות הנהג והנוסעים – מציינת כמה עודף יש לתת, מה שמחייב להריץ את השאילתה הראשונה שוב – בהנחה שהנהג נותן עודף מדוייק.

למשל- הנוסע נותן מטבע בן 10 ₪ (האפשרות הראשונה מצילום המסך הנ"ל של השליפה השנייה),

וכעת הנהג מריץ את השליפה הראשונה עבור 4 ₪ עודף, ומקבל 35 אפשרויות – החל משני מטבעות של 2 ₪ וכלה ב-40 מטבעות של 10 אגורות.

זה הכל? לא: הרבה פעמים קורה שנוסע מעביר מטבע של 10 ₪, והנהג שואל אם יש לו 1 ₪ כדי לעזור לו (לנהג) עם העודף כך שיחזיר מטבע של 5 ₪. כיצד נייצג מצבים אפשריים כאלה?

למעשה מדובר פה בתהליך איטרטיבי בו הנוסע שילם 10 והנהג צריך להחזיר לו 4,

כעת הנהג משלם 5 והנוסע צריך להחזיר לו 1,

ולבסוף הנוסע מעביר 1 ₪ והכל מסתדר.

לשם כך נצטרך להוסיף עוד תיקון קוסמטי לשליפה השנייה כדי לוודא שאנחנו מתכנסים ושהנהג שקיבל 10 לא יחזיר גם הוא 10 (או גרוע מכך – שטר של 200..) אלא סכום קטן יותר מזה שקיבל:

Declare @N1 Int=400,

        @N0 Int=1000;

With Mt As

(Select 10 V Union All

Select  50 V Union All

Select  100 V Union All

Select  200 V Union All

Select  500 V Union All

Select  1000 V Union All

Select  2000 V Union All

Select  5000 V Union All

Select  10000 V Union All

Select  20000 V),

T as

(Select V,

        Cast(V As Varchar(Max)) Vs,

        @N1-V V1

From    Mt

Where   V<@N0

Union All

Select  Mt.V,

        T.Vs+','+Cast(Mt.V As Varchar(Max)) Vs,

        T.V1-Mt.V V1

From    T

Inner Join Mt

        On T.V>=Mt.V

        And T.V1>0)

Select  *

From    T

Where   V1<=0

option  (MaxRecursion 0);

clip_image006

לנהג יש כעת 36 אפשרויות כיצד להחזיר 4 ₪ שכוללות בנוסף ל-35 הנ"ל גם אופציה של מטבע בן 5 ₪,

הנוסע יריץ את השליפה האחרונה עם הפרמטרים @N1=100, @N2=500 ויקבל 5 אפשרויות כיצד לשלם 1 ₪

שאחת מהן – כדי לסבך את הסיפור – היא במטבע של 2 ₪,

ואת מה שנותר – 1 ₪ – הנהג כבר יצטרך להחזיר במדוייק.

כמובן שאין פירוש הדבר שתוך כדי נסיעה הכסף יעבור הלוך ושוב בין הנהג לנוסע, אלא הדברים יתנהלו כך:

הנוסע יעביר 10 ₪,

הנהג ישאל אותו אם יש לו 1 ₪,

הנוסע יומר שיש לו 2 ₪,

הנהג יאשר ויחזיר לו 6 ₪ במטבע של 5 ₪ ועוד 1 ₪ לפי איך שימצא לנכון.

דרך צלחה ותודה שנסעתם במונית השירות!

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *