View Full Version : math question
darelf
08-21-2002, 12:25 PM
I'm trying to simulate a table in my code.
I feed a function a number and it returns the result.
Given the sequence [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], I need the function to return [0,1,2,3,3,4,5,6,6,7,8,9,9,10,11,12,12,13,14,15]
Is there a simple algorithm for this, or do I need to code it as a table?
Halide
08-21-2002, 01:33 PM
Here's what I'm thinking :wtf:
seriously, I would just hardcode it IF it's as crazy as it sounds :)
sans-hubris
08-21-2002, 02:59 PM
You want a sorting algorithm. There are a large number of sorting algorithms out there. Try using quicksort.
darelf
08-21-2002, 03:12 PM
Wait, now it's my turn. What?
I'm just wondering if there is a simple expression I can use to get a number from the first sequence to turn into its corresponding number in the second sequence.
I guess I will have to hard-code it as a lookup table.
EDIT:
As an example... I have a different sequence that can be expressed as floor( n / 2 )
i.e. feed it 1 and you get 0. Feed it 2 and you get 1. Feed it 3 and you get 1.
In this case I want to do the same thing, only with the above sequence ( 1 = 0, 2=1, 3=2, 4=3, 5=3, etc )
Am I a bad person for wanting this?
(For the astute among you; Yes, it is the BaB chart for "medium" classes like Cleric or Rogue.)
(For the more astute among you; Yes, I *AM* a DnD geek and most of my hobby programming is centered on that one hobby)
file13
08-21-2002, 04:24 PM
probably a "case" statement is what you want. i've been playing around with a gurps system in Ocaml and Lisp. in Lisp i just use a cond statement:
(defun stats-to-points (level)
"Returns the points cost of a stat given the level"
(cond ((= level 1) (values level -80))
((= level 2) (values level -70))
((= level 3) (values level -60))
((= level 4) (values level -50))
((= level 5) (values level -40))
((= level 6) (values level -30))
((= level 7) (values level -20))
((= level 8) (values level -15))
((= level 9) (values level -10))
((= level 10) (values level 0))
((= level 11) (values level 10))
((= level 12) (values level 20))
((= level 13) (values level 30))
((= level 14) (values level 45))
((= level 15) (values level 60))
((= level 16) (values level 80))
((= level 17) (values level 100))
((= level 18) (values level 125))
((= level 19) (values level 150))
((= level 20) (values level 175))
((> level 20) (values level (+ 175 (* (- level 20) 25))))
(t nil)))
notice how at the end if it's about 20 it figures out the cost and if it dosen't find anything it'll return nil. this is probably you're best bet for RPG's. one thing i've noticed is that table pretty much translate into if/case statments depending on the language you're using.
BTW: if you're curious:
http://www.qlippoth.com/gurps.ml
http://www.qlippoth.com/gurps.lisp
good luck
Okay, I must be misunderstanding what's going on, because I don't see why you can't just use a dictionary.
darelf
08-21-2002, 05:01 PM
temporary workaround is me putting it in an array.
I just figured since there was a progression that repeats, there would be a mathematical expression to describe that progression.
I had to do something similar for a gurps chargen program, where I had to add up the points spent for attributes, since it isn't a straight progression. Sucks, and feels kludgy, but there just may not be a way around it.
EDIT:
cool, that middle paragraph rhymes....
TacKat
08-21-2002, 11:56 PM
The difference between the output and the input increases by one for every four values. So, in pseudo-code:
cycle = input / 4 (must be integer division)
if (input mod 4) != 0 then
cycle = cycle+1
output = input - cycle
sans-hubris
08-22-2002, 01:44 AM
I'm sorry, I looked at your arrays too quickly. Now that I looked at them more closely, it just looks like you're trying to double count all multiples of three, right? If you're doing a table of numbers, then you need to figure out a mathematical relationship either in the sequence or to the first array. The only one that I can see in the second array is that you're double counting multiples of three.
darelf
08-22-2002, 09:52 AM
Originally posted by TacKat
The difference between the output and the input increases by one for every four values. So, in pseudo-code:
cycle = input / 4 (must be integer division)
if (input mod 4) != 0 then
cycle = cycle+1
output = input - cycle
You got me on the right track...
Here's how I got it to work in PHP:
$x = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
$z = 0;
foreach ( $x as $value ) {
$i = $value;
$j = 0;
if ( ($value % 4) != 0 ) { $j = -1; } else { $z -= 1; }
echo $i+$j+$z . ", ";
}
This script will output:
0,1,2,3,3,4,5,6,6,7,8,9,9,10,11,
Which is precisely what I need.
With the algorithm you gave me, I ended up with:
0,1,2,4,4,5,6,8,8,9,10,12,12,13,14,
Anyway, thanks for the help. Without that hint about the modulus, I probably would have never figured it out.
TacKat
08-22-2002, 11:24 AM
That's odd, it works fine for me. In C:
#include <stdio.h>
int func(int in)
{
int cycle;
cycle= in / 4;
if( (in % 4) != 0)
cycle++;
return in-cycle;
}
int main(void)
{
int i;
for(i=1; i <=20; i++)
printf("%d %d\n",i,func(i));
return 0;
}
At least you got it working though.
darelf
08-22-2002, 12:01 PM
It could just be that PHP doesn't have an integer division.... from the manual "the division operator ("/") returns a float value anytime, even if the two operands are integers..."
TacKat
08-22-2002, 02:03 PM
And that would do it. My ignorance of PHP shines through.
You can cast variables in PHP as you would in C: (int)$x. Alternatively, use intval( $x ) or floor( $x ).
vBulletin® v3.7.0, Copyright ©2000-2009, Jelsoft Enterprises Ltd.