Rumah > pembangunan bahagian belakang > Tutorial Python > Laporan AoC &#Day Red-Nosed (C# dan Python)

Laporan AoC &#Day Red-Nosed (C# dan Python)

Mary-Kate Olsen
Lepaskan: 2024-12-07 21:02:15
asal
963 orang telah melayarinya

AoC

Penyelesaian Hari ini adalah lebih kompleks sedikit daripada hari sebelumnya yang menjamin lebih sedikit kod, tetapi bagaimanapun ia agak lurus ke hadapan.

Konsep asas penyelesaian:

Untuk menjadi sah, syarat berikut untuk Bahagian 1 mesti dipenuhi:

  • Kita perlu memutuskan sama ada bilangannya semakin meningkat, atau berkurangan dari satu ke seterusnya.

  • jurang antara nombor tidak boleh lebih daripada 3

Bahagian 1

var reports = File.ReadAllLines("./input1.txt")
    .Select(x => x.Split(" "))
    .ToList();

Part1(reports);

void Part1(List<string[]> input)
{
    var validReports = input
        .Select(report => report.Select(int.Parse).ToList())
        .Count(IsValidReport);

    Console.WriteLine(validReports);
}

bool IsValidReport(List<int> levels)
{
    // We don't care about the numbers, just wether going up or down, not both
    var isIncreasing = IsIncreasing(levels);
    var isDecreasing = IsDecreasing(levels);

    if (!isIncreasing && !isDecreasing) return false;

    // Check that all adjacent levels differ by at least 1 and at most 3
    for (var i = 0; i < levels.Count - 1; i++)
    {
        var diff = Math.Abs(levels[i + 1] - levels[i]);
        if (diff is < 1 or > 3)
        {
            return false;
        }
    }

    return true;
}

bool IsIncreasing(List<int> numbers)
{
    for (var i = 1; i < numbers.Count; i++)
    {
        if (numbers[i] < numbers[i - 1]) return false;
    }

    return true;
}

bool IsDecreasing(List<int> numbers)
{
    for (var i = 1; i < numbers.Count; i++)
    {
        if (numbers[i] > numbers[i - 1]) return false;
    }

    return true;
}

Salin selepas log masuk
Salin selepas log masuk

Penjelasan mudah, ialah kami menggunakan LINQ menghuraikan nombor rentetan kepada integer sebelum menghantar laporan kepada kaedah IsValidReport() pembantu kami.

Kaedah ini menyemak sama ada semua nombor sama ada meningkat atau berkurangan. Ini dilakukan dengan membandingkan id dengan senarai tersusun, yang akan membuktikan semua nombor menuju ke satu arah.

Sebaik sahaja kami tahu mereka semua berada dalam satu arah (bukan band) kami boleh menyemak sama ada setiap nombor berada dalam lingkungan 3 nombor antara satu sama lain. Menggunakan kaedah Math.Abs(), yang mengembalikan nombor mutlak, membantu kami mengambil kira angka tolak.

Nota: nombor mutlak, ialah nombor antara nombor dan sifar, iaitu -5 dan 5 akan mengembalikan 5;

Bahagian 2

Untuk Bahagian 2, kami mempunyai arahan yang sama ada lebih kompleks, tetapi kedengarannya lebih sukar daripada yang sebenarnya.

Bahagian kedua memperkenalkan kaveat kesilapan manusia, dengan konsep asas yang perlu anda ketahui jika anda boleh mengalih keluar mana-mana 1 item daripada laporan dan ia masih akan dianggap sebagai laporan yang sah.

void Part2(List<string[]> input)
{
    var validReports = 0;

    foreach (var ints in input.Select(report => report.Select(int.Parse).ToList()))
    {
        // If valid as-is, count it
        if (IsValidReport(ints))
        {
            validReports++;
            continue;
        }

        // Check if removing any single level makes it valid
        if (ints.Select((t, i) => ints.Where((_, index) => index != i).ToList())
            .Any(IsValidReport))
        {
            validReports++;
        }
    }

    Console.WriteLine(validReports);
}
Salin selepas log masuk

Di sini kami memaksimumkan kuasa LINQ, menghuraikan laporan rentetan, serta menggunakannya untuk mengubah suai tatasusunan ints. Kami mengubah suai dengan menggelung melalui tatasusunan dan mengalih keluar item semasa pada indeks, sekali gus mengubah suai tatasusunan int.

Setelah diubah suai, kami menjalankan laporan yang diubah suai melalui pengesah. Ini boleh dilakukan sekali gus menggunakan kaedah LINQ Select(), digabungkan dengan Any() yang akan litar pintas sebaik sahaja syarat dipenuhi (iaitu sebaik sahaja laporan yang diubah suai sah).

