Created
February 1, 2021 20:31
-
-
Save Butanium/e294469ffbd680cea1a80714693c680e to your computer and use it in GitHub Desktop.
codinGame fall challenge 2020
This file contains 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
import sys | |
import math | |
import numpy as np | |
REST = "REST" | |
WAIT = "WAIT" | |
# Auto-generated code below aims at helping you parse | |
# the standard input according to the problem statement. | |
class Action: | |
def __init__(self, inp): | |
self.id = int(inp[0]) # the unique ID of this spell or recipe | |
self.type = inp[1] # in the first league: BREW; later: CAST, OPPONENT_CAST, LEARN, BREW | |
self.deltas = list(map(int, inp[2:6])) # tier-0 ingredient change | |
self.price = int(inp[6]) # the price in rupees if this is a potion | |
self.tome_index = int(inp[7]) # in the first two leagues: always 0; later: the index in the tome if this is a | |
# tome spell, equal to the read-ahead tax; For brews, this is the value of the current urgency bonus | |
self.tax_count = int(inp[8]) # in the first two leagues: always 0; later: the amount of taxed tier-0 | |
# ingredients you gain from learning this spell; For brews, this is how many times | |
# you can still gain an urgency bonus | |
self.castable = inp[9] != "0" # in the first league: always 0; later: 1 if this is a castable player spell | |
self.repeatable = inp[10] != "0" # for the first two leagues: always 0; later: 1 if this is a | |
# repeatable player spell | |
debug(str(self.id) + " : " + str(self.deltas)) | |
def debug(message): | |
print(message, file=sys.stderr, flush=True) | |
class Witch: | |
def __init__(self, inp): | |
self.inventory = inp[:-1:] | |
self.score = inp[-1] | |
def is_doable(action: Action, inv, deltas=()): | |
if not deltas: | |
for i, delta in enumerate(action.deltas): | |
debug("need {} and have {} ingredient {}".format(-delta, inv[i], i)) | |
if delta >= 0: | |
continue | |
if -delta > inv[i]: | |
return 0 | |
debug(action.id) | |
return 1 | |
else: | |
new_inv = np.array(deltas) + np.array(inv) | |
return is_doable(action, new_inv) | |
# game loop | |
while True: | |
action_count = int(input()) # the number of spells and recipes in play | |
actions = [] | |
for i in range(action_count): | |
inputs = input().split() | |
actions.append(Action(inputs)) | |
witches = [] | |
for i in range(2): | |
witches.append(Witch([int(j) for j in input().split()])) | |
nd_potions = [] | |
d_potions = [] | |
max_price = 0 | |
best_pot_id = False | |
for potion in actions: | |
if potion.type != "BREW": | |
continue | |
if is_doable(potion, witches[0].inventory): | |
d_potions.append(potion) | |
if potion.price > max_price: | |
best_pot_id, max_price = potion.id, potion.price | |
else: | |
nd_potions.append(potion) | |
# in the first league: BREW <id> | WAIT; later: BREW <id> | CAST <id> [<times>] | LEARN <id> | REST | WAIT | |
if max_price: | |
print("BREW " + str(best_pot_id)) | |
continue | |
c_spell_count = 0 | |
doable_spells = [] | |
spells = [] | |
for spell in actions: | |
if spell.id != "SPELL": | |
continue | |
spells.append(spell) | |
if is_doable(spell, witches[0].inventory): | |
doable_spells.append(spell) | |
if spell.castable: | |
c_spell_count += 1 | |
best_spell = 0 | |
max_price = 0 | |
for spell in doable_spells: | |
for potion in nd_potions: | |
if is_doable(potion, witches[0].inventory, spell.deltas): | |
if potion.price > max_price: | |
max_price, best_spell = potion.price, spell | |
if potion.price == max_price: | |
if spell.castable and not best_spell.castable: | |
best_spell = spell | |
if max_price: | |
if best_spell.castable: | |
print("CAST " + str(best_spell.id)) | |
continue | |
else: | |
print(REST) | |
continue | |
else: | |
if c_spell_count != 4: | |
print(REST) | |
else: | |
print(WAIT) |
This file contains 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
open Array;; | |
module Toolbox = struct | |
let (+=) i v = i:= !i+v | |
let (+=.) i v = i:= !i +. v | |
let rec contains l e = match l with | |
|x::xs -> if e = x then true else contains xs e | |
|[] -> false | |
let (@@) e l = contains l e | |
let (+++) a b = let m = min (Array.length a) (Array.length b) | |
in let l = Array.make m 0 in | |
for k = 0 to m-1 do | |
l.(k) <- (a.(k) + b.(k)); | |
done; | |
l | |
end;; | |
open Toolbox;; | |
type poids = Inf | P of int | |
let (++) a b = match a,b with | |
|P(a),P(b) -> P(a+b) | |
|_ -> Inf | |
let (>>) a b = match a,b with | |
|P(a), P(b) -> a > b | |
|Inf, _ -> true | |
|_ -> false | |
let (++=) a b = a := !a ++ b;; | |
class action (actionid:int) (actiontype:string) (delta0:int) delta1 delta2 delta3 (price:int) (tomeindex:int) (taxcount:int) (castable:bool) (repeatable:bool) | |
= | |
object (self) | |
val id = actionid | |
val atype = actiontype | |
val delta = [|delta0; delta1; delta2; delta3|] | |
val price = price | |
val tomeindex = tomeindex | |
val taxcount = taxcount | |
val castable = castable | |
val repeatable = repeatable | |
method id = id | |
method atype = atype | |
method delta = delta | |
method price = price | |
method tomeindex = tomeindex | |
method taxcount = taxcount | |
method castable = castable | |
method repeatable = repeatable | |
end;; | |
class witch inv0 inv1 inv2 inv3 score= | |
object (self) | |
val inventory = [|inv0;inv1;inv2;inv3|] | |
val score = score | |
method inventory = inventory | |
method score = score | |
end;; | |
(* Auto-generated code below aims at helping you parse *) | |
(* the standard input according to the problem statement. *) | |
let rec getGains spells output = match spells with | |
|x::xs -> | |
for i = 0 to 3 do | |
if x#deltas.(i) > 0 then output.(i) <- x::output.(i); | |
done; | |
getGains xs; | |
|[] -> ();; | |
let getMissingsI p inv = | |
let r = make 4 0 and t = ref true in | |
for i = 0 to 3 do | |
let d = p.(i) + inv.(i) in | |
r.(i) <- d; | |
if d < 0 then t := false; | |
done; | |
r, !t;; | |
let getLen potion inventory gains maxDepth= | |
let fut_inv, t = getMissingsI potion inventory in if t then 0 else begin | |
let rec aux inv len oldInvs path = | |
let i = ref 0 in | |
while !i < 4 and inv.(!i) > 0 do | |
i += 1; | |
done; | |
if !i = 3 then len, path else begin if len >= maxDepth then Inf, path else begin | |
let tempLen = ref P 0 and oInv = inv::oldInvs and newPath = ref [] in | |
for k = 0 to 3 do let i = 3-k in | |
if inv.(i) < 0 then begin | |
let rec crossGains g = match g with | |
|x::xs -> let aux (inv+++x#deltas) | |
for i = 0 to (length gains) - 1 do | |
nL, nP = aux (inv +++ gains.(i)#deltas) | |
(*todo: start tree search *) | |
(* game loop *) | |
while true do | |
let actioncount = int_of_string (input_line stdin) (* the number of spells and recipes in play *) | |
in let actions = make actioncount (new action 0 0 0 0 0 0 0 0 0 0 0) and actionListR = ref [] in | |
for i = 0 to actioncount - 1 do | |
(* actionid: the unique ID of this spell or recipe *) | |
(* actiontype: in the first league: BREW; later: CAST, OPPONENT_CAST, LEARN, BREW *) | |
(* delta0: tier-0 ingredient change *) | |
(* delta1: tier-1 ingredient change *) | |
(* delta2: tier-2 ingredient change *) | |
(* delta3: tier-3 ingredient change *) | |
(* price: the price in rupees if this is a potion *) | |
(* tomeindex: in the first two leagues: always 0; later: the index in the tome if this is a tome spell, equal to the read-ahead tax; For brews, this is the value of the current urgency bonus *) | |
(* taxcount: in the first two leagues: always 0; later: the amount of taxed tier-0 ingredients you gain from learning this spell; For brews, this is how many times you can still gain an urgency bonus *) | |
(* castable: in the first league: always 0; later: 1 if this is a castable player spell *) | |
(* repeatable: for the first two leagues: always 0; later: 1 if this is a repeatable player spell *) | |
let actionid, actiontype, delta0, delta1, delta2, delta3, price, tomeindex, taxcount, castable, repeatable = Scanf.sscanf (input_line stdin) " %d %s %d %d %d %d %d %d %d %d %d" (fun actionid actiontype delta0 delta1 delta2 delta3 price tomeindex taxcount castable repeatable -> (actionid, actiontype, delta0, delta1, delta2, delta3, price, tomeindex, taxcount, castable = 1, repeatable = 1)) in | |
in let a = (new action actionid actiontype delta0 delta1 | |
delta2 delta3 price tomeindex taxcount castable repeatable) in | |
actions.(i) <- a; l:= a:: !l; | |
done; | |
let witches = make 2 (new witch 0 0 0 0 0); | |
for i = 0 to 1 do | |
(* inv0: tier-0 ingredients in inventory *) | |
(* score: amount of rupees *) | |
let inv0, inv1, inv2, inv3, score = Scanf.sscanf (input_line stdin) " %d %d %d %d %d" (fun inv0 inv1 inv2 inv3 score -> (inv0, inv1, inv2, inv3, score)) in | |
witches.(i) <- (new witch inv0 inv1 inv2 inv3 score); | |
done; | |
let spellList = let rec isSpell l = match l with | |
|x::xs -> let t = (isSpell xs) in if x#atype = "CAST" then x::t else t | |
|[] -> []; in | |
isSpell !actionListR;; | |
for i = 0 to actioncount - 1 do | |
let a = actions.(i) in | |
if a#atype = "CAST" then | |
spellList | |
let myInv = witches.(0)#inventory in | |
for i=0 to actioncount - 1 do | |
(* Write an action using print_endline *) | |
(* To debug: prerr_endline "Debug message"; *) | |
(* in the first league: BREW <id> | WAIT; later: BREW <id> | CAST <id> [<times>] | LEARN <id> | REST | WAIT *) | |
print_endline "BREW 0"; | |
(); | |
done;; |
This file contains 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
open Array;; | |
class c (d:int array) (i:int) = | |
object(self) | |
val deltas = d | |
val id = i | |
method deltas = deltas | |
method id = id | |
method print = print_int(id); print_string(" : "); | |
print_arr(deltas); | |
end;; | |
let print_arr t = print_string("["); | |
for i=0 to (length t) - 1 do | |
print_int(t.(i)); print_string(", "); | |
done;print_string("]");; | |
let spelList = [(new c [|1;(-3);0;0|] 0); | |
(new c [|(-2);0;1;1|] 1); (new c [|0;(-3);2;0|]) 2];; | |
let rec print_clist l = match l with | |
|x::xs -> print_int(x#id);print_string(" ; "); print_clist xs; | |
|[] -> ();; | |
let gainList = make 4 [];; | |
let rec getGains spells = match spells with | |
|x::xs -> | |
for i = 0 to 3 do | |
if x#deltas.(i) > 0 then begin | |
gainList.(i) <- x::gainList.(i); | |
print_int(x#id); print_string(" has "); print_int(i); | |
print_newline(); end | |
done; | |
getGains xs; | |
|[] -> (); in | |
getGains spelList;; | |
for i = 0 to 3 do | |
print_clist gainList.(i); | |
print_newline(); | |
done;; | |
type poids = Inf | P of int | |
let (++) a b = match a,b with | |
|P(a),P(b) -> P(a+b) | |
|_ -> Inf | |
let (>>) a b = match a,b with | |
|P(a), P(b) -> P(a) > P(b) | |
|Inf, _ -> true | |
|_ -> false | |
let (++=) a b = a := !a ++ b;; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment