From: Martin Mares Date: Fri, 13 Jul 2007 08:43:15 +0000 (+0200) Subject: Initial commit. X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=46fd143a6cede94247d8220277bd50595eda308f;p=misc.git Initial commit. --- 46fd143a6cede94247d8220277bd50595eda308f diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d58e035 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +CC=gcc +LD=gcc +CFLAGS=-O2 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -std=gnu99 + +all: + @echo "Please choose what to make:" + @grep '^[^ ]*:' Makefile + +parrot: parrot.c + +clean: + rm -f `find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core -or -name .depend -or -name .#*` diff --git a/ant.c b/ant.c new file mode 100644 index 0000000..0749a29 --- /dev/null +++ b/ant.c @@ -0,0 +1,345 @@ +/* + * A simple ant-ology of genetic algorithms. + * + * mj@ucw.cz, Discord YOLD 3166 + */ + +#include +#include +#include + +#define NSTATES 16 +#define NMARKS 4 +#define SENSE_FOOD +#ifdef SENSE_FOOD +#define NTYPES 3 +#else +#define NTYPES 8 +#endif +#define NWAYS 1 +#define NSLOTS (NMARKS*NTYPES*NWAYS) +#define SLOT(m,t,w) (((m)*NTYPES+(t))*NWAYS+(w)) + +struct slot { + unsigned char op, mark, state; +}; + +#define OP_NOP 0 +#define OP_LEFT 1 +#define OP_RIGHT 2 +#define OP_UTB 3 +#define OP_MAX 4 + +struct state { + struct slot slots[NSLOTS]; +}; + +struct automaton { + struct state states[NSTATES]; + int fitness; +}; + +#if 0 +#define XSIZE 10 +#define YSIZE 10 +#define XSTART 1 +#define YSTART 1 + +char *maze = +"##########" +"#.#$#....#" +"#.#.#$$$.#" +"#.#.#$$$.#" +"#.#.#$$$.#" +"#.#.####.#" +"#.#...$..#" +"#.##.#####" +"#.$......#" +"##########" +; +#else +#define XSIZE 34 +#define YSIZE 34 +#define XSTART 1 +#define YSTART 1 +char *maze = +"##################################" +"#.$$$............................#" +"#...$............................#" +"#...$.....................$$$....#" +"#...$....................$....$..#" +"#...$....................$....$..#" +"#...$$$$.$$$$$........$$.........#" +"#............$................$..#" +"#............$.......$...........#" +"#............$.......$...........#" +"#............$.......$........$..#" +"#....................$...........#" +"#............$...................#" +"#............$................$..#" +"#............$.......$...........#" +"#............$.......$.....$$$...#" +"#.................$.....$........#" +"#................................#" +"#............$...................#" +"#............$...$.......$.......#" +"#............$...$..........$....#" +"#............$...$...............#" +"#............$...$...............#" +"#............$.............$.....#" +"#............$..........$........#" +"#...$$..$$$$$....$...............#" +"#.$..............$...............#" +"#.$..............$...............#" +"#.$......$$$$$$$.................#" +"#.$.....$........................#" +"#.......$........................#" +"#..$$$$..........................#" +"#................................#" +"##################################" +; + +#endif + +#define MI(a,b) ((b)*XSIZE+(a)) +char mazec[XSIZE*YSIZE]; +char *types = "$#.012345"; + +#define POPSIZE 100 + +struct automaton autpool[POPSIZE]; +struct automaton *pop[POPSIZE]; + +void +maze_init(void) +{ + int i; + + puts("Initializing maze"); + for(i=0; istates[i].slots[j]; + s->op = random() % OP_MAX; + s->state = random() % NSTATES; + s->mark = random() % NMARKS; + } +} + +void +show(char *z) +{ + int i, j; + int x = 0; + for(i=0; i 0) + { + int way = random() % NWAYS; + int here = tmp[MI(x,y)]; + int mark = (here < 3) ? 0 : here-3; + int ahead = tmp[MI(x+dx[d],y+dy[d])]; + int right = tmp[MI(x+dx[(d+1)%4],y+dy[(d+1)%4])]; + int left = tmp[MI(x+dx[(d+3)%4],y+dy[(d+3)%4])]; +#ifdef SENSE_FOOD + int view = (ahead >= 2) ? 2 : ahead; +#else + int view = ((ahead==1)?4:0) | ((left==1)?2:0) | ((right==1)?1:0); +#endif + struct slot *s = &aut->states[state].slots[SLOT(mark, view, way)]; + tmp[MI(x,y)] = s->mark + 3; + bonus++; + energy--; + switch (s->op) + { + case OP_NOP: break; + case OP_LEFT: d = (d+3) % 4; break; + case OP_RIGHT: d = (d+1) % 4; break; + case OP_UTB: d = (d+2) % 4; break; + } + ahead = tmp[MI(x+dx[d],y+dy[d])]; + switch (ahead) + { + case 0: energy+=10; bonus+=100; /* food */ + default: x+=dx[d]; y+=dy[d]; break; /* empty */ + case 1: energy-=5; break; /* wall */ + } + state = s->state; + } + if (flag) + show(tmp); + return bonus; +} + +void +pop_init(void) +{ + int i; + + for(i=0; ifitness; + int fb = (*b)->fitness; + + return (fa < fb) ? -1 : (fa > fb) ? 1 : 0; +} + +void +mutate(struct automaton *a) +{ + int state, slot, i; + struct slot *s; + + for(i=0; i<40; i++) + { + state = random() % NSTATES; + slot = random() % NSLOTS; + s = &a->states[state].slots[slot]; + s->op = random() % OP_MAX; + s->state = random() % NSTATES; + s->mark = random() % NMARKS; + } +} + +void +crossover(struct automaton *a, struct automaton *b) +{ + int marks[NMARKS], types[NTYPES], ways[NWAYS], slots[NSLOTS]; + int i, j, k; + + if (a == b) + return; + for(i=0; istates[i].slots[j]; + a->states[i].slots[j] = b->states[i].slots[j]; + b->states[i].slots[j] = z; + } +} + +struct automaton * +rgenom(struct automaton **x, int n, int t) +{ + int z = random() % t; + int k = 0; + int i = 0; + + while (k <= z && n--) + k += x[i++]->fitness; + return x[i-1]; +} + +void +step(void) +{ + int i, total, death; + + for(i=0; ifitness = (fitness(a,0) + fitness(a,0) + fitness(a,0)) / 3; + } + qsort(pop, POPSIZE, sizeof(struct automaton *), (int(*)(const void *,const void *)) fcmp); + for(i=0; ifitness); + total += a->fitness; + } + fitness(pop[POPSIZE-1], 1); + printf("best=%d worst=%d\n", pop[POPSIZE-1]->fitness, pop[0]->fitness); + + total = 0; + death = POPSIZE/2; + for(i=death; ifitness; + for(i=0; i +#include +#include + +#define MAX 100 +#define BASE 10 + +int first(int *X) +{ + /* Find the leftmost non-zero digit of X */ + int n = MAX-1; + while (n >= 0 && !X[n]) + n--; + return n; +} + +int mul2(int *X, int n) +{ + /* Multiply X by 2 and return its new length */ + int c = 0; + for (int i=0; i<=n; i++) { + int x = 2*X[i] + c; + X[i] = x % BASE; + c = x / BASE; + } + if (c) + X[++n] = c; + return n; +} + +int submul(int *X, int xn, int *Y, int yn, int z, int *T) +{ + /* T = X-z*Y, returns -1 if it's <0; T and X can be the same array */ + if (!z) + return 0; + if (yn > xn) + return -1; + int c = 1, d = 0; + for (int i=0; i<=xn; i++) { + int y = z*((i <= yn) ? Y[i] : 0) + d; + d = y / BASE; + y %= BASE; + int x = X[i] + (BASE-1-y) + c; + T[i] = x % BASE; + c = x / BASE; + } + return (c ? 0 : -1); +} + +void divide(int *X0, int *Y0, int *Z) +{ + /* A copy of X and Y will be needed to avoid overwriting inputs */ + int X[MAX], Y[MAX]; + memcpy(X, X0, MAX * sizeof(*X)); + memcpy(Y, Y0, MAX * sizeof(*Y)); + + /* Find the leftmost digit of X and Y */ + int xn = first(X), yn = first(Y); + if (yn < 0) // Division by 0 + exit(1); + + /* While Y starts with = 0) { + int T[MAX]; + while (xn > 0 && !X[xn]) /* Fix the estimate of size of X */ + xn--; + int z = X[xn]; + if (xn-zn > yn) /* First 1 or 2 digits of X */ + z = 10*z + X[xn-1]; + Z[zn] = z / Y[yn]; + if (submul(X+zn, xn-zn, Y, yn, Z[zn], T) < 0) + Z[zn]--; + submul(X+zn, xn-zn, Y, yn, Z[zn], X+zn); + zn--; + } +} + +int main(void) +{ + int A[MAX] = { 6, 7, 5, 8, 4, 0, 1 }; + int B[MAX] = { 4, 6 }; + int C[MAX]; + divide(A, B, C); + for (int i=MAX-1; i>=0; i--) + printf("%d", C[i]); + putchar('\n'); + return 0; +} diff --git a/bmap.c b/bmap.c new file mode 100644 index 0000000..742e63f --- /dev/null +++ b/bmap.c @@ -0,0 +1,48 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +int main(void) +{ + int bs; + if (ioctl(0, FIGETBSZ, &bs) < 0) + { + perror("FIGETBSZ"); + return 1; + } + printf("Block size is %d\n", bs); + long long len = lseek64(0, 0, SEEK_END); + printf("File size is %Ld\n", len); + int blx = (len+bs-1)/bs; + printf("... that is %d blocks\n", blx); + int blk, pos; + int small_gaps = 0; + int large_gaps = 0; + int last_pos = -1; + for (blk=0; blk= 0) + { + if (pos == last_pos+1) + ; + else if (pos >= last_pos && pos < last_pos + 1024) + small_gaps++; + else + large_gaps++; + } + last_pos = pos; + } + printf("Gaps: %d small, %d large\n", small_gaps, large_gaps); + return 0; +} diff --git a/buckets.c b/buckets.c new file mode 100644 index 0000000..f5f955d --- /dev/null +++ b/buckets.c @@ -0,0 +1,107 @@ +#include + +#define MAX 12 // actually, it's 1 more than max +#define NST (MAX*MAX*MAX) + +int status[NST], queue[NST], back[NST], qr, qw; +int capa[3], goal[MAX], gback[MAX]; + +#define ENCODE(i,j,k) ((i)*MAX*MAX+(j)*MAX+(k)) +#define DECODE(i,j,k,x) (i)=(x)/(MAX*MAX), (j)=(x)/MAX%MAX, (k)=(x)%MAX + +static void go(int x, int *t) +{ + // printf("\t-> %d %d %d\n", t[0], t[1], t[2]); + int y = ENCODE(t[0], t[1], t[2]); + if (status[y] < 0) + { + status[y] = status[x] + 1; + queue[qw++] = y; + back[y] = x; + } +} + +static void search(void) +{ + for (int i=1; i t[i]) + r = t[i]; + t[i]-=r; t[j]+=r; + go(x, t); + t[i]+=r; t[j]-=r; + } + } +} + +int main(void) +{ +#if 1 + for (int f=0; f goal[best]) + best = i; + int reach = 0; + for (int i=0; i= 0) + reach++; + printf("%2d (%d) r=%d\n", goal[best], best, reach); + } +#else + capa[0] = 8; + capa[1] = 5; + capa[2] = 3; + search(); + int r = gback[4]; + while (r > 0) + { + int a,b,c; + DECODE(a,b,c,r); + printf("%d,%d,%d\n", a,b,c); + r = back[r]; + } +#endif + return 0; +} diff --git a/callback.c b/callback.c new file mode 100644 index 0000000..1c62ccb --- /dev/null +++ b/callback.c @@ -0,0 +1,317 @@ +/* + * Modem Call Back + * + * (c) 1995 Martin Mares + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODEM_PORT "/dev/cua3" + +int modem_handle; +int alarm_got; +int termios_backed_up; +int modem_active; +struct termios old_termios; + +struct termios new_termios = { + IGNBRK | IGNPAR, + 0, + 0, + 0, + N_TTY, + { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + +void err(char *); + +void +set_timeout(int n) +{ + alarm_got = 0; + alarm(n); +} + +void +delay(int n) +{ + set_timeout(n); + do pause(); while (!alarm_got); +} + +void +pulse_dtr(void) +{ +int o = new_termios.c_cflag; + fprintf(stderr, "Pulsing DTR\n"); + new_termios.c_cflag &= ~CBAUD; + if (tcsetattr(modem_handle, TCSANOW, &new_termios)) + err("Unable to lower DTR"); + delay(2); + new_termios.c_cflag = o; + if (tcsetattr(modem_handle, TCSANOW, &new_termios)) + err("Unable to raise DTR"); +} + +void +send(char *s) +{ + fprintf(stderr, "Sending %s", s); + write(modem_handle, s, strlen(s)); +} + +int +wait_for(char *c, int tim) +{ +char *s = c; +char b; +int l; + fprintf(stderr,"Waiting %d sec for %s\n", tim, c); + while (*s) + { + set_timeout(tim); + l = read(modem_handle, &b, 1); + if (!l) + err("EOF"); + if (l == -1) + { + if (errno == EINTR) + return 0; + else + err("Read error"); + } + fprintf(stderr, "Got %c\n", b); + if (b == *s) + s++; + else + s = c; + } + alarm(0); + return 1; +} + +void +cmd(char *s) +{ + send(s); + if (!wait_for("OK",5)) + err("Timeout"); +} + +void +drain(void) +{ +char buf[256]; + if (!fcntl(modem_handle, F_SETFL, O_NONBLOCK)) + { + while (read(modem_handle, buf, 256) > 0) ; + fcntl(modem_handle, F_SETFL, 0); + } +} + +void +modem_init(char *name) +{ + modem_handle = open(name, O_RDWR); + if (modem_handle < 0) + err("Unable to open modem device"); + if (tcgetattr(modem_handle, &old_termios)) + err("Unable to fetch old termios"); + termios_backed_up = 1; + new_termios.c_cflag = (old_termios.c_cflag | CRTSCTS) & ~HUPCL; + if (!(new_termios.c_cflag & CBAUD)) + new_termios.c_cflag |= B19200; + if (tcsetattr(modem_handle, TCSANOW, &new_termios)) + err("Unable to set termios"); + modem_active = 1; + pulse_dtr(); + send("ATZ\r\n"); + delay(2); + drain(); + cmd("ATE0M1Q0\r\n"); +} + +void +err2(char *text) +{ + perror(text); +} + +void +cleanup(void) +{ + if (modem_handle < 0) + return; + fprintf(stderr, "Cleanup.\n"); + if (modem_active) + { + modem_active = 0; + pulse_dtr(); + send("ATZ\n"); + delay(1); + pulse_dtr(); + } + if (termios_backed_up) + { + termios_backed_up = 0; + if (tcsetattr(modem_handle, TCSANOW, &old_termios)) + err2("Termios cannot be restored"); + } + fprintf(stderr, "Done.\n"); + close(modem_handle); + modem_handle = -1; +} + +void +sig_err(int n) +{ + fprintf(stderr, "Caught fatal signal %d -- aborting !\n", n); + cleanup(); + exit(1); +} + +void +sig_alarm(int n) +{ + alarm_got = 1; + signal(SIGALRM, sig_alarm); +} + +void +signal_init(void) +{ +int i; + for (i=0; i<32; i++) + signal(i, sig_err); + signal(SIGALRM, sig_alarm); +} + +void +err(char *txt) +{ + err2(txt); + cleanup(); + exit(1); +} + +int +connect(char *nr) +{ +char buf[256]; +int i; + sprintf(buf, "atd%s\r\n", nr); + send(buf); + i = wait_for("CONNECT", 60); + delay(1); + drain(); + return i; +} + +struct termios tios = { + ICRNL | IXON | IXOFF, + OPOST | ONLCR, + 0, + ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE, + N_TTY, + { 3, 0x1c, 0x7f, 0x15, 4, 0, 1, 0, 0x11, 0x13, 0x1a, 0, 0x12, 0x0f, 0x17, + 0x16, 0 } + }; + +void +okay(void) +{ +int pid, i, wt; +struct utmp ut; +char *port = MODEM_PORT; + pid = fork(); + if (pid < 0) + err("Cannot fork()"); + if (!pid) + { + setsid(); + for (i=0; i<3; i++) + { + close(i); + open(port, O_RDWR); + } + tios.c_cflag = new_termios.c_cflag | HUPCL; + tcsetattr(0, TCSANOW, &tios); + utmpname(_PATH_UTMP); + memset(&ut, 0, sizeof(ut)); + strcpy(ut.ut_user, "LOGIN"); + strcpy(ut.ut_line, port+5); + strncpy(ut.ut_id, ut.ut_line + 3, sizeof(ut.ut_id)); + time(&ut.ut_time); + ut.ut_type = LOGIN_PROCESS; + ut.ut_pid = getpid(); + pututline(&ut); + endutent(); + wt = open(_PATH_WTMP, O_APPEND|O_WRONLY); + if (wt >= 0) + { + flock(wt, LOCK_EX); + write(wt, &ut, sizeof(ut)); + flock(wt, LOCK_UN); + close(wt); + } + execl("/usr/sbin/callback-login", "/usr/sbin/callback-login", NULL); + } + else + { + wait(&i); + i = open(MODEM_PORT, O_RDWR); + close(modem_handle); + modem_handle = i; + if (modem_handle >= 0) + tcsetattr(modem_handle, TCSANOW, &new_termios); + } +} + +void +main(int argc, char **argv) +{ +char *dest; +int i; + if (geteuid()) + { + fprintf(stderr, "Must be run by root!\n"); + exit(1); + } + if (getuid() != 1000 && getuid()) + { + fprintf(stderr,"Only mj is allowed to call this utility!\n"); + exit(1); + } + if (argc != 2) + { + fprintf(stderr,"Usage: callback \n"); + exit(1); + } + dest = argv[1]; + signal_init(); + for(i=0;i<3;i++) + { + modem_init(MODEM_PORT); + if (connect(dest)) + { + fprintf(stderr, "Connected...\n"); + okay(); + fprintf(stderr, "Disconnecting...\n"); + cleanup(); + return; + } + cleanup(); + fprintf(stderr, "Retrying...\n"); + } + fprintf(stderr, "Failed.\n"); + exit(1); +} diff --git a/censor.p b/censor.p new file mode 100644 index 0000000..4a036eb --- /dev/null +++ b/censor.p @@ -0,0 +1,50 @@ +program censor; + +var w0,s01,w1,s12,w2,s23:string[255]; + c:char; + +procedure shift; +var i,j,k:integer; + t:string[255]; +begin + t:=w1; + for i:=1 to length(t) do + if t[i]='o' then begin + if w0='' then + j:=length(w2) + else if (w2='') or (length(w0)'' then w0[length(w0)-(k-i)]:='*'; + if k<=length(w1)-i then w1[i+k]:='*' + else if w2<>'' then w2[k-(length(w1)-i)]:='*'; + end; + end; + write(w0); + for i:=1 to length(s01) do + if s01[i]='n' then writeln + else write(s01[i]); + w0:=w1; s01:=s12; w1:=w2; s12:=s23; + w2:=''; s23:=''; +end; + +begin + w0:=''; s01:=''; w1:=''; s12:=''; w2:=''; s23:=''; + while not eof(input) do begin + if eoln(input) then begin + readln; + s23:=s23+'n'; + end else begin + read(c); + if (c >= 'a') and (c <= 'z') or (c >= 'A') and (c <= 'Z') then begin + if s23<>'' then shift; + w2 := w2+c; + end else + s23 := s23+c; + end; + end; + shift; shift; shift; +end. diff --git a/checkaddr.pl b/checkaddr.pl new file mode 100644 index 0000000..8e7addb --- /dev/null +++ b/checkaddr.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl +# A checker for e-mail addresses +# Written by Martin Mares and put into public domain + +# We follow the e-mail address syntax in RFC 2822, but with a couple of exceptions: +# - control characters are not allowed, even if properly escaped +# - we allow dots not only between non-empty atoms, but also as separate atoms +# - some obsolete constructs are not supported +# - at least one dot is required in the domain + +sub email_ok($) { + my $addr = shift @_; + return ($addr =~ + /^([!#-'*+.-9=?A-Z^-~-]+|"([ !#-\[\]-~]|\\[ -~])*")@([!#-'*+-9=?A-Z^-~-]+\.[!#-'*+.-9=?A-Z^-~-]+|\[([ -Z^-~]|\\[ -~])+(\.|\\\.)([ -Z^-~]|\\[ -~])+\])$/ + ) ? 1 : 0; +} + +my @tests = ( + 'a.b.c.d' => 0, # no @ + 'a@b' => 0, # no dot in domain + 'a@b.c' => 1, # ok + 'a@b@c.d' => 0, # multiple @'s + '"a@b"@c.d' => 1, # but ok in quotes + 'a b@c.d' => 0, # spaces not permitted + '"a b"@c.d' => 1, # but again they are ok when quoted + '"x y"z@c.d' => 0, # quoting must not be partial + '""@c.d' => 1, # strange, but correct + '!#$%&*+-/=?^_`{}|@c.d' => 1, # all sorts of perrmited weird chars + '"a \"\\@\@"@c.d' => 1, # backslash escapes + '"\"@c.d' => 0, # misquoted + '...@c.d' => 1, # RFC disallows this, but generally accepted + 'baba@a b.cz' => 0, # no spaces in domain + 'ganesha@a.' => 0, # dot here is not enough + 'ganesha@a.b.' => 1, # but trailing dots are ok, although not canonical + 'odin@[1.2.3.4]' => 1, # numeric address + 'odin@1.2.3.4' => 1, # correct, although probably undeliverable + 'odin@[valhalla . gov]' => 1, # spaces allowed here + 'odin@[val\[halla\].\\gov]' => 1, # escapes as well + 'odin@[val\]' => 0, # but we must not forget to close ] + 'odin@[abc].def' => 0, # mixed is invalid + '"@"@[@.@]' => 1, # wow! + '[@.@]@[@.@]' => 0, # but this is not OK (unquoted "[") + 'a@a..b' => 1, # undeliverable, but syntactically OK +); + +print "Testing:\n"; +while (@tests) { + my $addr = shift @tests; + my $res = email_ok($addr); + print "$addr: $res\n"; + $res == shift @tests or die "Test failed"; +} +print "All tests passed.\n\nTry yourself:\n"; +while (<>) { + chomp; + print email_ok($_), "\n"; +} diff --git a/chocolate.c b/chocolate.c new file mode 100644 index 0000000..8196abe --- /dev/null +++ b/chocolate.c @@ -0,0 +1,30 @@ +#include +#include + +#define MAX 100 +#define MAXT 128 + +int main(void) +{ + int nim[MAX+1][MAX+1]; + int f[MAXT+1]; + for (int i=1; i<=MAX; i++) { + for (int j=1; j<=MAX; j++) { + bzero(f, sizeof(f)); + for (int k=1; k %d\n", i, j, z); + printf("%d", z); + } + putchar('\n'); + } + return 0; +} diff --git a/count.c b/count.c new file mode 100644 index 0000000..4377eb7 --- /dev/null +++ b/count.c @@ -0,0 +1,76 @@ +#include +#include + +struct state { + struct state *fwd[256], *back, *qnext, *qprev; + char *out; + int count; +}; + +struct state root, *head, *tail; + +struct state *step(struct state *s, int c) +{ + while (s) { + if (s->fwd[c]) + return s->fwd[c]; + s = s->back; + } + return &root; +} + +void insert(char *x) +{ + struct state *s = &root; + int c; + for (char *y = x; c=*y++; ) { + if (!s->fwd[c]) + s->fwd[c] = calloc(1, sizeof(struct state)); + s = s->fwd[c]; + } + s->out = x; +} + +void build(void) +{ + struct state *s; + head = tail = &root; + while (head) { + for (int c=0; c<256; c++) + if (s = head->fwd[c]) { + s->back = step(head->back, c); + tail->qnext = s; + s->qprev = tail; + tail = s; + } + head = head->qnext; + } +} + +void run(void) +{ + struct state *s = &root; + for (int c; (c = getchar()) != EOF;) { + s = step(s, c); + s->count++; + } +} + +void count(void) +{ + for (struct state *s=tail; s != &root; s=s->qprev) { + s->back->count += s->count; + if (s->out) + printf("%6d %s\n", s->count, s->out); + } +} + +int main(int argc, char **argv) +{ + for (int i=1; i + */ + +#include +#include +#include +#include + +static FILE *f; + +struct entry { + struct entry *next; + char x[1]; +}; + +struct entry *fe, **le = &fe; + +static void +scan(time_t when, int cnt) +{ + struct tm *tm = localtime(&when); + char p[10], xb[256]; + struct entry *e; + + sprintf(p, "%02d-%02d-%02d", tm->tm_mday, tm->tm_mon+1, tm->tm_year % 100); + for(e=fe; e; e=e->next) + { + char *x, *y; + x = e->x; + y = p; + while (*x && *y) + { + if (*x != '?' && *x != *y) + goto xx; + x++, y++; + } + if (!*x) + continue; + if (*x > ' ') + { + if (*x - 'A' < cnt) + continue; + x++; + } + strcpy(xb, x); + y = strchr(xb, '('); + if (y && y[1] && y[2] && y[3] == ')') + { + int q; + sscanf(y+1, "%d", &q); + sprintf(y+1, "%02d", tm->tm_year - q); + y[3] = ')'; + } + printf("%s:%s\n", p, xb); + xx: + } +} + +int +main(int argc, char **argv) +{ + char buf[256]; + int m, cnt; + time_t now = time(NULL); + + if (argc < 2 || argc > 3) + { + fprintf(stderr, "Usage: diary []\n"); + return 1; + } + f = fopen(argv[1], "r"); + if (!f) + { + perror("fopen"); + return 1; + } + while (fgets(buf, 256, f)) + { + char *b = strchr(buf, '\n'); + struct entry *e; + + if (!b) + break; + *b = 0; + if (buf[0] <= ' ' || buf[0] == '#') + continue; + e = malloc(sizeof(struct entry) + strlen(buf)); + *le = e; + le = &e->next; + strcpy(e->x, buf); + } + *le = NULL; + m = (argc > 2) ? atol(argv[2]) : 1; + cnt = 0; + while (m--) + { + scan(now, cnt); + now += 86401; /* Dirty trick... */ + cnt++; + } + return 0; +} diff --git a/false-true/Makefile b/false-true/Makefile new file mode 100644 index 0000000..24f41ec --- /dev/null +++ b/false-true/Makefile @@ -0,0 +1,9 @@ +# Makefile for False True + +all: true + +true: mktrue + ./mktrue + +clean: + rm -f true diff --git a/false-true/mktrue b/false-true/mktrue new file mode 100755 index 0000000..7bab592 --- /dev/null +++ b/false-true/mktrue @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# +# 'False True' -- An Example of How Not To Write Code +# +# (c) 1998 Martin Mares , GPL'ed +# +# This is an attempt to write a shortest possible program which is still +# useful. I decided to make a replacement for `true' (anyway, `false' would +# fit in the same space as well). It is _NOT_ a correct ELF program (the +# headers are a bit messy and we have non-zero values in reserved fields +# and certain mandatory parts are missing), but `file' still recognizes +# it as ELF (although `objdump' doesn't) and, which is much more important, +# Linux kernel still runs it. Share and enjoy... +# + +open X, ">true" or die "No write access, no truth"; +while () { + s/#.*$//; s/\b(\w{4})(\w{4})\b/$2 $1/g; s/\b(\w\w)(\w\w)\b/$2 $1/g; + foreach $a (split /\s+/) { print X pack("c",hex $a); } +} chmod 0755, "true" or die "Executables aren't"; + +__END__ + +7f 45 4c 46 # Identification +01 # We're 32-bit +01 # Little endian +01 # Header version +# Next 9 bytes are ELF header padding and RFU, but we dare to put +# our code into them. +31 c0 # xor eax,eax (offset 9) +40 # inc eax +31 db # xor ebx,ebx +cd 80 # int 0x80 +4d 4a # Author's Signature :-) +0002 # Type: Executable File +0003 # Machine: i386 +00000001 # Version: Current :) +10000007 # Entry point +0000002c # PH offset +00000000 # SH offset +00000000 # Machine-specific flags +0034 # EH size +0020 # Size of single PH entry +0001 # Number of PH entries +0000 # Size of single SH entry +0000 # Number of SH entries +0000 # String table offset + +# Offset 2C: Program Header + +# These two entries are overlaid with the ELF header +#00000001 # Type: Loadable +#00000000 # Offset of section start +10000000 # Virtual address +10000000 # Physical address: ignored +0000004c # File image size +0000004c # Memory image size +00000007 # Flags: rwx +# Linux doesn't use alignment, so we can omit it. The kernel will try +# to read the full header size and get 4 bytes less, but it won't +# complain and it will use whatever was left in the memory. Ugly. +#00001000 # Align to page size diff --git a/false-true/mktrue2 b/false-true/mktrue2 new file mode 100755 index 0000000..a1adede --- /dev/null +++ b/false-true/mktrue2 @@ -0,0 +1,70 @@ +#!/usr/bin/perl + +while () { + s/#.*$//; s/\b(\w{4})(\w{4})\b/$2 $1/g; s/\b(\w\w)(\w\w)\b/$2 $1/g; + foreach $a (split /\s+/) { print pack("c",hex $a); } +} + +__END__ + +7f 45 4c 46 # Identification +01 # We're 32-bit +01 # Little endian +01 # Header version +00 00000000 00000000 # Padding +0002 # Type: Executable File +0003 # Machine: i386 +00000001 # Version: Current :) +100000A4 # Entry point +00000084 # PH offset +00000034 # SH offset +00000000 # Machine-specific flags +0034 # EH size +0020 # Size of single PH entry +0001 # Number of PH entries +0028 # Size of single SH entry +0002 # Number of SH entries +0000 # String table offset + +# Offset 34: Section Header for section 0 + +00000000 # Name (ST offset) +00000000 # Type: Void +00000000 # Flags +00000000 # Address +00000000 # Offset +00000000 # Size +00000000 # Link +00000000 # Info +00000000 # Align +00000000 # Size of single entry + +# Offset 5C: Section Header for section 1 + +00000000 # Name (ST offset) +00000001 # Type: Program bits +00000007 # Flags: writeable, allocate, executable +100000A4 # Address +000000A4 # Offset +00000009 # Size +00000000 # Link +00000000 # Info +00000000 # Align +00000000 # Size of single entry: No entries + +# Offset 84: Program Header + +00000001 # Type: Loadable +000000A4 # Offset of section start +100000A4 # Virtual address +100000A4 # Physical address: ignored +00000009 # File image size +00000009 # Memory image size +00000007 # Flags: rwx +00001000 # Align to page size + +# Offset A4: Our Program + +b8 01 00 00 00 +31 db +cd 80 diff --git a/false-true/true b/false-true/true new file mode 100755 index 0000000..6e86e34 Binary files /dev/null and b/false-true/true differ diff --git a/fortcmp.c b/fortcmp.c new file mode 100644 index 0000000..ee45606 --- /dev/null +++ b/fortcmp.c @@ -0,0 +1,190 @@ +/* + * Fortune Cookie Comparison + * + * (c) 1996 Martin Mares, + */ + +#include +#include +#include + +static void +die(char *msg) +{ + fputs(msg, stderr); + exit(1); +} + +static void * +xmalloc(unsigned i) +{ + void *k = malloc(i); + + if (!k) + die("Out of memory!\n"); + return k; +} + +#define HASH 16384 + +struct woord { + struct woord *next; + unsigned id; + char w[1]; + }; + +static struct woord *words[HASH]; +static unsigned lastid; + +static struct woord * +findword(char *wd) +{ + unsigned h; + char *c; + struct woord *p; + + c = wd; + h = strlen(wd); + while (*c) + h = 13*h + *c++; + h = h & (HASH-1); + for(p = words[h]; p; p = p->next) + if (!strcasecmp(p->w, wd)) + return p; + p = xmalloc(sizeof(struct woord) + strlen(wd)); + p->next = words[h]; + words[h] = p; + strcpy(p->w, wd); + p->id = lastid++; +} + +#define MFL 4096 +#define FHASH 16384 + +struct fortune { + struct fortune *next; + char *fn; + unsigned line; + unsigned count; + unsigned words[0]; + }; + +static struct fortune *forts[FHASH]; + +static int +comp(unsigned *p, unsigned *q) +{ + if (*p < *q) + return -1; + else if (*p > *q) + return 1; + else + return 0; +} + +static void +addfort(char *fn, unsigned line, unsigned *fort, unsigned len) +{ + unsigned i, h; + struct fortune *foo; + +// printf("Adding %s:%d (%d)\n", fn, line, len); + qsort(fort, len, sizeof(unsigned), (void *) comp); + h = len; + for(i=0; inext) + if (len == foo->count && !memcmp(fort, foo->words, sizeof(unsigned)*len)) + { + printf("Possible DUP %s:%d with %s:%d\n", fn, line, foo->fn, foo->line); + return; + } + foo = xmalloc(sizeof(struct fortune) + sizeof(unsigned)*len); + foo->next = forts[h]; + forts[h] = foo; + foo->fn = fn; + foo->line = line; + foo->count = len; + memcpy(foo->words, fort, len * sizeof(unsigned)); +} + +static void +dofort(char *fn) +{ + struct woord *name = findword(fn); + struct woord *wo; + FILE *f; + char line[256]; + unsigned forty[MFL]; + unsigned posn, lino, cnt, xxx; + char *c, *d, e; + + printf("%s...", fn); + fflush(stdout); + f = fopen(fn, "r"); + if (!f) + die("open failed!\n"); + xxx = lino = posn = cnt = 0; + for(;;) + { + lino++; + fgets(line, 256, f); + if (feof(f)) + break; + c = strchr(line, '\n'); + if (c) + *c = 0; + if (line[0] == '%' && !line[1]) + { + if (cnt) + { + addfort(name->w, posn, forty, cnt); + xxx++; + } + cnt = 0; + } + else + { + if (!cnt) + posn = lino; + c = line; + for(;;) + { + while (*c && (*c < 'A' || *c > 'Z') && (*c < 'a' || *c > 'z') && (*c < '0' || *c > '9')) + c++; + if (!*c) + break; + d = c; + while ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || (*c >= '0' && *c <= '9')) + { + *c = toupper(*c); + c++; + } + e = *c; + *c = 0; + wo = findword(d); + *c = e; + if (cnt >= MFL) + die("Too long!\n"); + forty[cnt++] = wo->id; + } + } + } + fclose(f); + printf("%d lines, %d fortunes\n", lino, xxx); +} + +int +main(int argc, char **argv) +{ + if (argc < 2) + die("Nothing to do.\n"); + while (argc > 1) + { + dofort(argv[1]); + argc--; + argv++; + } + return 0; +} diff --git a/guesstrans.c b/guesstrans.c new file mode 100644 index 0000000..9af2284 --- /dev/null +++ b/guesstrans.c @@ -0,0 +1,116 @@ +/* +Text Conversion With Guessing +(c) 1997 Martin Mares +*/ + +#include +#include +#include + +typedef unsigned char uchar; + +uchar dest[256],flag[256],line[4096],ans[256]; +int changed; + +FILE *ii,*oo; +#define UNPRINTABLE(c) (c<32 && c != 10 && c != 9 || c >= 0x80 && c < 0xa0) + +void putxc(uchar c,int flg) +{ + if (!flg && flag[c] || flg && UNPRINTABLE(c)) printf("[%d]",c); + else putchar(flg ? c : dest[c]); +} + +void halfcontext(uchar *c,uchar *stop,int flg) +{ + while (*c && c != stop) + putxc(*c++,flg); +} + +void context(uchar *c) +{ + halfcontext(line,c,1); + printf("<%d>",*c); + halfcontext(c+1,NULL,0); +} + +void main(int ac,char **av) +{ + if (ac != 3 && ac != 4) + { + printf("Syntax: guesstrans []\n"); + exit(0); + } + { + int c; + for (c=0;c<256;c++) dest[c]=c; + for (c=0;c<32;c++) flag[c]=1; + for (c=128;c<256;c++) flag[c]=1; + flag[13]=0; flag[10]=0; flag[9]=0; + } + if (ac == 4) + { + FILE *f; + if (f=fopen(av[3],"r")) + { + if (fread(dest,1,256,f) != 256) + { + failed: + fprintf(stderr,"Error reading translation table!\n"); + exit(1); + } + if (fread(flag,1,256,f) != 256) goto failed; + fclose(f); + } + } + if (!(ii=fopen(av[1],"r"))) + { + fprintf(stderr,"Unable to read %s\n",av[1]); + exit(1); + } + if (!(oo=fopen(av[2],"w"))) + { + fprintf(stderr,"Unable to write %s\n",av[2]); + exit(1); + } + while (fgets(line,4096,ii)) + { + uchar *c; + if (c = strchr(line, '\r')) + *c = 0; + if (!strchr(line, '\n')) + strcat(line, "\n"); + for(c=line;*c;c++) + { + if (flag[*c]) + { + context(c); + gets(ans); + if (*ans && *ans != '\n') + { + flag[*c]=0; + if (*ans == '\\') dest[*c]=atol(ans+1); + else dest[*c]=*ans; + changed=1; + } + } + *c=dest[*c]; + } + fputs(line,oo); + } + if (changed && ac == 4) + { + FILE *f; + if (f=fopen(av[3],"w")) + { + if (fwrite(dest,1,256,f) != 256) goto wrfail; + if (fwrite(flag,1,256,f) != 256) goto wrfail; + } + else + { + wrfail: + fprintf(stderr,"Error writing conversion table!\n"); + exit(1); + } + } +} diff --git a/heapsort.p b/heapsort.p new file mode 100644 index 0000000..edf9c2e --- /dev/null +++ b/heapsort.p @@ -0,0 +1,39 @@ +const max=100; + +var A:array [1..max] of integer; + i,N:integer; + +procedure bubbledown(n,i:integer); +var j,x:integer; +begin + while 2*i <= n do begin + j := 2*i; + if (j A[j]) then inc(j); + if A[i] >= A[j] then break; + x := A[i]; + A[i] := A[j]; + A[j] := x; + i := j; + end; +end; + +procedure heapsort; +var i,x:integer; +begin + for i:=N div 2 downto 1 do + bubbledown(N,i); + for i:=N downto 2 do begin + x := A[1]; + A[1] := A[i]; + A[i] := x; + bubbledown(i-1,1); + end; +end; + +begin + read(N); + for i:=1 to N do read(A[i]); + heapsort; + for i:=1 to N do write(A[i], ' '); + writeln; +end. diff --git a/hidtest b/hidtest new file mode 100755 index 0000000..3f21a82 Binary files /dev/null and b/hidtest differ diff --git a/hidtest.c b/hidtest.c new file mode 100644 index 0000000..0e51a0b --- /dev/null +++ b/hidtest.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include "/home/mj/linux/linux-2.6.20-rc3/include/linux/hiddev.h" + +void die(char *x) +{ + fprintf(stderr, "hidtest: %s: %m\n", x); + exit(1); +} + +int main(void) +{ + int i, j; + int fd = open("/dev/usb/hid/hiddev0", O_RDWR); + if (fd < 0) die("open"); + + int ver; + if (ioctl(fd, HIDIOCGVERSION, &ver) < 0) + die("getversion"); + printf("hiddev version %x\n", ver); + + struct hiddev_devinfo di; + if (ioctl(fd, HIDIOCGDEVINFO, &di) < 0) + die("gdevinfo"); + printf("%d:%d:%d vendor %04x, product %04x, version %04x, num_appl %d\n", + di.busnum, di.devnum, di.ifnum, di.vendor, di.product, di.version, di.num_applications); + +#if 0 + for (i=0; i<100; i++) { + struct hiddev_string_descriptor ss; + ss.index = 0; + if (ioctl(fd, HIDIOCGSTRING, &ss) < 0) + printf("S%d: ???\n", i); + else + printf("S%d: %s\n", i, ss.value); + } +#endif + + for (i=0; i= 0) { + printf("rinfo: type=%d, id=%d, fields=%d\n", rinfo.report_type, rinfo.report_id, rinfo.num_fields); + for (i = 0; i < rinfo.num_fields; i++) { + finfo.report_type = rinfo.report_type; + finfo.report_id = rinfo.report_id; + finfo.field_index = i; + ioctl(fd, HIDIOCGFIELDINFO, &finfo); + printf("\tField %d:\n", i); + printf("\t\tflags: %04x, phys: %d, log: %d, appl: %x, log=<%d,%d>, phys=<%d,%d>, unit=%d E%d\n", + finfo.flags, finfo.physical, finfo.logical, finfo.application, + finfo.logical_minimum, finfo.logical_maximum, + finfo.physical_minimum, finfo.physical_maximum, + finfo.unit, finfo.unit_exponent); + for (j = 0; j < finfo.maxusage; j++) { + uref.report_type = finfo.report_type; + uref.report_id = finfo.report_id; + uref.field_index = i; + uref.usage_index = j; + ioctl(fd, HIDIOCGUCODE, &uref); + ioctl(fd, HIDIOCGUSAGE, &uref); + printf("\t\tUsage %d: code=%x, value=%d\n", j, uref.usage_code, uref.value); + } + } + rinfo.report_id |= HID_REPORT_ID_NEXT; /* FIXME: bug in hiddev.h, beware */ + ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); + } + + int f = HIDDEV_FLAG_UREF; + if (ioctl(fd, HIDIOCSFLAG, &f) < 0) die("sflag"); + struct hiddev_usage_ref ev; + while (read(fd, &ev, sizeof(ev))) { + printf("EV: %x = %d\n", ev.usage_code, ev.value); + } + + return 0; +} diff --git a/hobble.c b/hobble.c new file mode 100644 index 0000000..c233ba5 --- /dev/null +++ b/hobble.c @@ -0,0 +1,248 @@ +/* + * The Hobbling Horse Problem + * + * (c) 1996 Martin Mares, + */ + +#include +#include +#include +#include + +#define MAX 35 + +signed char dist[MAX][MAX][2]; + +signed char queue[15*MAX*MAX]; + +int M, N, x0, y0, x1, y1; + +struct delta { int dx, dy; }; + +struct delta king[] = { {-1,-1}, {0,-1}, {1,-1}, {-1,0}, {1,0}, {-1,1}, {0,1}, {1,1} }; +struct delta horse[] = { {-1,-2}, {-1,2}, {-2,-1}, {2,-1}, {-2,1}, {2,1}, {1,-2}, {1,2} }; + +void +fill(void) +{ + int qr, qw, x, y, z, k, xx, yy, rho; + struct delta *d; + + memset(dist, 99, sizeof(dist)); + queue[0] = x0; + queue[1] = y0; + queue[2] = 0; + dist[x0][y0][0] = 0; + qr = 0; + qw = 3; + while (qr < qw) + { + x = queue[qr++]; + y = queue[qr++]; + z = queue[qr++]; + if (z) + { + d = king; + k = sizeof(king) / sizeof(struct delta); + } + else + { + d = horse; + k = sizeof(horse) / sizeof(struct delta); + } + rho = dist[x][y][z] + 1; + z = !z; + while (k--) + { + xx = x + d->dx; + yy = y + d->dy; + if (xx >= 0 && xx < M && yy >= 0 && yy < N && dist[xx][yy][z] > rho) + { + dist[xx][yy][z] = rho; + queue[qw++] = xx; + queue[qw++] = yy; + queue[qw++] = z; + } + d++; + } + } +} + +void +bug1(void) +{ + int qr, qw, x, y, z, k, xx, yy, rho; + struct delta *d; + + memset(dist, 99, sizeof(dist)); + queue[0] = x0; + queue[1] = y0; + dist[x0][y0][0] = 0; + qr = 0; + qw = 2; + while (qr < qw) + { + x = queue[qr++]; + y = queue[qr++]; + rho = dist[x][y][0] + 1; + z = rho & 1; + if (!z) + { + d = king; + k = sizeof(king) / sizeof(struct delta); + } + else + { + d = horse; + k = sizeof(horse) / sizeof(struct delta); + } + while (k--) + { + xx = x + d->dx; + yy = y + d->dy; + if (xx >= 0 && xx < M && yy >= 0 && yy < N && dist[xx][yy][0] > rho) + { + dist[xx][yy][0] = rho; + queue[qw++] = xx; + queue[qw++] = yy; + } + d++; + } + } +} + +void +draw(void) +{ + int i,j,k,l; + + for(i=0; i l) + k = l; + printf("%3d", k); + } + putchar('\n'); + } +} + +int +dlt(int a, int b) +{ + if (a < b) + return b-a; + else + return a-b; +} + +void +checkpath(int lim) +{ + int x,y,d; + + x = x0; + y = y0; + d = 0; + for(;;) + { +// printf("%d %d\n", x, y); + if (dist[x][y][0] > d++) + { + printf("BUG: %dx%d: %d.%d->%d.%d\n", M, N, x0, y0, x1, y1); + exit(1); + } + if (dlt(x, x1) <= lim && dlt(y, y1) <= lim) + break; + if (dlt(x, x1) > dlt(y, y1)) + { + if (x < x1) + x += 2; + else if (x > x1) + x -= 2; + else if (x >= M/2) + x -= 2; + else + x += 2; + if (y < y1) + y++; + else if (y > y1) + y--; + else if (y >= N/2) + y--; + else + y++; + } + else + { + if (y < y1) + y += 2; + else if (y > y1) + y -= 2; + else if (y >= N/2) + y -= 2; + else + y += 2; + if (x < x1) + x++; + else if (x > x1) + x--; + else if (x >= M/2) + x--; + else + x++; + } +// printf("%d %d\n", x, y); + if (dist[x][y][1] > d++) + { + printf("BUG: %dx%d: %d.%d->%d.%d\n", M, N, x0, y0, x1, y1); + exit(1); + } + if (dlt(x, x1) <= lim && dlt(y, y1) <= lim) + break; + if (x < x1) + x++; + else if (x > x1) + x--; + if (y < y1) + y++; + else if (y > y1) + y--; + } +} + +int +main(void) +{ + int i; + + srand(time(NULL)); + +#if 1 + for(i=0; i<100000; i++) + { + M = 2 + rand() % 5; + N = 3 + rand() % 5; + x0 = rand() % M; + y0 = rand() % N; + x1 = rand() % M; + y1 = rand() % N; + printf("\n %dx%d: %d.%d->%d.%d\n", M, N, x0, y0, x1, y1); + fill(); + draw(); + checkpath(2); + } +#else + M = 30; + N = 30; + x0 = 13; + y0 = 14; + fill(); + draw(); +#endif + + return 0; +} diff --git a/hull b/hull new file mode 100755 index 0000000..79467f9 Binary files /dev/null and b/hull differ diff --git a/hull.c b/hull.c new file mode 100644 index 0000000..f9679a0 --- /dev/null +++ b/hull.c @@ -0,0 +1,62 @@ +#include +#include + +#define MAX 20000 + +struct pt { int x, y; char c; }; + +struct pt pt[MAX]; +int N; +typedef long long int ll; +struct pt up[MAX], down[MAX]; +int Nu, Nd; + +int cmp(const void *X, const void *Y) +{ + const struct pt *x = X, *y = Y; + if (x->x < y->x) + return -1; + if (x->x > y->x) + return 1; + return 0; +} + +ll sign(ll ax, ll ay, ll bx, ll by) +{ + return ax*by - ay*bx; +} + +int main(void) +{ + N=0; + while (scanf("%d %d '%c'", &pt[N].x, &pt[N].y, &pt[N].c) == 3) { + //pt[N].y -= 4000000; pt[N].x -= 4000000; + N++; + } + qsort(pt, N, sizeof(pt[0]), cmp); + //for (int i=0; i 1 && sign(up[Nu-2].x - up[Nu-1].x, up[Nu-2].y - up[Nu-1].y, + pt[i].x - up[Nu-1].x, pt[i].y - up[Nu-1].y) < 0) + Nu--; + up[Nu++] = pt[i]; + while (Nd > 1 && sign(down[Nd-2].x - down[Nd-1].x, down[Nd-2].y - down[Nd-1].y, + pt[i].x - down[Nd-1].x, pt[i].y - down[Nd-1].y) > 0) + Nd--; + down[Nd++] = pt[i]; + } + + printf("### Upper hull:\n"); + for (int i=0; i +#include +#include +#include +#include +#include + +#define session 0 + +struct pl { + struct pl *next; + int id; + char *name; + int tstart, tstop, fstart, fstop; +}; + +static struct pl * +load_pl(char *name) +{ + struct pl *pl = NULL, *p, **l = &pl; + int cnt = 0; + char buf[1024], b2[1024]; + FILE *f = fopen(name, "r"); + if (!f) { + fprintf(stderr, "Unable to open %s: %m\n", name); + exit(1); + } + while (fgets(buf, sizeof(buf), f)) { + p = malloc(sizeof(struct pl)); + p->id = cnt++; + if (sscanf(buf, "%d%d %[^\n]", &p->tstart, &p->tstop, b2) != 3) { + fprintf(stderr, "Syntax error in %s, line %d\n", name, cnt); + exit(1); + } + p->name = g_strdup(b2); + p->fstart = p->tstart + 1000; + p->fstop = p->tstop - 1000; + printf("%02d: <%s> %d %d %d %d\n", p->id, p->name, p->tstart, p->fstart, p->fstop, p->tstop); + *l = p; + l = &p->next; + } + *l = NULL; + fclose(f); + if (!pl) { + fprintf(stderr, "The track list is empty!\n"); + exit(1); + } + return pl; +} + +static void +feed_pl(struct pl *pl) +{ + GList *l; + xmms_remote_stop(session); + xmms_remote_set_main_volume(session, 0); + xmms_remote_playlist_clear(session); + l = NULL; + while (pl) { + l = g_list_append(l, pl->name); + pl = pl->next; + } + xmms_remote_playlist_add(session, l); + g_list_free(l); +} + +void fade_in(int l) +{ + int t0 = xmms_remote_get_output_time(session); + for(;;) { + int t = xmms_remote_get_output_time(session) - t0; + printf("%d %d\n",t,t0 ); + if (t >= l || t < 0) { + xmms_remote_set_main_volume(session, 100); + return; + } + xmms_remote_set_main_volume(session, t*100/l); +// usleep(10000); + } +} + +static void +vol(int n) +{ + static int lv = -1; + if (lv != n) { + lv = n; + xmms_remote_set_main_volume(session, n); + } +} + +int main(int argc, char **argv) +{ + struct pl *pl, *this = NULL; + int state = -1, st, t; + + if (argc != 2) { + fprintf(stderr, "Usage: jukebox \n"); + return 1; + } + pl = load_pl(argv[1]); + + if (!xmms_remote_is_running(session)) { + fprintf(stderr, "No XMMS session found.\n"); + return 1; + } + feed_pl(pl); + for(;;) { + if (!xmms_remote_is_running(session)) { + fprintf(stderr, "XMMS exited.\n"); + return 0; + } + if (!xmms_remote_is_playing(session)) { + if (state >= 0) { + state = -1; + puts("### Stop"); + vol(0); + } + } else { + st = xmms_remote_get_playlist_pos(session); + if (state != st) { + state = st; + printf("### Start %d\n", state); + for (this=pl; this && this->id != state; this = this->next) + ; + if (!this) { + fprintf(stderr, "Internal error: unknown song ID\n"); + return 1; + } + vol(0); + xmms_remote_jump_to_time(session, this->tstart); + } + t = xmms_remote_get_output_time(session); + //printf(" %d %d\n", st, t); + if (t < this->tstart) + ; + else if (t < this->fstart) + vol(100 * ((t - this->tstart) / (float)(this->fstart - this->tstart))); + else if (t < this->fstop) + vol(100); + else if (t < this->tstop) + vol(100 * (1-((t - this->fstop) / (float)(this->tstop - this->fstop)))); + else { + vol(0); + if (this->next) + xmms_remote_playlist_next(session); + else + xmms_remote_stop(session); + } + } + usleep(10); + } + return 0; +} diff --git a/jukebox.mk b/jukebox.mk new file mode 100644 index 0000000..d24773b --- /dev/null +++ b/jukebox.mk @@ -0,0 +1,10 @@ + +GLIB_CFLAGS:=$(shell glib-config --cflags) +GLIB_LDFLAGS:=$(shell glib-config --libs) + +CFLAGS=-O2 -Wall -W $(GLIB_CFLAGS) +LDFLAGS=$(GLIB_LDFLAGS) -lxmms + +all: jukebox + +jukebox: jukebox.c diff --git a/logik1.c b/logik1.c new file mode 100644 index 0000000..09c5d40 --- /dev/null +++ b/logik1.c @@ -0,0 +1,138 @@ +#include +#include +#include + +#define BITS 10 +#define NUM (1 << BITS) + +static char state[NUM]; +static int question; + +static void +calc_answer(int secret, int guess, int *black, int *white) +{ + int b = 0, w = 0, i; + int s0=0, s1=0, g0=0, g1=0; + + for(i=0; i j) + j = answer[x][y]; + if (j <= besti) + { + besti = j; + best = i; + } + } + question = best; + printf("Selected %04x, %d of %d\n", best, besti, total); +} + +static void +recalc(int b, int w) +{ + int bl, wh, i, red = 0; + + for(i=0; i maxr) + maxr = round; + puts("------------------------------------------"); + } + printf("MAX=%d rounds\n", maxr); + + return 0; +} diff --git a/logik2.c b/logik2.c new file mode 100644 index 0000000..48d300d --- /dev/null +++ b/logik2.c @@ -0,0 +1,277 @@ +#include +#include +#include + +#define ORDER 5 +#define COLORS 8 +#define SHOTS 4 + +int states; +char *flags; +int secret; + +int +pack(int *z) +{ + int k = 0; + int i; + + for(i=0; i= 0; i--) + { + z[i] = k % COLORS; + k /= COLORS; + } +} + +void +eval(int *sec, int *guess, int *black, int *white) +{ + int b, w, i, sc[COLORS], gc[COLORS]; + + b = 0; + bzero(sc, sizeof(sc)); + bzero(gc, sizeof(gc)); + for(i=0; i= ramax); + i %= sz; + return i; +} + +#if 1 + +int sec[ORDER]; + +#if 0 + +void +pl_init(void) +{ + int i; + + printf("Secret: "); + for(i=0; i G) + G = cc[b][w]; + return G; +} + +int +find_best(void) +{ + int shot[SHOTS], badness[SHOTS], i, z[ORDER], sz, whe, besti, best, worsti; + + sz = 0; whe = 0; + for(i=0; i worsti) + worsti = badness[i]; + } +// printf("Best: %d (%d)\n", best, besti); + printf("(%7d-%7d/%7d) ", worsti, besti, sz); + return shot[best]; +} + +int +main(void) +{ + int i,gue[ORDER],round,b,w,wc=0,N=0,sum=0; + + states = 1; + for(i=0; i %d/%d -> %d states\n", b, w, reduce(gue,b,w)); + if (b == ORDER) + break; + } + if (round > wc) + wc = round; + sum += round; + printf("--- DONE --- (try=%d, worst case=%d, avg=%d) ---\n", N, wc, (sum+N-1)/N); + } + + return 0; +} + diff --git a/math.c b/math.c new file mode 100644 index 0000000..f563e41 --- /dev/null +++ b/math.c @@ -0,0 +1,400 @@ +/* +Simple Numeric Operations +(c) 1995 Martin Mares, MJSoft System Software +*/ + +#include +#include + +#define MAXSTEPS 9 +#define MAXNUM 5001 + +#define FIRSTUNARY 10 +#define NUMOPS 15 + +int able[MAXSTEPS+1][MAXNUM]; +int func[MAXSTEPS+1][MAXNUM]; +int op1[MAXSTEPS+1][MAXNUM]; +int op2[MAXSTEPS+1][MAXNUM]; +int op1l[MAXSTEPS+1][MAXNUM]; +int op2l[MAXSTEPS+1][MAXNUM]; +int max[MAXSTEPS+1]; +int penalty[MAXSTEPS+1][MAXNUM]; + +int maxdisp,digit,maxsteps,maxnum; + +/* 0 1 2 3 4 5 6 7 8 9 10 1112 13 */ +#if 0 +int pen[] = { 1,1,2,2,6,3,60,30,60,6,4,20,3,150,150 }; +#else +int pen[] = { 1,1,2,2,5,3,8 ,6 ,8 ,5,4,6 ,3,13 ,13 }; +#endif +/* + - * / % ^ @ C $ \ ! S R r t */ +int pri[] = { 2,2,3,3,4,5,3, 7, 3, 3,9,7, 7,7, 7 }; + +/* PRI == 7 <=> left-associative function with no priority */ + +int op(int code,int a,int b,int src1,int src2) +{ +int i,j,k,l; + switch(code) + { + case 0: return a+b; + case 1: return a-b; + case 2: return a*b; + case 3: if (b && !(a%b)) return a/b; else return -1; /* DIV */ + case 4: if (b) return a%b; else return -1; /* MODULO */ + case 5: i=1; /* POWER */ + while (b--) + { + i *= a; + if (i >= maxnum) return -1; + } + return i; + case 6: if (!b || a%b || able[src2][b] != 2) return -1; /* A/.(B) */ + i=0; + a/=b; + while (b) + { + i=i*10+9; + b/=10; + } + return a*i; + case 7: if (a < b) return -1; /* COMBINATION */ + i=1; j=a; k=2; l=b; + while (l || k<=b) + { + while (k<=b && !(i%k)) + { + i/=k; + k++; + } + if (l) + { + i*=j; + l--; + j--; + } + if (i>100000) return -1; + } + return i; + case 8: if (!b || a%b || able[src2][b] != 2) return -1; /* A/.B */ + i=1; + a/=b; + while (b) + { + i=i*10; + b/=10; + } + return a*i; + case 9: if (b) return a/b; else return -1; /* DIV */ + case FIRSTUNARY: i=1; /* FACT */ + while (a) + { + i*=a; + if (i >= maxnum) return -1; + a--; + } + return i; + case FIRSTUNARY+1: if (a) return 1; else return 0; /* SIGNUM */ + case FIRSTUNARY+2: for(i=0;i a) return -1; + } + return -1; + case FIRSTUNARY+3: for(i=0;i= a) return i; + } + return -1; + case FIRSTUNARY+4: for(i=0;i a) return i-1; + } + return -1; + } + return -1; +} + +int doop(int dest,int k,int i,int j,int src1,int src2,int p) +{ +int l = op(k,i,j,src1,src2); + if (l>=0 && l p+pen[k]) + { + able[dest][l] = 1; + func[dest][l] = k; + op1[dest][l] = i; + op1l[dest][l] = src1; + op2[dest][l] = j; + op2l[dest][l] = src2; + penalty[dest][l] = p+pen[k]; + if (l > max[dest]) max[dest] = l; + return 1; + } + return 0; +} + +void try(int dest,int src1,int src2) +{ +int i,j,k,l; + fprintf(stderr,"Trying %d %d -> %d\n",src1+1,src2+1,dest+1); + l=0; + for(i=0;i<=max[src1];i++) + if (able[src1][i]) + { + if (i-l>=10 || i<15) { fprintf(stderr,"%d\r",i); l=i; } + for(j=0;j<=max[src2];j++) + if (able[src2][j]) + for(k=0;ka[0].p; + } + else p=malloc(sizeof(struct node)); + return p; +} + +void free_node(struct node *p) +{ + p->a[0].p = firstfree; + firstfree=p; +} + +void free_tree(struct node *p) +{ + if (p->op != OP_CONST) + { + free_tree(p->a[0].p); + if (p->op < FIRSTUNARY) free_tree(p->a[1].p); + } + free_node(p); +} + +struct node *build_tree(int level,int i) +{ +struct node *p = obtain_node(); + if (able[level][i] == 2) + { + p->op = OP_CONST; + p->a[0].value = i; + } + else + { + p->op = func[level][i]; + p->a[0].p = build_tree(op1l[level][i],op1[level][i]); + if (p->op < FIRSTUNARY) + p->a[1].p = build_tree(op2l[level][i],op2[level][i]); + } + return p; +} + +void print_tree(struct node *n,int p,int orop) +{ +int g,r; + if (n->op == OP_CONST) printf("%d",n->a[0].value); + else + { + g = (pri[n->op] < p + || (pri[n->op] == p && + (orop == 1 || orop == 3 || orop == 4 || orop == 6 + || orop == 8)) + ); + if (g) putchar('('); + r=pri[n->op]; + if (r==7) r=0; + if (n->op <= 5) /* standard binary */ + { + print_tree(n->a[0].p,r,n->op); + putchar("+-*/%^"[n->op]); + print_tree(n->a[1].p,r,n->op); + } + else if (n->op == 6) /* /.() */ + { + print_tree(n->a[0].p,r,n->op); + printf("/.("); + print_tree(n->a[1].p,r,n->op); + putchar(')'); + } + else if (n->op == 7) /* COMB */ + { + printf("C("); + print_tree(n->a[0].p,r,n->op); + putchar(','); + print_tree(n->a[1].p,r,n->op); + putchar(')'); + } + else if (n->op == 8) /* /. */ + { + print_tree(n->a[0].p,r,n->op); + printf("/."); + print_tree(n->a[1].p,r,n->op); + } + else if (n->op == 9) /* DIV */ + { + print_tree(n->a[0].p,r,n->op); + putchar('\\'); + print_tree(n->a[1].p,r,n->op); + } + else if (n->op == FIRSTUNARY) /* FACT */ + { + print_tree(n->a[0].p,r,n->op); + putchar('!'); + } + else /* classical prefix unary */ + { + printf(unam[n->op-FIRSTUNARY-1]); + print_tree(n->a[0].p,255,255); + } + if (g) putchar(')'); + } +} + +void dump(int level,int i) +{ +struct node *root; + root = build_tree(level,i); + print_tree(root,0,-1); + free_tree(root); +} + +#endif + +void fillin(void) +{ +int i,j; + i=0; + for(j=0;j<=maxsteps;j++) + { + i=i*10+digit; + if (i>=maxnum) return; + able[j][i]=2; + max[j]=i; + } +} + +void findall(void) +{ +int steps,i; + tryuna(0); + for(steps=1;steps<=maxsteps;steps++) + { + for(i=0;i \n"); + return 0; + } + digit = atol(argv[1]); + if (digit<0 || digit>9) err("Invalid digit!"); + maxsteps = atol(argv[2])-1; + if (maxsteps<0 || maxsteps>MAXSTEPS) err("Invalid digit count!"); + maxdisp = atol(argv[3])+1; + maxnum = atol(argv[4])+1; + if (maxnum<1 || maxnum>MAXNUM) err("Invalid internal maximum!"); + if (maxdisp<1 || maxdisp>maxnum) err("Invalid limit!"); + fillin(); + findall(); + prtall(); + return 0; +} diff --git a/merge.c b/merge.c new file mode 100644 index 0000000..6df6ff1 --- /dev/null +++ b/merge.c @@ -0,0 +1,138 @@ +/* In-place merging of integer sequences */ + +#define MIN(x,y) ((x)<(y) ? (x) : (y)) +#define SWAP(x,y) do { int _=(x); (x)=(y); (y)=_; } while(0) +#define BLEN(x) ((x) == p1pos ? p1len : (x) == p2pos ? p2len : B) + +static void reverse(int *A, int n) // reverse a sequence +{ + int x = 0; + n--; + while (x < n) { + SWAP(A[x], A[n]); + x++, n--; + } +} + +static void rotate(int *A, int p, int q) // rotate a sequence +{ + reverse(A, p); + reverse(A+p, q); + reverse(A, p+q); +} + +static void merge(int *A, int M, int N) +{ + int T = M+N; // total length of the buffer + int B = 1; // block size = ceil(sqrt(N)) + while (B*B < T) + B++; + + int Z = MIN(B+T%B,T); // aux buffer size + int Mz=0, Nz=0; // find Z largest items + while (Mz+Nz < Z) { + if (Mz == M || A[M-Mz-1] > A[T-Nz-1]) + Mz++; + else + Nz++; + } + M -= Mz; // fix up lengths + N -= Nz; + rotate(A, M, Mz); // and move the items to the beginning + rotate(A, T-Nz, Nz); + + // select-sort all blocks & track the mixed block + int mixed_block = M%B ? Z+M-M%B : -1; + for (int i=Z; i= 0) { + p1len = M%B; + p2len = B-p1len; + p1pos = Z; + while (p1pos= T) + break; + int s2 = es1; + int es2 = s2 + BLEN(s2); + while (s1 < es1) { + if (A[s1] <= A[s2]) { + SWAP(A[dest], A[s1]); + s1++; + } else { + SWAP(A[dest], A[s2]); + s2++; + } + dest++; + } + s1 = s2; + es1 = es2; + } + rotate(A+dest, Z, T-s1); + + // sort the rest + for (int i=T-Z; i +#include +#include + +int main(void) +{ +#if 0 + int A[] = { 2, 4, 8, 9, 10, 11, 13, 14, 16, 1, 5, 6, 11, 12, 15, 17, 18 }; + int i; + merge(A, 9, 8); + for (i=0; i + */ + +#include +#include +#include +#include +#include +#include + +struct sysrq_pkt { + __u8 password[16]; + __u8 command; +}; + +int main(int argc, char **argv) +{ + char *p; + struct sysrq_pkt sp; + struct hostent *h; + int s; + struct sockaddr_in sa; + + bzero(&sp, sizeof(sp)); + + if (argc != 3 && argc != 4) { + fprintf(stderr, "Usage: netrq []\n"); + return 1; + } + + if (! (h = gethostbyname(argv[1]))) { + fprintf(stderr, "Unable to resolve machine name: %m\n"); + return 1; + } + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + fprintf(stderr, "socket: %m\n"); + return 1; + } + sa.sin_family = AF_INET; + memcpy(&sa.sin_addr.s_addr, h->h_addr, sizeof(struct in_addr)); + sa.sin_port = htons(555); + if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) { + fprintf(stderr, "connect: %m\n"); + return 1; + } + + if (argc > 3) + p = argv[3]; + else + p = getpass("Enter password: "); + if (strlen(p) > 15) { + fprintf(stderr, "Password is too long!\n"); + return 1; + } + strcpy(sp.password, p); + sp.command = argv[2][0]; + + if (write(s, &sp, sizeof(sp)) != sizeof(sp)) { + fprintf(stderr, "write: %m\n"); + return 1; + } + + return 0; +} diff --git a/oggtest.c b/oggtest.c new file mode 100644 index 0000000..98e3b23 --- /dev/null +++ b/oggtest.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +int main(void) +{ + ogg_sync_state osy; + + ogg_sync_init(&osy); + for (;;) + { + char *buf = ogg_sync_buffer(&osy, 4096); + int len = read(0, buf, 4096); + if (len < 0) + { + fprintf(stderr, "read error: %m\n"); + return 1; + } + if (!len) + break; + ogg_sync_wrote(&osy, len); + + int ok; + ogg_page opg; + while (ok = ogg_sync_pageout(&osy, &opg)) + { + if (ok < 0) + fprintf(stderr, "Skipping...\n"); + else + { + fprintf(stderr, "Page (v=%d, stream=%x, bos=%d, eos=%d, pos=%Ld, pgno=%d)\n", + ogg_page_version(&opg), + ogg_page_serialno(&opg), + ogg_page_bos(&opg), + ogg_page_eos(&opg), + (unsigned long long) ogg_page_granulepos(&opg), + (unsigned int) ogg_page_pageno(&opg)); + } + } + } + fprintf(stderr, "Done.\n"); + + return 0; +} diff --git a/parens.c b/parens.c new file mode 100644 index 0000000..022e27e --- /dev/null +++ b/parens.c @@ -0,0 +1,65 @@ +#include + +int isprime(int i) +{ + int j=2; + while (j*j <= i) { + if (!(i%j)) return 0; + j++; + } + return 1; +} + +int nextprime(int i) +{ + while (!isprime(++i)) + ; + return i; +} + +void enc(int i) +{ + if (!i) putchar('.'); + else { + putchar('('); + int j=1; + while (i > 1) { + j = nextprime(j); + int k=0; + while (!(i%j)) + i/=j, k++; + enc(k); + } + putchar(')'); + } +} + +int dec(void) +{ + int j=1, k=1; + int c=getchar(); + if (c == '.') return 0; + if (c != '(') exit(1); + while ((c = getchar()) != ')') { + ungetc(c, stdin); + j = nextprime(j); + int l = dec(); + while (l--) + k *= j; + } + return k; +} + +int main(int argc, char **argv) +{ + if (argc > 1 && !strcmp(argv[1], "-e")) { + int i; + scanf("%d", &i); + enc(i); + putchar('\n'); + } else { + int i = dec(); + printf("%d\n", i); + } + return 0; +} diff --git a/parrot.c b/parrot.c new file mode 100644 index 0000000..f105c1c --- /dev/null +++ b/parrot.c @@ -0,0 +1,270 @@ +/* + * Parrot Picking Fortune Cookies aka Simple Text Associator + * + * (c) 2001 Martin Mares + */ + +#include +#include +#include +#include + +#define TEXTLEN 1024 +#define WORDLEN 64 +#define HASHSIZE 32768 +#define MAXFUZZ 3 +#define SKIP_PTS -10 +#define MATCH_PTS_LOW 20 +#define MATCH_PTS_HIGH 1000 + +struct wd { + struct wd *next; + int cnt; + int ref; + char w[1]; +}; +static struct wd *hash[HASHSIZE]; +static int wcnt; + +static int n; +static struct wd *input[TEXTLEN]; +static int next[TEXTLEN]; + +static struct wd * +findword(char *x) +{ + struct wd *w; + unsigned h=0; + char *y; + + for (y=x; *y; y++) + h = h*13 + *y; + h %= HASHSIZE; + for (w=hash[h]; w; w=w->next) + if (!strcmp(w->w, x)) + return w; + w = malloc(sizeof(struct wd) + strlen(x)); + w->next = hash[h]; + hash[h] = w; + w->cnt = 0; + w->ref = -1; + strcpy(w->w, x); + wcnt++; + return w; +} + +static int +getword(FILE *f, char *buf) +{ + int c, l; + + do + { + c = fgetc(f); + if (c == '\n' && + (c = fgetc(f)) == '%' && + (c = fgetc(f)) == '\n') + { + *buf = 0; + return -1; + } + } + while (c != EOF && !isalnum(c)); + if (c == EOF) + return 0; + l = WORDLEN-1; + do + { + *buf++ = tolower(c); + c = fgetc(f); + } + while (c != EOF && isalnum(c) && --l); + if (c != EOF) + ungetc(c, f); + *buf = 0; + return 1; +} + +static void +voc_build(FILE *f) +{ + char buf[WORDLEN]; + + while (getword(f, buf)) + if (buf[0]) + { + struct wd *w = findword(buf); + w->cnt++; + } + printf("Found %d words.\n", wcnt); +} + +static void +scan_in(FILE *f) +{ + char buf[WORDLEN]; + + while (getword(f, buf)) + if (buf[0]) + { + struct wd *w = findword(buf); + input[n] = w; + if (w->ref < 0) + w->ref = n; + else + { + int i = w->ref; + while (next[i] >= 0) + i = next[i]; + next[i] = n; + } + next[n] = -1; + n++; + if (n >= TEXTLEN) + { + fprintf(stderr, "Input too long!\n"); + exit(1); + } + } + printf("Scanned input of %d words.\n", n); +} + +static void +associate(FILE *f) +{ + off_t start = 0, best_start = 0; + char buf[WORDLEN]; + int cost[TEXTLEN]; + int pos[TEXTLEN]; + int pts, xpos, p, pp, i, j; + int best_pts = 0; + + newfort: + if (start) + { + pp = 0; + for (i=0; i pp) + pp = cost[i]; + // printf("%d pts\n", pp); + if (pp > best_pts) + { + best_pts = pp; + best_start = start; + } + } + start = ftell(f); + bzero(cost, n*sizeof(int)); + memset(pos, -1, n*sizeof(int)); + pts = 0; + xpos = 0; + + while (getword(f, buf)) + if (!buf[0]) + goto newfort; + else + { + struct wd *w = findword(buf); + for (i=w->ref; i >= 0; i=next[i]) + { + j = i - MAXFUZZ; + if (j < 0) + j = 0; + pp = cost[i]; + if (pp < w->cnt) + pp = w->cnt; + while (j < i) + { + if (pos[j] >= 0) + { + p = xpos - pos[j]; + if (p < i-j) + p = i-j; + p = SKIP_PTS*p + cost[j] + w->cnt; + if (p > pp) + pp = p; + } + j++; + } + if (pp > cost[i]) + { + cost[i] = pp; + pos[i] = xpos; + } + } + xpos++; + } + + printf("Best: %d points at %d\n", best_pts, best_start); + puts("---"); + fseek(f, best_start, SEEK_SET); + while (getword(f, buf) > 0) + { + struct wd *w = findword(buf); + if (w->ref >= 0) + printf("<%s> ", buf); + else + printf("%s ", buf); + } + puts("\n---"); + i = ftell(f) - best_start; + fseek(f, best_start, SEEK_SET); + while (i--) + putchar(fgetc(f)); +} + +static int +cmp(const void *a, const void *b) +{ + struct wd *x = *(struct wd **)a; + struct wd *y = *(struct wd **)b; + return (x->cnt < y->cnt) - (x->cnt > y->cnt); +} + +static void +voc_val(void) +{ + int i, j; + struct wd *w, *wa[wcnt]; + + j = 0; + for (i=0; inext) + wa[j++] = w; + qsort(wa, wcnt, sizeof(struct wd *), cmp); +#if 0 + for (i=0; icnt, w->w); + } +#endif + for (i=0; icnt = MATCH_PTS_LOW; + for (; icnt = MATCH_PTS_HIGH; +} + +int +main(int argc, char **argv) +{ + FILE *fort; + + if (argc != 2) + { + fprintf(stderr, "Usage: parrot \n"); + return 1; + } + fort = fopen(argv[1], "r"); + if (!fort) + { + fprintf(stderr, "%s: %m\n", argv[1]); + return 1; + } + + voc_build(fort); + voc_val(); + scan_in(stdin); + rewind(fort); + associate(fort); +} diff --git a/phone.c b/phone.c new file mode 100644 index 0000000..20f4cca --- /dev/null +++ b/phone.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include + +FILE *f; + +#define HASH_SIZE 16384 + +typedef unsigned char byte; + +struct word { + struct word *next; + int len; + byte w[1]; +}; + +struct word *htab[HASH_SIZE]; + +byte c2n[256]; +/* 0 1 2 3 4 5 6 7 8 9 */ +byte *n2c[10] = { "OQZ", "IJ", "ABC", "DEF", "GH", "KL", "MN", "PRS", "TUV", "WXY" }; + +void init(void) +{ + int i; + byte *c; + + for(i=0; i<10; i++) + { + for(c=n2c[i]; *c; c++) + { + c2n[*c] = '0'+i; + c2n[tolower(*c)] = '0'+i; + } + c2n['0'+i] = '0'+i; + } +} + +unsigned int hash(byte *x, int len) +{ + int h = len; + + while (*x && len--) + h = h * 13337 + c2n[*x++]; + return h & (HASH_SIZE - 1); +} + +void read_it(void) +{ + byte l[256]; + int h, s, c=0; + struct word *w; + + while (fgets(l, sizeof(l)-1, f)) + { + byte *z = strchr(l, '\n'); + if (z) + *z = 0; + s = strlen(l); + h = hash(l, s); + w = malloc(sizeof(struct word) + s); + if (!w) + { + perror("malloc"); + exit(1); + } + w->next = htab[h]; + htab[h] = w; + w->len = s; + strcpy(w->w, l); + c++; + } + printf("Scanned %d words.\n", c); +} + +struct word *find(byte *x, int l) +{ + int h = hash(x, l); + struct word *w = htab[h]; + byte *p, *q; + while (w) + { + if (w->len == l) + { + int ll = l; + p = x; + q = w->w; + while (ll && *p++ == c2n[*q++]) + ll--; + if (!ll) + return w; + } + w = w->next; + } + return NULL; +} + +#define MAXL 128 + +struct word *last[MAXL]; +int best[MAXL]; + +void print(int z) +{ + struct word *w; + + if (!z) + return; + w = last[z]; + if (!w) + { + printf("!!!BUG!!!"); + return; + } + print(z - w->len); + printf("%s ", w->w); +} + +void sentence(byte *z) +{ + int l = strlen(z); + int i, j; + struct word *w; + + if (l >= MAXL-1) + { + printf("TOO LONG.\n"); + return; + } + best[0] = 0; + for(i=1; i<=l; i++) + { + last[i] = NULL; + best[i] = -1; + for(j=0; j= 0 && (w = find(z+j, i-j)) && (best[i] < 0 || best[i] > best[j] + 1)) + { + last[i] = w; + best[i] = best[j] + 1; + } + } + if (best[l] <= 0) + printf("NO SOLUTION."); + else + print(l); + putchar('\n'); +} + +int main(int argc, char **argv) +{ + byte l[256]; + byte *k; + + if (!(f = fopen("voc", "r"))) + { + perror("Unable to open vocabulary"); + return 1; + } + init(); + read_it(); + + while (fgets(l, sizeof(l), stdin) && (k = strchr(l, '\n'))) + { + *k = 0; + sentence(l); + } + return 0; +} diff --git a/prime.c b/prime.c new file mode 100644 index 0000000..c363ad3 --- /dev/null +++ b/prime.c @@ -0,0 +1,46 @@ +/* +Generate Prime Number +*/ + +int isprime(unsigned x) +{ +unsigned z,y; + z = x%6U; + if (z!=1 && z!=5) return 0; + z = 5; + for (;;) + { + y = x / z; + if (y < z || z == x) return 1; + if (!(x % z)) return 0; + z += 2; + } +} + +void calcprim(unsigned c) +{ + while (c >= 2) + { + if (isprime(c)) + { + printf("Found prime number %u.\n",c); + exit(0); + } + c--; + } + printf("Prime number not found!\n"); + exit(1); +} + +void main(int argc,char **argv) +{ +int c; +char *k; + if (argc != 2) + { + printf("Usage: prime \n"); + exit(1); + } + c = strtoul(argv[1], &k, 0); + calcprim(c); +} diff --git a/proof.c b/proof.c new file mode 100644 index 0000000..ca3601c --- /dev/null +++ b/proof.c @@ -0,0 +1,217 @@ +#include +#include +#include + +typedef struct formula fmla; + +struct formula { + fmla *next; + int op; + int key; + fmla *arg[2]; +}; + +#define OP_X 0 +#define OP_Y 1 +#define OP_NOT 2 +#define OP_IMP 3 + +static void putf(fmla *a) +{ + switch (a->op) + { + case OP_X: + putchar('X'); + break; + case OP_Y: + putchar('Y'); + break; + case OP_NOT: + putchar('^'); + putf(a->arg[0]); + break; + default: + putchar('('); + putf(a->arg[0]); + putchar('>'); + putf(a->arg[1]); + putchar(')'); + } +} + +static void duf(fmla *f) +{ + putf(f); + putchar('\n'); +} + +static inline fmla *newf(int op, fmla *l, fmla *r) +{ + fmla *f = malloc(sizeof(fmla)); + f->op = op; + f->arg[0] = l; + f->arg[1] = r; + f->next = NULL; + switch (op) { + case OP_IMP: + f->key = 313*l->key + 17*r->key + 2; + break; + case OP_NOT: + f->key = 1733*l->key + 5; + break; + default: + f->key = op + 1; + } + return f; +} + +static inline int match(fmla *a, fmla *b) +{ + int i; + + if (a->op != b->op || a->key != b->key) + return 0; + switch (a->op) + { + case OP_IMP: + if (!match(a->arg[1], b->arg[1])) + return 0; + case OP_NOT: + if (!match(a->arg[0], b->arg[0])) + return 0; + } + return 1; +} + +#define G_DEPTH 3 + +fmla *head_depth[G_DEPTH+1]; + +void gen(void) +{ + int i, j, k; + fmla *x, *y, *z, **h; + + puts("Generator..."); + duf(head_depth[1] = newf(OP_X, NULL, NULL)); + duf(head_depth[1]->next = newf(OP_Y, NULL, NULL)); + for(i=2; i<=G_DEPTH; i++) { + printf("### depth %d\n", i); + h = head_depth + i; + x = head_depth[i-1]; + while (x) { + z = newf(OP_NOT, x, NULL); + duf(z); + z->next = *h; + *h = z; + x = x->next; + } + for(j=1; jnext = *h; + *h = z; + y = y->next; + } + x = x->next; + } + } + } +} + +fmla *flist; + +#define A_DEPTH 20 + +void axi(void) +{ + int i,j,k; + fmla *x, *y, *z, *w; + + puts("Axiom #1..."); + /* A->(B->A) */ + for(i=1; i<=G_DEPTH; i++) + for(j=1; j<=G_DEPTH; j++) + if (2*i+j+2 <= A_DEPTH) + for(x = head_depth[i]; x; x=x->next) + for(y = head_depth[j]; y; y=y->next) { + z = newf(OP_IMP, x, newf(OP_IMP, y, x)); + duf(z); + z->next = flist; + flist = z; + } + + puts("Axiom #2..."); + /* (A->(B->C)) -> ((A->B) -> (A->C)) */ + for(i=1; i<=G_DEPTH; i++) + for(j=1; j<=G_DEPTH; j++) + for(k=1; k<=G_DEPTH; k++) + if (3*i+2*j+2*k+6 <= A_DEPTH) + for(x=head_depth[i]; x; x=x->next) + for(y=head_depth[j]; y; y=y->next) + for(z=head_depth[k]; z; z=z->next) { + w = newf(OP_IMP, + newf(OP_IMP, x, newf(OP_IMP, y, z)), + newf(OP_IMP, + newf(OP_IMP, x, y), + newf(OP_IMP, x, z))); + duf(w); + w->next = flist; + flist = w; + } + + puts("Axiom #3..."); + /* (^A->^B)->(B->A) */ + for(i=1; i<=G_DEPTH; i++) + for(j=1; j<=G_DEPTH; j++) + if (2*i+2*j+5 <= A_DEPTH) + for(x = head_depth[i]; x; x=x->next) + for(y = head_depth[j]; y; y=y->next) { + z = newf(OP_IMP, + newf(OP_IMP, newf(OP_NOT, x, NULL), newf(OP_NOT, y, NULL)), + newf(OP_IMP, y, x)); + duf(z); + z->next = flist; + flist = z; + } +} + +void derive(void) +{ + fmla *x, *y, *last, *z; + int flag; + + puts("Derived:"); + for(last=flist; last->next; last=last->next) + ; + do { + puts("PASS"); + flag = 0; + /* Modus Ponens: A, A->B =] B */ + for(x=flist; x; x=x->next) + for(y=flist; y; y=y->next) { + if (x->op == OP_IMP && + match(x->arg[0], y)) { + z = x->arg[1]; + if (!z->next && z != last) { + duf(z); + last->next = z; + last = z; + flag = 1; + } + } + } + } while (flag); +} + +int main(void) +{ + gen(); + axi(); + derive(); + return 0; +} diff --git a/puzzle.c b/puzzle.c new file mode 100644 index 0000000..10b059c --- /dev/null +++ b/puzzle.c @@ -0,0 +1,166 @@ +#include + +struct { + int id; + char x[4]; +} list[] = { + { 0, {0,0,0,0} }, + { 11, {0,0,0,1} }, + { 13, {0,0,0,2} }, + { 11, {0,0,1,0} }, + { 3, {0,0,1,1} }, + { 15, {0,0,1,2} }, + { 13, {0,0,2,0} }, + { 16, {0,0,2,1} }, + { 4, {0,0,2,2} }, + { 11, {0,1,0,0} }, + { 6, {0,1,0,1} }, + { 21, {0,1,0,2} }, + { 3, {0,1,1,0} }, + { 9, {0,1,1,1} }, + { 18, {0,1,1,2} }, + { 15, {0,1,2,0} }, + { 22, {0,1,2,1} }, + { 19, {0,1,2,2} }, + { 13, {0,2,0,0} }, + { 21, {0,2,0,1} }, + { 7, {0,2,0,2} }, + { 16, {0,2,1,0} }, + { 17, {0,2,1,1} }, + { 23, {0,2,1,2} }, + { 4, {0,2,2,0} }, + { 20, {0,2,2,1} }, + { 10, {0,2,2,2} }, + { 11, {1,0,0,0} }, + { 3, {1,0,0,1} }, + { 16, {1,0,0,2} }, + { 6, {1,0,1,0} }, + { 9, {1,0,1,1} }, + { 22, {1,0,1,2} }, + { 21, {1,0,2,0} }, + { 17, {1,0,2,1} }, + { 20, {1,0,2,2} }, + { 3, {1,1,0,0} }, + { 9, {1,1,0,1} }, + { 17, {1,1,0,2} }, + { 9, {1,1,1,0} }, + { 1, {1,1,1,1} }, + { 14, {1,1,1,2} }, + { 18, {1,1,2,0} }, + { 14, {1,1,2,1} }, + { 5, {1,1,2,2} }, + { 15, {1,2,0,0} }, + { 18, {1,2,0,1} }, + { 23, {1,2,0,2} }, + { 22, {1,2,1,0} }, + { 14, {1,2,1,1} }, + { 8, {1,2,1,2} }, + { 19, {1,2,2,0} }, + { 5, {1,2,2,1} }, + { 12, {1,2,2,2} }, + { 13, {2,0,0,0} }, + { 15, {2,0,0,1} }, + { 4, {2,0,0,2} }, + { 21, {2,0,1,0} }, + { 18, {2,0,1,1} }, + { 19, {2,0,1,2} }, + { 7, {2,0,2,0} }, + { 23, {2,0,2,1} }, + { 10, {2,0,2,2} }, + { 16, {2,1,0,0} }, + { 22, {2,1,0,1} }, + { 20, {2,1,0,2} }, + { 17, {2,1,1,0} }, + { 14, {2,1,1,1} }, + { 5, {2,1,1,2} }, + { 23, {2,1,2,0} }, + { 8, {2,1,2,1} }, + { 12, {2,1,2,2} }, + { 4, {2,2,0,0} }, + { 19, {2,2,0,1} }, + { 10, {2,2,0,2} }, + { 20, {2,2,1,0} }, + { 5, {2,2,1,1} }, + { 12, {2,2,1,2} }, + { 10, {2,2,2,0} }, + { 12, {2,2,2,1} }, + { 2, {2,2,2,2} } +}; + +int rect[8][8], hbound[8][8], vbound[8][8]; + +static void +dump(void) +{ + int x,y; + + for (x=1; x<=6; x++) + { + for (y=1; y<=4; y++) + printf(".%d. ", list[rect[x][y]].x[1]); + putchar('\n'); + for (y=1; y<=4; y++) + printf("%d.%d ", list[rect[x][y]].x[0], list[rect[x][y]].x[2]); + putchar('\n'); + for (y=1; y<=4; y++) + printf(".%d. ", list[rect[x][y]].x[3]); + putchar('\n'); + putchar('\n'); + } +} + +static void +fill(int x, int y, unsigned int mask) +{ + int i,j; + + i = 9*(3*hbound[x][y]+vbound[x][y]); + for (j=0; j<9; i++, j++) + if (!(mask & (1 << list[i].id))) + { + // printf("place <%d,%d> %d\n", x, y, list[i].id); + rect[x][y] = i; + // if (hbound[x][y] != list[i].x[0] || + // vbound[x][y] != list[i].x[1]) puts("BUG!!!"); + hbound[x][y+1] = list[i].x[2]; + vbound[x+1][y] = list[i].x[3]; + if (x == 6) + { + if (vbound[x+1][y]) + continue; + if (y == 4) + { + if (hbound[x][y+1] != 2) + continue; + else + { + puts("Gotcha!!!"); + dump(); + fflush(stdout); + // exit(0); + return; + } + } + fill(x,y+1,mask | (1 << list[i].id)); + } + else if (y == 4) + { + if (hbound[x][y+1]) + continue; + fill(x+1,1,mask | (1 << list[i].id)); + } + else + fill(x,y+1,mask | (1 << list[i].id)); + } +} + +int +main(int argc, char **argv) +{ + int x; + for (x=1; x<=4; x++) + vbound[1][x] = 1; + fill(1,1,0); + puts("No chance"); + return 0; +} diff --git a/randomize.c b/randomize.c new file mode 100644 index 0000000..adc4992 --- /dev/null +++ b/randomize.c @@ -0,0 +1,72 @@ +#include +#include +#include + +struct line { + struct line *next; + char x[1]; +}; + +unsigned int +r(unsigned int max) +{ + unsigned int r, l; + + l = (RAND_MAX + 1U) - ((RAND_MAX + 1U) % max); + do + r = random(); + while (r >= l); + return r % max; +} + +int +main(int argc, char **argv) +{ + char buf[4096]; + struct line *f = NULL, *n, **b, **w; + int cnt = 0, i, j, k; + + while (fgets(buf, sizeof(buf)-1, stdin)) + { + if (!strchr(buf, '\n')) + { + fprintf(stderr, "Line too long\n"); + return 1; + } + n = malloc(sizeof(struct line) + strlen(buf)); + if (!n) + { + fprintf(stderr, "Out of memory\n"); + return 1; + } + n->next = f; + f = n; + strcpy(n->x, buf); + cnt++; + } + if (!cnt) + return 0; + w = b = malloc(sizeof(struct line *) * cnt); + if (!b) + { + fprintf(stderr, "Out of memory\n"); + return 1; + } + while (f) + { + *b++ = f; + f = f->next; + } + srandom(time(NULL)); + for(i=0; ix, stdout); + return 0; +} diff --git a/seek.c b/seek.c new file mode 100644 index 0000000..274d475 --- /dev/null +++ b/seek.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + unsigned long off; + char *ep; + if (argc != 2) { + fprintf(stderr, "Usage: seek \n"); + return 1; + } + off = strtoul(argv[1], &ep, 0); + if (!argv[1][0] || *ep || off == ULONG_MAX) { + fprintf(stderr, "seek: Invalid offset\n"); + return 1; + } + if (lseek(0, off, SEEK_SET) == (off_t)-1) { + fprintf(stderr, "seek: %m\n"); + return 1; + } + return 0; +} diff --git a/sig.c b/sig.c new file mode 100644 index 0000000..63dbdbe --- /dev/null +++ b/sig.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + struct passwd *p; + int n, len, f; + char buf[256], *z, *i; + + p = getpwuid(getuid()); + if (!p) { puts("You don't exist and thus you don't have a signature!"); return 1; } + chdir(p->pw_dir); + f = open((argc > 1) ? argv[1] : ".sigbase", O_RDONLY); + if (f < 0) { puts("No file, no signature!"); return 1; } + while ((n = read(f, buf, sizeof(buf))) > 0) write(1, buf, n); + close(f); + f = open(".misfortune", O_RDONLY); + if (!f || (len = lseek(f, 0, SEEK_END)) <= 0) { + puts("No fortune, no luck, no sig!"); + return 1; + } + lseek(f, 0, SEEK_SET); + z = malloc(len+1); + if (!z) { puts("ENOMEM"); return 1; } + read(f, z, len); + z[len] = 0; + n = 0; + for(i=z; i/dev/null ; then + echo Already present. +else + echo Not present + echo $xxx >>tla.db +fi +done diff --git a/tla.db b/tla.db new file mode 100644 index 0000000..0450d3b --- /dev/null +++ b/tla.db @@ -0,0 +1,481 @@ +abs +acc +ack +acs +adc +add +ads +afd +afm +ale +alf +alt +alu +amd +ami +arj +arp +arq +ash +asn +atn +avg +awk +bak +bbs +bcc +bcd +bcs +beq +bge +bgt +bhi +bin +bit +ble +bls +blt +bmi +bmp +bne +bpe +bpl +brk +bvc +bvs +cad +cam +cas +cat +cbm +cbw +ccd +cck +ccp +ccr +ced +cga +chk +clc +cli +clk +cmc +cmd +cmi +cmp +cmr +cms +cmu +cmy +cnt +col +com +cos +cpl +cpr +crt +csh +ctc +cti +cts +cur +cwd +dac +dat +dbf +dbm +dca +dcb +dcd +ddt +dec +deg +del +des +dfc +dft +dil +dim +dip +dir +div +dll +dma +dos +dra +drv +dsp +dsr +dtl +dtr +dvi +ecc +ecl +ega +emi +emm +ems +ena +enb +env +eps +erc +erl +ern +err +esc +exe +exg +exp +ext +faq +fat +fdc +fdd +fet +ffp +ffs +fft +fiz +fli +fmt +fpr +fpu +ftp +fyi +gal +gas +gcc +gcd +gcr +gdb +gdt +gid +gif +gnd +gnu +gpl +gpr +grp +gsf +gst +gus +hal +ham +hdc +hdd +hdr +hex +hgc +hlp +hma +hsv +hup +ibm +icc +icr +ier +iff +ifs +iil +imo +imr +inc +inp +ins +int +ipl +ipx +irc +irq +isa +isp +jcc +jcs +jeq +jle +jmi +jmp +jne +jns +jnz +jpl +kms +ksh +lan +ldt +led +len +ler +lha +lpq +lpr +lpt +lru +lsm +lzh +lzw +mam +man +mcu +mda +mfj +mfm +mft +mkd +mkf +mki +mkl +mml +mmu +mnp +mnt +mos +mrm +msd +msw +mul +mux +nak +ncc +ncd +ncr +ndd +nfs +nic +nmi +nop +nsl +ntp +nul +ocr +oct +ofs +oop +opl +ovl +ovr +pal +par +pbm +pci +pcl +pcx +pfm +pfs +pga +pgm +pgp +pha +pkg +pla +pld +pnm +ppi +ppm +ppp +psu +pwd +pxl +qed +qic +qwk +rad +ram +rar +ras +rbf +rcl +rcp +rcr +rcs +ref +rev +rgb +rip +rkm +rla +rlc +rld +rle +rll +rmt +rol +rom +ror +rot +rpc +rra +rrc +rrd +rsa +rsh +rsr +rtd +rte +rtg +rts +rxd +sad +sbb +sbc +scc +sdb +sec +sed +sfc +sid +sin +sla +sli +sls +smd +snd +spc +sql +sqr +sra +srl +ssp +stb +sti +stk +sto +str +sub +swp +sys +tac +tan +tar +tas +tbe +tcl +tcp +tee +tfm +tic +tla +tmp +tpa +tpc +tph +tpl +tpu +trk +tsr +tss +ttl +ttp +tts +tty +txd +ucc +ucw +udd +udp +uid +ula +umb +upp +ups +url +usp +val +vbr +vfs +vga +vim +vlb +vma +vms +vpa +wan +wrt +xbm +xga +xms +xon +yak +zif +png +pbx +atm +ppc +ggi +ddr +mtu +mru +cdr +rpm +bbn +bpm +brt +lim +dce +dte +dtp +apm +arm +xor +iso +itu +pcm +pdf +rtl +fcc +mbr +bgp +egp +igp +ssh +mib +rfu +rpg +rtt +lcp +icp +ioi +fel +lea +vtm +zcu +mff +etc +cet +lst +cvs +cpp +cls +vip +ccm +cpm +hga +fwd +fig +rtf +sak +xdr +sgp +dct +csc +phd +yam +tgv +tft +lcd +lpd +ean +elm +ipc +rms +clr +inn +nis +nan +inf +gem +gfx +igi +gpm +std diff --git a/trains.c b/trains.c new file mode 100644 index 0000000..3ae3dab --- /dev/null +++ b/trains.c @@ -0,0 +1,96 @@ +#include +#include +#include + +struct tariff { int kmax, price; }; + +struct tariff tar[] = { + { 10, 6 }, + { 15, 8 }, + { 20, 11 }, + { 25, 13 }, + { 30, 16 }, + { 35, 19 }, + { 40, 22 }, + { 50, 27 }, + { 60, 32 }, + { 70, 38 }, + { 80, 43 }, + { 90, 48 }, + { 100, 53 }, + { 110, 58 }, + { 120, 62 }, + { 140, 72 }, + { 160, 82 }, + { 180, 92 }, + { 200, 101 }, + { 225, 114 }, + { 250, 126 }, + { 275, 138 }, + { 300, 148 }, + { 350, 170 }, + { 400, 192 }, + { 450, 214 }, + { 500, 236 }, + { 550, 258 }, + { 600, 278 }, + { 650, 298 }, + { 700, 318 }, + { 99999, 342 } +}; + +int ftar(int km) +{ + int t; + for(t=0; tar[t].kmax < km; t++) + ; + return t; +} + +int lo(int t) +{ + return t ? tar[t-1].kmax+1 : 0; +} + +#define hi(t) tar[t].kmax +#define pri(t) tar[t].price + +int main(int argc, char **argv) +{ + int km, t, orp, l, h; + + if (argc != 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 0; + } + km = atol(argv[1]); + if (km > 10000) + km = 10000; + t = ftar(km); + printf("Original: %d-%d %d\n", lo(t), hi(t), pri(t)); + orp = pri(t); + while (--t >= 0) + { + int l0 = km - hi(t); + int h0 = km - lo(t); + l = ftar(l0); + h = ftar(h0); +// printf("Trying %d-%d %d-%d\n", lo(t), hi(t), l0, h0); + while (l <= h) + { + int p = pri(t) + pri(l); + int L = lo(l) < l0 ? l0 : lo(l); + int H = hi(l) > h0 ? h0 : hi(l); +// printf("Combined %d-%d %d-%d: p=%d\n", lo(l), hi(l), L, H, p); + if (p < orp) + printf("::: %d-%d(%d) + %d-%d(%d) = %d (saved %d)\n", + L, H, pri(l), + lo(t), hi(t), pri(t), + p, orp - p); + l++; + } + } + + return 0; +} diff --git a/ukkonen.c b/ukkonen.c new file mode 100644 index 0000000..7e597cb --- /dev/null +++ b/ukkonen.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#define INFTY 1000000 + +struct node { + struct node *first_son; + struct node *next_sibling; + struct node *backlink; /* We use them only for internal nodes */ + char *label; /* Label of edge above this node */ + int lablen; +}; + +static void dump_tree(struct node *n, int level, char *strend) +{ + for (int i=0; i [%p] {%p}\n", + (n->lablen >= INFTY/2 ? strend-n->label : n->lablen), n->label, + (n->lablen >= INFTY/2 ? "*" : ""), n, n->backlink); + for (n=n->first_son; n; n=n->next_sibling) + dump_tree(n, level+1, strend); +} + +static struct node *new_node(void) +{ + struct node *n = malloc(sizeof(*n)); + bzero(n, sizeof(*n)); + return n; +} + +static struct node *lookup_edge(struct node *x, int c) +{ + x = x->first_son; + while (x && x->label[0] != c) + x = x->next_sibling; + return x; +} + +static struct node *build_tree(char *string) +{ + struct node *root = new_node(); + struct node *l = root; /* Currently longest nested suffix as a canonical reference pair (node, label) */ + char *llabel = string; + int llablen = 0; + struct node *x, *y, *z, *trash, **blp; + + for (int i=0; string[i]; i++) { + blp = &trash; + for(;;) { + while (llablen) { /* Canonicalize the reference pair */ + x = lookup_edge(l, llabel[0]); + if (x->lablen > llablen) + break; + l = x; + llabel += x->lablen; + llablen -= x->lablen; + } + if (!llablen) { /* LNS is an internal node or root */ + *blp = l; + blp = &trash; + if (lookup_edge(l, string[i])) { /* Found LNS for the new string */ + llabel = string+i; + llablen = 1; + break; + } + z = new_node(); + z->next_sibling = l->first_son; + l->first_son = z; + } else { /* LNS is in the middle of an edge */ + x = lookup_edge(l, llabel[0]); + if (x->label[llablen] == string[i]) { /* found LNS for the new string */ + llablen++; + break; + } + y = new_node(); /* New interior node which gets all sons of x */ + z = new_node(); /* New leaf connected below x */ + y->first_son = x->first_son; + y->next_sibling = NULL; + y->backlink = x->backlink; + y->label = x->label + llablen; + y->lablen = x->lablen - llablen; + x->first_son = z; + x->backlink = NULL; + *blp = x; + blp = &x->backlink; /* Backlink will be filled in later */ + x->lablen = llablen; + z->next_sibling = y; + } + z->label = string+i; + z->lablen = INFTY; + + if (l == root) { /* Cut the first character of the LNS */ + if (!llablen) + break; + llabel++; + llablen--; + } else + l = l->backlink; + } + *blp = root; + } + return root; +} + +int main(int argc, char **argv) +{ + char *string = argv[1]; + struct node *root = build_tree(string); + puts("Result:"); + dump_tree(root, 0, string+strlen(string)); + return 0; +} diff --git a/un602.c b/un602.c new file mode 100644 index 0000000..34e01d4 --- /dev/null +++ b/un602.c @@ -0,0 +1,29 @@ +#include + +int main(void) +{ + int i; + int bol = 1; + + while ((i = getchar()) != EOF) + { + if (i == 10) + { + bol = 1; + putchar(10); + continue; + } + if (i < 32) + continue; + if (i == '@' && bol) + { + while ((i = getchar()) != EOF && i != 10) + ; + continue; + } + bol = 0; + putchar(i); + } + + return 0; +} diff --git a/unword.c b/unword.c new file mode 100644 index 0000000..12b5ed1 --- /dev/null +++ b/unword.c @@ -0,0 +1,333 @@ +/* + * Extract ASCII Text from M$ Word Document + * + * (c) 1997 Martin Mares + */ + +/* FIXME: endianity dependencies! */ + +#include +#include +#include + +FILE *fi, *fo; + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned int ulg; + +byte +gb(void) +{ + return fgetc(fi); +} + +word +gw(void) +{ + word k = fgetc(fi); + k = k | (fgetc(fi) << 8); + return k; +} + +ulg +gl(void) +{ + ulg l = gw(); + l = l | (gw() << 16); + return l; +} + +void +ole(void) +{ + ulg p, word; + byte oh[0x80], pn[0x80]; + int z, x, y; + + fseek(fi, 0x30, SEEK_SET); + p = 0x200 * gl() + 0x200; /* Position of central directory */ + word = 0; + printf("Central OLE directory at 0x%x\n", p); + fseek(fi, p, SEEK_SET); + while (fread(oh, sizeof(oh), 1, fi) == 1) + { + z = y = 0; + if ((!oh[0] && !oh[1]) || (!oh[2] && !oh[3])) + break; + if (oh[z] < 32 && !oh[z+1]) + { + z += 2; + pn[y++] = '>'; + pn[y++] = ' '; + } + while (oh[z] || oh[z+1]) + { + x = oh[z] | (oh[z+1] << 8); + if (x >= 32 && x < 127) + pn[y++] = x; + else + pn[y++] = '?'; + z += 2; + } + pn[y] = 0; + p = 0x200 * (oh[0x74] | (oh[0x75] << 8) | (oh[0x76] << 16) | (oh[0x77] << 24)) + 0x200; + printf("%08x %s\n", p, pn); + if (!strcmp(pn, "WordDocument")) + word = p; + } + if (!word) + { + fprintf(stderr, "Word doc stream not found!\n"); + exit(1); + } + fseek(fi, word, SEEK_SET); +} + +struct fib { + word magic; + word vers; + word product; + word lang; + word pnnext; + byte flags1; + byte flags2; + word back; + ulg cryptkey; + byte environ; + byte rfu; + word textcharset; /* 0=win, 256=mac */ + word tablecharset; /* 0=win, 256=mac */ + ulg firsttextchar; + ulg xx[6]; + ulg textlen; + ulg footlen; + ulg hdrlen; + ulg macrolen; + ulg annolen; + ulg endnotelen; + ulg textboxlen; + ulg htextboxlen; + ulg rfu2; + ulg stshorigp, stshorigl; + ulg stshp, stshl; + ulg footrefp, footrefl; + ulg foottxtp, foottxtl; + ulg annorefp, annorefl; + ulg annotxtp, annotxtl; + ulg sedp, sedl; + ulg pardp, pardl; + ulg pahp, pahl; + ulg glossp, glossl; + ulg glosp, glosl; + ulg hdrp, hdrl; + ulg chpbp, chpbl; + ulg papbp, papbl; + ulg seap, seal; + ulg ffnsp, ffnsl; + ulg mainfpp, mainfpl; + ulg headfpp, headfpl; + ulg footfpp, footfpl; + ulg annofpp, annofpl; + ulg macfpp, macfpl; + ulg boosp, boosl; + ulg bookop, bookol; + ulg booklp, bookll; + ulg cmdsp, cmdsl; + ulg mcrpp, mcrpl; + ulg mcrsp, mcrsl; + ulg pdrvp, pdrvl; + ulg prenvpp, prenvpl; + ulg prenvlp, prenvll; + ulg wssp, wssl; + ulg dopp, dopl; + ulg assosp, assosl; + ulg compp, compl; /* Complex file info! */ + ulg footpgp, footpgl; + ulg orignamep, orignamel; + ulg annoownp, annoownl; + ulg annobnp, annobnl; +} __attribute__((packed)); + +ulg txl, lbf; + +int +cc(void) +{ + if (txl) + { + txl--; + return gb(); + } + return -1; +} + +char lb[86]; +int lbi; + +void +flb(void) +{ + lb[lbi++] = '\n'; + lb[lbi] = 0; + fputs(lb, fo); + lbi = 0; +} + +void +pc(int c) +{ + if (lbi >= 80) + { + int lc = lbi; + while (lc > 0 && lb[--lc] != ' ') + ; + if (!lc) + { + lbf++; + flb(); + } + else + { + char exb[80]; + lb[lbi] = 0; + lb[lc] = 0; + lbi = lc++; + strcpy(exb, lb+lc); + flb(); + strcpy(lb, exb); + lbi = strlen(lb); + } + } + lb[lbi++] = c; +} + +void +text(void) +{ + int c; + + for(;;) + switch (c = cc()) + { + case -1: + flb(); + if (lbf) + printf("%d line breaks failed\n", lbf); + return; + case 12: + flb(); + fputc(12, fo); + break; + case 13: + lb[lbi++] = '\n'; + /* FALL-THRU */ + case 11: + flb(); + break; + case 9: + case 14: + pc(9); + break; + case 31: + pc('-'); + break; + case 7: + case 19: + case 20: + case 21: + break; + case 160: + pc('~'); + break; + default: + pc(c); + } +} + +void +unword(void) +{ + struct fib fib; + ulg where = ftell(fi); + +printf("%d %d\n", (int)&(((struct fib *)0)->compp), where); + printf("Reading %d bytes of file header\n", sizeof(fib)); + if (fread(&fib, sizeof(fib), 1, fi) != 1) + { + fprintf(stderr, "FIB read error!\n"); + exit(1); + } + if (fib.magic != 0xa5db && fib.magic != 0xa5dc) + { + fprintf(stderr, "Black magic!\n"); + exit(1); + } + printf("Lang=%d, charset=[%d,%d]\n", fib.lang, fib.textcharset, fib.tablecharset); + if (fib.flags1 & 4) + { + if (fib.magic == 0xa5db) + puts("Complex format, old magic"); + else + { + printf("Complex format, abs start=0x%x, len=%d\n", fib.compp + where, fib.compl); + fprintf(stderr, "Fast-saved format not supported yet!\n"); + exit(1); + } + } + if (fib.flags2 & 1) + { + fprintf(stderr, "Encrypted files not supported yet!\n"); + exit(1); + } + if (fib.flags2 & 0x1000) + puts("Extended charsets detected"); + printf("First text char at 0x%x, len=%d\n", fib.firsttextchar + where, fib.textlen); + fseek(fi, fib.firsttextchar + where, SEEK_SET); + txl = fib.textlen; + text(); +} + +void +convert(void) +{ + word id = gw(); + if (id == 0xa5db || id == 0xa5dc) + { + fseek(fi, 0, SEEK_SET); + puts("Plain M$-Word file..."); + } + else if (id == 0xcfd0) + { + puts("OLE file..."); + ole(); + } + else + { + fprintf(stderr, "Unknown file format!\n"); + exit(1); + } + unword(); +} + +int +main(int argc, char **argv) +{ + if (argc != 3) + { + fprintf(stderr, "Usage: unword \n"); + return 1; + } + if (!(fi = fopen(argv[1], "r"))) + { + fprintf(stderr, "Unable to open input file: %m\n"); + return 1; + } + if (!(fo = fopen(argv[2], "w"))) + { + fprintf(stderr, "Unable to open output file: %m\n"); + return 1; + } + convert(); + return 0; +} diff --git a/whatsit.c b/whatsit.c new file mode 100644 index 0000000..a14387e --- /dev/null +++ b/whatsit.c @@ -0,0 +1,12 @@ +int f(int x, int y) +{ + return x ? f((x&y) << 1, x^y) : y; +} + +#include +#include +int main(int argc, char **argv) +{ + printf("%d\n", f(atol(argv[1]), atol(argv[2]))); + return 0; +}