백엔드 개발 Golang 코드의 출현 ay n Golang: 주문 페이지

코드의 출현 ay n Golang: 주문 페이지

Dec 28, 2024 am 07:33 AM

소개

코드 출현 5일째입니다. 오늘은 페이지 순서 지정에 관한 흥미로운 문제가 발생했습니다. 문제와 제가 어떻게 접근했는지 살펴보겠습니다. 좋게 생각하면 꽤 간단한 문제였는데, 그렇지 않으면 맵, 리스트, 인덱스가 엉망이 될 뻔했습니다.

여기 GitHub에서 제 솔루션을 확인하실 수 있습니다.

Advent of Code ay n Golang: Ordering Pages 미스터 파괴자 / 출현_코드

코드의 출현

입력

5일차 입력에는 두 개의 섹션이 있습니다. 첫 번째 섹션은 페이지 순서 규칙, 특히 어떤 페이지가 어느 페이지 앞에 와야 하는지를 정의하고 두 번째 섹션은 페이지의 실제 순서를 포함합니다.

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
로그인 후 복사
로그인 후 복사
로그인 후 복사

첫 번째 섹션에는 매핑된 규칙이 있고, 다른 섹션에는 페이지 순서가 있으며, 각 줄은 처리할 실제 데이터인 쿼리 또는 페이지 목록입니다. 파트 1과 2의 처리에 사용해야 합니다.

섹션 읽기

따라서 이러한 섹션을 구문 분석하고 더 쉽게 액세스할 수 있는 데이터 구조로 읽어야 합니다.

그렇게 하는 한 가지 방법은

  • 두 개의 섹션으로 구성된 목록

  • 첫 번째 섹션은 목록입니다

    • 목록은 규칙을 위해 두 개의 정수를 보유하는 정수 목록입니다.
  • 두 번째 섹션은 목록입니다

    • 목록은 페이지 목록을 담을 정수 목록입니다

따라서 데이터 구조는 정수 목록의 목록처럼 보입니다.

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
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

ReadFileSections라는 위의 함수는 논의된 대로 입력 파일의 경로를 취하고 정수 목록의 슬라이스/배열을 반환합니다. 먼저 파일을 읽고 바이트를 섹션 구분 기호가 될 두 개의 개행 문자로 분할합니다. 행을 문자열 목록으로 저장합니다. 첫 번째에는 규칙 행이 포함되고 두 번째에는 페이지 목록 행이 포함됩니다.

그런 다음 섹션을 반복하고 각 구분 기호(예: | 첫 번째 섹션의 경우, 두 번째 섹션의 경우 (공백)입니다. 각 행을 구문 분석하여 정수 목록을 가져와 해당 섹션에 추가합니다.

이제 문제 처리에 도움이 되는 규칙과 페이지를 구성하는 데 사용할 수 있는 데이터가 생겼습니다.

규칙 구성

이제 편리한 액세스를 위해 규칙 목록을 처리해야 하며, 특정 페이지 뒤에 표시되어야 하는 페이지 번호를 가져와야 하므로 정수 목록이 포함된 정수 맵을 사용합니다. 여기서 키는 다음과 같습니다. 첫 번째 숫자와 값 중 하나가 두 번째 숫자(페이지 순서대로 뒤에 표시되어야 하는 숫자)가 됩니다.

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
}
로그인 후 복사
로그인 후 복사

정수 목록을 반복하고 첫 번째 요소를 키로 매핑하고 값을 목록의 두 번째 요소로 매핑하므로 시각화할 수 있습니다.

FROM

[][]int

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

TO

map[int][]int
{
    47: [53]
    97: [13,61]
}
로그인 후 복사

이제 정수와 정수의 맵으로 규칙을 갖습니다.

인덱스 구성

이제 첫 번째와 두 번째 부분을 더 쉽게 만들기 위해 페이지 목록에 나타나는 색인을 사용하여 규칙 섹션의 각 숫자에 대한 지도를 만들어야 합니다.

그래서 우리는 정수와 정수의 맵인 규칙을 반복하고 규칙에서 고유한 정수 목록을 만드는 데 도움이 되는 정수 맵을 생성할 것입니다.

이제 규칙에서 정수 목록을 얻었으면 모든 숫자를 반복하고 각 페이지 줄에서 어떤 인덱스가 나타나는지 확인하여 정수(인덱스) 목록을 만듭니다.

따라서 페이지 줄의 모든 숫자를 반복합니다. 페이지 목록에서 해당 숫자를 찾으면 색인을 추가하지만, 그렇지 않으면 -1을 추가하므로 각 줄에 대해 다음과 같이 해당 숫자에 색인을 추가해야 합니다.

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
로그인 후 복사
로그인 후 복사
로그인 후 복사

그래서 위의 예에서는 75를 참고로 하여 각 페이지 번호 목록에 대한 색인을 얻고, 75가 나타나는 색인 목록을 얻습니다.

이제 다음 기능을 사용하여 이 작업을 수행할 수 있습니다.

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
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 규칙의 각 페이지 번호 목록에 색인이 매핑되었습니다.

