Heim > Backend-Entwicklung > Python-Tutorial > Erklimmen eines Tiefensuchhügels, Advent of Code, Tag 10

Erklimmen eines Tiefensuchhügels, Advent of Code, Tag 10

Patricia Arquette
Freigeben: 2025-01-13 14:09:43
Original
330 Leute haben es durchsucht

Die heutige Herausforderung befasst sich mit dem Rätsel von Tag 10, einem 2D-Gitter ähnlich wie Tag 6, erfordert jedoch die Erkundung mehrerer Pfade. Dieses Rätsel demonstriert auf elegante Weise die Leistungsfähigkeit der Tiefensuche (DFS).

Climbing a depth-first search hill, Advent of Code day 10
Eine KI-generierte Illustration des Puzzles

Die Karte wird als Wörterbuch dargestellt; Schlüssel sind (x, y)-Koordinaten und Werte sind einstellige Ganzzahlen (0-9), die die Höhe angeben, wobei 9 den Gipfel darstellt. Die Parsing-Funktion verarbeitet diese Datenstruktur effizient:

<code class="language-python">def parse(input: str) -> dict[tuple[int, int], int | None]:
    return {
        (x, y): int(item) if item.isdigit() else None
        for y, row in enumerate(input.strip().splitlines())
        for x, item in enumerate(row)
    }</code>
Nach dem Login kopieren

Wege steigen vom Ausgangspunkt (Höhe 0) bis zum Gipfel (Höhe 9) an und erhöhen die Höhe um genau 1 pro Schritt. Die Funktion next_step identifiziert gültige nächste Schritte:

<code class="language-python">TRAIL_MAX = 9

def next_step(
    topo_map: dict[tuple[int, int], int | None], x: int, y: int
) -> tuple[tuple[int, int], ...]:
    assert topo_map[(x, y)] != TRAIL_MAX

    return tuple(
        incoming
        for incoming in (
            (x + 1, y),
            (x, y + 1),
            (x - 1, y),
            (x, y - 1),
        )
        if (
            isinstance(topo_map.get(incoming), int)
            and isinstance(topo_map.get((x, y)), int)
            and (topo_map[incoming] - topo_map[(x, y)] == 1)
        )
    )</code>
Nach dem Login kopieren

Wanderwege (Höhe 0) werden mit find_trailheads:

lokalisiert
<code class="language-python">TRAILHEAD = 0

def find_trailheads(
    topo_map: dict[tuple[int, int], int | None],
) -> tuple[tuple[int, int], ...]:
    return tuple(key for key, value in topo_map.items() if value == TRAILHEAD)</code>
Nach dem Login kopieren

Kern der Lösung ist die climb-Funktion, die eine Tiefensuche implementiert. Gemäß der Wikipedia-Definition von DFS untersuchen wir jeden Zweig vollständig, bevor wir einen Rückzieher machen.

Climbing a depth-first search hill, Advent of Code day 10
Eine visuelle Darstellung der Tiefensuche

Kartenpunkte sind unsere „Knotenpunkte“, und wir steigen jeweils eine Höhenstufe auf. Die Funktion climb verwaltet den DFS-Prozess:

<code class="language-python">def climb(
    topo_map: dict[tuple[int, int], int | None], trailheads: tuple[tuple[int, int], ...]
) -> dict[
    tuple[tuple[int, int], tuple[int, int]], tuple[tuple[tuple[int, int], ...], ...]
]:
    candidates: list[tuple[tuple[int, int], ...]] = [(head,) for head in trailheads]

    result = {}

    while candidates:
        current = candidates.pop()
        while True:
            if topo_map[current[-1]] == TRAIL_MAX:
                result[(current[0], current[-1])] = result.get(
                    (current[0], current[-1]), ()
                ) + (current,)
                break

            elif steps := next_step(topo_map, *current[-1]):
                incoming, *rest = steps

                candidates.extend([current + (step,) for step in rest])

                current = current + (incoming,)
            else:
                break

    return result</code>
Nach dem Login kopieren

Das else der break-Klausel behandelt Sackgassen und verhindert so Endlosschleifen. Die Funktion gibt alle Pfade von jedem Ausgangspunkt zum Gipfel zurück.

Teil 1 zählt die einzigartigen Gipfelziele auf:

<code class="language-python">def part1(input: str) -> int:
    topo_map = parse(input)

    return len(climb(topo_map, find_trailheads(topo_map)))</code>
Nach dem Login kopieren

Teil 2 zählt alle eindeutigen Pfade:

<code class="language-python">def part2(input: str) -> int:
    topo_map = parse(input)

    return sum(
        len(routes) for routes in climb(topo_map, find_trailheads(topo_map)).values()
    )</code>
Nach dem Login kopieren

Obwohl es alternative Ansätze gibt (z. B. die Integration der Trailhead-Erkennung in das Parsing), ist die Leistung dieser Lösung akzeptabel. Die jüngsten Rückschläge bei der Jobsuche haben meine Stimmung nicht getrübt; Ich bleibe hoffnungsvoll. Wenn Sie auf der Suche nach einem Python-Entwickler mittlerer Führungsebene sind, wenden Sie sich bitte an uns. Bis nächste Woche!

Das obige ist der detaillierte Inhalt vonErklimmen eines Tiefensuchhügels, Advent of Code, Tag 10. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage