Sorting skills by mana cost

Winterbay

Active member
I have an int[skill]-map where the int is the manacost of the skill. I'd like to sort the map by mana cost but can't figure out how to do it.
The function generating the map looks like this:
Code:
int [skill] allMySkills()
{
	int [skill] allmyskills;
	
	foreach s in $skills[Spaghetti Spear, Ravioli Shurikens, Cannelloni Cannon, Stuffed Mortar Shell, Weapon of the Pastalord, Salsaball, Stream of Sauce, Saucestorm, Wave of Sauce, Saucegeyser]
	{
		if (have_skill(s))
		{
			allmyskills[s] = mp_cost(s);
		}
	}
	return allmyskills;
}

Adding a "sort allmyskills by value" does not appear to help. Is there another, preferably easy, way to do this?

ETA: Currently the list seems to be in alphabetical order of skill name.
 

slyz

Developer
You can't sort a map if you care about both keys. Since mp_cost() is readily available, why not do this:
PHP:
skill [ int ] allMySkills()
{
	skill [ int ] allmyskills;
	
	foreach s in $skills[Spaghetti Spear, Ravioli Shurikens, Cannelloni Cannon, Stuffed Mortar Shell, Weapon of the Pastalord, Salsaball, Stream of Sauce, Saucestorm, Wave of Sauce, Saucegeyser]
	{
		if ( have_skill( s ) )
		{
			allmyskills[ count( allmyskills ) ] = s;
		}
	}
	sort allmyskills by value.mp_cost();
	return allmyskills;
}

foreach i, s in allMySkills() print( s + " ( " + s.mp_cost() + " MP )" );

This is the result for me:
Code:
> call test.ash

Wave of Sauce ( 16 MP )
Saucegeyser ( 28 MP )
but this is what I get if I return all the skills:
Code:
> call test.ash

Spaghetti Spear ( 1 MP )
Salsaball ( 1 MP )
Stream of Sauce ( 3 MP )
Ravioli Shurikens ( 4 MP )
Cannelloni Cannon ( 6 MP )
Saucestorm ( 10 MP )
Stuffed Mortar Shell ( 13 MP )
Wave of Sauce ( 16 MP )
Weapon of the Pastalord ( 24 MP )
Saucegeyser ( 28 MP )

EDIT: for some reading on sort, check here.
EDIT2: I think there was a more educational thread out there, but I can't seem to find it.
EDIT3: Here it is.
EDIT4: And this was the post I was thinking about. I'm done with Mafia archeology for the night :)
 
Last edited:

Bale

Minion
ETA: Currently the list seems to be in alphabetical order of skill name.

maps are always, ALWAYS, ALWAYS in alphanumerical order. That's just how they roll.

slyz only indirectly addressed your point of confusions so I'll spell it out clearly. You misunderstand what sort does. It actually rearranges the values of a map so that they are related to different keys.
 

Winterbay

Active member
Thanks. That helped a lot. I've mainly used sort on records where the key isn't important and sinc ethe wiki page on sort mentioned that you could use it on maps as well I thought i'd give it a shot without apparently really understanding what I was doing :)

Now to get the script to calculate things in the correct manor while I foreach over the skills 5 times...
 

Winterbay

Active member
Mainly trying to get it to go through all combinations of the skills in falling damage order, which corresponds to falling mana cost. I have realised that adding a
Code:
if(mp_cost(skill a) > mp_cost(skill b))
{
    continue;
}

works in much the same way, but now at least my datafile looks nice :)

I will post the result of my work somewhere so that it may be used if wanted since it is, more or less, an expansion of your code in BCCascend 0.22 refactored to work as a macro.

I will test it tomorrow to see if it works, I do now that it runs, but not if the optimisation works since I had no turns left when I finally figured the last part out.
 

zarqon

Well-known member
maps are always, ALWAYS, ALWAYS in alphanumerical order.

foreach s in $strings[a,b,d,c] print(s);