1부

이제 1부에서는 각 페이지 업데이트(줄)를 반복한 다음 페이지 번호가 규칙을 따르고 있는지 확인해야 하며, 각 번호는 규칙을 따라야 합니다. 즉, 숫자가 특정 숫자 뒤에 있지만 규칙에 따라 그 이전이어야 한다고 명시되어 있는 경우 해당 업데이트의 페이지 번호 매기기 규칙을 위반한 것이므로 올바른 순서의 페이지로 간주할 수 없으므로 중간 페이지를 추가해야 합니다. 1부의 답변으로 올바르게 정렬된 각 업데이트의 번호입니다.

이를 위해 각 페이지 업데이트를 반복한 다음 해당 페이지 업데이트의 각 숫자를 반복해야 합니다. 정수 목록이 있는 정수 맵입니다. 이제 현재 우리가 속한 숫자가 규칙에 있는 숫자보다 앞에 있는지 확인해야 합니다. 그래서 우리는 정수 목록을 인덱스로 포함하는 숫자 맵인 우리가 만든 숫자 인덱스를 사용하여 현재 숫자의 인덱스를 확인합니다. 따라서 현재 번호를 맵의 키로 사용하고 목록의 인덱스를 현재 행/페이지 업데이트 수로 사용하여 맵의 인덱스 목록을 얻습니다.

그런 다음 현재 숫자에 대한 색인을 얻은 후에는 해당 규칙의 모든 숫자인 두 번째 숫자에 대해 동일한 색인을 얻습니다. 규칙의 해당 숫자가 해당 페이지 줄/업데이트에 존재하는 경우 즉, -1이 아니고 그렇다면 유사하게 인덱스를 가져와서 규칙에 따라 현재 숫자 뒤에 나타나는지 확인합니다. 따라서 숫자가 규칙을 위반하면 페이지 업데이트가 올바르지 않은 것으로 표시해야 합니다. 주문하세요.

해당 페이지 업데이트에 대한 색인 규칙을 위반한 것으로 확인되어 해당 순서를 false로 표시합니다. 순서가 지정된 플래그가 여전히 true인 경우 해당 페이지 업데이트의 중간 요소로 점수를 업데이트합니다.

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
}
로그인 후 복사
로그인 후 복사

다시 말해서, 정수 목록이 있는 정수 맵과 페이지 업데이트에 따라 정수 목록인 페이지로 규칙과 숫자 인덱스가 있는 GetOrderedPage라는 함수를 만듭니다. 이 함수의 출력으로 점수를 반환합니다.

각 페이지 업데이트를 반복한 다음 업데이트의 각 페이지 번호를 통해 해당 번호의 규칙을 확인하고 해당 번호의 인덱스가 현재 번호보다 낮으면 주문되지 않은 것으로 표시합니다. 각 페이지 업데이트가 끝날 때 순서가 올바른 경우 페이지 업데이트의 중간 요소로 점수를 업데이트합니다.

이제 1부를 요약하겠습니다. 올바르게 주문된 페이지 업데이트의 점수를 얻으면 됩니다.

2부

그러나 2부에서는 페이지 업데이트가 순서대로 되었는지 확인하고, 그렇지 않다면 순서대로 만들어야 합니다.

파트 2에서도 비슷한 작업을 수행합니다. 각 페이지 업데이트를 반복해야 하며 해당 페이지 업데이트의 각 번호에 대해 규칙을 위반했는지 여부를 확인해야 합니다. 숫자에 관계없이 규칙을 위반하면 주문한 플래그를 false로 표시하고 이를 사용하여 페이지 업데이트 순서를 수정합니다. 해당 페이지 라인/업데이트에서 페이지를 업데이트한 후 페이지 업데이트 순서를 수정한 중간 요소로 점수를 추가해야 합니다.

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
로그인 후 복사
로그인 후 복사
로그인 후 복사

페이지 행이나 페이지 업데이트 및 규칙을 받아들이는 CorrectPageOrder 함수를 구현해야 하며, 모든 규칙을 따르는 페이지를 채우는 새 페이지 업데이트를 생성해야 합니다.

따라서 먼저 초기화된 요소 인덱스를 추적하고 그 이전 요소를 이동해야 하는 경우 인덱스를 업데이트합니다.

따라서 페이지 업데이트의 모든 숫자를 반복하고 규칙의 숫자 앞에 인덱스를 설정합니다. 규칙 맵에서 그러한 숫자를 발견하면 해당 숫자의 인덱스로 인덱스를 업데이트해야 합니다.

그리고 요소를 교체하려는 인덱스를 얻은 후에는 해당 인덱스 앞에 슬라이스를 만들고 그 숫자를 추가한 다음 해당 인덱스 뒤에 모든 것을 추가합니다.

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
}
로그인 후 복사
로그인 후 복사
로그인 후 복사

따라서 이 함수는 숫자의 인덱스를 찾아 가장 왼쪽(목록의 시작 부분)에 배치하여 해당 숫자에 대한 규칙을 위반하지 않도록 한 다음 슬라이스를 생성하여 해당 숫자를 앞에 추가합니다. 색인을 생성하고 해당 색인 뒤의 모든 항목을 추가합니다.

