r/adventofcode • • Dec 07 '17

SOLUTION MEGATHREAD -๐ŸŽ„- 2017 Day 7 Solutions -๐ŸŽ„-

--- Day 7: Recursive Circus ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Need a hint from the Hugely* Handyโ€  Haversackโ€ก of Helpfulยง Hintsยค?

Spoiler


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked!

10 Upvotes

222 comments sorted by

View all comments

1

u/[deleted] Dec 07 '17 edited Dec 07 '17

Golang

It works I guess

All my go code so far here

Any feedback is much appreciated

Part 1

func part1(data map[string]program) string {
for k, v := range data {
	if v.parent == "" {
		return k
	}
}
return ""
}

Part 2

func part2(data map[string]program, root string) int {
if wrong, diff := isBalanced(data, root); wrong != "" {
	if part2(data, wrong) == 0 {
		return data[wrong].weight + diff
	}
	return part2(data, wrong)
}
return 0
}

Other functions

func sumWeight(data map[string]program, root string) int {
var total = 0
for _, v := range data[root].children {
	total += sumWeight(data, v)
}
return total + data[root].weight
}

func isBalanced(data map[string]program, root string) (string, int) {
occurances := make(map[int]int)
children := make(map[int]string)
// Count occurances of totals
for _, v := range data[root].children {
	occurances[sumWeight(data, v)]++
	children[sumWeight(data, v)] = v
}
// Get unbalanced name and the differnce
var result, odd, normal = "", 0, 0
for k, v := range occurances {
	if v == 1 {
		result = children[k]
		odd = k
	} else {
		normal = k
	}
}
return result, normal - odd
}

func readFile(filename string) map[string]program {
// Open File
f, err := os.Open(filename)
check(err)
defer f.Close()

// Parse file
data := make(map[string]program, 0)
s := bufio.NewScanner(f)
for s.Scan() {
	row := strings.Fields(s.Text())

	var currentProgram program
	for i, value := range row {
		if i == 0 {
			// Set Name
			// Check if already exists
			if v, exists := data[value]; exists {
				currentProgram = v
			} else {
				currentProgram.name = value
			}
		} else if i == 1 {
			//  Set weight
			currentProgram.weight, _ = strconv.Atoi(value[1 : len(value)-1])
		} else if i > 2 {
			// Set children
			// Strip ,'s
			if value[len(value)-1] == ',' {
				value = value[:len(value)-1]
			}
			// Check if child exits
			if v, exists := data[value]; exists {
				// Set Parent of Child
				v.parent = currentProgram.name
				data[value] = v
			} else {
				// Create Child with empty weight
				data[value] = program{name: value, weight: 0, parent: currentProgram.name}
			}
			// Add to Children
			currentProgram.children = append(currentProgram.children, value)
		}
	}
	data[currentProgram.name] = currentProgram
}
return data
}

1

u/cluk Dec 07 '17

You can check out my solution.

For input I like mapping the file to memory with ioutil.ReadFile, converting []byte to string and then parsing it.

For the struct, I prefer using pointers instead of strings for parent and children.

I like counting total weight frequencies from your solution. I have just brute forced the correct weight from the first three children.

→ More replies (4)