אתגר Advent Of Code יום שני

תראה את הפלט זה איזה מספר הוא חילק באיזה , והוסיף את המנה של החילוק לרס
לטבלה הזו
5 9 2 8
9 4 7 3
3 8 6 5
בשורה השנייה זה רס אחרי שהוספת לו את מנת החחילוק אתה רואה שהוא הוסיף
נגיד פה
(5, 5)
1
הוא חילק את חמש בחמש ואת המנה שהיא אחד הוסיף לרס
שורה אחכ
(9, 9)
2
הוא חילק את תשע בעצמו ואז המנה (אחד) נוספה לרס והוא כבר נהיה 2

עוד בעיה בקוד שלך שאחרי שהוא מוצא מתחלקים ללא שארית בשורה אחת הוא אמור ללכת לשורה הבאה

בשביל זה השתמשתי בלולאת while
אבל את החלק הראשון של דבריך לא הבנתי

לקחתי את הקוד שלך

 if num % lst[index] == 0:
                    print(num,lst[index])
                    res += num / lst[index]
                    print(res)

הוספתי לו הדפסות כפי שאתה רואה
הפעלתי אותו על הדוגמא הזו
5 9 2 8
9 4 7 3
3 8 6 5
והפלט הוא כפי שהבאתי למעלה
שים לב הוא מדפיס רק כשהתנאי חיובי

שבת שלום

בכל שורה אתה בודק אם יש מספר שמתחלק במספר אחר ללא שארית. ניקח שורה לדוגמה:

[1,2,3,4]

תחילה נבדוק אם 1 מתחלק בשאר המספרים, כלומר אינדקס 0 מול אינדקסים 1-3.
לאחר מכן נבדוק אם 2 מתחלק בשאר המספרים, כלומר אינדקס 1 מול אינדקסים 0, 2-3.
וכן הלאה, כלומר עבור כל בדיקה יש לבדוק ש-index שונה מהאינדקס של num.

כן הבנתי אבל עוד לא הצלחתי למצוא את התנאי שמדלג על האינדקס של num
זה מה שתוקע אותי

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

ניסיתי את זה
ללא הועיל

path_r = r"C:\Python\Advent_of_code\exercise_2.txt"
res = 0
index = 0
with open(path_r,"r") as f_r:
    arr = [line.split() for line in f_r]

    for lst in arr:
        lst = map(int,lst)
        for num in lst:
            while True:
                index = (index + 1) % len(lst)
                if num % lst[index] == 0 and num / lst[index] != num / num:
                    res += num / lst[index]
                    break

print res


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

לייק 1

כדי לא לבדוק מספר מול עצמו, נרצה לדלג על האינדקס של הערך הנבדק, כלומר עבור הערך הראשון נדלג על אינדקס 0, עבור הערך השני נדלג על אינדקס 1 וכן הלאה.

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

for num in lst:
    while True:

הרצתי אצלי עם הדפסות, נראה שלא ממשיכים לערך הבא בשורה מכיוון שלולאת ה-while לא עוצרת בסוף השורה אם לא נמצאה חלוקה למספר הנבדק מהשורה.

לייק 1

תודה, אנסה לתקן זאת אח"כ

לייק 1

הי כולם,

@miryeh תיקנתי על פי מה שהצעת(הוספתי תנאי יציאה מה while במידה ולא נמצאה חלוקה למספר הנבדק מהשורה) וזה אכן עובד - תודה רבה !!!

ותודה לכל המסייעים בדרך !


path_r = r"C:\Python\Advent_of_code\exercise_2.txt"
res = 0
index = 0
with open(path_r,"r") as f_r:
    arr = [line.split() for line in f_r]

    for lst in arr:
        lst = map(int,lst)
        for num in lst:
            while True:
                index = (index + 1) % len(lst)
                if num % lst[index] == 0 and num / lst[index] != num / num:
                    res += num / lst[index]
                    break
                if lst[index] == lst[-1]:
                    break
print res
לייק 1

הלכתי לפי התגובה שהגבת לי בתרגיל הראשון ובהחלט עושה סדר בראש לפרק לתת בעיות קטנות:

  1. הפיכת כל שורה לאיבר במערך
  2. הפיכת כל איבר במערך למערך של מספרים (כמספר או כמחרוזת)
  3. מיון על מנת לשמור את המינ והמקס בהתחלה ובסוף (ראיתי פה עוד דרכים אבל מבחינת כתיבה הסתדר לי)
  4. צמצום למי ומקס
  5. מציאת הפרש
  6. סכימה

5-4 אפשר היה לעשות בצעד אחד, אבל למען הפירוק של תתי הבעיות ניסיתי שיהיה נקי יותר לקריאה

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

function getCheckSum(input){
	return input
		.split('\n') // 1
		.map(line => line.split('\t')) // 2
		.map(line => line.sort((a,b) => a - b)) // 3
		.map(line => [line[0], line[line.length-1]]) // 4
		.map(line => Number(line[1]) - Number(line[0])) // 5
		.reduce((acc, cur) => acc + cur, 0); // 6
}

הרבה יותר קריא!

אני חושב שאם מתחיל בלהפוך הכל למספרים היית יכול לוותר על הפרמטרים ל sort (ולעבוד עם מיון ברירת המחדל של מספרים)

ועוד אגב זה שאני אוהב לקחת את האיבר האחרון עם slice:

line[line.length - 1] == line.slice(-1)

והטריק הכי אהוב עליי בהקשר הזה נקרא Destructuring כי הוא עוזר לשבור את line אוטומטית כלומר שאפשר לכתוב:

.map(([min, max]) => max - min) // 5

ואפשר גם להגדיר קצת פונקציות עזר ואז מקבלים:

Array.prototype.sum = function() {
  return this.reduce((acc, val) => acc + val, 0);
};

Array.prototype.toNumericArray = function() {
  return this.map(x => Number(x));
}

function getCheckSum(input){
  return input
    .split('\n') // 1
    .map(line => line.split('\t')) // 2
    .map(line => line.toNumericArray())
    .map(line => line.sort()) // 3
    .map(line => [line[0], line.slice(-1)]) // 4
    .map(([min, max]) => max - min) // 5
    .sum()
}

console.log(getCheckSum("5\t1\t9\t5\n7\t5\t3\n2\t4\t6\t8"));

ועוד אגב-

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

function allPairs() { ... }

של מערך שמחזירה מערך עם כל הזוגות. אחרי שאתה כותב אותה החלק השני נהיה ממש פשוט

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

לייק 1

רק עוד דבר אחד, המיון ללא פונקציית הקומפייר לא עובד על מספרים הוא ממיין לפי UNICODE. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters

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

היי ינון, הבנתי למה המרת למספרים, אבל כנראה לא הבהרתי את עצמי,

[1,11,2].sort() is not [1,2,11]