여기까지 2부에서 페이지 순서에 차이가 있을 경우 페이지 순서를 업데이트했습니다.

여기 GitHub에서 제 솔루션을 확인하실 수 있습니다.

Advent of Code ay n Golang: Ordering Pages 미스터 파괴자 / 출현_코드

코드의 출현

결론

그럼 Golang의 Advent of Code 5일차는 여기까지입니다. 제안 사항과 이에 접근한 방법이 있으면 알려주시기 바랍니다. 더 나은 솔루션이 있나요?

행복한 코딩하세요 :)

위 내용은 코드의 출현 ay n Golang: 주문 페이지의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Golang의 목적 : 효율적이고 확장 가능한 시스템 구축 Golang의 목적 : 효율적이고 확장 가능한 시스템 구축 Apr 09, 2025 pm 05:17 PM

Go Language는 효율적이고 확장 가능한 시스템을 구축하는 데 잘 작동합니다. 장점은 다음과 같습니다. 1. 고성능 : 기계 코드로 컴파일, 빠른 달리기 속도; 2. 동시 프로그래밍 : 고어 라틴 및 채널을 통한 멀티 태스킹 단순화; 3. 단순성 : 간결한 구문, 학습 및 유지 보수 비용 절감; 4. 크로스 플랫폼 : 크로스 플랫폼 컴파일, 쉬운 배포를 지원합니다.

Golang 및 C : 동시성 대 원시 속도 Golang 및 C : 동시성 대 원시 속도 Apr 21, 2025 am 12:16 AM

Golang은 동시성에서 C보다 낫고 C는 원시 속도에서 Golang보다 낫습니다. 1) Golang은 Goroutine 및 Channel을 통해 효율적인 동시성을 달성하며, 이는 많은 동시 작업을 처리하는 데 적합합니다. 2) C 컴파일러 최적화 및 표준 라이브러리를 통해 하드웨어에 가까운 고성능을 제공하며 극도의 최적화가 필요한 애플리케이션에 적합합니다.

Golang vs. Python : 주요 차이점과 유사성 Golang vs. Python : 주요 차이점과 유사성 Apr 17, 2025 am 12:15 AM

Golang과 Python은 각각 고유 한 장점이 있습니다. Golang은 고성능 및 동시 프로그래밍에 적합하지만 Python은 데이터 과학 및 웹 개발에 적합합니다. Golang은 동시성 모델과 효율적인 성능으로 유명하며 Python은 간결한 구문 및 풍부한 라이브러리 생태계로 유명합니다.

공연 경주 : 골랑 대 c 공연 경주 : 골랑 대 c Apr 16, 2025 am 12:07 AM

Golang과 C는 각각 공연 경쟁에서 고유 한 장점을 가지고 있습니다. 1) Golang은 높은 동시성과 빠른 발전에 적합하며 2) C는 더 높은 성능과 세밀한 제어를 제공합니다. 선택은 프로젝트 요구 사항 및 팀 기술 스택을 기반으로해야합니다.

Golang vs. Python : 성능 및 확장 성 Golang vs. Python : 성능 및 확장 성 Apr 19, 2025 am 12:18 AM

Golang은 성능과 확장 성 측면에서 Python보다 낫습니다. 1) Golang의 컴파일 유형 특성과 효율적인 동시성 모델은 높은 동시성 시나리오에서 잘 수행합니다. 2) 해석 된 언어로서 파이썬은 천천히 실행되지만 Cython과 같은 도구를 통해 성능을 최적화 할 수 있습니다.

Golang의 영향 : 속도, 효율성 및 단순성 Golang의 영향 : 속도, 효율성 및 단순성 Apr 14, 2025 am 12:11 AM

goimpactsdevelopmentpositively throughlyspeed, 효율성 및 단순성.

C와 Golang : 성능이 중요 할 때 C와 Golang : 성능이 중요 할 때 Apr 13, 2025 am 12:11 AM

C는 하드웨어 리소스 및 고성능 최적화가 직접 제어되는 시나리오에 더 적합하지만 Golang은 빠른 개발 및 높은 동시성 처리가 필요한 시나리오에 더 적합합니다. 1.C의 장점은 게임 개발과 같은 고성능 요구에 적합한 하드웨어 특성 및 높은 최적화 기능에 가깝습니다. 2. Golang의 장점은 간결한 구문 및 자연 동시성 지원에 있으며, 이는 동시성 서비스 개발에 적합합니다.

Golang 및 C : 성능 상충 Golang 및 C : 성능 상충 Apr 17, 2025 am 12:18 AM

Golang과 C의 성능 차이는 주로 메모리 관리, 컴파일 최적화 및 런타임 효율에 반영됩니다. 1) Golang의 쓰레기 수집 메커니즘은 편리하지만 성능에 영향을 줄 수 있습니다. 2) C의 수동 메모리 관리 및 컴파일러 최적화는 재귀 컴퓨팅에서 더 효율적입니다.

See all articles