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

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

להלן הפתרון שלי ב Python

path_r = r"C:\Python\Advent_of_code\exercise_2.txt"
res = 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)
        res += max(lst) - min(lst)

print res

ותודה לספלינטור על הסבר השאלה

2 לייקים

חלק 2

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

לדוגמא עבור הקלט:

5 9 2 8
9 4 7 3
3 8 6 5

בשורה הראשונה 8 מתחלק ב-2 ללא שארית והתוצאה 4.
בשורה השניה 9 מתחלק ב-3 ללא שארית והתוצאה 3.
בשורה השלישית 6 מתחלק ב-3 ללא שארית והתוצאה 2.
סה״כ סכום התוצאות 4+3+2 נותן 9 ולכן זוהי ספרת הביקורת שלנו.

עדכנו את התוכניות שכתבתם כך שיחשבו את ספרת הביקורת לפי השיטה החדשה.

function checksum2(s) {
    return s.split(/[\r\n]+/)
        .map(l => l.split(/\W+/))
        .reduce((acc, l) => acc +
            l.reduce((lineAcc, item, index) => lineAcc ||
                l.reduce((innerAcc, innerItem, innerIndex) => index !== innerIndex && item % innerItem === 0 ? item / innerItem : innerAcc, 0), 0), 0);
}
לייק 1

אין ספק שהלכת עד הקצה (ואולי טיפה אחרי :slight_smile: ) עם ה reduce כאן… נדמה לי שיצא יותר קריא אם חלק מהקוד הפנימי יוגדר כפונקציה בפני עצמו

זה יותר טוב…? :smile:

function findQuota(line, itemToDivide, itemToDivideIndex) {
    return line.reduce((acc, item, index) => itemToDivideIndex !== index && itemToDivide % item === 0 ? itemToDivide / item : acc, 0);
}

function checksum2(s) {
    return s.split(/[\r\n]+/).map(l => l.split(/\W+/)).reduce((acc, l) => acc + l.reduce((lineAcc, item, index) => lineAcc || findQuota(l, item, index), 0), 0);
}

אני חושב שיותר מדויק לכוון למגבלה של 80 תווים בשורה. אתה כרגע על 160…

לייק 1

אני כבר מחכה לחידה השלישית

2 לייקים

איך זה?

function checksum2(s) {
    function findQuota(line, itemToDivide, itemToDivideIndex) {
        return line.reduce((acc, item, index) =>
            itemToDivideIndex !== index && itemToDivide % item === 0
                ? itemToDivide / item : acc, 0);
    }

    function lineQuota(line) {
        return line.reduce((lineAcc, item, index) =>
            lineAcc || findQuota(line, item, index), 0);
    }

    const parsedLines = s.split(/[\r\n]+/).map(l => l.split(/\W+/));
    return parsedLines.reduce((acc, line) => acc + lineQuota(line), 0);
}

עדיין מבלבל אבל לפחות לא צריך לגלול ימינה :slight_smile:

פיתרון שלי ב Ruby לחלק השני:

res = 0

ARGF.each_line do |line|
  values = line
    .split
    .map(&:to_i)
    .combination(2)    
    .select {|i, j| i % j == 0 || j % i == 0}
    .flatten
  
  res += values.max / values.min
end

puts res

חלק ב
זה לא עובד

לא מצליח להבין למה התנאי :if num % lst[index] == 0 מתקיים תמיד…

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:
                    res += num / lst[index]
                    break

print res






מה הערכים של num, lst ו index שעבורם זה מתקיים (ושאתה חושב שלא בצדק) ?

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

הוא מחלק גם 5 ב5 והשארית באמת 0 צריך להוסיף תנאי לזה

לא הבנתי
השמשתי בשיטה שינון הציע עם האינדקסים.

אני חושב שהבעיה שאתה לא ״מדלג״ על הערך הנוכחי

לדוגמא אם השורה היא:

9 - 5 - 3 - 1

אז אתה בודק אם תשע מתחלק בכל הארבעה כשבעצם צריך לבדוק רק אם הוא מתחלק באחרים (ב 5, 3 ו 1). כל מספר הרי מתחלק בעצמו

בדיוק זה הפלט שלו

(5, 5)
1
(9, 9)
2
(2, 2)
3
(8, 8)
4
(9, 9)
5
(4, 4)
6
(7, 7)
7
(3, 3)
8
(3, 3)
9
(8, 8)
10
(6, 6)
11
(5, 5)
12
12

הוא מדפיס את נאם ואינדקס ואז את רס והכל בתוך התנאי לדוגמא שהובאה בפוסט

לייק 1

למה לא מדלג?
num מתחיל באינדקס 0 ואני מחלק אותו באינדקס 1 (כלומר מפעל עליו מודולו)

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

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

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