Coûts des ressources du réseau électrique

14

Coûts des ressources du réseau électrique

introduction

Dans le jeu de société Power Grid , une partie intégrante du jeu consiste à acheter des ressources pour alimenter vos centrales électriques. Il existe quatre types de ressources utilisées dans le jeu (cinq, si vous incluez des énergies renouvelables, mais vous ne pouvez évidemment pas acheter de ressources pour cela). Ce sont le charbon, le pétrole, les déchets et l'uranium. Le marché des ressources ressemble à ceci:

Une illustration du marché des ressources, tirée du règlement

1---- | 2---- | 3---- | 4---- | 5---- | 6---- | 7---- | 8---- | 10  | 12
CCC   | CCC   | CCC   | CCC   | CCC   | CCC   | CCC   | CCC   |  U  |  U
OOO U | OOO U | OOO U | OOO U | OOO U | OOO U | OOO U | OOO U | 14  | 16
GGG   | GGG   | GGG   | GGG   | GGG   | GGG   | GGG   | GGG   |  U  |  U

Lorsque les ressources sont achetées, elles sont prises à gauche du marché, où elles sont les moins chères. Lorsque de nouvelles ressources sont ajoutées au marché, elles sont ajoutées par la droite. Comme on peut le voir, cela produit un équilibre entre l'offre et la demande - si plus de ressources d'un type particulier sont achetées que réapprovisionnées à chaque tour, le prix de cette ressource augmentera. De même, si c'est moins, le coût diminuera.

Le charbon, le pétrole et les déchets augmentent tous au même rythme, tandis que l'uranium évolue beaucoup plus rapidement. Une seule unité d'une ressource non uranifère coûte 8 - floor((<units available> - 1) / 3). Une seule unité d'Uranium coûte 13 - <units available>s'il y a 5 unités ou plus disponibles, et 18 - (2 * <units available>)autrement.

Par exemple, au début du jeu, les 24 unités de charbon sont disponibles à l'achat. Si le premier joueur souhaite acheter 4 unités de charbon, les trois premières unités coûteront 1 chacune, et la 4ème en coûtera 2, ce qui rend le coût total 5. Cela laisse 20 unités disponibles. Si le deuxième joueur souhaite également acheter 4 unités de charbon, le coût serait (2 * 2 + 2 * 3) = 10.

Le défi

Votre défi consiste à écrire un programme ou une fonction qui calcule le coût d'achat d'une quantité donnée d'une ressource particulière, en supposant qu'une quantité donnée de cette ressource soit présente sur le marché.

Votre soumission doit accepter, dans n'importe quel format d'entrée raisonnable et dans n'importe quel ordre, les paramètres suivants:

  • Type de ressource - garanti comme étant l'un des [C, O, G, U].
  • La quantité de cette ressource qui est présente sur le marché - garantie d'être un entier non négatif. Si le type de ressource n'est pas U, il ne sera pas supérieur à 24. Si le type de ressource est U, il ne sera pas supérieur à 12.
  • Le montant de cette ressource qu'un joueur voudrait acheter - garanti d'être un entier non négatif qui est inférieur ou égal au montant déjà présent sur le marché.

Le résultat devrait être le coût des ressources demandées.

Règles supplémentaires

  • Les formules données sont à titre indicatif seulement, n'hésitez pas à utiliser n'importe quelle méthode de calcul des coûts que vous aimez.
  • Les codes alphabétiques des différents types de ressources (C, O, G, U) peuvent être remplacés par leurs équivalents minuscules. Vous pouvez également remplacer les lettres pour les chiffres, sous la forme C=0, O=1, G=2, U=3ou C=1, O=2, G=3, U=4.
  • Il s'agit de , donc la plus petite soumission en octets sera gagnante.
  • Si votre soumission nécessite la saisie dans un ordre ou un format différent de celui spécifié dans la section précédente, vous devez fournir des détails.

Cas de test

Format du scénario de test:

resource type, amount in market, amount to buy
> result

Cas de test:

C, 24, 4
> 5

C, 20, 4
> 10

O, 3, 3
> 24

U, 1, 1
> 16

C, 1, 1
> 8

G, 0, 0
> 0

O, 10, 7
> 44

U, 12, 4
> 10

G, 11, 4
> 22
Sok
la source
Supposons-nous que les entrées sont légales, ou devons-nous gérer des choses comme f("O",1,5)?
Katenkyo
@Katenkyo Non, comme détaillé dans les spécifications, les entrées sont garanties pour être valides. La vérification des erreurs de l'OMI dans le code golf est fastidieuse, je l'ai donc supprimée: o)
Sok
Parfait, aurait pu manquer cela dans les spécifications. Je vais faire le post pour ma soumission :)
Katenkyo
Je pense qu'il y a des erreurs dans les cas de test. J'ai revérifié et obtenu f(G, 11, 4) = 22et f(O, 10, 7) = 44.
PurkkaKoodari
@ Pietu1998 Vous avez absolument raison, vous ne savez pas comment je me suis trompé: \ édition maintenant
Sok

Réponses:

3

Javascript (ES6), 71 59 octets

f=(t,m,b)=>b&&(t>2?m>4?13-m:18-m*2:9+~(~-m/3))+f(t,m-1,b-1)

Prend type, market_amountet buy_amountcomme arguments. typeest un entier compris entre 0 et 3.

Démo

PurkkaKoodari
la source
4

Python 3, 71 69 octets

Merci à @xnor pour -2 octets

f=lambda r,a,b:b and[8-int(~-a/3),max(18-2*a,13-a)][r>2]+f(r,a-1,b-1)

Une fonction qui prend une entrée via un argument du type de ressource indexé zéro r , le montant disponible aet le montant à acheter b, et renvoie le coût.

Cela fait usage du fait que Trueet Falseéquivalent à1 et 0en Python, permettant l'utilisation d'expressions booléennes pour indexer dans des listes.

Comment ça fonctionne

f=lambda r,a,b           Function with input resource type r, amount available a and amount
                         to buy b
b and...                 Base case: return 0 if b=0
[8-int(~-a/3),...][r>2]  If not uranium, yield the unit cost 8-floor((a-1)/3)...
max(18-2*a,13-a)         ..else yield the current uranium unit cost
...f(r,a-1,b-1)          Decrement a and b, then pass to function
...+...                  Add the cost of each unit to give the total cost
:...                     Return the above

Essayez-le sur Ideone

TheBikingViking
la source
1
Vous pouvez faire max(18-2*a,13-a)à la place de [18-2*a,13-a][a>4].
xnor
3

Befunge, 142 octets

&2`#v_&&>:!#v_\:1-3/8\-v
v:&&<   ^-1\ -1p15+g15 <
v>#<v       <
! v5<
# 1:
>^g-
| 81
\ 4\
: *-
4 -1
` .p
# @^15+g15<
>:49+\-   ^
|
>:2*92*\- ^

Essayez-le ici!Prend l'entrée comme 3 entiers, où le type de ressource est 0,1,2,3. La sortie est un entier.

Aucune idée si cela peut être mieux joué au golf. Il n'y a pas beaucoup d'espace, mais les nouvelles lignes font probablement mal.


la source
3

Python 2.7, 85 octets:

F,G,H=input();B=0;exec"B+=[[18-(2*G),13-G][G>5],8-((G-1)/3)][F!='U'];G-=1;"*H;print B

Basé sur la réponse de R. Kap, mais vous pouvez raser un octet jusqu'à 85 en supprimant la division supplémentaire / pour le plancher. Parce que ce sont tous des entiers, il est automatiquement réduit à un nombre entier.

Strother
la source
1
Bienvenue chez PPCG!
FantaC
2

Python 2.7, 86 octets:

F,G,H=input();B=0;exec"B+=[[18-(2*G),13-G][G>5],8-((G-1)//3)][F!='U'];G-=1;"*H;print B

Prend l'entrée par un tableau au format [resource type, units available, units to purchase] . La sortie est un entier. Va essayer de jouer au golf avec le temps.

Essayez-le en ligne! (Ideone)

R. Kap
la source
2

Lua, 107 101 octets

Fonction récursive qui doit être appelée avec f(resource,stock,buy) . ressource doit être un nombre compris entre 0 et 3. La sortie se fait via la valeur retournée.

Merci LeakyNun de m'avoir sauvé 6 octets: (25-y+(y-1)%3)/3est plus court que 8-math.floor((y-1)/3)5 octets et me permet de gagner un octet de plus en raison de son placement.

function f(x,y,z)return z<1 and 0or(x<3 and(25-y+(y-1)%3)/3or(y<5 and 18-y*2or 13-y))+f(x,y-1,z-1)end

Non golfé

function f(x,y,z)                      -- define a function f with 3 parameters
  return z<1                           -- if we don't buy anything else
           and 0                       --   return 0
         or(                           -- else
           x<3                         --   if we're not buying Uranium
             and (25-y+(y-1)%3)/3      --     return 8-floor((stock-1)/3)                       
           or(y<5                      --   elseif there's less than 5 Uranium left
                and 18-y*2             --     return 18-stock*2
              or 13-y))                --   else return 13-stock
         +f(x,y-1,z-1)                 -- if we bought this iteration
                                       -- add f(resource,stock-1,toBuy-1) 
                                       -- to the returned value
end

Vous pouvez tester ce code en ligne en copiant-collant l'extrait de code suivant.

function f(x,y,z)return z<1 and 0or(x<3 and(25-y+(y-1)%3)/3or(y<5 and 18-y*2or 13-y))+f(x,y-1,z-1)end
print(f(1,24,4))
print(f(2,20,4))
print(f(0,10,7))
print(f(3,1,1))
print(f(3,12,4))
Katenkyo
la source
@ Pietu1998 c'est Lua 5.3. Je ne connais pas le 5.2, mais en 5.3 il ne s'en plaindra pas quand ils ne formeront pas de valeurs hexadécimales. par exemple, 6andne fonctionnera pas car 6aest une valeur hexadécimale, mais 6anne l'est pas.
Katenkyo
8-math.floor((y-1)/3)est vraiment(25-y+(y-1)%3)/3
Leaky Nun