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

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

 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]

אויש כן אני רואה עכשיו הטעות לגמרי שלי … שפה קשה JavaScript

לייק 1

שוב, מוסיף פתרונות של 2017:

import itertools
from operator import floordiv


def parse(s):
    for line in s.splitlines():
        yield [int(x) for x in line.split()]


def f(s):
    return sum(max(row) - min(row) for row in parse(s))


assert f("""5 1 9 5
7 5 3
2 4 6 8""") == 18


def divisible(a):
    for a, b in itertools.combinations(a, 2):
        if b % a == 0:
            return b, a


assert divisible([2, 5, 8, 9]) == (8, 2)
assert divisible([3, 4, 7, 9]) == (9, 3)


def f2(s):
    return sum(floordiv(*divisible(sorted(row))) for row in parse(s))


assert (f2("""5 9 2 8
9 4 7 3
3 8 6 5
""")) == 9

INPUT = """6046	6349	208	276	4643	1085	1539	4986	7006	5374	252	4751	226	6757	7495	2923
1432	1538	1761	1658	104	826	806	109	939	886	1497	280	1412	127	1651	156
244	1048	133	232	226	1072	883	1045	1130	252	1038	1022	471	70	1222	957
87	172	93	73	67	192	249	239	155	23	189	106	55	174	181	116
5871	204	6466	6437	5716	232	1513	7079	6140	268	350	6264	6420	3904	272	5565
1093	838	90	1447	1224	744	1551	59	328	1575	1544	1360	71	1583	75	370
213	166	7601	6261	247	210	4809	6201	6690	6816	7776	2522	5618	580	2236	3598
92	168	96	132	196	157	116	94	253	128	60	167	192	156	76	148
187	111	141	143	45	132	140	402	134	227	342	276	449	148	170	348
1894	1298	1531	1354	1801	974	85	93	1712	130	1705	110	314	107	449	350
1662	1529	784	1704	1187	83	422	146	147	1869	1941	110	525	1293	158	1752
162	1135	3278	1149	3546	3686	182	149	119	1755	3656	2126	244	3347	157	865
2049	6396	4111	6702	251	669	1491	245	210	4314	6265	694	5131	228	6195	6090
458	448	324	235	69	79	94	78	515	68	380	64	440	508	503	452
198	216	5700	4212	2370	143	5140	190	4934	539	5054	3707	6121	5211	549	2790
3021	3407	218	1043	449	214	1594	3244	3097	286	114	223	1214	3102	257	3345"""

print(f(INPUT))
print(f2(INPUT))