prints:

a
b
d
c

foreach i in $ints[0,5,-2,1] print(i);

prints

0
5
-2
1

Plural typed constants are the exception to this rule -- they are iterated in the order typed.
 

xKiv

Active member
Plural typed constants are the exception to this rule -- they are iterated in the order typed.

I think they are actually not maps (internally, they are allocated as new ArrayList(), then stuffed into PluralValue, which is distinct from MapValue and ArrayValue).
 

zarqon

Well-known member
In ASH they are handled like maps. I wanted to avoid confusion, since I was curious about this very issue recently.
 

Veracity

Developer
Staff member
They're not even (ASH) arrays, really. You do a foreach on an ASH array, you get keys from 0 to n and the values are whatever is in the array.
You do a foreach on a PluralValue, you get the "keys" as the various elements and the value - should you care to look - will be "true".
 

slyz

Developer
I never really understood what an array was, in ASH. It it just a map indexed by keys 0 to n with only one dimension?
 

Veracity

Developer
Staff member
It looks and behaves that way, but is implemented internally in terms of java arrays. Either a map or an array is, really, one dimensional; multi-dimensional ones are simply maps or arrays whose values are maps or arrays.

item [12] array;

Can use keys 0 - 11. You get a runtime error if you use any other key. It always uses memory to hold 12 items, even if you only use a couple of them. But it's a constant time - O(1) - to access any element.

item [int] map;

Can use any int as a key. It has constant memory for the Java map, and additional memory for each element in the map, but is O( log n) to access any particular element.

Each has its use.

If you are able to use (a fairly densely packed set of) integers as keys, your program will be faster and use (potentially) slightly more memory.
If you have a sparse set of integers, you can still use an array and get fast access, but you will waste a lot of memory.
If you can't use integers as keys or don't want to waste memory on a sparse array, you can have a slower but less memory consuming map.
 
Last edited:

zarqon

Well-known member
Thanks Veracity, that's very useful info and should probably be in the ASH Wiki.

I wasn't picking a nit with Bale's remark. I just wanted to avoid confusion, since plural constants (which are commonly used and could easily be assumed to be maps) are not quite arrays and not quite maps, and many people don't even seem to realize ASH arrays exist. I'd actually assumed they would be sorted by key until fairly recently. If I assumed it, it's probably fair to say that others would too.

This might be a good opportunity to ask an academic question -- which of these is faster:

if (a == item1 || a == item2 || a == item3)

or

if ($items[item1, item2, item3] contains a)

I would assume the first, but I like the compactness of the second. I would love to be surprised by the answer. :)
 
Thanks Veracity, that's very useful info and should probably be in the ASH Wiki. ... and many people don't even seem to realize ASH arrays exist.

Indeed. I had assumed that split_string() was the only (and maybe other similar functions) way to get an array, and that creating one yourself was strictly out of the question and should be handled by using a map.

Good to know.
 

jasonharper

Developer
This might be a good opportunity to ask an academic question -- which of these is faster:

if (a == item1 || a == item2 || a == item3)

or

if ($items[item1, item2, item3] contains a)

I would assume the first, but I like the compactness of the second. I would love to be surprised by the answer. :)
This is going to depend on the number of items in the list, and which one happens to match; if 'a' is almost always item1, then the first form is likely to win on practical grounds, even though it's theoretically slower (O(n) vs. O(log n)).

The second form is a definite win assuming no such coincidences of the item chosen, a somewhat larger set of items, and that the code is executed more than once per run of the script. The first lookup in a plural constant actually builds an internal map that allows such queries to be efficiently done; this is deferred because typical use of a plural constant involves only iteration, not lookups.

There's always the "profile" command, if you really need to know which is more efficient in a given situation - although it's unlikely that either would have a noticeable effect on your script's performance.
 

Bale

Minion
That was a very interesting and useful answer. Thank you for asking it zarqon, and thanks for answering it Jason.
 
Top