12ffbc7e69
FossilOrigin-Name: b5ca80d924f8c6d31f036247ba6e20d234f4482e
112 lines
3.0 KiB
C
112 lines
3.0 KiB
C
/*
|
|
** 2013-06-10
|
|
**
|
|
** The author disclaims copyright to this source code. In place of
|
|
** a legal notice, here is a blessing:
|
|
**
|
|
** May you do good and not evil.
|
|
** May you find forgiveness for yourself and forgive others.
|
|
** May you share freely, never taking more than you give.
|
|
**
|
|
*************************************************************************
|
|
** This file contains a simple command-line utility for converting from
|
|
** integers and WhereCost values and back again and for doing simple
|
|
** arithmetic operations (multiple and add) on WhereCost values.
|
|
**
|
|
** Usage:
|
|
**
|
|
** ./wherecosttest ARGS
|
|
**
|
|
** Arguments:
|
|
**
|
|
** 'x' Multiple the top two elements of the stack
|
|
** '+' Add the top two elements of the stack
|
|
** NUM Convert NUM from integer to WhereCost and push onto the stack
|
|
** ^NUM Interpret NUM as a WhereCost and push onto stack.
|
|
**
|
|
** Examples:
|
|
**
|
|
** To convert 123 from WhereCost to integer:
|
|
**
|
|
** ./wherecosttest ^123
|
|
**
|
|
** To convert 123456 from integer to WhereCost:
|
|
**
|
|
** ./wherecosttest 123456
|
|
**
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
|
|
typedef unsigned short int WhereCost; /* 10 times log2() */
|
|
|
|
WhereCost whereCostMultiply(WhereCost a, WhereCost b){ return a+b; }
|
|
WhereCost whereCostAdd(WhereCost a, WhereCost b){
|
|
static const unsigned char x[] = {
|
|
10, 10, /* 0,1 */
|
|
9, 9, /* 2,3 */
|
|
8, 8, /* 4,5 */
|
|
7, 7, 7, /* 6,7,8 */
|
|
6, 6, 6, /* 9,10,11 */
|
|
5, 5, 5, /* 12-14 */
|
|
4, 4, 4, 4, /* 15-18 */
|
|
3, 3, 3, 3, 3, 3, /* 19-24 */
|
|
2, 2, 2, 2, 2, 2, 2, /* 25-31 */
|
|
};
|
|
if( a<b ){ WhereCost t = a; a = b; b = t; }
|
|
if( a>b+49 ) return a;
|
|
if( a>b+31 ) return a+1;
|
|
return a+x[a-b];
|
|
}
|
|
WhereCost whereCostFromInteger(int x){
|
|
static WhereCost a[] = { 0, 2, 3, 5, 6, 7, 8, 9 };
|
|
WhereCost y = 40;
|
|
if( x<8 ){
|
|
if( x<2 ) return 0;
|
|
while( x<8 ){ y -= 10; x <<= 1; }
|
|
}else{
|
|
while( x>255 ){ y += 40; x >>= 4; }
|
|
while( x>15 ){ y += 10; x >>= 1; }
|
|
}
|
|
return a[x&7] + y - 10;
|
|
}
|
|
static unsigned long int whereCostToInt(WhereCost x){
|
|
unsigned long int n;
|
|
if( x<10 ) return 1;
|
|
n = x%10;
|
|
x /= 10;
|
|
if( n>=5 ) n -= 2;
|
|
else if( n>=1 ) n -= 1;
|
|
if( x>=3 ) return (n+8)<<(x-3);
|
|
return (n+8)>>(3-x);
|
|
}
|
|
|
|
int main(int argc, char **argv){
|
|
int i;
|
|
int n = 0;
|
|
WhereCost a[100];
|
|
for(i=1; i<argc; i++){
|
|
const char *z = argv[i];
|
|
if( z[0]=='+' ){
|
|
if( n>=2 ){
|
|
a[n-2] = whereCostAdd(a[n-2],a[n-1]);
|
|
n--;
|
|
}
|
|
}else if( z[0]=='x' ){
|
|
if( n>=2 ){
|
|
a[n-2] = whereCostMultiply(a[n-2],a[n-1]);
|
|
n--;
|
|
}
|
|
}else if( z[0]=='^' ){
|
|
a[n++] = atoi(z+1);
|
|
}else{
|
|
a[n++] = whereCostFromInteger(atoi(z));
|
|
}
|
|
}
|
|
for(i=n-1; i>=0; i--){
|
|
printf("%d (%lu)\n", a[i], whereCostToInt(a[i]));
|
|
}
|
|
return 0;
|
|
}
|