国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home Backend Development Golang Advent of Code ay n Golang: Ordering Pages

Advent of Code ay n Golang: Ordering Pages

Dec 28, 2024 am 07:33 AM

Introduction

It is day 5 of the advent of code, and today we have an interesting problem of ordering pages. Let’s dive into the problem and how I approached it. It was a pretty simple problem if thought it peacefully, otherwise, it would get into a map, list, and indices mess.

You can check out my solutions here on GitHub.

Advent of Code ay n Golang: Ordering Pages Mr-Destructive / advent_of_code

Advent of Code

Input

In the input for day 5, we have two sections, The first defines the rules for ordering the pages, specifically which page should come before which and the second contains the actual order of pages.

47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13

75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

So, the first section has the rules mapped out, the other has the ordering of pages, and each line is a query or a list of pages as our actual data to process. We need to use it in the processing of parts 1 and 2.

Reading Sections

So, we need to parse these sections and read them in a data structure that could be easier to access.

One way to do that would be

  • A list with two sections

  • The first section will be a list

    • The list will be a list of integers to hold the two integers i.e. for rules
  • The second section will be a list

    • The list will be a list of integers to hold the page list

So, the data structure would look like a list of list of list of integers.

func ReadFileSections(path string) [][][]int {

    fileBytes := ReadFileBytes(path)
    lines := []string{}
    separator := []byte("\n\n")
    for _, line := range bytes.Split(fileBytes, separator) {
        if string(line) != "" {
            lines = append(lines, string(line))
        }
    }

    sections := [][][]int{}
    for i, section := range lines {
        nums := [][]int{}
        lineStrs := strings.Split(section, "\n")
        separator := ","
        if i == 0 {
            separator = "|"
        }
        for _, lineStr := range lineStrs {
            if lineStr == "" {
                continue
            }
            numL := []int{}
            for _, numStr := range strings.Split(lineStr, separator) {
                num, _ := strconv.Atoi(numStr)
                numL = append(numL, num)
            }
            nums = append(nums, numL)
        }
        sections = append(sections, nums)
    }
    return sections
}

The above function called ReadFileSections takes in a path to the input file and returns a slice/array) of the list of list of integers as discussed. We first read the file and split the bytes into two newline characters that will be the separator for the sections, we will store the lines as a list of strings, the first will contain the rule lines and the second will contain the page list lines.

Then we iterate over the section and split the individual lines for sections separately with the respective separator i.e. | for the first section and (whitespace) for the second section. We are parsing each line to get a list of integers and append them to the respective sections.

So, we now have data that we can use to construct the rules and pages to help process the problem.

Constructing Rules

Now, we need to process the rules list for convenient access, we need to get the page number that should appear after a given page, so we will use a map of integer with a list of integers, where the key will be the first number and the one of the value will be the second number ( the number that should appear after in order of the pages).

func ConstructRules(rulesList [][]int) map[int][]int {
    rules := make(map[int][]int)
    for _, rule := range rulesList {
        rules[rule[0]] = append(rules[rule[0]], rule[1])
    }
    return rules
}

We simply iterate over the list of integers and map the first element as the key and the value as the second element in the list, so to visualize:

FROM

[][]int

[
    [47,53]
    [97,13]
    [97,61]
]

TO

map[int][]int
{
    47: [53]
    97: [13,61]
}

So, now have the rules as a map of integers with integers.

Constructing indices

Now, to make the first and second parts easier, we need to make a map for each number in the rules section with the indices that appear in the pages list.

So, we will iterate over the rules, which is a map of integers and integers, we will create a map of integers that will help us create a unique list of integers from the rules.

Now, once we have the list of integers from the rules, we will iterate over all the numbers and on each page line, check on which index it appears, for creating a list of integers(indices).

So, we iterate over all the numbers in the line of pages, if we find that number in the list of pages, we append the index, however, if we don’t we append -1, so for each line we need to have an index appended for that number like so:

47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13

75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

So, in the above example, we have taken 75 for reference, we will get the index for each list of page numbers, and we get the list of indexes where 75 appears.

Now, this can be done with the following function:

func ReadFileSections(path string) [][][]int {

    fileBytes := ReadFileBytes(path)
    lines := []string{}
    separator := []byte("\n\n")
    for _, line := range bytes.Split(fileBytes, separator) {
        if string(line) != "" {
            lines = append(lines, string(line))
        }
    }

    sections := [][][]int{}
    for i, section := range lines {
        nums := [][]int{}
        lineStrs := strings.Split(section, "\n")
        separator := ","
        if i == 0 {
            separator = "|"
        }
        for _, lineStr := range lineStrs {
            if lineStr == "" {
                continue
            }
            numL := []int{}
            for _, numStr := range strings.Split(lineStr, separator) {
                num, _ := strconv.Atoi(numStr)
                numL = append(numL, num)
            }
            nums = append(nums, numL)
        }
        sections = append(sections, nums)
    }
    return sections
}

So, we now have the index mapped at each page numbers list from the rules.

Part 1

Now, for part one we need to iterate over each page update (line), then we need to check if the page numbers are following the rules, each number should follow the rules. This means that if a number is after a certain number but the rule says it should be before, then it has violated the page numbering rule in that update, so we cannot consider it as the correct ordered page, we need to add the middle page number of each update which is correctly ordered as the answer for the part one.

To do that, we iterate over each page update, then we need to iterate over each of the numbers in that page update, we obtain all the rules associated with that number (let’s call it the current number) since we have a map of integers with a list of integers. Now, we have to check if the number that we currently are in is before the numbers in its rules. So, we check with the index of the current number using the number indices that we created which is a map of the number with a list of integers as indices. So, we obtain the list of indices of the map with the current number as the key for the map and the index in the list as the number of line/page updates we are currently in.

Then once we have got the index for the current number, we obtain the same for the second number which is all the numbers in its rule, and if that number in its rule is present in that page line/update i.e. it is not -1 and if that is the case, we get the index of it similarly and check if it appears after the current number following the rule, And so if any number violates the rule, we need to mark the page update as not in correct order.

As we see that the index rule for that page update is violated, we mark the order as false. If we see the ordered flag is still true, we update the score with the middle element of that page update.

func ConstructRules(rulesList [][]int) map[int][]int {
    rules := make(map[int][]int)
    for _, rule := range rulesList {
        rules[rule[0]] = append(rules[rule[0]], rule[1])
    }
    return rules
}

So, to reiterate, we create a function called GetOrderedPage with rule and number indices as a map of integers with a list of integers and the pages which is a list of integers as the page update. We return the score as the output of this function.

We iterate through each of the page updates, then through each page number in the update, we check for the rule of that number and if the index of that is lower than the current number we mark it as not ordered, and hence at the end of each page update we update the score with the middle element of the page update, if the order is correct.

So, that will be part one summed up, we just have to get the score of the correct ordered page updates.

Part 2

In part 2 however, we need to check if the page update is in order, if it is not then we need to make it in order.

We do a similar thing for part 2, we need to iterate over each of the page updates, and for each number in that page update, we need to check if the rule is violated or not, if we encounter any case where the rule is violated for any number, we mark the flag ordered as false, this we will use to correct the order of the page updates. After updating the pages in that page line/update, we need to add the score with middle element of the corrected order of page update.

47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13

75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

We need to implement the CorrectPageOrder function that takes in the page line or page update and the rules, we need to create a new page update, that will populate the page that follows all the rules.

So, we first keep track of the initialized elements index and update the index if we need to move the element before it.

So, we iterate over all the numbers in the page update and set the index before any number in the rule, if we encounter any such number in the rule map, we need to update the index with the index of that number.

And once we have got the index where we want to swap the element to, we create a slice before that index and append that number into it, and append everything after that index.

func ReadFileSections(path string) [][][]int {

    fileBytes := ReadFileBytes(path)
    lines := []string{}
    separator := []byte("\n\n")
    for _, line := range bytes.Split(fileBytes, separator) {
        if string(line) != "" {
            lines = append(lines, string(line))
        }
    }

    sections := [][][]int{}
    for i, section := range lines {
        nums := [][]int{}
        lineStrs := strings.Split(section, "\n")
        separator := ","
        if i == 0 {
            separator = "|"
        }
        for _, lineStr := range lineStrs {
            if lineStr == "" {
                continue
            }
            numL := []int{}
            for _, numStr := range strings.Split(lineStr, separator) {
                num, _ := strconv.Atoi(numStr)
                numL = append(numL, num)
            }
            nums = append(nums, numL)
        }
        sections = append(sections, nums)
    }
    return sections
}

So, this function will find the index of a number to place it at the most extreme left (beginning of the list) so that we are not violating any rules for that number, then we create a slice to append that number before that index and append everything after that index.

That’s it from part two, we have updated the page order if there were any discrepancies in the page order.

You can check out my solutions here on GitHub.

Advent of Code ay n Golang: Ordering Pages Mr-Destructive / advent_of_code

Advent of Code

Conclusion

So, that is it from day 5 of Advent of Code in Golang, let me know if you have any suggestions, and how you approached it. any better solutions?

Happy Coding :)

The above is the detailed content of Advent of Code ay n Golang: Ordering Pages. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How do I create a buffered channel in Go? (e.g., make(chan int, 10)) How do I create a buffered channel in Go? (e.g., make(chan int, 10)) Jun 20, 2025 am 01:07 AM

To create a buffer channel in Go, just specify the capacity parameters in the make function. The buffer channel allows the sending operation to temporarily store data when there is no receiver, as long as the specified capacity is not exceeded. For example, ch:=make(chanint,10) creates a buffer channel that can store up to 10 integer values; unlike unbuffered channels, data will not be blocked immediately when sending, but the data will be temporarily stored in the buffer until it is taken away by the receiver; when using it, please note: 1. The capacity setting should be reasonable to avoid memory waste or frequent blocking; 2. The buffer needs to prevent memory problems from being accumulated indefinitely in the buffer; 3. The signal can be passed by the chanstruct{} type to save resources; common scenarios include controlling the number of concurrency, producer-consumer models and differentiation

How do I call a method on a struct instance in Go? How do I call a method on a struct instance in Go? Jun 24, 2025 pm 03:17 PM

In Go language, calling a structure method requires first defining the structure and the method that binds the receiver, and accessing it using a point number. After defining the structure Rectangle, the method can be declared through the value receiver or the pointer receiver; 1. Use the value receiver such as func(rRectangle)Area()int and directly call it through rect.Area(); 2. If you need to modify the structure, use the pointer receiver such as func(r*Rectangle)SetWidth(...), and Go will automatically handle the conversion of pointers and values; 3. When embedding the structure, the method of embedded structure will be improved, and it can be called directly through the outer structure; 4. Go does not need to force use getter/setter,

What are interfaces in Go, and how do I define them? What are interfaces in Go, and how do I define them? Jun 22, 2025 pm 03:41 PM

In Go, an interface is a type that defines behavior without specifying implementation. An interface consists of method signatures, and any type that implements these methods automatically satisfy the interface. For example, if you define a Speaker interface that contains the Speak() method, all types that implement the method can be considered Speaker. Interfaces are suitable for writing common functions, abstract implementation details, and using mock objects in testing. Defining an interface uses the interface keyword and lists method signatures, without explicitly declaring the type to implement the interface. Common use cases include logs, formatting, abstractions of different databases or services, and notification systems. For example, both Dog and Robot types can implement Speak methods and pass them to the same Anno

Strategies for Integrating Golang Services with Existing Python Infrastructure Strategies for Integrating Golang Services with Existing Python Infrastructure Jul 02, 2025 pm 04:39 PM

TointegrateGolangserviceswithexistingPythoninfrastructure,useRESTAPIsorgRPCforinter-servicecommunication,allowingGoandPythonappstointeractseamlesslythroughstandardizedprotocols.1.UseRESTAPIs(viaframeworkslikeGininGoandFlaskinPython)orgRPC(withProtoco

How do I use string functions from the strings package in Go? (e.g., len(), strings.Contains(), strings.Index(), strings.ReplaceAll()) How do I use string functions from the strings package in Go? (e.g., len(), strings.Contains(), strings.Index(), strings.ReplaceAll()) Jun 20, 2025 am 01:06 AM

In Go language, string operations are mainly implemented through strings package and built-in functions. 1.strings.Contains() is used to determine whether a string contains a substring and returns a Boolean value; 2.strings.Index() can find the location where the substring appears for the first time, and if it does not exist, it returns -1; 3.strings.ReplaceAll() can replace all matching substrings, and can also control the number of replacements through strings.Replace(); 4.len() function is used to obtain the length of the bytes of the string, but when processing Unicode, you need to pay attention to the difference between characters and bytes. These functions are often used in scenarios such as data filtering, text parsing, and string processing.

How do I use the io package to work with input and output streams in Go? How do I use the io package to work with input and output streams in Go? Jun 20, 2025 am 11:25 AM

TheGoiopackageprovidesinterfaceslikeReaderandWritertohandleI/Ooperationsuniformlyacrosssources.1.io.Reader'sReadmethodenablesreadingfromvarioussourcessuchasfilesorHTTPresponses.2.io.Writer'sWritemethodfacilitateswritingtodestinationslikestandardoutpu

How do I use the time package to work with time and durations in Go? How do I use the time package to work with time and durations in Go? Jun 23, 2025 pm 11:21 PM

Go's time package provides functions for processing time and duration, including obtaining the current time, formatting date, calculating time difference, processing time zone, scheduling and sleeping operations. To get the current time, use time.Now() to get the Time structure, and you can extract specific time information through Year(), Month(), Day() and other methods; use Format("2006-01-0215:04:05") to format the time string; when calculating the time difference, use Sub() or Since() to obtain the Duration object, and then convert it into the corresponding unit through Seconds(), Minutes(), and Hours();

How do I use if statements to execute code based on conditions in Go? How do I use if statements to execute code based on conditions in Go? Jun 23, 2025 pm 07:02 PM

InGo,ifstatementsexecutecodebasedonconditions.1.Basicstructurerunsablockifaconditionistrue,e.g.,ifx>10{...}.2.Elseclausehandlesfalseconditions,e.g.,else{...}.3.Elseifchainsmultipleconditions,e.g.,elseifx==10{...}.4.Variableinitializationinsideif,l

See all articles