Last active
December 25, 2022 20:14
-
-
Save dmitry-vsl/9bb0a5e1da97f9ff9d3746e3876eeae1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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