http://www.perlmonks.org?node_id=11125777


in reply to using ref to hash of hash effectively

It's not clear for me what you want and all those typos don't help make it clearer.

The following example should get you started

It shows how to iterate easily thru a nested HoH

use strict; use warnings; use 5.10.0; my $weapons_ref = { dagger => { cost => 8, damage => 4, armor => 0 }, shortsword => { cost => 10, damage => 5, armor => 0 }, warhammer => { cost => 25, damage => 6, armor => 0 }, longsword => { cost => 40, damage => 7, armor => 0 }, greataxe => { cost => 74, damage => 8, armor => 0 }, }; while ( my ($k1, $v1) = each %$weapons_ref ){ while ( my ($k2, $v2) = each %$v1 ){ say "$k1 $k2 $v2"; } }

I'd love to see your "easy" JS code tho! ;-)

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^2: using ref to hash of hash effectively
by kalee (Initiate) on Dec 27, 2020 at 15:14 UTC

    Solution in javascript. I don't think this is necessarily the correct way to do this, just one way. I wanted to figure out an efficient way to use the data structures that are available in Perl to solve this. Setting up the data is really what I want to learn

    // Day 21: RPG Simulator 20XX // boss's stats // Hit Points: 100 // Damage: 8 // Armor: 2 function part1() { const WEAPONS = new Map([ ["dagger", { cost: 8, damage: 4, armor: 0 }], ["shortsword", { cost: 10, damage: 5, armor: 0 }], ["warhammer", { cost: 25, damage: 6, armor: 0 }], ["longsword", { cost: 40, damage: 7, armor: 0 }], ["greataxe", { cost: 74, damage: 8, armor: 0 }], ]); const ARMOR = new Map([ ["nothing", { cost: 0, damage: 0, armor: 0 }], ["leather", { cost: 13, damage: 0, armor: 1 }], ["chainmail", { cost: 31, damage: 0, armor: 2 }], ["splintmail", { cost: 53, damage: 0, armor: 3 }], ["bandedmail", { cost: 75, damage: 0, armor: 4 }], ["platemail", { cost: 102, damage: 0, armor: 5 }], ]); const RINGS = new Map([ ["nothing", { cost: 0, damage: 0, armor: 0 }], ["damage+1", { cost: 25, damage: 1, armor: 0 }], ["damage+2", { cost: 50, damage: 2, armor: 0 }], ["damage+3", { cost: 100, damage: 3, armor: 0 }], ["defense+1", { cost: 20, damage: 0, armor: 1 }], ["defense+2", { cost: 40, damage: 0, armor: 2 }], ["defense+3", { cost: 80, damage: 0, armor: 3 }], ]); const BOSS = new Map([ ["damage", 8], ["armor", 2], ["health", 100], ]); const PLAYER = new Map([ ["damage", 0], ["armor", 0], ["health", 100], ]); const getTotalStats = (weapon, armor, leftRing, rightRing) => { return { cost: weapon.cost + armor.cost + leftRing.cost + rightRing.cost, damage: weapon.damage + armor.damage + leftRing.damage + rightRi +ng.damage, armor: weapon.armor + armor.armor + leftRing.armor + rightRing.a +rmor, }; }; const hitPerSecond = (defenderHealth, defenderArmor, attackerDmg) => Math.ceil(defenderHealth / Math.max(1, attackerDmg - defenderArmor +)); const makeMove = (boss, player) => hitPerSecond(boss.get("health"), boss.get("armor"), player.get("da +mage")) <= hitPerSecond(player.get("health"), player.get("armor"), boss.get(" +damage")); function* possibleBundles() { for (let weapon of WEAPONS.values()) { for (let armor of ARMOR.values()) { for (let leftRing of RINGS.values()) { for (let rightRing of RINGS.values()) { if (rightRing.cost !== leftRing.cost) yield getTotalStats(weapon, armor, leftRing, rightRing); } } } } } let result = Infinity; for (let bundle of possibleBundles()) { PLAYER.set("damage", bundle.damage).set("armor", bundle.armor); if (makeMove(BOSS, PLAYER)) result = Math.min(result, bundle.cost) +; } console.log(result); } part1();