This commit is contained in:
Dmitry Fedotov
2023-12-17 11:51:39 +03:00
parent 14e3008925
commit 1ab7137882
8 changed files with 785 additions and 2 deletions

143
day5/day2_2.go Normal file
View File

@@ -0,0 +1,143 @@
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
const MaxInt = int((^uint(0) >> 1))
type Range struct {
dst int
src int
len int
}
func (r Range) Map(n int) (int, bool) {
if n < r.src || n > (r.src+r.len-1) {
return 0, false
}
return r.dst - r.src + n, true
}
type Map struct {
name string
ranges []Range
}
func (m *Map) Append(r Range) {
m.ranges = append(m.ranges, r)
}
func (m *Map) Map(n int) int {
for i := range m.ranges {
x, ok := m.ranges[i].Map(n)
if ok {
return x
}
}
return n
}
type Almanac struct {
seeds []int
maps []*Map
}
func (a *Almanac) ParseFile(name string) error {
f, err := os.Open(name)
if err != nil {
return err
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Scan()
seedsStr := scanner.Text()
seeds := strToInts(seedsStr[7:])
a.seeds = seeds
scanner.Scan()
var m *Map
for scanner.Scan() {
s := scanner.Text()
s = strings.Trim(s, " \n")
if s == "" {
a.maps = append(a.maps, m)
continue
}
if s[0] > '9' {
m = &Map{
name: s,
ranges: []Range{},
}
continue
}
nums := strToInts(s)
r := Range{
dst: nums[0],
src: nums[1],
len: nums[2],
}
m.Append(r)
}
a.maps = append(a.maps, m)
return nil
}
func (a *Almanac) seedToLoc(n int) int {
for i := range a.maps {
n = a.maps[i].Map(n)
}
return n
}
func (a *Almanac) ClosestForSeeds() int {
result := MaxInt
for _, n := range a.seeds {
loc := a.seedToLoc(n)
if loc < result {
result = loc
}
}
return result
}
func (a *Almanac) ClosestForRanges() int {
result := MaxInt
for i := 0; i < (len(a.seeds) - 2); i += 2 {
for j := a.seeds[i]; j < (a.seeds[i] + a.seeds[i+1]); j++ {
loc := a.seedToLoc(j)
if loc < result {
result = loc
}
}
}
return result
}
func strToInts(s string) []int {
s = strings.Trim(s, " \n")
split := strings.Split(s, " ")
nums := []int{}
for _, x := range split {
n, err := strconv.Atoi(x)
if err != nil {
panic(err)
}
nums = append(nums, n)
}
return nums
}
func main() {
a := new(Almanac)
a.ParseFile("input.txt")
x := a.ClosestForSeeds()
fmt.Println(x)
y := a.ClosestForRanges()
fmt.Println(y)
}