Skip to content

Instantly share code, notes, and snippets.

@dmitry-vsl
Last active December 25, 2022 20:14
Show Gist options
  • Save dmitry-vsl/9bb0a5e1da97f9ff9d3746e3876eeae1 to your computer and use it in GitHub Desktop.
Save dmitry-vsl/9bb0a5e1da97f9ff9d3746e3876eeae1 to your computer and use it in GitHub Desktop.
const assert = require('assert')
/*
Blueprint 1:
Each ore robot costs 4 ore.
Each clay robot costs 2 ore.
Each obsidian robot costs 3 ore and 14 clay.
Each geode robot costs 2 ore and 7 obsidian.
*/
const bp_1 = [
[4, 0, 0, 0],
[2, 0, 0, 0],
[3, 14, 0, 0],
[2, 0, 7, 0],
]
/*
Blueprint 2:
Each ore robot costs 2 ore.
Each clay robot costs 3 ore.
Each obsidian robot costs 3 ore and 8 clay.
Each geode robot costs 3 ore and 12 obsidian.
*/
const bp_2 = [
[2, 0, 0, 0],
[3, 0, 0, 0],
[3, 8, 0, 0],
[3, 0, 12, 0],
]
function gte(a,b) {
for(let i = 0; i < a.length; i++) {
if(a[i] < b[i]) {
return false
}
}
return true
}
function add(a, b) {
for(let i = 0; i < a.length; i++) {
a[i] += b[i]
}
}
function sub(a, b) {
for(let i = 0; i < a.length; i++) {
a[i] -= b[i]
}
}
assert.equal(gte([1,2], [1,1]), true)
assert.equal(gte([0,2], [1,1]), false)
function score_blueprint(bp, set, minutes_left) {
const LENGTH = set.resources.length
let max_score = 0
let best_decision
const decision = []
function do_score(minutes_left) {
if(minutes_left == 0) {
const result = set.resources.at(-1)
if(max_score < result) {
max_score = result
best_decision = decision.slice()
}
return
}
for(let i = 0; i < LENGTH; i++) {
if(gte(set.resources, bp[i])) {
// enough resources to build robot of type `i`
decision.push(i)
sub(set.resources, bp[i])
add(set.resources, set.robots)
set.robots[i]++
do_score(minutes_left - 1)
// rollback
set.robots[i]--
sub(set.resources, set.robots)
add(set.resources, bp[i])
decision.pop()
}
}
// try not building robot and just collecting resources
decision.push(-1)
add(set.resources, set.robots)
do_score(minutes_left - 1)
// rollback set.resources
sub(set.resources, set.robots)
decision.pop()
}
do_score(minutes_left)
return {
max_score,
best_decision,
}
}
const initial_set = {
resources: [0, 0, 0, 0],
robots: [1, 0, 0, 0],
}
function score_blueprint_print_decision(...args) {
const names = ['ore', 'clay', 'obsidian', 'geode']
const {max_score, best_decision} = score_blueprint(...args)
console.log({max_score})
for(let i = 0; i < best_decision.length; i++) {
const d = best_decision[i]
const name = d == -1 ? 'skip' : names[d]
console.log(i + 1, name)
}
}
console.time('run')
console.log(score_blueprint_print_decision(bp_1, initial_set, 22))
console.timeEnd('run')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment