User:Ledrug/bits: Difference between revisions

From Rosetta Code
Content added Content deleted
mNo edit summary
No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 2: Line 2:
#include <stdlib.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdint.h>
#include <math.h>


#define N 100
typedef uint32_t pint;
#define D 6
typedef uint64_t xint;
typedef unsigned int uint;


typedef float flt;
int is_prime(xint);
typedef struct { flt p1, p2; int32_t hold; } strat;
strat ** prob;
#define P(op, sc, h) (prob[(op) * N + (sc)][h])
inline flt better(strat * p) {
return p->hold ? p->p1 : p->p2;
}


inline int next_prime(pint p)
inline flt p_better(int op, int sc, int h) {
return better(&P(op, sc, h));
}

#define FOR(x, n) for (x = 0; x < n; x++)

void mkarray()
{
{
int i, j;
if (p == 2) return 3;
prob = malloc(sizeof(*prob) * N * N);
for (p += 2; p > 1 && !is_prime(p); p += 2);
strat * pp = calloc(sizeof(*pp), N * N * (N + 1) / 2);
if (p == 1) return 0;

return p;
FOR(i, N) FOR(j, N)
prob[i * N + j] = pp, pp += N - j;
}
}


int is_prime(xint n)
int step_array()
{
{
int converged = 1;
# define NCACHE 8192
int i, j, k, r;
# define S (sizeof(uint) * 2)
static uint cache[NCACHE] = {0};


FOR(i, N) FOR(j, N) FOR(k, N - j) {
pint p = 2;
strat *p = &P(i, j, k);
int ofs, bit = -1;


flt p_current = p_better(i, j, k), chance1, chance2;
if (n < NCACHE * S) {
ofs = n / S;
bit = 1 << ((n & (S - 1)) >> 1);
if (cache[ofs] & bit) return 1;
}


chance1 = 1 - p_better(j + k, i, 0); // if holding
do {
if (n % p == 0) return 0;
if (p * p > n) break;
} while ((p = next_prime(p)));


chance2 = 1 - p_better(j, i, 0); // if rolling
if (bit != -1) cache[ofs] |= bit;
for (r = 2; r <= D; r++)
return 1;
chance2 += (j + k + r >= N) ? 1 : p_better(i, j, k + r);
chance2 /= D;

p->p1 = chance1;
p->p2 = chance2;
p->hold = k && chance1 > chance2;

if (converged && fabs(p_better(i, j, k) - p_current) > 1e-4)
converged = 0;
}

return converged;
}
}


void write_array()
int decompose(xint n, pint *out)
{
{
int i = 0;
int i, j, k;
FOR(i, N) {
pint p = 2;
while (n > p * p) {
FOR(j, N - i) {
while (n % p == 0) {
printf("%2d %2d: ", i, j);
out[i++] = p;
FOR(k, N) {
n /= p;
strat *p = &P(k,i,j);
putchar(p->hold ? '.' : 'R');
printf("(%.3f %.3f) ", p->p1, p->p2);
}
putchar('\n');
}
}
putchar('\n');
if (!(p = next_prime(p))) break;
}
}
if (n > 1) out[i++] = n;
return i;
}
}


int main()
int main(void)
{
{
int i, j, len;
int i = 0;
mkarray();
xint z;

pint out[100];
while (!step_array())
for (i = 2; i < 64; i = next_prime(i)) {
fprintf(stderr, "iter %d\n", ++i);
z = (1ULL << i) - 1;

printf("2^%d - 1 = %llu = ", i, z);
write_array();
fflush(stdout);
len = decompose(z, out);
for (j = 0; j < len; j++)
printf("%u%s", out[j], j < len - 1 ? " x " : "\n");
}


return 0;
return 0;
}</lang>
}</lang>

<lang c>#include <stdio.h>
<lang c>#include <ucontext.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <string.h>


struct hist_t {
typedef uint32_t pint;
ucontext_t caller, callee;
typedef uint64_t xint;
void **in, *out;
typedef unsigned int uint;
int first;
struct hist_t *prev;
uint8_t *pbits;
} *hist;
pint sieved;


void backtrack() {
#define MAX_PRIME (~(uint32_t)1)
if (!hist) {
#define MAX_PRIME_SQ 65535U
puts("backtracking exhausted");
#define PBITS (MAX_PRIME * 8 / 30 + 1)
abort();
pint next_prime(pint);
}
int is_prime(xint);
setcontext(&hist->callee);
void sieve(pint);
}


ucontext_t* hpush()
uint8_t bit_pos[30] = {
{
0, 1<<0, 0, 0, 0, 0,
struct hist_t *h = malloc(sizeof(*h));
0, 1<<1, 0, 0, 0, 1<<2,
h->in = 0;
0, 1<<3, 0, 0, 0, 1<<4,
h->out = 0;
0, 1<<5, 0, 0, 0, 1<<6,
h->prev = hist;
0, 0, 0, 0, 0, 1<<7,
hist = h;
};
return &hist->caller;
}


void hpop() {
uint8_t rem_num[] = { 1, 7, 11, 13, 17, 19, 23, 29 };
struct hist_t *s = hist;
hist = hist->prev;


if (s->in) free(s->in);
void init_primes()
free(s->callee.uc_stack.ss_sp);
{
free(s);
pint tgt = 4;
pbits = malloc(PBITS);


backtrack();
FILE *fp = fopen("primebits", "r");
}
if (fp) {
fread(pbits, 1, PBITS, fp);
sieved = MAX_PRIME_SQ;
fclose(fp);
return;
}


void yield(void *p)
memset(pbits, 255, PBITS);
{
sieved = 5;
hist->out = p;
while (sieved < MAX_PRIME_SQ) {
swapcontext(&hist->callee, &hist->caller);
if (sieved > tgt) {
tgt *= 2;
fprintf(stderr, "sieve %u\n", sieved);
}
sieve(sieved);
}
fp = fopen("primebits", "w");
fwrite(pbits, 1, PBITS, fp);
fclose(fp);
}
}


void hinit(void **in, void (*func)())
int is_prime(xint x)
{
{
if (!hist->in) {
pint p;
hist->in = in;
if (x > 5) {
getcontext(&hist->callee);
if (x < MAX_PRIME)
hist->callee.uc_stack.ss_sp = malloc(4096);
return pbits[x/30] & bit_pos[x % 30];
hist->callee.uc_stack.ss_size = 4096;
for (p = 2; p && (xint)p * p <= x; p = next_prime(p))
hist->callee.uc_link = &hist->caller;
if (x % p == 0) return 0;
makecontext(&hist->callee, func, 0);
return 1;
setcontext(&hist->callee);
}
}
return x == 2 || x == 3 || x == 5;
}
}


#define amb (getcontext(hpush())+_amb)
void sieve(pint p)
void *_amb(int n, ...)
{
{
void iter() {
xint p1 = p * p;
int i;
pint o = sieved;
for (i = 0; hist->in[i]; i++)
unsigned char bits;
yield(hist->in[i]);
uint32_t addr;
hpop();
off_t shift[8];
int n_shift = 0, i;

if (sieved > 5)
while (sieved < p + 30) {
addr = p1 / 30;
bits = bit_pos[p1 % 30];
if (!n_shift || addr > shift[n_shift - 1])
shift[n_shift++] = addr;

pbits[addr] &= ~bits;
sieved = next_prime(sieved);
p1 = p * sieved;
}
}
sieved = next_prime(o);


i = 0;
int i;
va_list ap;
addr = o = shift[0] + p;
void **buf = calloc((1 + n), sizeof(buf[0]));
while (addr < PBITS) {
pbits[addr] = pbits[addr - p];
addr = o + shift[i++];
if (i == n_shift) {
i = 0;
o += p;
}
}


va_start(ap, n);
}
for (i = 0; i < n; i++)

buf[i] = va_arg(ap, void*);
pint next_prime(pint p)
va_end(ap);
{
off_t addr;
uint8_t bits, rem;


if (p > 5) {
hinit(buf, iter);
return hist->out;
addr = p / 30;
bits = bit_pos[ p % 30 ] << 1;
for (rem = 0; (1 << rem) < bits; rem++);
while (pbits[addr] < bits || !bits) {
addr++;
bits = 1;
rem = 0;
}
if (addr >= PBITS) return 0;
while (!(pbits[addr] & bits)) {
rem++;
bits <<= 1;
}
p = addr * 30 + rem_num[rem];
return p;
}
switch(p) {
case 2: return 3;
case 3: return 5;
case 5: return 7;
}
return 2;
}
}


int main(void)
int decompose(xint n, xint *f)
{
{
int join(char *a, char *b) {
pint p = 0;
return a[strlen(a) - 1] == b[0];
int i = 0;
while (n >= (xint)p * p) {
if (!(p = next_prime(p))) break;
while (n % p == 0) {
n /= p;
f[i++] = p;
}
}
}
if (n > 1) f[i++] = n;
return i;
}


char *a = amb(3, "the", "that", "a"),
int main()
*b = amb(3, "frog", "elephant", "thing"),
{
*c = amb(3, "walked", "treaded", "grows"),
int i, len;
*d = amb(3, "slowly", "quickly", "deathly");
pint p = 0;
xint f[100], po;
init_primes();


for (p = 1; p < 64; p++) {
if (join(a, b) && join(b, c) && join(c, d))
po = (1LLU << p) - 1;
printf("%s %s %s %s\n", a, b, c, d);
else
printf("2^%u - 1 = %llu = ", p, po);
fflush(stdout);
amb(0);

// should put a backtrack barrier here

int s[] = {1, 2, 3, 4};

int x = *(int*)amb(4, s, s+1, s+2, s+3);
int y = *(int*)amb(3, s, s+1, s+2);
int z = *(int*)amb(3, s, s+1, s+2);

//if (! (x > y && y < z && z < x && (x > 4))) // make "thing grows slowly"
if (! (x > y && y < z && z < x && !(x & 1)))
backtrack();

printf("%d %d %d\n", x, y, z);


len = decompose(po, f);
for (i = 0; i < len; i++)
printf("%llu%s", f[i], i == len - 1 ? "\n" : " x ");
}
return 0;
return 0;
}</lang>
}</lang>

<lang lisp>(defmacro or= (x y) `(setf ,x (logior ,x ,y)))
(defmacro and= (x y) `(setf ,x (logand ,x ,y)))

(defconstant +N+ 1)
(defconstant +S+ 2)
(defconstant +W+ 4)
(defconstant +E+ 8)
(defconstant +V+ 16)

(defun show-maze (a)
(let ((h (1- (array-dimension a 0)))
(w (1- (array-dimension a 1)))
(g " │││─┘┐┤─└┌├─┴┬┼"))
(write-line "")
(loop for y from 0 to h do
(loop for x from 0 to w do
(format t "~c" (char g (logand (aref a y x) (lognot +V+)))))
(format t "~%"))))

(defun make-maze (w h)
(let* (xs (size (* (1- w) (1- h)))
(w2 (* 2 w)) (h2 (* 2 h))
(walls (make-array (list (1+ h2) (1+ w2))
:element-type 'integer :initial-element 0)))

(flet ((visit (y x) (or= (aref walls y x) +V+))
(rand-element (list r)
(loop for x in list with c = 1 with sel do
(if (zerop (random c)) (setf sel x))
(incf c r)
finally (return sel)))
(connect (c1 c2)
(let ((y1 (car c1)) (y2 (car c2))
(x1 (cdr c1)) (x2 (cdr c2)))
(if (= x1 x2)
(progn (or= (aref walls (min y1 y2) x1) +S+)
(or= (aref walls (1+ (min y1 y2)) x1) +S+)
(or= (aref walls (1+ (min y1 y2)) x1) +N+)
(or= (aref walls (max y1 y2) x1) +N+))
(progn (or= (aref walls y1 (min x1 x2)) +E+)
(or= (aref walls y1 (1+ (min x1 x2))) +E+)
(or= (aref walls y1 (1+ (min x1 x2))) +W+)
(or= (aref walls y1 (max x1 x2)) +W+)))))
(neighbor (cell)
(loop with cnt = 0 with next-cell
for (dy dx) in '((-2 0) (2 0) (0 2) (0 -2)) do
(let ((y (+ (car cell) dy)) (x (+ (cdr cell) dx)))
(if (and (array-in-bounds-p walls y x)
(not (logtest (aref walls y x) +V+))
(zerop (random (incf cnt))))
(setf next-cell (cons y x))))
finally (return next-cell))))
(setf xs (append
(loop for y from 0 to h
collect (cons (* 2 y) 0) collect (cons (* 2 y) w2)
do (let ((y2 (* 2 y)))
(visit y2 0) (visit y2 w2)
(when (< y2 h2)
(connect (cons y2 0) (cons (+ 2 y2) 0))
(connect (cons y2 w2) (cons (+ 2 y2) w2)))))
(loop for x from 0 to w
collect (cons 0 (* 2 x)) collect (cons h2 (* 2 x))
do (let ((x2 (* 2 x)))
(visit 0 x2) (visit h2 x2)
(when (< x2 w2)
(connect (cons 0 x2) (cons 0 (+ 2 x2)))
(connect (cons h2 x2) (cons h2 (+ 2 x2))))))))

(loop while xs do
;(let* ((c (elt xs (random (length xs)))) (c2 (neighbor c)))
(let* ((c (rand-element xs 100)) (c2 (neighbor c)))
;(let* ((c (first xs)) (c2 (neighbor c)))
(cond ((not c2) (setf xs (remove c xs :test #'equal)))
(t (connect c c2)
(visit (car c2) (cdr c2))
(decf size)
(push c2 xs)
))))

(show-maze walls))))

(print (make-maze 42 25))</lang>

Latest revision as of 21:26, 16 September 2012

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <stdint.h>
  3. include <math.h>
  1. define N 100
  2. define D 6

typedef float flt; typedef struct { flt p1, p2; int32_t hold; } strat; strat ** prob;

  1. define P(op, sc, h) (prob[(op) * N + (sc)][h])

inline flt better(strat * p) { return p->hold ? p->p1 : p->p2; }

inline flt p_better(int op, int sc, int h) { return better(&P(op, sc, h)); }

  1. define FOR(x, n) for (x = 0; x < n; x++)

void mkarray() { int i, j; prob = malloc(sizeof(*prob) * N * N); strat * pp = calloc(sizeof(*pp), N * N * (N + 1) / 2);

FOR(i, N) FOR(j, N) prob[i * N + j] = pp, pp += N - j; }

int step_array() { int converged = 1; int i, j, k, r;

FOR(i, N) FOR(j, N) FOR(k, N - j) { strat *p = &P(i, j, k);

flt p_current = p_better(i, j, k), chance1, chance2;

chance1 = 1 - p_better(j + k, i, 0); // if holding

chance2 = 1 - p_better(j, i, 0); // if rolling for (r = 2; r <= D; r++) chance2 += (j + k + r >= N) ? 1 : p_better(i, j, k + r); chance2 /= D;

p->p1 = chance1; p->p2 = chance2; p->hold = k && chance1 > chance2;

if (converged && fabs(p_better(i, j, k) - p_current) > 1e-4) converged = 0; }

return converged; }

void write_array() { int i, j, k; FOR(i, N) { FOR(j, N - i) { printf("%2d %2d: ", i, j); FOR(k, N) { strat *p = &P(k,i,j); putchar(p->hold ? '.' : 'R'); printf("(%.3f %.3f) ", p->p1, p->p2); } putchar('\n'); } putchar('\n'); } }

int main(void) { int i = 0; mkarray();

while (!step_array()) fprintf(stderr, "iter %d\n", ++i);

write_array();

return 0; }</lang>

<lang c>#include <ucontext.h>

  1. include <stdlib.h>
  2. include <stdio.h>
  3. include <stdarg.h>
  4. include <string.h>

struct hist_t { ucontext_t caller, callee; void **in, *out; int first; struct hist_t *prev; } *hist;

void backtrack() { if (!hist) { puts("backtracking exhausted"); abort(); } setcontext(&hist->callee); }

ucontext_t* hpush() { struct hist_t *h = malloc(sizeof(*h)); h->in = 0; h->out = 0; h->prev = hist; hist = h; return &hist->caller; }

void hpop() { struct hist_t *s = hist; hist = hist->prev;

if (s->in) free(s->in); free(s->callee.uc_stack.ss_sp); free(s);

backtrack(); }

void yield(void *p) { hist->out = p; swapcontext(&hist->callee, &hist->caller); }

void hinit(void **in, void (*func)()) { if (!hist->in) { hist->in = in; getcontext(&hist->callee); hist->callee.uc_stack.ss_sp = malloc(4096); hist->callee.uc_stack.ss_size = 4096; hist->callee.uc_link = &hist->caller; makecontext(&hist->callee, func, 0); setcontext(&hist->callee); } }

  1. define amb (getcontext(hpush())+_amb)

void *_amb(int n, ...) { void iter() { int i; for (i = 0; hist->in[i]; i++) yield(hist->in[i]); hpop(); }

int i; va_list ap; void **buf = calloc((1 + n), sizeof(buf[0]));

va_start(ap, n); for (i = 0; i < n; i++) buf[i] = va_arg(ap, void*); va_end(ap);

hinit(buf, iter); return hist->out; }

int main(void) { int join(char *a, char *b) { return a[strlen(a) - 1] == b[0]; }

char *a = amb(3, "the", "that", "a"), *b = amb(3, "frog", "elephant", "thing"), *c = amb(3, "walked", "treaded", "grows"), *d = amb(3, "slowly", "quickly", "deathly");

if (join(a, b) && join(b, c) && join(c, d)) printf("%s %s %s %s\n", a, b, c, d); else amb(0);

// should put a backtrack barrier here

int s[] = {1, 2, 3, 4};

int x = *(int*)amb(4, s, s+1, s+2, s+3); int y = *(int*)amb(3, s, s+1, s+2); int z = *(int*)amb(3, s, s+1, s+2);

//if (! (x > y && y < z && z < x && (x > 4))) // make "thing grows slowly" if (! (x > y && y < z && z < x && !(x & 1))) backtrack();

printf("%d %d %d\n", x, y, z);

return 0; }</lang>

<lang lisp>(defmacro or= (x y) `(setf ,x (logior ,x ,y))) (defmacro and= (x y) `(setf ,x (logand ,x ,y)))

(defconstant +N+ 1) (defconstant +S+ 2) (defconstant +W+ 4) (defconstant +E+ 8) (defconstant +V+ 16)

(defun show-maze (a)

 (let ((h (1- (array-dimension a 0)))

(w (1- (array-dimension a 1))) (g " │││─┘┐┤─└┌├─┴┬┼"))

   (write-line "")
   (loop for y from 0 to h do

(loop for x from 0 to w do (format t "~c" (char g (logand (aref a y x) (lognot +V+))))) (format t "~%"))))

(defun make-maze (w h)

 (let* (xs (size (* (1- w) (1- h)))

(w2 (* 2 w)) (h2 (* 2 h)) (walls (make-array (list (1+ h2) (1+ w2)) :element-type 'integer :initial-element 0)))

   (flet ((visit (y x) (or= (aref walls y x) +V+))

(rand-element (list r) (loop for x in list with c = 1 with sel do (if (zerop (random c)) (setf sel x)) (incf c r) finally (return sel))) (connect (c1 c2) (let ((y1 (car c1)) (y2 (car c2)) (x1 (cdr c1)) (x2 (cdr c2))) (if (= x1 x2) (progn (or= (aref walls (min y1 y2) x1) +S+) (or= (aref walls (1+ (min y1 y2)) x1) +S+) (or= (aref walls (1+ (min y1 y2)) x1) +N+) (or= (aref walls (max y1 y2) x1) +N+)) (progn (or= (aref walls y1 (min x1 x2)) +E+) (or= (aref walls y1 (1+ (min x1 x2))) +E+) (or= (aref walls y1 (1+ (min x1 x2))) +W+) (or= (aref walls y1 (max x1 x2)) +W+))))) (neighbor (cell) (loop with cnt = 0 with next-cell for (dy dx) in '((-2 0) (2 0) (0 2) (0 -2)) do (let ((y (+ (car cell) dy)) (x (+ (cdr cell) dx))) (if (and (array-in-bounds-p walls y x) (not (logtest (aref walls y x) +V+)) (zerop (random (incf cnt)))) (setf next-cell (cons y x)))) finally (return next-cell))))

     (setf xs (append

(loop for y from 0 to h collect (cons (* 2 y) 0) collect (cons (* 2 y) w2) do (let ((y2 (* 2 y))) (visit y2 0) (visit y2 w2) (when (< y2 h2) (connect (cons y2 0) (cons (+ 2 y2) 0)) (connect (cons y2 w2) (cons (+ 2 y2) w2))))) (loop for x from 0 to w collect (cons 0 (* 2 x)) collect (cons h2 (* 2 x)) do (let ((x2 (* 2 x))) (visit 0 x2) (visit h2 x2) (when (< x2 w2) (connect (cons 0 x2) (cons 0 (+ 2 x2))) (connect (cons h2 x2) (cons h2 (+ 2 x2))))))))

     (loop while xs do

 ;(let* ((c (elt xs (random (length xs)))) (c2 (neighbor c))) (let* ((c (rand-element xs 100)) (c2 (neighbor c)))  ;(let* ((c (first xs)) (c2 (neighbor c))) (cond ((not c2) (setf xs (remove c xs :test #'equal))) (t (connect c c2) (visit (car c2) (cdr c2)) (decf size) (push c2 xs) ))))

     (show-maze walls))))

(print (make-maze 42 25))</lang>