Mengapa hanya menyemak satu laporan diubah suai yang sah?

Ini kerana ia menyatakan jika mana-mana satu item boleh dialih keluar maka laporan tersebut boleh dianggap sah. Ia tidak menyatakan item tertentu, jadi sebaik sahaja kami menemui item sepadan yang apabila dialih keluar bermakna laporan itu sah, kami boleh berhenti melihat semua yang lain.

Kami kemudian menambah kaunter Laporan yang sah, untuk menjejaki laporan kami yang sah.

Inilah percubaan saya untuk menukar ini kepada Python:

def main():
    # Read the input file and split each line into a list of strings
    with open("./input1.txt") as file:
        reports = [line.split() for line in file]

    part1(reports)
    part2(reports)


def part1(reports):
    # Count valid reports using a list comprehension and the IsValidReport function

    valid_reports = 0
    for report in reports:
        levels = list(map(int, report))

        if is_valid_report(levels):
            valid_reports += 1

    print(valid_reports)


def part2(reports):
    valid_reports = 0

    for report in reports:
        ints = list(map(int, report))

        # If valid as-is, count it
        if is_valid_report(ints):
            valid_reports += 1
            continue

        # Check if removing any single level makes it valid
        valid_with_dampener = False

        # Iterate over each element in ints
        for i in range(len(ints)):
            # Create a new list without the element at index i
            modified_report = [x for j, x in enumerate(ints) if j != i]

            # Check if the modified report is valid
            if is_valid_report(modified_report):
                valid_with_dampener = True
                break

        if valid_with_dampener:
            valid_reports += 1

    print(valid_reports)


def is_valid_report(levels):
    # Check if the sequence is either all increasing or all decreasing
    is_increasing = is_increasing_sequence(levels)
    is_decreasing = is_decreasing_sequence(levels)

    if not is_increasing and not is_decreasing:
        return False

    # Check that all adjacent levels differ by at least 1 and at most 3
    for i in range(len(levels) - 1):
        diff = abs(levels[i + 1] - levels[i])
        if diff < 1 or diff > 3:
            return False

    return True


def is_increasing_sequence(numbers):
    for i in range(1, len(numbers)):
        if numbers[i] < numbers[i - 1]:
            return False
    return True


def is_decreasing_sequence(numbers):
    for i in range(1, len(numbers)):
        if numbers[i] > numbers[i - 1]:
            return False
    return True


if __name__ == "__main__":
    main()

Salin selepas log masuk

Untuk penyelesaian yang kurang bertele-tele, kami boleh menggantikan bahagian dalam untuk gelung dengan pengubahsuaian dan penyemakan , seperti yang kami lakukan dengan LINQ dalam penyelesaian C#, seperti:

var reports = File.ReadAllLines("./input1.txt")
    .Select(x => x.Split(" "))
    .ToList();

Part1(reports);

void Part1(List<string[]> input)
{
    var validReports = input
        .Select(report => report.Select(int.Parse).ToList())
        .Count(IsValidReport);

    Console.WriteLine(validReports);
}

bool IsValidReport(List<int> levels)
{
    // We don't care about the numbers, just wether going up or down, not both
    var isIncreasing = IsIncreasing(levels);
    var isDecreasing = IsDecreasing(levels);

    if (!isIncreasing && !isDecreasing) return false;

    // Check that all adjacent levels differ by at least 1 and at most 3
    for (var i = 0; i < levels.Count - 1; i++)
    {
        var diff = Math.Abs(levels[i + 1] - levels[i]);
        if (diff is < 1 or > 3)
        {
            return false;
        }
    }

    return true;
}

bool IsIncreasing(List<int> numbers)
{
    for (var i = 1; i < numbers.Count; i++)
    {
        if (numbers[i] < numbers[i - 1]) return false;
    }

    return true;
}

bool IsDecreasing(List<int> numbers)
{
    for (var i = 1; i < numbers.Count; i++)
    {
        if (numbers[i] > numbers[i - 1]) return false;
    }

    return true;
}

Salin selepas log masuk
Salin selepas log masuk

Tetapi saya rasa anda boleh bersetuju, kaedah verbose dengan pembolehubah bernama yang lebih bagus adalah lebih mudah dibaca.

Terima kasih kerana membaca, sertai saya lagi esok, dan seperti biasa hantarkan saya ikuti di twitter

Atas ialah kandungan terperinci Laporan AoC &#Day Red-Nosed (C# dan Python). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan