f

#### Best attack order for groups of numbers trying to destroy each other, given a victory chance for number to number attack.

```Hello,

(This problem is probably too computationally intensive to solve with Pytho=
n, though Python + Cuda could be interesting, and also Python has some inte=
resting expressive powers, so it could be interesting to see how Python pro=
grammers might be able to express this problem with Python code, so I am go=
ing to give this Python group a try... maybe it will surprise me ! :) At le=
ast now you have a nice computational problem for those boring rainy days (=
when the net is down?and the offline games bore you ;) LOL :))

There are two groups of numbers which try to destroy each other:

Group X =3D 1,2,3,4
Group Y =3D 1,2,3,4

There is a 4 by 4 victory table which describes the chance of a number=20
destroying another number:

Victory table =3D
50,  3, 80, 70
90, 60, 20, 40
30, 90, 55, 65
75, 90, 98, 60

(Currently implemented as a chance by diving it by 100 and storing as=20
floating point, but since these are subtracted only from 1.0 I guess they=
=20
can be stored as integers instead, even bytes)

This leads to the following computational problem as far as I am concerned:

Each number has an attack order permutation as follows (factorial 4 =3D=20
1x2x3x4 =3D 24)

1,2,3,4    // 1
1,2,4,3    // 2
1,3,2,4    // 3
1,3,4,2    // 4
1,4,2,3    // 5
1,4,3,2    // 6
2,1,3,4    // 7
2,1,4,3    // 8
2,3,1,4    // 9
2,3,4,1    // 10
2,4,1,3    // 11
2,4,3,1    // 12
3,1,2,4    // 13
3,1,4,2    // 14
3,2,1,4    // 15
3,2,4,1    // 16
3,4,1,2    // 17
3,4,2,1    // 18
4,1,2,3    // 19
4,1,3,2    // 20
4,2,1,3    // 21
4,2,3,1    // 22
4,3,1,2    // 23
4,3,2,1   // 24

(These attack orders can be numbered from 1 to 24 or 0 to 23 and then it's=
=20
attack order/permutation can be looked up to safe memory.)

Each number has it's own attack order and thus this leads to the following=
=20
combinational computational problem:

All combinations of permutations in which order group X can attack Group Y=
=20
and vice versa:

Group X =3D 24 x 24 x 24 x 24
Group Y =3D 24 x 24 x 24 x 24

So this is 24 possibility to the power of 8.

Final computation complexity at the very minimum is (24 to the power of 8)=
=20
multiplied by roughly 4 attacks perhaps even 5 or 6 to finally destroy a=20
group of numbers.

24 to the power of 8 =3D 110.075.314.176

I have already written a computer program which can solve this, however the=
=20
computer program estimates it takes 19 hours on a 2.0 gigahertz AMD Athlon=
=20
X2 core.

Using dual core could solve the problem over night, though I do not feel=20
comfortable running my PC at night unattended.

So now I have the idea to make this program run when my computer is idling=
=20
during the day, it should also be able to store it's progress so that it ca=
n=20
continue after it was shutdown.

(Idea for now is to make it multi threaded and assign a low thread priority=
=20
so it can run during the day when I use my computer and it's not doing much=
=20
so it can use the reserve computational horse power).
(I still have to try these "idle/reverse" ideas to see which one works best=
=20
without interrupting my web browsing or music listening too much ;))

My system has 4 GB of ram, so other ideas could be to store a data structur=
e=20
partially which could keep some computations so that it doesn't have to be=
=20
done again... Though memory lookups might be a bit slow so not sure if that=
=20
makes any sense.

I might also try GPU/Cuda since there seems to be lots of loops/reoccurence=
s=20
of the same computations that will happen over and over again... So maybe=
=20
cuda can detect "same branch execution" and some "computations" and might=
=20
speed it up, not sure about that.

Just the 8 index loops already cost a lot of instructions. Since there are=
=20
only 24 permutation it would be enough to store it in 5 bits. Perhaps a=20
rounded floating point which increases by 1/24 might be enough to trigger=
=20
the 4th bit from incrementing when it actually needs to.
2x2x2x2x2 =3D 32  (it should increment bit 6 when the 5 bits reach 24).
So the idea here was to create 8 indexes from just 1 index being incremente=
d=20
to create the 8 combinations of indexes "instruction cheaply".
Not sure if this will work, just an idea I might try :)

Then those bits would still need to be extract and makes. So perhaps on=20
older systems this is not efficient.

The 8 indexes need at least 3 instructions, 1 index increment, 1=20
comparision, 1 jump.

The inner loop contains some while loops to increment attack index per=20
number.

Each number has a "alive" variable which starts at 1.0 and is decreased=20
everytime it's attacked.

Once a number is dead below 0.0000001 it's considered dead and can no longe=
r=20
attack.

(Since victory table was described as integers above this can also be read=
=20
as: Alive starts at 100 and once it goes zero or negative it's dead).

Anyway the main reason why I wrote to this/these groups is that the numbers=
=20
themselfes are not that larger and can fit in a byte, even a few bits.

Thus they will fit into SSE registers and such and I also know SSE has some=
=20
permutations instructions.

I am not expert at SSE but I am wondering if there are perhaps some=20
SSE1/2/3/4/5 instructions which can help at solving/computing this problem =
?

Now the question you might be wondering about is ? What am I actually tryin=
g=20
to compute ?

Well the final output could simply be the number of victories that each=20
attack order has had per number. I am particullary interested in victories=
=20
of number 4. So that would be sufficient for now.

Number 4 has 24 permutations.

So I want to know how each permutation of number 4 performs under all other=
=20
circumstances/permutations of all other numbers/combinations and so forth.

This basically requires the entire set to be computed and then record numbe=
r=20
of victories for for example Group X number 4.

Only the results of one group needs to be outputted since the two groups ar=
e=20
a mirror of each other.

Also during the development of the computer program I finally had a=20
successfull implementation by keeping it as simple as possible and working=
=20
with direct variables, instead of much more complex arrays.

Later on I made a more code efficient version which uses arrays/lookups and=
=20
such. It was much harder to try the array approach at first since it become=
s=20
mindly complex and can obscure "vision to a solution".

So I suggest anybody trying to implement a solver for this to keep the code=
=20
as simple as possible at first, since this is already an 8 dimensional=20
problem with a 9th dimension.

Also it was interesting to see the Delphi for loops not allowing array=20
fields as loop variables, so those loops will need to be fleshed out anyway=
,=20
or one big linear loop could be used and then 8 indexes calculated from=20
that.

That approach will probably be necessary for a cuda solution anyway... 32=
=20
bit might be sufficient if remainders are reincluded in the conversion from=
=20
thread/block dimensions to linear dimension back to 8 dimensional indexes.

Perhaps such computation might even be a bit quicker than the 3 instruction=
s=20
per loop.

For example 8 divisions and 8 remainders will be necessary to compute 8=20
indexes from one big linear indexes. Since div/mod can be the same=20
instruction this might only require 8 instructions to compute these loop=20
indexes from a big linear index.
However computing the big linear index already requires between 6 or 10=20
instructions.

So just to compute those 100+ billion data entries requires something like=
=20
20 instructions just to be able to compute those loop indexes.

This is my finding with bigger data sets which consists out of small little=
=20
data units... The closer the number of entries/data items get to the=20
actually processing computing power the more time/processing/instructions=
=20
are wasted on just computing these loop indexes.

It makes sense from this perspective: A problem of 100 items only needs 100=
=20
loops. Thus lots of processing power remains for the data. But for 2 billio=
n=20
data items, the number of items already matches the gigaherts of the core..=
..=20
so the core is already swamped... with just loop index calculations.

I hope this reasoning/explanation convinces some CPU/GPU designers to=20
include more instructions to compute loop indexes in all kinds of ways that=
=20
could speed that up somewhat and safe some processing time.

Anyway... let me know if you think SSE could be of some help in solving thi=
s=20
permutation/combination problem ?!

Also for the python newsgroup:

Maybe python is more powerfull than I thought and it has some weird/kinda c=
razy/cool new permutation/combination algorithmic classes that can solve th=
ese kinds of problems faster than just the average run of the mill general =
code ! ;)
(Or perhaps build in solver support, that will be my next try/posting :P :)=
)

Bye,
Skybuck.=20
```
 0
skybuck2000
12/9/2016 12:26:21 PM
comp.lang.python 77058 articles. 6 followers.

31 Replies
801 Views

Similar Articles

[PageSpeed] 40

```On Fri, 9 Dec 2016 04:26:21 -0800 (PST), skybuck2000@hotmail.com declaimed
the following:

>I have already written a computer program which can solve this, however the
>computer program estimates it takes 19 hours on a 2.0 gigahertz AMD Athlon
>X2 core.
>

>Using dual core could solve the problem over night, though I do not feel
>comfortable running my PC at night unattended.
>
Why? Is it going to let the magic smoke out when you aren't watching
it?

If you've implemented any decent sort of back-up procedure, running
late at night is probably the best time for backups to run, so running
overnight is common {reminds me, I still need to set up the back-up
schedule for the new OS install -- system failed catastrophically, and DELL
in its wisdom did not provide stand-alone OS installer media, just a
recovery partition on the original drive... Cloning the first partitions to
a new drive and using the "repair" CD burned when first receiving the
system just gave "No valid OS found"... So goodbye Win7, hello 1980s flat
windows with 8-crayon color scheme \$200 Win10}

>So now I have the idea to make this program run when my computer is idling
>during the day, it should also be able to store it's progress so that it can
>continue after it was shutdown.
>

Periodic snap-shots of the running environment will likely take up a
majority of the run-time. Especially if your idea is to first generate two
lists of the permutations of the inputs, then generate a list of the
"combat" permutations, and you want to be able to store-off/reload all
those lists.

>(Idea for now is to make it multi threaded and assign a low thread priority

It's CPU-bound, so using multiple threads for the computation won't be
the threads, and for common Python, you run into the GIL (so even if you
get subsets of processing assigned to each of multiple processor cores, the
GIL will block all but one from doing any work at any moment -- say you
partitioned it so core0 handles only the set where X begins [1, ...], core
1 handles [2, ...], etc.).

>so it can run during the day when I use my computer and it's not doing much
>so it can use the reserve computational horse power).
>(I still have to try these "idle/reverse" ideas to see which one works best
>without interrupting my web browsing or music listening too much ;))
>

Web browsing and such will tend to be I/O bound -- those applications
spend most of their time waiting for I/O operations to complete. Any modern
multi-tasking OS will let computational processes run while the I/O stuff
is blocked -- and should pre-empt the computational stuff when I/O
completes (interrupt from I/O device or DMA processor).

>My system has 4 GB of ram, so other ideas could be to store a data structure
>partially which could keep some computations so that it doesn't have to be
>done again... Though memory lookups might be a bit slow so not sure if that
>makes any sense.
>
<SNIP>
>Just the 8 index loops already cost a lot of instructions. Since there are
>only 24 permutation it would be enough to store it in 5 bits. Perhaps a
>rounded floating point which increases by 1/24 might be enough to trigger
>the 4th bit from incrementing when it actually needs to.
>2x2x2x2x2 = 32  (it should increment bit 6 when the 5 bits reach 24).
>So the idea here was to create 8 indexes from just 1 index being incremented
>to create the 8 combinations of indexes "instruction cheaply".
>Not sure if this will work, just an idea I might try :)
>
Not seeing any code makes it hard to estimate where your slow-downs
would be, however all your mentions of keeping "index" values implies (as I
mention above) that you are trying to build huge tables of permutations
first, then beating each entry against those of the other. In truth, I
can't figure out what you consider a combat, what you consider a number,
nor how your result table works (you don't identify x vs y, and since it is
not diagonally symmetric that makes a difference... nor do the rows/columns
sum to 100%)

>>> import itertools
>>> for x in itertools.permutations("1234"):
.... 	xout = "".join(x)
.... 	for y in itertools.permutations("1234"):
.... 		print xout, "".join(y)
....
1234 1234
1234 1243
1234 1324
1234 1342
1234 1423
1234 1432
1234 2134
1234 2143
1234 2314
1234 2341

Replace the print with something to compute just the win/loss stuff for the
single x vs y, and save the result off -- since I couldn't work out your
scoring I can't say if a dictionary keyed by the permutation makes sense...
And are you generating random numbers to determine the winner/loser? How
many cycles -- loop on random values until one or the other is "dead". What
is the statistics? How many combats the digits took (ie, number of cycles
of random)... How many it took for all four digits to die?

--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/9/2016 2:01:36 PM
```Hello,

is not visible on google groups. I wonder why, maybe it's a banned troll o=
r something, but perhaps not.

Anyway... my ISP has problems accessing their newsserver. They won't offer =
the service to new customers or changing subscriptions and they lack softwa=
re to access the server. The server currently has a technical problem. Uplo=
ading messages is not possible. Some kind of bug... this has been going on =
for months. Seems like the bug will be ever lasting.

Just called ISP helpdesk... I forgot to ask them if they could simply reset=
the server... but with the little information I was giving it seems to be =
a "remote control problem".

The server is probably remotely controlled and somehow that remote control =
has been lost... Either password lost, or software is not working anymore..=
.. kinda strange story... especially for such a large ISP which should have =
sufficient technical people to solve this... weird story isn't it... perhap=
s they just don't want to fix it to drop people of of it....

This kinda sucks for me because using usenet via google newsgroups complete=
ly sucks... and is like 1.000.000 times more difficult with this very lacki=
ng interface.

But for messages that I consider worth it... like this one, I might keep on=
going(/presserve? gotta look that up in dictionary) for now... :)

Anyway here is my reply, it might enlighting others as well to this exact p=
roblem:

>So now I have the idea to make this program run when my computer is idling
>during the day, it should also be able to store it's progress so that it=
=20
>can
>continue after it was shutdown.
>

"
Periodic snap-shots of the running environment will likely take up a
majority of the run-time.
"

(Since you the only one who has replied so far I will take some time to try=
=20
=20
usefull to others as well).

Haven't implemented this yet, but I don't see why that would be the case.

It would probably need to store very little. Only 8 indexes, and perhaps=20
4x24 entries so that's nothing.

This could be then everything index4 increments for example, or index 3.

Somewhere below in this posting I will give some pseudo code for the indexe=
s=20
since it seems you might be struggling with that a little bit or you are=20
trying to solve it a different way which is interesting to see but in this=
=20
case I don't think it's better so I will adjust you there, but first

I reply to the rest of your posting so the pseudo code will be somewhere=20
below...

"
Especially if your idea is to first generate two lists of the permutations=
=20
of the inputs
"

The permutations were already given by me in my original post. No further=
=20
permutation lists are needed. The permutation table was simple generated=20
with some 1234 string with some Delphi code found from the internet.

Generating permutations is not the real issue here, since there is code on=
=20
the internet which already solves that.

"
then generate a list of the "combat" permutations, and you want to be able=
=20
those lists.
"

I don't see why it would be necessary to store any lists at all, except fro=
m=20
the permutation table as to avoid having to implement a complex permutation=
=20
algorithm. Generating permutations is a topic in itself so I tried to avoid=
=20
that by simply hard coding the small permutation list into the code to side=
=20
step that sub problem.

possible because of lack of memory or would require way too much time.

What should however be stored is the number of victories for each=20
permutation.

>(Idea for now is to make it multi threaded and assign a low thread priorit=
y

"It's CPU-bound, so using multiple threads for the computation won't be
that effective..."

I disagree, the problem is pretty straight forward and can be split just=20
fine by duplicating some simple indexes/data structures.

And should be able to run on each core at nearly 100% efficiency.

The results could be merged together at the very end.

At least in Delphi/native code this will work nicely...

the threads, and for common Python, you run into the GIL (so even if you
get subsets of processing assigned to each of multiple processor cores, the
GIL will block all but one from doing any work at any moment -- say you
partitioned it so core0 handles only the set where X begins [1, ...], core
1 handles [2, ...], etc.).
"

Your last sentence made the most sense to me... I don't know what GIL is or=
=20

I would assume it would not be to bad concerning overhead and that python=
=20
threads can run pretty efficient as well, if not that would surprise me a=
=20
little bit.

Ofcourse there would only be 2 threads since it's a dual core system. If yo=
u=20
ment running more than 2 threads then yes there would be context overswitch=
=20

But why would anybody want to run more threads than the number of cores ?!=
=20
;) Since it's not necessary to run more threads to divide up the problem.

>so it can run during the day when I use my computer and it's not doing muc=
h
>so it can use the reserve computational horse power).
>(I still have to try these "idle/reverse" ideas to see which one works bes=
t
>without interrupting my web browsing or music listening too much ;))
>

<snip>

"
Not seeing any code makes it hard to estimate where your slow-downs
would be, however all your mentions of keeping "index" values implies (as I
mention above) that you are trying to build huge tables of permutations
first, then beating each entry against those of the other.
"

I quickly realised that this approach (generating huge lists) won't work=20
because out of memory.

So instead each possibility is simply calculated and only results are=20
stored.

"In truth, I can't figure out what you consider a combat"

I did not use the term "combat". I do think of them as "attacks".

We could define "combat" as simple "one of the possibilities".

So let's look at a single possibility to explain it to you.

I will simply produce a random index example:

Index1: 7
Index2: 22
Index3: 12
Index4: 10
Index5: 4
Index6: 9
Index7: 11
Index8: 5

Now the task for program is to calculate the outcome of battle.

The program will eventually lookup the permutations from the permutation=20
table so let's get those first:

First let's copy & paste the permutation table from original posting:

1,2,3,4    // 1
1,2,4,3    // 2
1,3,2,4    // 3
1,3,4,2    // 4
1,4,2,3    // 5
1,4,3,2    // 6
2,1,3,4    // 7
2,1,4,3    // 8
2,3,1,4    // 9
2,3,4,1    // 10
2,4,1,3    // 11
2,4,3,1    // 12
3,1,2,4    // 13
3,1,4,2    // 14
3,2,1,4    // 15
3,2,4,1    // 16
3,4,1,2    // 17
3,4,2,1    // 18
4,1,2,3    // 19
4,1,3,2    // 20
4,2,1,3    // 21
4,2,3,1    // 22
4,3,1,2    // 23
4,3,2,1   // 24

Now let's retrieve the permutations for the indexes:

(instead of calling it a permutation I will now call it an "attack order"):

Index1: 7  Attack order: 2,1,3,4
Index2: 22  Attack order: 4,2,3,1
Index3: 12  Attack order: 1,3,2,4
Index4: 10  Attack order: 2,3,4,1
Index5: 4  Attack order: 1,3,4,2
Index6: 9  Attack order: 2,3,1,4
Index7: 11  Attack order: 2,4,1,3
Index8: 5  Attack order: 2,1,4,3

Now the computer program can perform the combat.

However perform I explain further how a combat would be performed I will tr=
y=20

", what you consider a number,"

A number is a tag uppon an object. The object could be a ship, a tank, an=
=20
airplane, or whatever the real world scenerio is behind the problem.

I was considering mentioning this, but I thought it let it out just for the=
=20
fun of it. Consider "number" the number of the object performing the attack=
..

Perhaps giving some context to these numbers might have helped to imagine=
=20
the problem better. If this is indeed the case then perhaps a little "sorry=
"=20
might be in place.

Numbers usually don't fight each other... so that concept/idea is kinda=20
weird/vague... I was kinda hoping that people would find it a bit funny...=
=20
but could see through that and understand by themselfes that these
numbers probably could represent a solder,tank,plane,ship and so forth. I=
=20
also want to conceal what this program will be used for just to thart any=
=20
possible/potential enemy that might read these postings ! :)
But if you must know it's written to help me understand which attack=20
strategies work better and which work less well in a specific online game..=
..=20
but that's all I will say about it... perhaps you can now already interfere=
=20
which game it might be ;)

"nor how your result table works"

Hmmm fair enough point I guess perhaps that wasn't so clearly described. If=
=20
you want me to give you an exact definition then fair enough.

The results table is simply the number of numbers on each team dimensionall=
y=20
multiplied by the number of permutations (=3Dattack orders).

So since momentarily the team consists out of 4 contenders/numbers and sinc=
e=20
attack orders are 24 the entire result table would be a 2D table: 4 by 24.

"you don't identify x vs y"

X is a group
Y is a group

I think this was pretty clearly defined ? However I can see how your=20
question might be related to the victory table since you seem to be unsure=
=20
what the rows and columns represent.

I was kinda hoping that you would automatically understand what it ment=20
based on the description of "numbers fighting each others". But perhaps tha=
t=20
description was too vague and too multi-interpretable. Or simply too=20
confusing/unclear to what it relates.

To put it simply: The victory table describes the "number to number" attack=
=20
chance. Which means the individual chance of an individual number attacking=
=20
another individual number. In other words the victory table has nothing to=
=20
do with the groups themselfes.

Since there are only two groups I don't see how a victory table could be=20
related to the groups themselfes. However the groups were tag as X/Y also t=
o=20
prevent confusing with the speaking term "a table", "a bank", "a bike".

However now that I see me writing this table if you plot the table versus=
=20
the x-axis and the y-axis... and put some numbers on it... it might have=20
been more clear. I am afraid that apperently it's still not clear ?!

So I will have to explain harder... at least for you... maybe for others=20
two... perhaps an example will help to clearify how the Victory Table is to=
=20
be used.

Also perhaps I should have mentioned that each number is also a type. That=
=20
might have made it more clear how the envision the victory table.

So to help you understand I will now describe that number 1 could represent=
=20
a horse, number 2 could represent a tank, number 3 could represent a plane,=
=20
number 4 could represent a ship.

What the numbers/types truely represent will remain concealed for now to=20
thart any enemies reading this text :)

However I hope by "applieing" types/classes to the numbers that maybe now i=
t=20
is starting to make some sense to you.

The victory table basically describes what the chance is that for example a=
=20
horse will win from a tank.

Or what the chance will be of a tank winning against a ship.

Or what the chance will be of a plane winning against a ship.

So basically the Y-Axis describes the source=3Dattacker

So basically the X-Axis describes the destination=3Dtarget

Finally the chance in the table itself thus describes the chance of the=20
attacker killing the target.

(The chance could also be interpreted as "damage done" which is actually=20
what my code uses for now).

", and since it is not diagonally symmetric that makes a difference... "

I don't quite understand this sentence of yours... a bit weird... but I=20
guess this was because of your confusion and because you trying to sum the=
=20
entries in the victory table for some reason, which is because of=20
misunderstand... it's not necessary, I hope to have cleared that up above=
=20
and will continue with an example below.

"nor do the rows/columns sum to 100%)"

Not required.

Finally an example.

Let's say a horse attacks a tank.

What would it's chance of winning be ?

Let's first define the numbering as describes above:
Horse=3D1
Tank=3D2
Plane=3D3
Ship=3D4

Let's re-examine our victory table:

Let's apply some row/column numbering perhaps that will clearify it a bit=
=20
for you.

1   2   3   4
1: 50,  3, 80, 70
2: 90, 60, 20, 40
3: 30, 90, 55, 65
4: 75, 90, 98, 60

Now the program wants to know what is the chance of a horse defeating a tan=
k=20
?

So horse =3D 1

So proceed to row.

So tank =3D 3

So proceed to column 3.

This gives the horse a winning chance of 80%.

Ofcourse this makes completely nosense with these horse, tank, plane,ship=
=20
descriptions.

But I hope you get the idea.

So finally what could a possible solution program do to calculate outcome o=
f=20
battle ?!? Let's proceed with the example:

Index1: 7  Attack order: 2,1,3,4
Index2: 22  Attack order: 4,2,3,1
Index3: 12  Attack order: 1,3,2,4
Index4: 10  Attack order: 2,3,4,1
Index5: 4  Attack order: 1,3,4,2
Index6: 9  Attack order: 2,3,1,4
Index7: 11  Attack order: 2,4,1,3
Index8: 5  Attack order: 2,1,4,3

Index 1,2,3,4 belongs to group X
index 5,6,7,8 belongs to group Y (5,6,7,8 renumbered as 1,2,3,4)

From the information above it's now clear how group X will attack group Y=
=20
and how group Y will attack group X.

X1 will first attack Y2
X2 will first attack Y4
X3 will first attack Y1
X4 will first attack Y2

Y1 will first attack X1
Y2 will first attack X2
Y3 will first attack X2
Y4 will first attack X2

From looking at this first round of attacks from above it's already pretty=
=20
clear that Group Y has "chosen" to attack X2 with 3 objects. Thus it's very=
=20
likely that X2 will be destroyed.

Funny enough groupX is also attacking Y2 but only with 2 objects. So Y2 is=
=20
also likely to be destroyed but a bit less likely.

How the program now proceeds with calculations is open to debate.

There are two possibilities:

Either the program considers X2 destroyed if the chances are subtracted fro=
m=20
100 and it goes below 0. (The chances are lookup in the victory table as=20
describes in the example above for horse vs tank).

This I would call the "dynamic" approach... it complexifies the problem=20
somewhat... a number which is destroyed cannot further attack so it will no=
t=20
take part in the next round of attacks.

However another approach could be taken which stays more true to the concep=
t=20
of a "decision tree". Instead of subtracting the chances, the chances could=
=20
also be multiplied... this will reduce the chance of X2 being alive, but it=
=20
is still allowed to participate in the fight assuming
it had a very low chance of surviving but might have miracously survived. T=
o=20
compensate for this perhaps further attacks from X2 should have it's chance=
=20
of success reduced... to make the computation a bit more realistic but stil=
l=20
computationally easy to do: just a multiplication, no branches.

So for now I will explain how my program proceeds. Without actually looking=
=20
up the chances... which would be a bit much work to do... I will simply=20
assume that X2 died and perhaps Y2 too.

So the next round commences as follows:

(attack targets/indexes acquired from attack order from above):

X1 will first attack Y1
X2 (destroyed)
X3 will first attack Y3
X4 will first attack Y3

Y1 will first attack X1
Y2 (destroyed)
Y3 will first attack X4
Y4 will first attack X1

Perhaps after this second round Y3 is destroyed, perhaps X1 is destroyed

So round 3 commences:

X1 (destroyed)
X2 (destroyed)
X3 will first attack Y2
X4 will first attack Y4

Y1 will first attack X4
Y2 (destroyed)
Y3 (destroyed)
Y4 will first attack X4

Apperently group Y had the more lucky permutation of attack orders, here=20
they jointly attack 4 so it's likely 4 was described which gives them a=20
better chance of winning since now they are +1 vs the enemy, while Y2/Y4 ar=
e=20
only damaged but not yet destroyed.

Let's see what happens in potentially the final round:

X1 (destroyed)
X2 (destroyed)
X3 will first attack Y4
X4 (destroyed)

Y1 will first attack X2, cycles to X1, cycles to X3
Y2 (destroyed)
Y3 (destroyed)
Y4 will first attack X3

Here my program if I remember correctly will detect that enemy X2 is alread=
y=20
destroyed so it's starts cycling/wrapping it's attack order index to find=
=20
which one it should attack next until it finds X3 still alive and attacks=
=20
it.
(First Y1 tried X1 according to it's attack order "table" but X1 is also=20
already destroyed so it proceeds to X3).

From this "permutation" example it seems likely that X3 was destroyed and=
=20
group Y might be the winner.

However if group Y is truely the winner will depend on the actually victory=
=20
chances... perhaps something weird occured and one of the objects was easil=
y=20
destroyed by a high victory chance... even though it was 1 vs 1... thus thi=
s=20
might have completely altered the outcome of battle.

So that's what the computer program will have to do/compute.

Also finally let's look at the results table.

For this outcome the results table would be adjusted as follows:

Group Y won, so no adjustment. Only Group X is examined, since it's a mirro=
r=20
of each other.

However let's assume that the exact same battle happens but vice versa.=20
Group X/Y swapped.

In that case the results table would be adjusted as follows:

Index1: 7   Victories +1
Index2: 22  Victories +1
Index3: 12  Victories +1
Index4: 10  Victories +1

This basically means that the permutation 7 for object 1 has +1 victories=
=20
independently record of what the rest did.
This basically means that the permutation 22 for object 2 has +1 victories=
=20
independently record of what the rest did.
This basically means that the permutation 12 for object 3 has +1 victories=
=20
independently record of what the rest did.
This basically means that the permutation 10 for object 4 has +1 victories=
=20
independently record of what the rest did.

So basically in C/Delphi like terminology:
ObjectPermutationVictories[1,7]++
ObjectPermutationVictories[2,22]++
ObjectPermutationVictories[3,12]++
ObjectPermutationVictories[4,10]++

*** Continueing with the rest, unrelated to above ***

(By the way I made a little typo in this weird text below 3th should have=
=20
been 5th, I thought 3 bits would be enough but it actually needed 5 bits):

"
Just the 8 index loops already cost a lot of instructions. Since there are
only 24 permutation it would be enough to store it in 5 bits. Perhaps a
rounded floating point which increases by 1/24 might be enough to trigger
the 5th bit from incrementing when it actually needs to.
2x2x2x2x2 =3D 32  (it should increment bit 6 when the 5 bits reach 24).
So the idea here was to create 8 indexes from just 1 index being incremente=
d
to create the 8 combinations of indexes "instruction cheaply".
Not sure if this will work, just an idea I might try :)
"

If you don't understand this crazy idea above in quotations then you can=20
safely ignore it. It is not used it was an experimental thought how things=
=20
might be done differently in regards to advancing the indexes.

***

Now continueing with the rest of your questions

"
>>> import itertools
>>> for x in itertools.permutations("1234"):
.... xout =3D "".join(x)
.... for y in itertools.permutations("1234"):
.... print xout, "".join(y)
....
1234 1234
1234 1243
1234 1324
1234 1342
1234 1423
1234 1432
1234 2134
1234 2143
1234 2314
1234 2341
"

I don't quite understand that python code, but I can imagine what it might=
=20
be doing... but it's probably not correct, it's too simplistic. Or perhaps=
=20
this was just to generate the permutations.

As I wrote above... generating the permutations is not really the problem,=
=20
they can be looked up from the permutation table.

"
Replace the print with something to compute just the win/loss stuff for the
single x vs y, and save the result off -- since I couldn't work out your
scoring I can't say if a dictionary keyed by the permutation makes sense...
"

For now I will not reply to this...  there seems to be some understanding i=
n=20
what you wrote... but for now I will wait to see if this new reply of mine=
=20
will have clearified a lot for you and thus perhaps I do not need to respon=
d=20
to the text above.

"
And are you generating random numbers to determine the winner/loser?
"

No, brute force is applied to calculate which group wins, in case you ment=
=20
which group wins/losses. If you ment which number wins, then that is giving=
=20
by a chance lookup and perhaps a health variable per object which is=20
decremented. However you are free to decide what
to do... kill of numbers ? keep them alive ? Use a different way of=20
reasoning what should happen to them. The victory chance should be applied=
=20
somehow though. It definetly should influence the outcome of battle somehow=
..

" How many cycles -- loop on random values until one or the other is "dead"=
..=20
"

A "while loop" which examines the "alive status" of each number/object is=
=20
used to examine if the battle came to an end. As long as each team has an=
=20
alive member the fight/combat continues.
Once the numbers of one group are completely destroyed, the other group=20
wins. In case both groups destroy each other at the same time, it's a draw.

"What is the statistics? How many combats the digits took (ie, number of=20
cycles of random)... How many it took for all four digits to die?"

Nice question.

This depends on the approach taken. I decided to take a "natural" feeling=
=20
approach, which I call the "dynamic approach". The combat for each=20
possibility is continued until one group dies. Therefore it's hard to say=
=20
what the exact number of "rounds" or "cycles" as you call them it will take=
..

However it will probably be something like 4 or 5 cycles. This is kind of a=
n=20
interesting question. Some additional statistical analysis variables could=
=20
be added to the code to track what the average number of rounds is, what th=
e=20
minimum was and what the maximum was !

Thanks for this feedback it's kinda interesting ! ;)

Bye,
Skybuck.=20
```
 0
skybuck2000
12/15/2016 11:23:43 AM
```skybuck2000@hotmail.com wrote:

> I received a reply from somebody on my ISP newsserver. Apperently his
> reply is not visible on google groups. I wonder why, maybe it's a banned
> troll or something, but perhaps not.

No, that's Dennis Lee Bieber who doesn't want his posts to be kept, and
seems to be the only one to post here with the X-No-Archive flag set.

```
 0
Peter
12/15/2016 12:16:33 PM
```On Thu, 15 Dec 2016 03:23:43 -0800 (PST), skybuck2000@hotmail.com declaimed
the following:

>Hello,
>
>I received a reply from somebody on my ISP newsserver. Apperently his reply is not visible on google groups. I wonder why, maybe it's a banned troll or something, but perhaps not.
>
It is almost impossible to get anyone banned by Google Groups... It is
more the other way around -- a lot of Google Groups/GMAIL spam gets
filtered out when the posts move into the Python mailing list (which is
gatewayed between Usenet comp.lang.python -- with that being where Google
gets the stuff).

As for my posts disappearing: I run with "X-NoArchive" set. I have from
before Google absorbed DejaNews. Back then, most news-servers expired posts
on some periodic basis (my ISP tended to hold text groups for 30 days or
so, binaries groups cycled in less than 36 hours). When DejaNews arrived,
many objected to the non-expiration facet:

>
>But for messages that I consider worth it... like this one, I might keep on going(/presserve? gotta look that up in dictionary) for now... :)
>

"Persevere"

>
>I don't see why it would be necessary to store any lists at all, except from
>the permutation table as to avoid having to implement a complex permutation
>algorithm. Generating permutations is a topic in itself so I tried to avoid
>that by simply hard coding the small permutation list into the code to side
>step that sub problem.
>
>possible because of lack of memory or would require way too much time.
>
>What should however be stored is the number of victories for each
>permutation.
>
>>(Idea for now is to make it multi threaded and assign a low thread priority
>
>"It's CPU-bound, so using multiple threads for the computation won't be
>that effective..."
>
>I disagree, the problem is pretty straight forward and can be split just
>fine by duplicating some simple indexes/data structures.
>
>And should be able to run on each core at nearly 100% efficiency.
>
>The results could be merged together at the very end.
>
>At least in Delphi/native code this will work nicely...
>
>the threads, and for common Python, you run into the GIL (so even if you
>get subsets of processing assigned to each of multiple processor cores, the
>GIL will block all but one from doing any work at any moment -- say you
>partitioned it so core0 handles only the set where X begins [1, ...], core
>1 handles [2, ...], etc.).
>"
>
>Your last sentence made the most sense to me... I don't know what GIL is or
>
Global Interpreter Lock. Since all the data objects in Python are
encapsulated in complex structures (an integer will have, besides the
integer value, a reference count, a type identifier, etc.)  behind the
scenes, the GIL ensures that only one thread of execution can manipulate
those structures at a time. A simple

X = Y

requires looking up the current object that is attached (bound) to the name
"Y", binding it to the name "X" (in effect, a behind the scenes pointer
assignment), AND incrementing the object's reference counter.

Rather than having to put locks on every object (and where would one
stop? A lock on a dictionary containing keyed lists, then a lock on the
list containing some set of integers, and a lock on the integer...
X = {"first" : [1, 2, 3]}["first"][1]
That's three potential locks needed just for that statement) the normal
Python (that is, the common C-based version most encountered: Jython and
IronPython are different, using the Java or .NET runtimes respectively) has
a global lock. While a thread holds the lock and is executing Python level
code, no other thread can manipulate the state of objects, regardless of
how many cores are available.
https://docs.python.org/2/glossary.html#term-global-interpreter-lock

If one writes C-language extensions (most of the number crunching
libraries), and if the extension can do its work without needing constant
access to the Python level data objects (say it can collect all its needed
data at the start, crunch it, and only at the end return some result) then
the extension can "give up" the GIL while doing the crunch phase -- it
needs to hold the GIL during the preliminary collection, and during the
"return result" portion; both places where it has to access the Python
structures.

So... As a result, using multiple threads for CPU-bound (number
crunchers) is not usable in Python; regardless of cores/threads, only one
thread can do actual work at any moment, and the others are blocked waiting
for the GIL to come to them. I/O bound threads work fine, since when a
thread blocks to await some I/O operation, the GIL gets released to

The multiprocessing library is one attempt to work around the GIL, by
spawning a whole separate OS level process with its own copy of the Python
interpreter, and hence its own GIL. On Linux, that is a fork() operation,
where the child and parent get different returns from the fork() call to
identify which is what. On Windows it is trickier, as Windows creates a
fresh process with no state carried over from the parent -- that process
starts from the top of the Python code, so said code has to contain logic
to ensure the new process does not really restart from scratch and instead
jumps into a function that can do the work. CF (Python 2.7 docs, 3.x should
be similar but with possibly different chapter number):
https://docs.python.org/2/library/multiprocessing.html

I'm afraid I need to prepare to go to work, so I'll "unread" the post
so it will still be in my news client when I get back tonight, where I'll
try to work through the rest.

{Note: a quick scan still appears to have too many similar "numbers"
meaning different things}
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/15/2016 1:31:49 PM
```On Thu, Dec 15, 2016, at 08:31, Dennis Lee Bieber wrote:
> 	As for my posts disappearing: I run with "X-NoArchive" set. I have from
> before Google absorbed DejaNews. Back then, most news-servers expired
> posts
> on some periodic basis (my ISP tended to hold text groups for 30 days or
> so, binaries groups cycled in less than 36 hours). When DejaNews arrived,
> many objected to the non-expiration facet:

As I recall, what most people *actually* said they objected to was the
fact that they profited from showing ads. X-No-Archive was just a
convenient blunt weapon to hit them with.
```
 0
Random832
12/15/2016 4:49:06 PM
```On 12/15/2016 6:23 AM, skybuck2000@hotmail.com wrote:

> Anyway... my ISP has problems accessing their newsserver. ...

If you want to read python-list as a news group, you might try
news.gmane.org.  About once a year, it goes down for a few hours to a
day, but has otherwise been dependable.  I found it when my ISP dropped
newsgroup access around a decade ago.

```
 0
Terry
12/15/2016 6:34:32 PM
```On Thu, 15 Dec 2016 13:34:32 -0500, Terry Reedy <tjreedy@udel.edu>
declaimed the following:

>On 12/15/2016 6:23 AM, skybuck2000@hotmail.com wrote:
>
>> Anyway... my ISP has problems accessing their newsserver. ...
>
>If you want to read python-list as a news group, you might try
>news.gmane.org.  About once a year, it goes down for a few hours to a
>day, but has otherwise been dependable.  I found it when my ISP dropped
>newsgroup access around a decade ago.

And I found it when the spam on comp.lang.python got overly annoying.
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/16/2016 1:42:46 AM
```On Thu, 15 Dec 2016 03:23:43 -0800 (PST), skybuck2000@hotmail.com declaimed
the following:

>
>"
>Not seeing any code makes it hard to estimate where your slow-downs
>would be, however all your mentions of keeping "index" values implies (as I
>mention above) that you are trying to build huge tables of permutations
>first, then beating each entry against those of the other.
>"
>
>I quickly realised that this approach (generating huge lists) won't work
>because out of memory.
>

That's what swap files are for <G> {Just don't put them on a flash
memory device, including SSD -- you'll kill the device rather soon; I had
occasion to run the HINT benchmark on Beaglebone Black and Raspberry Pi 3;
the final data points where it was using swap files on SD cards was
painfully slow -- and corrupted the RPI3 card, the next time I booted it
found 90% of the card to have duplicate inode references, et al)

>So instead each possibility is simply calculated and only results are
>stored.
>
>"In truth, I can't figure out what you consider a combat"
>
>I did not use the term "combat". I do think of them as "attacks".
>
>We could define "combat" as simple "one of the possibilities".
>
>So let's look at a single possibility to explain it to you.
>
>I will simply produce a random index example:
>
>Index1: 7
>Index2: 22
>Index3: 12
>Index4: 10
>Index5: 4
>Index6: 9
>Index7: 11
>Index8: 5
>
And here's one of my complaints... You are using a numeric "index?"
which is associated with a number that is itself an index into your
permutation table.

"Index 1" points to "index 7" points to permutation table

>Now the task for program is to calculate the outcome of battle.
>
>The program will eventually lookup the permutations from the permutation
>table so let's get those first:
>
>First let's copy & paste the permutation table from original posting:
>
>1,2,3,4    // 1
>1,2,4,3    // 2
<snip>
>4,2,3,1    // 22
>4,3,1,2    // 23
>4,3,2,1   // 24
>
>Now let's retrieve the permutations for the indexes:
>
>(instead of calling it a permutation I will now call it an "attack order"):
>
>Index1: 7  Attack order: 2,1,3,4
>Index2: 22  Attack order: 4,2,3,1
>Index3: 12  Attack order: 1,3,2,4
>Index4: 10  Attack order: 2,3,4,1
>Index5: 4  Attack order: 1,3,4,2
>Index6: 9  Attack order: 2,3,1,4
>Index7: 11  Attack order: 2,4,1,3
>Index8: 5  Attack order: 2,1,4,3
>

At this stage (remember, I've reading this from top to bottom) I have
to ask: what is the significance of an "attack order"? Is it "order" as in
time sequence (first send in whatever the first # represents, then after
that is concluded send in whatever the second # represents...), or is it
"order" is "assignments in combat" (first # takes the left flank, second #
takes the left forward, third takes right forward, fourth takes right flank
-- okay, I've seen a bit ahead <G>).

>Now the computer program can perform the combat.
>
>However perform I explain further how a combat would be performed I will try
>
>", what you consider a number,"
>
>A number is a tag uppon an object. The object could be a ship, a tank, an
>airplane, or whatever the real world scenerio is behind the problem.
>
>I was considering mentioning this, but I thought it let it out just for the
>fun of it. Consider "number" the number of the object performing the attack.
>

Let's not... It would be much clearer knowing what the numbers
represent (and Python's permutation function can work with anything, not
just numbers).

So... Let's say (since you are so secretive in subsequent statement,
I'm going to pick a fantasy setting)

1 => fighter (infantry)
2 => archer/mage (artillery)
3 => knight (cavalry)
4 => dragon (air support)

and that makes your "attack orders" an arrangement of troop type -- still
not clear is in time or position.. Since permutations don't have duplicates
(unless the original had duplicates) making it time-ordered seems
meaningless (we will send <some troop class> against <some opponent troop
class>, after that concludes we will send <some other troop class> against
<some other opponent troop class> -- send the foot soldiers against the
dragons -- oh dear, foot just got fried, better send the archers against
the knights instead) in contrast to position-ordered (send <some troop
class on left flank> against <some opponent class right flank>, AT THE SAME
TIME send <some other troop class front left> against <some other opponent
class right front>, ...)

>
>"you don't identify x vs y"
>
>X is a group
>Y is a group
>
I'd meant that, since the table isn't diagonally symmetrical you didn't
identify which is the X and which is the Y (as in X attacks Y).

But also, what is a "group". Your earlier permutation table implies
that all groups consist of one company of "fighter", one of "archer", one
of "knight", and one of "dragon" -- and only differ in either the time
sequence in which each attacks, or the positional sequence of the line of
battle.

>
>To put it simply: The victory table describes the "number to number" attack
>chance. Which means the individual chance of an individual number attacking
>another individual number. In other words the victory table has nothing to
>do with the groups themselfes.
>
But it does refer to the "class" of the attacker vs the defender, does
it not?

>So basically the Y-Axis describes the source=attacker
>
>So basically the X-Axis describes the destination=target
>

Again, significant information that should have been provided...

>
>", and since it is not diagonally symmetric that makes a difference... "
>
>I don't quite understand this sentence of yours... a bit weird... but I
>guess this was because of your confusion and because you trying to sum the
>entries in the victory table for some reason, which is because of
>misunderstand... it's not necessary, I hope to have cleared that up above
>and will continue with an example below.
>
A diagonally symmetric table would, at least, mean it didn't matter
which edge was attacker and which was defender:

50 67 75 90
67 50 65 85
75 65 50 30
90 85 30 50

is symmetric. (I set it up so "class X" vs "class X" is 50%).
Unfortunately, it also implies that "dragon" attack "foot" has the same
odds as "foot" attack "dragon".

More realistic (where attacker is on top and defender is down the side)

50 75 85 95
40 50 45 85
25 65 50 70
10 55 35 50

foot and cavalry stink against attacking dragons, but archers have a
chance.

>
>Let's say a horse attacks a tank.
>
>What would it's chance of winning be ?
>
Horse is too big and obvious <G>

If fighting tanks in central Europe (the scenario envisioned during the
Cold War/70s), a tank without an infantry escort is a sitting duck in
narrow-street villages and roadways through dense forests... CF:
http://digitalcommons.unl.edu/cgi/viewcontent.cgi?article=1000&context=usarmytrain

>Let's first define the numbering as describes above:
>Horse=1
>Tank=2
>Plane=3
>Ship=4
>
>Let's re-examine our victory table:
>
>Let's apply some row/column numbering perhaps that will clearify it a bit
>for you.
>
>    1   2   3   4
>1: 50,  3, 80, 70
>2: 90, 60, 20, 40
>3: 30, 90, 55, 65
>4: 75, 90, 98, 60
>

The numbers do not help... using the actual classes is much cleaner...
and taking the later comment that attackers are the row, defenders column

DEF
horse	tank	plane	ship
A	horse	50		3		80		70
T	tank	90		60		20		40
K	plane	30		90		55		65
ship	75		90		98		60

{comment: for some reason I'd think a horse would have better chances
attacking a tank than it would an airplane or ship; and if an A-10 Warthog
has a 90% chance against a tank, it should have a 99% chance against a
horse... see what happens when you try to hide the actual objects?}

>So finally what could a possible solution program do to calculate outcome of
>battle ?!? Let's proceed with the example:
>
>Index1: 7  Attack order: 2,1,3,4
>Index2: 22  Attack order: 4,2,3,1
>Index3: 12  Attack order: 1,3,2,4
>Index4: 10  Attack order: 2,3,4,1
>Index5: 4  Attack order: 1,3,4,2
>Index6: 9  Attack order: 2,3,1,4
>Index7: 11  Attack order: 2,4,1,3
>Index8: 5  Attack order: 2,1,4,3
>
>
>Index 1,2,3,4 belongs to group X
>index 5,6,7,8 belongs to group Y (5,6,7,8 renumbered as 1,2,3,4)
>

What is "group X" or "group Y"... I can substitute "Allies" and "Axis"
(to use WW-2 conventions) and make more sense of concept. And at this point
what are "Index1".. "Index8" -- Give them meaningful names and I might
Afrika Corps" (while improbable, those at least don't complicate matters of
numbers assigned to numbers): The "US First Battalion" is to use "plan #7"
which lays out the troops as ...

>
>From the information above it's now clear how group X will attack group Y
>and how group Y will attack group X.
>
>X1 will first attack Y2
>X2 will first attack Y4
>X3 will first attack Y1
>X4 will first attack Y2
>
>Y1 will first attack X1
>Y2 will first attack X2
>Y3 will first attack X2
>Y4 will first attack X2
>

Now you imply it is not an attack vs defend situation, but mutual
attacks.

>From looking at this first round of attacks from above it's already pretty
>clear that Group Y has "chosen" to attack X2 with 3 objects. Thus it's very
>likely that X2 will be destroyed.
>

And here more confusion sets in... Does the "2" indicate that three
"axis armies" are sending their "archers" (yes, mixing fictional WW2 with
fantasy) against the "Queen's Grenadiers"  "dragon company" (since that is
was is in "index2" "first column" (4)

If the number is indicating which "army" is being attacked, then what
indicates the class doing the attack?

Your "'chosen' to attack ... 3 objects" implies the number indicates
the target "army" (in which case there can only be four armies on either
side), but DOES NOT indicate the "company" (troop class) doing the
attacking nor defending. OTOH, if the number indicates the troop class
attacking/defending, then there is no information of which "army" is the
target of the attack.

Or... I'm unable to tell how you differentiate the "army" doing the
attack/defense from the "troop class" doing the attack/defense. In one
place you seem to say that "2" means "tank/archer", but then in the next
usage you imply that "2" means "2nd army of the defender"

And with ambiguity, I won't bother looking at the rest since it won't
make logical sense.
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/16/2016 4:40:48 AM
```Hi thanks for your (Dennis) reply,

You seem to have two main questions:

1. Is the attack order sequential in time or is it positional ?

The answer to this question is kinda:

Both, (which is kinda funny, since you did not think of this possibility th=
at it could be both, which you also did with the other issue, see below ;))

It indicates which object should be attacked first. And ofcourse objects ha=
ve a position in the real world, so this also implies position to some degr=
ee.

2. Do the numbers mean types or instances ?

Again the answer to this question is kinda:

Both, (^<-which is the real funny one, because the original model where the=
re were only 4 types and 7 instances was still too large to compute within =
reasonable time. So the number of instances has been brought back to the nu=
mber of types to represent each type exactly once so to at least keep the m=
odel somewhat realistic and include all types which is kinda important. I a=
m particularly interested in type 4 so it has to be in the model :) Type 4 =
can attack the other 3 types with easy this gives you some hint at what kin=
d of type it might be ;)).

(So there are 4 types, and 4 instances, which happen to overlap each other,=
so you can consider them the same thing type=3Dinstance (to simplify the p=
rogram)).

These were your two most important questions, however you seem to have some=

3. One of your questions was: why are the indexes called "index1,index2" an=
d so forth. This is simply because there are 8 objects. Each object needs i=
t's own index to create a brute force algorithm which can create all combin=
ations of the object attack patterns. The code for this is pretty simple/st=
raight forward so I will mention it below, I will also rename these indexes=
as you requested to give them more meaning, pascal style:

for FriendlyIndex1 :=3D 1 to 24 do
for FriendlyIndex2 :=3D 1 to 24 do
for FriendlyIndex3 :=3D 1 to 24 do
for FriendlyIndex4 :=3D 1 to 24 do
for EnemyIndex1 :=3D 1 to 24 do
for EnemyIndex2 :=3D 1 to 24 do
for EnemyIndex3 :=3D 1 to 24 do
for EnemyIndex4 :=3D 1 to 24 do
// ComputeCombat( FriendlyIndex1,FriendlyIn=
dex2,FriendlyIndex3,FriendlyIndex4, EnemyIndex1,EnemyIndex2,EnemyIndex3,Ene=
myIndex4)

So these indexes are simply 8 integer variables used to generate all possib=
le attack orders (permutation number).

Each index can then be used to look up the actual permutation and used in c=
ombat...

So this iteration code is a big help to make sure and produce all combinati=
ons, it's simple, it's effective, it's clear to what it's doing.

ComputeCombat could be a routine or simply replaced with actual code to pre=
vent "variable sharing issues". My suggestion in case you ever do try to wr=
ite code for it is to keep everything "global" or simply inside a single ro=
utine... so
that parameter hell or whatever doesn't occur... keep it as simple as possi=
ble for a first version... then later it can be enhance with nice python fe=
atures. Ofcourse if you think the problem is simple enough to try using mor=
e advanced features at first you welcome to try that as well but I would fi=
nd it very funny if that fails... so when it does fail... fall back to ultr=
a-simple code :) Perhaps python doesn't even have ultra simple data structu=
res which might actually complexify your capability of solving this problem=
, which would be somewhat of an interesting conclusion regarding the python=
language as a whole ! Consider yourself challenged by me to solve it and p=
rove that Python is not a bad language ! LOL :) Yes little bit trollish but=
for good reason. Eventually I do suspect python might be of some help... a=
t least you mentioned it can generate permutations... but that is a sub pro=
blem in this case...

4. There was one more somewhat interesting sub question, your question seem=
s to be about the attack/victory table, you seem to wonder about symetrical=
/asymetrical, and why it would not be symetrical ?

I think I can explain this issue for you. The reason why it's not symetrica=
l is that tanks for example have different armor thickness depending on the=
ir angle. So let's say Tank X sneaks up on Tank Y and Tank X manages to hit=
the Tank X in the back... then Tank X's victory chance is much higher then=
if Tank X was sneaked up on by Tank Y... in that case Tank X's victory cha=
nce would be much lower.

I think this is the main reason why you are seeing an asymterical victory c=
hance table. I hope that clears it up for you ;)

I think I have solved all your confusion, you should now have enough inform=
ation to write a computer program that could solve the problem. Solving the=
problem entirely would not be necessary for you to share any possible pyth=
on enhancements or pseudo code or own techniques or (computing efficiency) =
ideas you would have come up with it. Just compiling it and running it a li=
ttle bit should be sufficient to see if it actually works.

Bye,
Skybuck.
```
 0
skybuck2000
12/16/2016 11:59:04 AM
```A nice chinese-like saying might have come out of this, perhaps it even already exists:

"When you confused, the answer might be fused !" :)

Sounds like TZen Su ! That dude from Art of War or something like that :)

I will take this chance to correct a little pretty obvious typo corrected:

(*) Tank X changed to Tank Y

So let's say Tank X sneaks up on Tank Y and Tank X manages to hit the (*) Tank Y in the back... then Tank X's victory chance is much higher then if Tank X was sneaked up on by Tank Y... in that case Tank X's victory chance would be much lower.
```
 0
skybuck2000
12/16/2016 12:31:31 PM
```On 2016-12-16, Dennis Lee Bieber <wlfraed@ix.netcom.com> wrote:
> On Thu, 15 Dec 2016 13:34:32 -0500, Terry Reedy <tjreedy@udel.edu> declaimed the following:
>>
>>If you want to read python-list as a news group, you might try
>>news.gmane.org.  About once a year, it goes down for a few hours to a
>>day, but has otherwise been dependable.  I found it when my ISP dropped
>>newsgroup access around a decade ago.
>
> And I found it when the spam on comp.lang.python got overly
> annoying.

I didn't notice much spam on c.l.p (but then again, I filter out all
posts from google-groups).  The problem on c.l.p that caused me to
switch to gmane's NNTP server was the number of broken references.
They both have references that break in various scenarios, but my
tests indicated that it was worse on c.l.p.  [Yes, I actually wrote a
Python program that used an NNTP client library to check all the
reference values in a large sample of posts from both sources.]

--
Grant Edwards               grant.b.edwards        Yow! I wonder if I could
at               ever get started in the
gmail.com            credit world?

```
 0
Grant
12/16/2016 3:11:54 PM
```On 2016-12-16 10:11 AM, Grant Edwards wrote:
> I didn't notice much spam on c.l.p (but then again, I filter out all
> posts from google-groups).  The problem on c.l.p that caused me to

Yes, blocking GG was the biggest improvement to my reading this list
(mailing list in my case).  That and a few judicious PLONKs and it is
now useful.

Al I need to do now is figure out how to filter out the almost daily
Windows installer questions.

--
D'Arcy J.M. Cain
http://www.Vex.Net/ IM:darcy@Vex.Net
VoIP: sip:darcy@Vex.Net
```
 0
D
12/16/2016 4:12:11 PM
```On 16/12/2016 16:12, D'Arcy Cain wrote:
> On 2016-12-16 10:11 AM, Grant Edwards wrote:
>> I didn't notice much spam on c.l.p (but then again, I filter out all
>> posts from google-groups).  The problem on c.l.p that caused me to
>
> Yes, blocking GG was the biggest improvement to my reading this list
> (mailing list in my case).  That and a few judicious PLONKs and it is
> now useful.
>
> Al I need to do now is figure out how to filter out the almost daily
> Windows installer questions.
>

The ever-so-slight irony is that Mailman decided it didn't like this
post and held it for moderation! (Something to do with the headers; I
didn't bother to check since I recognised the sender).

TJG
```
 0
Tim
12/16/2016 6:20:02 PM
```On Fri, 16 Dec 2016 15:11:54 +0000 (UTC), Grant Edwards
<grant.b.edwards@gmail.com> declaimed the following:

>I didn't notice much spam on c.l.p (but then again, I filter out all
>posts from google-groups).  The problem on c.l.p that caused me to
>switch to gmane's NNTP server was the number of broken references.
>They both have references that break in various scenarios, but my
>tests indicated that it was worse on c.l.p.  [Yes, I actually wrote a
>Python program that used an NNTP client library to check all the
>reference values in a large sample of posts from both sources.]

Unfortunately, my client can only "pre filter" on subject and author; I
could kill all @gmail.*, but could not focus on just Google Groups
submissions...

Probably time for me to spend the \$19 to upgrade from Agent 6.0

--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/17/2016 1:16:38 AM
```On 2016-12-16 08:16 PM, Dennis Lee Bieber wrote:
> 	Unfortunately, my client can only "pre filter" on subject and author; I
> could kill all @gmail.*, but could not focus on just Google Groups
> submissions...

I don't know what client you use but perhaps you can adapt this procmail
recipe.

:0 Hir
* ^List-Id:.*python-list.python.org
* ^From:.*@gmail.com
* ^Newsgroups:.*
/dev/null

--
D'Arcy J.M. Cain
http://www.Vex.Net/ IM:darcy@Vex.Net
VoIP: sip:darcy@Vex.Net
```
 0
D
12/17/2016 3:52:52 AM
```On Fri, 16 Dec 2016 22:52:52 -0500, D'Arcy Cain <darcy@vex.net> declaimed
the following:

>
>I don't know what client you use but perhaps you can adapt this procmail
>recipe.
>
As the next sentence indicated (Forte) Agent 6.0 (soon to be Agent 8.0;
it's likely time, though the main additional features I don't use: IMAP
email and large binaries)

author: regex
subject: regex

(Now to shutdown this copy so the installer can run)
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/17/2016 4:03:10 PM
```On Sat, 17 Dec 2016 11:03:10 -0500, Dennis Lee Bieber
<wlfraed@ix.netcom.com> declaimed the following:

>
>author: regex
>subject: regex
>
>(Now to shutdown this copy so the installer can run)

And I'm back... Usenet still seems to be subject and author/from
headers (based on the main "filter expression" help). Email allows

BUT: there seems to have been an addition (on its own page) for
message-id which might have been useful for the googlegroups sourced
messages. And one for the newsgroups field (which only triggers when the
message body is downloaded, and appears to be meant to catch things that
were cross-posted to unwanted groups; regular filters can be set to
individual groups already, but wouldn't trap on cross-posts)
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/17/2016 4:24:09 PM
```On 2016-12-17, Dennis Lee Bieber <wlfraed@ix.netcom.com> wrote:
> On Fri, 16 Dec 2016 15:11:54 +0000 (UTC), Grant Edwards
><grant.b.edwards@gmail.com> declaimed the following:
>
>>I didn't notice much spam on c.l.p (but then again, I filter out all
>>posts from google-groups).  The problem on c.l.p that caused me to
>>switch to gmane's NNTP server was the number of broken references.
>>They both have references that break in various scenarios, but my
>>tests indicated that it was worse on c.l.p.  [Yes, I actually wrote a
>>Python program that used an NNTP client library to check all the
>>reference values in a large sample of posts from both sources.]
>
> 	Unfortunately, my client can only "pre filter" on subject and author; I
> could kill all @gmail.*, but could not focus on just Google Groups
> submissions...
>
> 	Probably time for me to spend the \$19 to upgrade from Agent 6.0

Or use the One True Newsreader: SLRN.

;)

--
Grant

```
 0
Grant
12/17/2016 5:21:34 PM
```On 2016-12-17, D'Arcy Cain <darcy@vex.net> wrote:
> On 2016-12-16 08:16 PM, Dennis Lee Bieber wrote:
>> 	Unfortunately, my client can only "pre filter" on subject and author; I
>> could kill all @gmail.*, but could not focus on just Google Groups
>> submissions...
>
> I don't know what client you use but perhaps you can adapt this procmail
> recipe.
>
>:0 Hir
> * ^List-Id:.*python-list.python.org
> * ^From:.*@gmail.com
> * ^Newsgroups:.*
> /dev/null

That's not what he wants to do.  He wants to filter out posts made via

Here's the rule for slrn:

Score:: =-9999

```
 0
Grant
12/17/2016 5:23:01 PM
```On Fri, 16 Dec 2016 03:59:04 -0800 (PST), skybuck2000@hotmail.com declaimed
the following:

>
>1. Is the attack order sequential in time or is it positional ?
>
>The answer to this question is kinda:
>
>Both, (which is kinda funny, since you did not think of this possibility that it could be both, which you also did with the other issue, see below ;))
>
>It indicates which object should be attacked first. And ofcourse objects have a position in the real world, so this also implies position to some degree.
>

So, in one respect you are again compounding things by having one
structure identify which unit (where there are no duplicates -- you can not
have a force with two "foot", no "archer", one "knight", one "dragon")
attack when, and using its position in the order to define which opposing
unit gets attacked (that being the unit in the corresponding position in
the order).

>2. Do the numbers mean types or instances ?
>
>Again the answer to this question is kinda:

Any problem description in which the answer to a question is "kinda" is
an incompletely defined problem, and needs to have the description expanded
until there is no ambiguity. Otherwise you run into this situation where
you think it is clearly explained but no one else understands it.

>
>These were your two most important questions, however you seem to have some additional (sub) questions which I will also try and answer.
>
>
>3. One of your questions was: why are the indexes called "index1,index2" and so forth. This is simply because there are 8 objects. Each object needs it's own index to create a brute force algorithm which can create all combinations of the object attack patterns. The code for this is pretty simple/straight forward so I will mention it below, I will also rename these indexes as you requested to give them more meaning, pascal style:
>
Pascal explains so much... The 1970s style where the only data types
are scalars (numbers) and arrays (of numbers). The complete lack of any
attempt at an object oriented analysis (much less OO design -- it is, with
difficulty, possible to implement OOD using a non-OO language -- but I
don't even see any hint of a Pascal record here).

>for FriendlyIndex1 := 1 to 24 do
>    for FriendlyIndex2 := 1 to 24 do
>        for FriendlyIndex3 := 1 to 24 do
>            for FriendlyIndex4 := 1 to 24 do
>                for EnemyIndex1 := 1 to 24 do
>                    for EnemyIndex2 := 1 to 24 do
>                        for EnemyIndex3 := 1 to 24 do
>                            for EnemyIndex4 := 1 to 24 do
>                                // ComputeCombat( FriendlyIndex1,FriendlyIndex2,FriendlyIndex3,FriendlyIndex4, EnemyIndex1,EnemyIndex2,EnemyIndex3,EnemyIndex4)
>
>So these indexes are simply 8 integer variables used to generate all possible attack orders (permutation number).
>
>Each index can then be used to look up the actual permutation and used in combat...
>

1)	What does ComputeCombat return -- you pass 8 entities to it, but
nothing comes back.

2)	This is Python, not a 70s limited language. You already built a
table of permutations -- use it

etc.

No indices needed, you cycle through each permutation directly, and
pass that permutation onward without needing to look it up by an index

3)	Since your earlier post indicated that combat aligns as

etc.

and the 4x4 victory table doesn't change, you should only need to compute
an intermediate results table (IRT), as it applies identically to any of

IRT = {}
resultLine = {}

Now to get the result of any permutation attacking any permutation you
just

result = IRT[tuple(attackerPermutation)][tuple(defenderPermutation)]

where, again, you are passing the actual permutation, not an index to it.

{note: all those calls to tuple() are there as I'm assuming you are still
using list of lists for permutationTable, et al, and dictionary keys have
to be immutable. If you build a list of tuples you don't need to coerce the
orders into tuples later}

>So this iteration code is a big help to make sure and produce all combinations, it's simple, it's effective, it's clear to what it's doing.
>

Really?  From my side it is still (to quote the Doctor) "a big ball of
wibbily wobbly timey wimey...stuff"

Let me approach this another way:

Can you write a description of what the program is supposed to do, what
it operates on, what it returns, WITHOUT EVER SAYING "number" or "index"?
Using my fantasy setting, consider:

UNIT each of FOOT, ARCHER, KNIGHT, and DRAGON troops. Each UNIT is arranged
in _priority order_ (FirstUnit, SecondUnit, ...). Units have an _offensive
strength_ (damage done) and a _defensive strength_ (health).
COMBAT takes place between two armies. Within a combat, the
Blue Army FirstTaskForce, etc.). For each such battle, the corresponding
units are used to resolve the RESULTS -- Red Army ThirdTaskForce FourthUnit
fights Blue Army ThirdTaskForce FourthUnit, and so on.

Win/Lose results are based upon a percentage table, with the attempt
randomly generated. The table consists of (attacker across the top,
defender down the left)

foot		archer		knight		dragon
foot
archer			{I'm not going try to fill in values}
knight
dragon

The randomly generated value must be less than or equal to the value in
the table for the attack to succeed. Damage is done by subtracting the
attacker's offensive strength from the defender's defensive strength.

The program is to compute a Min/Max (minimum health loss, maximum
damage done) result by simulating all permutations of combat between two
armies, summing the results for each attack permutation against all
defensive permutations.

Now -- I don't know how much of that is applicable to your desired
goal, but given such a description (notice I never once referred to an
"index", though one may be implied through the ordinals "first"/"second"...
in the description)... I digress... Given the above, I'd consider creating
the following classes (INCOMPLETE, JUST A SHELL GIVEN):

class Unit(object):
def __init__(self, damage, health):
self.damage = damage
self.health = health

class Foot(Unit):
#need to provide defaults for damage and health

class Archer(Unit):

class Knight(Unit):

class Dragon(Unit):

def __init__(self, firstUnit, secondUnit, thirdUnit, fourthUnit):
typeList = [type(unit) for unit in (firstUnit, secondUnit,
thirdUnit, fourthUnit)]
if typeList[0] in typeList[1:] or
typeList[1] in typeList[2:] or
typeList[2] in typeList[3:]:
raise DuplicateUnitError

self.firstUnit = firstUnit
self.secondUnit = secondUnit
self.thirdUnit = thirdUnit
self.fourthUnit = fourthUnit

class Army(object):

genericTaskForce = [Foot(), Archer(), Knight(), Dragon()]

permutations = [ tuple(tforce) for tforce in

#pick four task force permutations, allowing repeats, to make up the four
for Rtf in itertools.combinations_with_replacements(permutations, 4):
# * expands the list Rtf to fit the four parameters needed to define
# an army
redArmy = Army(*Rtf)

for Btf in itertools.combinations_with_replacements(permutations, 4):
blueArmy = Army(*Btf)

results = doCombat(redArmy, blueArmy)

{this assumes no prebuilt results table for single unit vs unit}
{nor have I made provision to do anything with the results}
{And still not a single index to be seen}

Somewhere in doCombat...

for (redu, blueu) in zip([redtf.firstUnit, redtf.secondUnit,
redtf.thirdUnit, redtf.fourthUnit],
[bluetf.firstUnit, bluetf.secondUnit,
bluetf.thirdUnit, bluetf.fourthUnit]):

if combatTable[redu][blueu] <= random(100):
inflictDamage(redu.damage, blueu.health)

{and still not a single mention of an index}
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/17/2016 8:38:55 PM
```Unless you are capable of expressing problems in numerical terms you'll hav=
e very hard luck having it computed by a computer ! ;)

I did find some interesting docs about "decision trees".

Exhaustive search
Branch and Bound
Hill Climbing
Random/Best Effort Solutions

and so forth.

A computer programmer should be able to handle abstract descriptions as wel=
l like I gave in my initial posting.

What kind of "dressing" you want to give it is up to you, the dressing won'=
t solve it though ! :)

Meanwhile I have also consider some kind of lookup table... or an intermedi=
ate table like you described...

Not yet sure if that will be of any help... (I am in doubt about the dynami=
c nature of the battles... perhaps an intermediate table would be wrong... =
or maybe it might be right, dynamic deaths vs staying alive inside intermed=
iate table and such).

I also tried the static approach by multiplieing chances instead of subtrac=
ting the chances like damage done.

I also experimented with "Pascal/Delphi sets" in combination with arrays...=
this produced a very easy/simple permutation algorithm which consisted out=
of multiple for loops, which is kinda the obvious way of easily creating p=
ermutations... but it was still kinda interesting.

There is a problem with such loops though, also like the one you mention "f=
or each" and "for in" and such... "under water" the compiler will loop the =
entire range of the type, and will use compare statements to see if it shou=
ld enter the inner loop. So there is hidden overhead associated with it.

Thus such "generating" of permutations on the fly might have a hidden overh=
ead cost associated with it, even if this was not the case, such for loop c=
onstructs will definetly have overheads in certain situations and this can =
quickly get out of hand and could even consume more processing time then th=
e entire program.

I did also briefly considered this permutation loop, though it would requir=
e a lot of programming, 8x4=3D24 for loops, plus possible an additional att=
ack loop.

You do have a little point that without a clear story it might be hard to u=
nderstand the exact problem. I may consider describing the problem one more=
time, but it might still be with number or blue berries ! LOL :)
```
 0
skybuck2000
12/17/2016 10:39:08 PM
```Specially for Dennis, a nice story:

There are four little animals. The first animal is a tiger, the second animal is a deer, the third animal a parrot, the fourth animal is a fish.

The animals are very angry at each other and want to EAT each other ! =D

However each animal has a certain specialization. For example, the tiger has very sharp teeth, but can't hold it's breath for long under water.

The parrot has the ability to drive others insane with his chilping. The fish can lure other animals into the water in hopes of drowning them.

And the deer can lure them into the swamp or make them fatigued from chasing them.

Fortunately for the four animals they don't need to EAT each other because another group of animals have arrived which are exactly like them.

So the four animals have decided to gang UP like negros in the GETTO ! LOL.

It's now GANG vs GANG.

But the poor little animals have run into a problem ?! Which of the other four animals should they EAT first ?! Or should they even attack multiple at the same time ?!

Should the tiger fight the tiger ?

Should the fish fight the fish ?

Should the parrot fight the parrot ?

Should the deer fight the deer ?

Or perhaps ?

Should the tiger eat the fish first ?

Should the fish try to drown the tiger first ?

Should the tiger and the fish gang up on the tiger ? But what about the enemy fish ? What will it do ?

Should all four animals attack the enemy tiger ? or another animal ?

Also for the gang to achieve victory all four enemy animals must be EATEN !

Now these animals wonder to themselfes ?

How should we attack the enemy ? Who should we attack first ?

Every individual attack has a chance of success as given by the victory table. (A survival table could be calculated as well. Which would be the inverse of this).

Many possibilities for attack exists ?!

Which one do you recommend for them ?!

Keep in mind that each animal is free to decide it's own attack plan. They do not need to agree with you.

Imagine yourself to be one of the animals.

Which attack strategy for yourself would be best to use to maximize your GANG of winning, no matter what other attack plans the animals have.

An example of a possible attack:

Red Tiger has his own attack plan eat in this order: Blue Tiger, Blue Fish, Blue Deer, Blue Parrot
Red Deer has his own attack plan eat in this order: Blue Fish, Blue Deer, Blue Parrot, Blue Tiger
Red Fish has his own attack plan eat in this order: Blue Fish, Blue Parrot, Blue Deer, Blue Tiger
Red Parrot has his own attack plan eat in this order: Blue Parrot, Blue Fish, Blue Deer, Blue Tiger

and vice versa for blue team ! ;) :)

```
 0
skybuck2000
12/17/2016 10:55:03 PM
```On Sat, 17 Dec 2016 14:55:03 -0800 (PST), skybuck2000@hotmail.com declaimed
the following:

>An example of a possible attack:
>
>
>Red Tiger has his own attack plan eat in this order: Blue Tiger, Blue Fish, Blue Deer, Blue Parrot
>Red Deer has his own attack plan eat in this order: Blue Fish, Blue Deer, Blue Parrot, Blue Tiger
>Red Fish has his own attack plan eat in this order: Blue Fish, Blue Parrot, Blue Deer, Blue Tiger
>Red Parrot has his own attack plan eat in this order: Blue Parrot, Blue Fish, Blue Deer, Blue Tiger
>
>and vice versa for blue team ! ;) :)

And that has changed the entire previous understanding in which you
indicated the combat was aligned

RT		RD		RF		RP
BT		BF		BD		BP

with the next combat being some other set of R vs some other set of B.

Instead you /now/ have ONE set of R marching down FOUR sets of B

RT		RD		RF		RP	<-		attackers
BT		BF		BF		BP			round 1
BF		BD		BP		BF			round 2
BD		BP		BD		BD			round 3
BP		BT		BT		BT			round 4

BTW: unlike many cats -- Tigers like water and are fairly good swimmers <G>
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/18/2016 12:28:33 AM
```Dennis wrote:

<snip>

"
Instead you /now/ have ONE set of R marching down FOUR sets of B

RT		RD		RF		RP	<-		attackers
BT		BF		BF		BP			round 1
BF		BD		BP		BF			round 2
BD		BP		BD		BD			round 3
BP		BT		BT		BT			round 4
"

Yes this is how the problem works.

Also keep in mind that an attack is only valid if the target is still alive, otherwise the attacker would move to the next one.

So pre-computing an attack plan/outcome or storing it might not be so usefull for on color, since the other color might already be dead and thus attack plan was calculated incorrectly potentially.

So it's quite a difficult/complex/dynamic problem !
```
 0
skybuck2000
12/18/2016 10:06:00 PM
```Skybuck wrote:

"
Also keep in mind that an attack is only valid if the target is still alive=
, otherwise the attacker would move to the next one.
=20
So pre-computing an attack plan/outcome or storing it might not be so usefu=
ll for on color, since the other color might already be dead and thus attac=
k plan was calculated incorrectly potentially.
"

^- Apperently this text/posting was essential/the key for Skybuck's Magical=
Brain to come up with a solution !

I love how Skybuck's Magical Brain comes up with solutions after some sleep=
! =3DD

Just need to input the problem before sleeping, then in the morning ! TA-TA=
: Solution ! =3DD

I just woke up, thought a little bit and then came up with the following so=
lution !

The problem with the lookup/intermediate table is ALIVE/DEATH of own object=
(also teammate objects), furthermore another problem is ALIVE/DEATH of ene=
my object(s).

So now the solution is obvious ! A special lookup table as follows:

(Furthermore I just had another idea to compute an enemy health reduction o=
r perhaps enemy health outcome, both are possible ! ;) Yeah... enemy health=
calculation probably possible and accurate, since alive/death of enemy als=
o known on input and thus result can be calculated/stored in table ! ;)

EnemyHealth (could also be EnemyHealthReduction if that were necessary for =
some reason ! ;) total damages would be summed, but probably not necessary =
to do it that way).

Enemy1Health,Enemy2Health,Enemy3Health,Enemy4Health =3D
Friendly1AliveStatus, Friendly2AliveStatus, Friendly3AliveStatus, Friendly4=
AliveStatus, Object1AttackPermutations, Object2AttackPermutations, Object3A=
ttackPermutations,Object4AttackPermutations,Enemy1AliveStatus,Enemy2AliveSt=
atus,Enemy3AliveStatus,Enemy4AliveStatus

^ So what I just tried to describe above is an 16 dimensional array as foll=
ows:

2x2x2x2x24x24x24x24x2x2x2x2

So computational complexity added by alive/death status is only x8 which is=
totally great... total complexity is therefore:

24x24x24x24x8

(For each attack the lookup table can be reused so that perfect too)

So the initial complexity of 24x24x24x24x24x24x24x24x4(?) has now been redu=
ced too:

1x24x24x24x24x8 (computations)

It will probably still be necessary to "compute/lookup" all possibilities j=
ust to be sure, however doing an 16 way array lookup should be way faster t=
han computing while loops and if statements and what not... though the tabl=
e is quite large so some random access may occur.

16 random access is roughly 16x100 nanoseconds. Plus some 5 minute looping =
overhead or so so let's calculate rough indication of new processing time.

24x24x24x24x24x24x24x24x4(?) (look ups)

But first I try and calculate some kind of indicator of current per loop pr=
ocessing time.

24^8 =3D 110075314176 battles / 80.000 seconds =3D 1375941.4272 battles per=
second.

just for that for now.

Now let's compute new expected running time.

Perhaps crazyly inaccurate calculation since it does not account for data c=
ache hits... but just worst case scenerio or something:

It will be at least 16x100 nanoseconds, then 8 branches or so to determine =
winner is about 8 x branch time which is roughly 15 cycle clocks of 2 gigah=
ertz or so. Then also 8 data field fetches another 8x1 cycle, and perhaps 8=
assignments or so to store healths so roughly 15+8+8 =3D 13 plus probably =
some while loop to repeat attacks until there is a winner though this was a=
lready accounted for in the branches above... so for now I'll stick with 31=
cycles or so

So 31 cycles of 2.000.000.000 hz machine I would guess is roughly:=20

0.0000000155 seconds, roughly 15.5 nanoseconds so worst case scenerio:

16x100 =3D 1600 + 15 =3D 1615.5 nanoseconds to compute/lookup a battle.

Number of battles: 110075314176 x 1615.5 =3D 177826670051328 nanoseconds

=3D 177826.670051328 seconds.

According to my initial calculations it will be far worse off lol !

However the 8x dimensions could be put close together so that at least thos=
e are cached, then perhaps a lookup will only take 10 nanoseconds or someth=
ing or maybe even less.

So then it becomes 8x10 nanoseconds + 8*100 nanoseconds =3D 880 nanoseconds

Seems like roughly a reduction... then I am back to square one roughly runn=
ing time of 90.000 seconds. Plus ofcourse some pre-compute overhead...

Though I am kinda bad at estimating running time like this...=20

I am hopefully that the look ups will proceed much faster...

Sometimes of those 8x100 nanosecond seeks there will be some L1/L2 data cac=
he hits hopefully so that should accelerate it somewhat.

What actually needs to be stored is enemy health... this can be done with o=
ne byte... 100 is near 128 bits... so at least 7 bits needed for 100, so on=
ly 1 bit could be saved so doesn't really seem worth it to save 4 bits in t=
otal ! ;)

The pre-compute time for the table lookups should be quite fast...

The main processing for generating the lookup is:

24^4 =3D 331776 x 8 =3D 2.654.208

That's nothing compared to the 110.000.000.000 that it used to be ! ;) :)

So I am very hopefull that I have found a nice data acceleration structure =
! ;) :)

Having this conversation with you was usefull, thanks !

Bye,
Skybuck =3DD
```
 0
skybuck2000
12/19/2016 9:34:42 AM
```Hmmm I see that I have made an old mistake of mine ;)

2x2x2x2 is not 8, it's deceptive... it looks like 4x2 = 8 but nope ! :)

This is 2x2=4x2=8x2=16.

and then the next 4 = 16x2 = 32x2 = 64x2 = 128 x 2=256

so it's roughly 24^4 x 256 = 84934656

```
 0
skybuck2000
12/19/2016 1:57:59 PM
```Hmmm now I think the lookup table cannot work... at least not for the dynamic one... where health is subtracted...

The ships have a certain health... and not just an alive/dead status...

The way they and the enemy attack each other will probably influence the outcome of battle... and for the next round ships will have different health status... so just dead/alive is not enough...

Also pre-computing the table for all 4 or more rounds seems not possible because this again depends on what the enemy was doing...

So I don't think there is a way around the full 24^8 calculations...

```
 0
skybuck2000
12/19/2016 2:07:28 PM
```On Mon, 19 Dec 2016 06:07:28 -0800 (PST), skybuck2000@hotmail.com declaimed
the following:

>Hmmm now I think the lookup table cannot work... at least not for the dynamic one... where health is subtracted...
>
>The ships have a certain health... and not just an alive/dead status...
>
>The way they and the enemy attack each other will probably influence the outcome of battle... and for the next round ships will have different health status... so just dead/alive is not enough...
>
>Also pre-computing the table for all 4 or more rounds seems not possible because this again depends on what the enemy was doing...
>

Any process where the input to one stage depends upon the output of a
previous stage -- and where said output can not be predetermined -- is
going to require sequential calculation.

>So I don't think there is a way around the full 24^8 calculations...
>

You'll likely have to come up with some pruning algorithm to remove
branches that have a poor chance of  advancing -- eg: if the first round
results in you losing your strongest unit, the odds of the remaining units
making it to end are severely reduced, and it may not be worth running the
subsequent rounds on the branch.

This is why master class chess programs run on big iron -- to explore
each branch and the downstream permutations that result from a move.

And learning to use classes in Python can simplify the task -- rather
than trying to track separate tables of damage, etc. the damage is part of
the object.
--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/19/2016 5:58:07 PM
```I first explored the possibility of a lookup table to speed up calculations=
, this possibility would probably give wrong results.

I am interested in calculating all possibilities to see which one is truely=
best, I am also interested in trying to speed up calculations to be able t=
o handle larger models.

Many other possibilities exist for further exploration:

1. One recursive function to try and split up the work as to recycle some o=
f it.
2. Perhaps multiple recursive functions to include different functionality =
at different "depths".
3. Other tree like structures to try and safe some computations by recyclin=
g results from previous visits across nodes.
4. Manually incrementing indexes (though this would probably requiring stor=
ing results in some form or another, perhaps a stack based approach might w=
ork... pushing/popping as index returns to a certain one, perhaps a stack p=
er index might work or something.

I still believe that it should be possible somehow to save some computation=
s.

Perhaps I am fooling myself ! Not sure yet ! ;) :)

6. Healths will need to be reset I think, however another possibility is co=
py&pasting healths to new nodes to compute them further.

s to other nodes.

One problem with all that node thinking is that the system will run out of =
memory, which should be fine, memory can be pre-allocated to speed stuff up=
, one it runs out, it will have to do full calculations.

but now it makes a bit more sense, now this text a bit more clear.

7. Maybe cuda or some other SIMD solution. Still not sure if CUDA can detec=
t that some instructions/data are being calculated... hmmm would guess not,=
not sure though.

It's kinda fun trying out all these possibilities to see which ones work...=
though I am also becoming a bit curious to what the actual outcome would b=
e.

For now my heuristic for a "good enough" solution would be "object attack o=
bject with best victory chance".

This seems a bit too easy/cheesy heuristic and I want to know what is reall=
y the best way... is there perhaps a team strategy/combined attack effort t=
hat might work better ? ;)

I would also like to be able to change chances perhaps in feature or expand=
model a little bit so also speeding it up would be nice.

For now multi threading is doable... and the calculate while idle seems nic=
e...

Though I am also kinda curious about cuda... these last ideas are probably =
easiest to implement and will give most statisfactory.

One problem with that is though, once I have the problem solved/calculated =
I might not be interested in trying out the harder possibilities.

So maybe it's best to try the hardest first... maybe I will learn something=
amuzing and even something usefull from it.

More failures perhaps, but in the end, success will come ! LOL.
```
 0
skybuck2000
12/20/2016 12:45:13 AM
```On Thursday, December 15, 2016 at 1:17:10 PM UTC+1, Peter Otten wrote:
> skybuck2000@hotmail.com wrote:
>
> > I received a reply from somebody on my ISP newsserver. Apperently his
> > reply is not visible on google groups. I wonder why, maybe it's a banned
> > troll or something, but perhaps not.
>
> No, that's Dennis Lee Bieber who doesn't want his posts to be kept, and
> seems to be the only one to post here with the X-No-Archive flag set.

I find this weird behaviour by google newsgroup.

At least google newsgroups could show his postings for something more reasonable like 30 days or something, instead of not showing it at all...

Totally weird. What's the point in posting then if software would not display it at all ? ;)
```
 0
skybuck2000
12/21/2016 6:10:23 PM
```On Wed, 21 Dec 2016 10:10:23 -0800 (PST), skybuck2000@hotmail.com declaimed
the following:

>On Thursday, December 15, 2016 at 1:17:10 PM UTC+1, Peter Otten wrote:
>> skybuck2000@hotmail.com wrote:
>>
>> > I received a reply from somebody on my ISP newsserver. Apperently his
>> > reply is not visible on google groups. I wonder why, maybe it's a banned
>> > troll or something, but perhaps not.
>>
>> No, that's Dennis Lee Bieber who doesn't want his posts to be kept, and
>> seems to be the only one to post here with the X-No-Archive flag set.
>
>I find this weird behaviour by google newsgroup.
>
>At least google newsgroups could show his postings for something more reasonable like 30 days or something, instead of not showing it at all...
>
>Totally weird. What's the point in posting then if software would not display it at all ? ;)

control; the only requirement is that the post not persist in perpetuity --
periods over a month may be pushing the intent (after all, would you accept
"we expire posts when the copyright runs out" as meaning they are not
archived -- what is that in these days of the Mouse? Life plus 99 years?

I don't know what period gmane uses... They seem to still have a post
of mine from Nov 25 -- so 30 days might be a reasonable guess.

And true mailing lists may not even have an archive. Mailing lists, at
the simplest, work by receiving a message, and then resending it to all
subscribers. Fancier are those that also have a digest format, where they
collect all messages received over, say, 6 hours, and send them as a single
digest message to those that asked for that format. Again, no requirement
to archive anything longer than needed to do the forwarding to others.

What it means for a use of Google Groups is: never go more than a day
without checking for replies to posts you are following.

--
Wulfraed                 Dennis Lee Bieber         AF6VN
wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

```
 0
Dennis
12/21/2016 7:23:16 PM