Alright people who know how to tell there computer what to do and how to get there... I bring you a challenge from the interweb.
THE 4K CODE CHALLENGE
Objective: To create the most productive/useful code that as source code is no larger than 4 kilobytes (4096 bytes). There is no restrictions as to what your code does, or what language it is used in.
Rules:
Gentlemen, START YOUR TEXTEDITORS
Well, I finally got a funny idea for this, and threw together this in an hour and a half. It's more like a 400 byte entry than a 4k entry, though:
package PerlHP;
use Filter::Simple;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
my $q=new CGI;
our %vars=$q->Vars;
FILTER {
s/^#!.*//;
s/(.*?)(?:<([\%\?])(?:perl)?(.*?)?\2>|$)/"print '".esc($1)."';$3;"/sgei;
$_=q{
print "Content-Type: text/html\n";
print "\n";
}.$_;
$_=(join "",map {
/\0/?"my \@$_=split /\0/,\$PerlHP::vars{$_};":"my \$$_=\$PerlHP::vars{$_};";
} keys %vars).$_;
};
sub esc { my $a=shift; $a=~s/(['\\])/\\$1/g; $a }
1;
It is the FANTASTICALLY FABULOUS PerlHP! It combines the concepts of Perl and PHP in one big headache-inducing mess! Now you can write code like this:
#!/usr/bin/perl
use PerlHP;
<html>
<head><title>It's a test page!</title></head>
<body>
<h1>PerlHP test page</h1>
<?
print "<h3>Three random numbers: ".int(rand 10)." ".int(rand 10)." ".int(rand 10)."</h3>";
print "<h3>The time is: ".localtime time."</h3>";
?>
<hr>
<? print "<h3>Value is: "$arg"</h3>" if($arg); ?>
<form action="test.pl" method="get">
<input name="arg" type="text" value="">
<input type="submit" value="Submit">
</form>
<hr>
<h3>Ten stars, drawn with an interleaved loop:
<? for(1..10) { ?>
*
<? } ?>
</h3>
</body>
</html>
FEATURES
PROBLEMS
Try out the demo page at http://wakaba.c3.cx/perlhp/.
you're right, this is pretty fucking retarded.
perl code with php like bindings.. what a pain in the ass.
submit it to freshmeat and see if you get a following.
there are people who code in brainfuck and malbolge and LIKE IT.
Hey, that's actually pretty slick...
Best something since something else!
Now that is a cool hack. XD
Are you ready for... PerlHP 2.0?
Now with bugfixes, support for cookies and headers, and more! I forget what the "more" is though. It's late, and I should be asleep. PerlHP is now a whopping 1.5k in size!
The header()
and cookie()
functions work much like PHP's header()
and setcookie()
, except that they don't need to be at the start of the code. Cookies are imported as global variables, too.
The latest example code is at http://wakaba.c3.cx/perlhp/.
package PerlHP;
require Exporter;
@ISA=qw(Exporter);
@EXPORT=qw(header cookie);
use strict;
use Filter::Simple;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
our @headers;
our $q=new CGI;
our %vars=$q->Vars;
$vars{$_}=$q->cookie($_) for($q->cookie());
FILTER {
s/^#!.*//;
s{(.*?)(?:<([\%\?])(?:perl)?(.*?)?\2>|$)}{
my ($html,$code)=($1,$3);
$html=~s/(['\\])/\\$1/g;
"print '$html';$code;"
}sgei;
$_=q{
open OLDOUT,">&STDOUT";
pipe PIPEIN,STDOUT;
}.
(join "",map { "my \@$_=split /\\0/,\$PerlHP::vars{$_}; my \$$_=\$PerlHP::vars{$_};" } keys %vars).
$_.
q{
push @PerlHP::headers,"Content-Type: text/html" unless(grep { /^Content-Type:/ } @PerlHP::headers);
open STDOUT,">&OLDOUT";
print "$_\n" for(@PerlHP::headers);
print "\n";
print while(<PIPEIN>);
};
};
sub header { push @headers,shift }
sub cookie($$;$$$$)
{
my ($name,$value,$expires,$path,$domain,$secure)=@_;
my $cookie="Set-Cookie: ".cookie_enc($name)."=".cookie_enc($value);
if(defined($expires))
{
my @days=qw(Sun Mon Tue Wed Thu Fri Sat);
my @months=qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my ($sec,$min,$hour,$mday,$mon,$year,$wday)=gmtime($expires);
$cookie.=sprintf("; expires=%s, %02d-%s-%04d %02d:%02d:%02d GMT",$days[$wday],$mday,$months[$mon],$year+1900,$hour,$min,$sec);
}
$cookie.="; path=$path" if($path);
$cookie.="; domain=$domain" if($domain);
$cookie.="; secure" if($secure);
header($cookie);
}
sub cookie_enc($) { $_=shift; s/([^0-9a-zA-Z])/my $c=ord $1; sprintf($c>255?'%%u%04x':'%%%02x',$c)/sge; $_ }
1;
Now that's what i call creativity at work =o
I am working on a crawler for bittorrent sites, since some indexers went offline for whatever reason and i was too lazy to look for another one. Currently, it's a beta and I assume that I've ironed out the major bugs since it works pretty well with what I've tested it with thus far. I upload new versions here from time to time:
http://membres.lycos.fr/madleser/coding/btl.rb
documentation is included. the file weights in at 4032 bytes (atm) when removing all comments.
This might be just another crawler but I found it useful on the commandline and as a candidate for cronjobs. Furthermore, you can enhance it yourself by writing (sort of) callbacks. The sample config includes some hints on this; additionally, I'd like to point out the "code:" field which is evaluated after startup, making it possible to (eg.) redefine the print function to write to a database instead and so on. If something's mystifying you or you have suggetions, bugreports etc., go ahead and tell me.
I'll refrain from spamming this thread by posting any more code, but PerlHP 3.0 has now been released!
escape_html()
function to match PHP's htmlspecialchars()
.If anyone ever actually uses this for anything, I'd love to hear about it.
do you have a job?
a girlfriend?
a friend friend?
regardless, this is immensely cool in the manner that only foolhardy tasks can be -- you tug at my heartstrings, waha.
thread-kun is back from the dead, yay. now let's try to keep it alive a little longer. i'll drop a quick and dirty one-liner shellscript i use since i constantly forget what i watched so far:mplayer $@ > /dev/null 2>&1 && echo $@ >> /strg/animes/anidb
saved me some unnecessary downloads and thinking.
Actually, this took me a couple of days work, total.
You want to see something that took a silly amount of effort, check out http://wakaba.c3.cx/sup/kareha.pl/1116806324
What follows is a color picker using JavaScript's new Canvas doodad. It supports 24-bit color and the alpha channel. It works in both Firefox 1.5 and Safari 2. Grab the necessary images from http://pichan.org/pc/index.php?t=178 . The code and the images together are 4203 bytes, but I'm counting it because it would be fairly easy to get down below 4K by sacrificing a bit of readability.
The idea is to maybe possibly use this as part of a larger side-project, though I don't know if it'll ever leave the ground. Anyway, I think it's awesome, and mommy tole me dat's awl dat counts.
----------
<html><head><script type="text/javascript">
col=new Array();
col[0]='r';
col[1]='g';
col[2]='b';
col[3]='a';
col['r']=0;
col['g']=0;
col['b']=0;
col['a']=0;
dragbar=false;
barimg=new Image();
barimg.src="bar.png";
colsimg=new Image();
colsimg.src="colors.png";
diamond=new Image();
diamond.src="diamond.png";
window.onload=function() {
//Can't have this part in header because we need to make the obj in HTML first.
cvs=document.getElementById("pic");
ctx=cvs.getContext("2d");
ptn=ctx.createPattern(diamond,"repeat");
colbarup();
}
function colfit(num) {
//Fit the color to an acceptable value.
if (num<0) {
return 0;
}
else if (num>255) {
return 255;
}
else {
return num;
}
}
function colbarup() {
//Update this color bar, and the color preview box. 0=r 1=g 2=b 3=a
ctx.drawImage(colsimg,0,0);
for(x=0;x<4;x++) {
ctx.drawImage(barimg,col[col[x]]-1,x*8);
if (col[col[x]]==255) {
ctx.clearRect(256,x*8,1,8);
}
}
ctx.fillStyle="rgb("+col['r']+","+col['g']+","+col['b']+")"; //JS and its wacky color assignment schemes. What a card.
ctx.fillRect(257,0,8,16);
ctx.fillStyle="rgba("+col['r']+","+col['g']+","+col['b']+","+goodalp(col['a'])+")";
ctx.fillRect(257,16,8,16);
window.status="rgba("+col['r']+","+col['g']+","+col['b']+","+goodalp(col['a'])+")";
}
function goodalp(a) {
//The rgba() function wants a value of alpha between 0 (transparent) and 1 (opaque). We're storing it as 0 (opaque) and 255 (transparent) for simplicity. This will convert our number to an acceptable value.
return 1-(a/255);
}
document.onmousedown=function(e) {
//This allows "dragging" the color bar.
if (e.clientX>255 || e.clientY>32) {
return;
}
dragbar=Math.floor(e.clientY/8);
col[col[dragbar]]=e.clientX;
}
document.onmousemove=function(e) {
if (dragbar!==false) {
fit=colfit(e.clientX);
col[col[dragbar]]=fit;
colbarup();
}
}
document.onmouseup=function(e) {
if (dragbar!==false) {
dragbar=false;
}
}
</script></head>
<body><canvas id="pic" width="800" height="600" style="left:0px;top:0px;position:absolute;cursor:crosshair;"></canvas></body></html>
A multi-threaded http server written in haskell that serves both regular files and CGI scripts, and weights 4095 bytes. I've been able to run Kareha on it, for example. It's also much faster than Apache, on my test machine, for static content (haven't had time to test dynamic content yet), but not as fast as lighttpd. It's a shortened (shorter function names, etc) version of the http server I wrote a few months ago, which is available at http://people.freebsd.org/~ssouhlal/stuff/httpd.hs and is almost 9k in size (but much more readable). I believe that with a bit more work it should be possible to shove off a few more hundred bytes.
<code>
module Main where
import Control.Monad.State
import Data.List
import Network
import Network.BSD
import Network.Socket
import qualified Data.Map as M
import Data.Char
import System.IO
import qualified System.IO.Error as I
import Foreign.Marshal.Alloc
import Control.Concurrent
import System.Time
import System.Process
import System.Posix.IO
import System.Directory
path="/Users/refugee/public_html"
port=1234
hV="rephttpd/0.1"
hP=hPutStr
r=reverse
c=concat
fI=fromIntegral
type S=String
fD x s=M.findWithDefault""x$hd s
data ParserState = ParserState {
met::S,
loc::S,
hd::M.Map S S,
ver::S,
err::Int,
cH::HostName
}
eS = ParserState""""M.empty""0""
pH x=case(last$head$words x)of
':'->pHd x
_->pMd x
pHd x=get>>= \s->put$s{hd=M.insert k v(hd s)}
where
(y:ys)=words x
k=r$tail$r y
v=filter(/='\r')$c ys
pMd x=pM'(words x)
where
pM'(m:l:v:[])=get>>= \s->put$s{met=m,loc=l,ver=v}
pM' _=get>>= \s->put$s{err=400}
sCH h=getClockTime>>=toCalendarTime>>=hP h.("Date: "++).calendarTimeToString>>(hP h$"Server: "++hV++"\r\n")
pR h s=do
name<-rN""sg
case name of
Just x->I.try(openFile(fst x)ReadMode)>>=either(sE h s.eC)(pM h s x)
Nothing->sE h s 404
where
sg=sp"/"fn
rN l[]=return$Just(l,"")
rN l("":xs)=rN l xs
rN l(x:xs)=do
dE<-doesDirectoryExist f
if dE==True then rN f xs else do
fileExists<-doesFileExist f
if fileExists==True then return$Just(f,c$intersperse"/"xs) else return$Nothing
where f=c[l,"/",x]
loc'=takeWhile(/='?')$loc s
fn=case loc' of
"/"->path++"/index.html"
_->path++loc'
eC e
|I.isDoesNotExistError e=404
|I.isPermissionError e=403
|otherwise=501
pM h s file h2=case(cT$fst file)of
"cgi-script"->dC h s file
_->case(met s)of
"GET"->sF h s h2
"HEAD"->sH h s h2
_->sE h s 501
sp g xs=s' xs
where
s'[]=[]
s' xs'=p:s'(dG r)
where
(p,r)=bOG g xs'
dG=drop(length g)
bOG _[]=([],[])
bOG g r@(x:y)
|isPrefixOf g r=([],r)
|otherwise=(x:p,r')
where (p,r')=bOG g y
dC h s f=do
hP h"HTTP/1.1 200 OK\r\n"
sCH h
hFlush h
(sR,sW)<-createPipe
r<-fdToHandle sR
w<-fdToHandle sW
ptr<-mallocBytes$fI len
hGetBuf h ptr$fI len
putStrLn$snd f
id<-runProcess(fst f)args(Just dir)(Just$c[env"127.0.0.1",hH])(Just r)(Just h)Nothing
hPutBuf w ptr$fI len
free ptr
hClose w
waitForProcess id
return()
where
len
|cT'==""=0::Integer
|otherwise=read cL
dir=r$tail$dropWhile(/='/')$r$fst f
cL=fD"Content-Length"s
cT'=fD"Content-Type"s
sH=takeWhile(/= ':')$fD"Host"s
sP=tail$dropWhile(/= ':')$fD"Host"s
hH=map(\(x,y)->("HTTP_"++map toUpper x,y))$M.toList$hd s
q'=dropWhile(/= '?')$loc s
q=if q'/=""then tail q' else""
args=if elem '='q then[]else sp"+"q
env hst=[("SERVER_SOFTWARE",hV),
("SERVER_NAME",sH),
("GATEWAY_INTERFACE","CGI/1.1"),
("SERVER_PROTOCOL",ver s),
("SERVER_PORT",sP),
("REQUEST_METHOD",met s),
("PATH_INFO","/"++snd f),
("PATH_TRANSLATED",fst f),
("SCRIPT_NAME",takeWhile(/= '?')$loc s),
("QUERY_STRING",q),
("REMOTE_ADDR",hst),
("CONTENT_TYPE",cT'),
("CONTENT_LENGTH",cL)]
sH h s h2=do
size<-hFileSize h2
hP h"HTTP/1.1 200 OK\r\n"
sCH h
hP h$"Content-Length: "++(show size)++"\r\n"
hP h$"Content-Type: "++cT(loc s)++"\r\n"
hP h"\r\n"
cT s=case s of
_:".jpg"->"image/JPEG"
_:".pdf"->"application/pdf"
_:".cgi"->"cgi-script"
_:".pl"->"cgi-script"
_->"text/html"
sF h s h2=do
z<-hFileSize h2
allocaBytes(fI z)$ \p->hGetBuf h2 p(fI z)>>sH h s h2>>hPutBuf h p(fI z)
sE h s n=do
hP h$"HTTP/1.1 "++(show n)++" Not Found\r\n"
sCH h
hP h"Content-Type: text/html; charset=iso-8859-1\r\n\r\n"
hP h$"ERROR "++(show n)++"\r\n"
hClose h
pC h=do
t<-lift$catch(hGetLine h)(const$return"")
case t of
"\r"->do
s<-get
lift$pR h s
(lift$I.try$hFlush h)>>=either(const$return())(const $ k s)
where
k s=case(fD "Connection" s)of
"close"->lift$hClose h
"keep-alive"->put eS>>pC h
_->lift$hClose h
""->return()
_->do
pH t
s<-get
if(err s/=0)then lift$sE h s$err s else pC h
mainLoop s=do
(h,hs,p)<-Network.accept s
forkOS$evalStateT(pC h)$eS{cH=hs}
mainLoop s
main=listenOn(PortNumber port)>>=mainLoop
</code
I got frustrated with a porn gallery that used Javascript popups for the images yesterday, and ended up learning Javascript to write this small Fusker implementation. It's not neat or anything, but at least it's slightly useful. Save as html file, call as (for example):
localdir/imgget.html?http://adultdreamhost.com/user/ayleen2/1012/15/0[01-15].jpg
<html>
<head>
<title>ImageGET!</title>
<script type="text/javascript">
function init() {
var t = document.forms[0].elements[0];
if(t.value = window.location.search.substring(1)) process(t.value);
t.focus();
}
function process(s) {
var left = s.indexOf("[");
if(left<0) {
var child = document.createElement("img");
child.setAttribute("src",s);
document.getElementById("content").appendChild(child);
} else {
var right = s.indexOf("]");
var range = s.substring(left+1,right);
var m = range.indexOf("-");
for(var i=range.substring(0,m); i<=range.substring(m+1); i++) {
var num = i.toString();
while(num.length < m) { num = "0" + num; }
process(s.substring(0,left) + num + s.substring(right+1));
}
}
}
</script>
<style>
body { margin: 0 16pt; padding: 0; background: #008; }
form { padding: 4pt 8pt; margin: 0; }
form { background: #88f; }
input { width: 100%; }
img { display: block; counter-increment: images; background: #eef; }
img:before {
background: #bbf;
content: counter(images) ". " attr(src) "\A";
font: 7pt sans-serif;
display: block;
padding: 4pt 8pt;
}
</style>
</head>
<body onload="init();">
<form action="" onsubmit="window.location = '?' + this.elements[0].value; return false;">
<input />
</form>
<div id="content" />
</body>
</html>
Oh, btw, apparently FF has some use CSS issues. It looks best in Opera.
Line-oriented text editor in C. Requires the <err.h> routines from BSD, but those are easy to write yourself if you don't have them. Usage is "tte filename". I had to remove the built-in help to get it under 4K, so the commands are:
s save file
p[num] print lines
.[num] advance
,[num] retreat
g[num] go to / print line number
i<text> insert before
a<text> insert after
c<text> replace
d delete line
tte.c (4013 bytes) follows...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
void *xmalloc(size_t size)
{
void *p;
p = malloc(size);
if (p == NULL)
err(1, "can't get %lu bytes", (unsigned long) size);
return p;
}
void *xrealloc(void *ptr, size_t size)
{
void *p;
p = realloc(ptr, size);
if (p == NULL)
err(1, "can't get %lu bytes", (unsigned long) size);
return p;
}
// get arbitrary length string
char *readstring(FILE *fp)
{
char *p = NULL, *q;
int size = 50;
p = xmalloc((size_t) size);
if (fgets(p, size, fp) == NULL)
return NULL;
while ((q = strchr(p, '\n')) == NULL)
{
size *= 2;
p = xrealloc(p, (size_t) size);
if (fgets(&p[size/2-1], size/2+1, fp) == NULL)
return NULL; // file must end with newline
}
*q = '\0';
size = strlen(p) + 1;
return xrealloc(p, (size_t) size); // save memory
}
static struct
{
char **lines;
int numlines, space;
} buf;
static const char *filename;
static int curline = 0;
static void usage(void)
{
extern char *__progname;
fprintf(stderr, "usage: %s file\n", __progname);
exit(1);
}
static void checkbufsize(int neededspace)
{
if (buf.space >= neededspace)
return;
while (buf.space < neededspace)
buf.space *= 2;
buf.lines = xrealloc(buf.lines, buf.space * sizeof (char *));
}
static void gotoline(int index)
{
curline = index;
if (curline >= buf.numlines)
curline = buf.numlines - 1;
if (curline < 0)
curline = 0;
}
static void addline(int index, char *line)
{
checkbufsize(buf.numlines + 1);
if (index > buf.numlines)
index = buf.numlines; // don't make gaps
memmove(&buf.lines[index+1], &buf.lines[index],
(buf.numlines - index) * sizeof (char *));
buf.numlines++;
buf.lines[index] = line;
}
static void deleteline(int index)
{
if (buf.numlines == 0)
{
warnx("no lines");
return;
}
memmove(&buf.lines[index], &buf.lines[index+1],
(buf.numlines - (index+1)) * sizeof (char *));
buf.numlines--;
gotoline(curline); // bounds check
}
static void replaceline(int index, char *newline)
{
if (buf.numlines == 0)
buf.numlines = 1;
else
free(buf.lines[index]);
buf.lines[index] = newline;
}
static void loadfile(void)
{
FILE *fp;
char *str;
buf.space = 10;
buf.numlines = 0;
buf.lines = xmalloc(buf.space * sizeof (char *));
fp = fopen(filename, "r");
if (fp == NULL)
{
warn("can't open %s, starting new file", filename);
return;
}
while ((str = readstring(fp)) != NULL)
addline(buf.numlines, str);
fclose(fp);
}
static void savefile(void)
{
int i;
FILE *fp;
fp = fopen(filename, "w");
if (fp == NULL)
{
warn("can't open %s", filename);
return;
}
for (i = 0; i < buf.numlines; i++)
fprintf(fp, "%s\n", buf.lines[i]);
fclose(fp);
}
static void printlines(int num)
{
int line = curline;
if (num < 0)
{
line += num;
if (line < 0)
{
num -= line;
line = 0;
}
num *= -1;
}
for (; num > 0 && line < buf.numlines; num--, line++)
printf("%s\n", buf.lines[line]);
}
static void execute(const char *cmd)
{
const char *arg = cmd + 1;
int hasarg = cmd[0] != '\0' && cmd[1] != '\0';
switch(cmd[0])
{
case 's': savefile(); break;
case 'p': if (!hasarg) printlines(1);
else printlines(atoi(arg));
break;
case '.': if (hasarg) gotoline(curline + atoi(arg));
else gotoline(curline + 1);
break;
case ',': if (hasarg) gotoline(curline - atoi(arg));
else gotoline(curline - 1);
break;
case 'g': if (!hasarg) printf("%d\n", curline);
else gotoline(atoi(arg));
break;
case 'i': addline(curline, strdup(arg)); break;
case 'a': addline(curline+1, strdup(arg));
gotoline(curline+1); break;
case 'c': replaceline(curline, strdup(arg)); break;
case 'd': deleteline(curline); break;
case '\0': break;
default: warnx("unrecognized command %c", cmd[0]);
}
}
int main(int argc, char *argv[])
{
char *cmd;
if (argc != 2)
usage();
filename = argv[1];
loadfile();
while ((cmd = readstring(stdin)) != NULL)
{
execute(cmd);
free(cmd);
}
return 0;
}
The "Javascript vs. Lua" topic made me think of this file, "play", a Lua script for playing various types of audio. It works by piping the output of a decoder into "waveplay", a utility available on Linux and several BSDs. Copy it to ~/bin and use it like "play something.mp3 crap.mid super.flac &" (this plays each of the files in the background, one after another).
Supported formats are Ogg Vorbis using oggdec; MP3 using lame; FLAC using, well, flac; WavPack using wvunpack; General MIDI using timidity; the big four module formats using dumb2wav; and Speex using speexdec (wideband only). Ironically, I never bothered making it play wav files because I never needed to do that. You can add a format if you have a program that converts/renders/decodes the format to a wav file, or to raw PCM data, on stdout. Code follows.
#!/usr/local/bin/lua
local fileext = function(filename)
local extstart, extend = string.find(filename, "%.%w+$")
if extstart == nil then
return nil
else
return string.sub(filename, extstart, extend)
end
end
local playfile = function(filename)
local unpackcmd
local playcmd = "waveplay -s "
local ext = string.lower(fileext(filename))
local israw = false -- set to true if there is no wav header
local samplerate = 44100 -- only use if raw
local numchannels = 2 -- only use if raw
-- don't bomb out on filenames with (, etc.
filename = "\"" .. filename .. "\""
if ext == ".flac" then
unpackcmd = "flac -sdo - " .. filename
elseif ext == ".wv" then
unpackcmd = "wvunpack -q -o - " .. filename
elseif ext == ".ogg" then
unpackcmd = "oggdec -Q -o - " .. filename
elseif ext == ".spx" then
unpackcmd = "speexdec " .. filename .. " - 2>/dev/null"
numchannels = 1
israw = true
samplerate = 16000 -- FIXME: not always true
elseif ext == ".mp3" then
-- lame's "--silent" option lies; it still prints
-- warnings onto stderr about ID3v2 tags.
unpackcmd = "lame --decode --silent 2>/dev/null "
.. filename .. " -"
elseif ext == ".mid" then
unpackcmd = "timidity -s 44100 -Ow1sl -o - -A84a "
.. filename .. " 2>/dev/null"
elseif ext == ".mod" or ext == ".s3m" or ext == ".it"
or ext == ".xm" then
unpackcmd = "dumb2wav -o - " .. filename
.. " 2>/dev/null"
else
io.stderr:write(filename
.. ": don't know how to play this file\n")
return nil
end
if israw then
playcmd = playcmd .. "-r "
if numchannels ~= 2 then
playcmd = playcmd .. "-C " .. numchannels .. " "
end
if samplerate ~= 44100 then
playcmd = playcmd .. "-S " .. samplerate .. " "
end
end
playcmd = playcmd .. "-"
return os.execute(unpackcmd .. " | " .. playcmd)
end
for i,v in ipairs(arg) do
playfile(v)
end
quick perl script i wrote so i could execute commands on my computer from my cell phone... only use this if you have your web server set up to do ssl and use .htaccess to restrict access to it!
#!/usr/bin/perl
use CGI;
my $query=new CGI;
my $cmd=$query->param("cmd");
if ($cmd) {
$cmd=~s/\\\`/\`/g;
$cmd=~s/\\~/~/g;
$cmd=~s/\\\$/\$/g;
$cmd=~s/\\\^/\^/g;
$cmd=~s/\\&/&/g;
$cmd=~s/\\\*/\*/g;
$cmd=~s/\\\(/\(/g;
$cmd=~s/\\\)/\)/g;
$cmd=~s/\\\[/\[/g;
$cmd=~s/\\\]/\]/g;
$cmd=~s/\\\{/\{/g;
$cmd=~s/\\\}/\}/g;
$cmd=~s/\\\|/\|/g;
$cmd=~s/\\\\/\\/g;
$cmd=~s/\\;/;/g;
$cmd=~s/\\:/:/g;
$cmd=~s/\\"/"/g;
$cmd=~s/\\'/'/g;
$cmd=~s/\\</</g;
$cmd=~s/\\>/>/g;
$cmd=~s/\\\?/\?/g;
$cmd=`$cmd`;
$cmd=~s/&/&/g;
$cmd=~s/</</g;
$cmd=~s/>/>/g;
$cmd=~s/"/"/g;
$cmd=~s/'/;/g;
$cmd=~s/\n/<br>/g;
print "Content-type: text/html;encoding=us-ascii\n\n",
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
" \"http://www.w3.org/TR/html4/strict.dtd\">\n",
"<html><head><title>exec.pl</title></head><body>\n",
"<form action=\"exec.pl\" method=\"POST\">\n",
"<input type=\"text\" name=\"cmd\">\n",
"<input type=\"submit\" value=\"exec\">\n",
"</form><p>",
$cmd,
"</p></body></html>\n";
} else {
print "Content-type: text/html;encoding=us-ascii\n\n",
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
" \"http://www.w3.org/TR/html4/strict.dtd\">\n",
"<html><head><title>exec.pl</title></head><body>\n",
"<form action=\"exec.pl\" method=\"POST\">\n",
"<input type=\"text\" name=\"cmd\">\n",
"<input type=\"submit\" value=\"exec\">\n",
"</form></body></html>\n";
}
Cool.
Let's have some more 4K programs, people!
A PHP-GTK calculator for geeks with a nice style. It evals PHP code. I have reduced it so that it fits 4 KB, haven't tested it as I don't have PHP-GTK installed here.
Uh, I don't know the code tag for this board, will try both usual tags just in case.
<code>[code]
<?php
//PHP-GTK calculator for geeks by Wiseman
//GTK COMMON CODE
if (!extension_loaded('gtk')) dl('php_gtk.'.PHP_SHLIB_SUFFIX);
function delete_event() {
return false;
}
function destroy() {
Gtk::main_quit();
}
//BEGIN WINDOW DEFINITIONS
function form_Main() {
global $q, $entry;
$w = new GtkWindow(GTK_WINDOW_DIALOG);
$w->set_name('Main');
$w->set_title('GeekCalc');
$w->set_usize(512, 280);
$w->connect('destroy', 'destroy');
$w->connect('delete-event', 'delete_event');
$w->set_border_width(2);
$w->set_position(GTK_WIN_POS_CENTER);
$w->set_policy(false, false, false);
$box1 = new GtkVBox();
$w->add($box1);
$box2 = new GtkHBox();
$box1->pack_start($box2);
$prompt = new GtkLabel('PHP:');
$box2->pack_start($prompt, false, true, 0);
$entry = new GtkEntry();
$box2->pack_start($entry, true, true, 0);
$entry->connect('activate', 'Calculate');
$separator = new GtkHSeparator();
$box1->pack_start($separator);
$t = new GtkTable(4, 2, true);
$box1->pack_start($t);
foreach (array('raw' => 'Result', 'int' => 'Decimal', 'uint' => 'Unsigned 32', 'hex' => 'Hexadecimal', 'oct' => 'Octal', 'bin' => 'Binary', 'char' => 'Character', 'float' => 'Float', 'sci' => 'Scientific') as $k => $v) {
$frame[$k] = new GtkFrame($v);
$q[$k] = new GtkLabel('-' . $k . '-');
$q[$k]->set_usize(246, -1);
$frame[$k]->add($q[$k]);
}
$z = GTK_FILL;
$t->attach($frame['raw'],0,2,0,1,$z,$z);
$t->attach($frame['int'],0,1,1,2,$z,$z);
$t->attach($frame['uint'],1,2,1,2,$z,$z);
$t->attach($frame['hex'],0,1,2,3,$z,$z);
$t->attach($frame['oct'],1,2,2,3,$z,$z);
$t->attach($frame['bin'],0,1,3,4,$z,$z);
$t->attach($frame['char'],1,2,3,4,$z,$z);
$t->attach($frame['float'],0,1,4,5,$z,$z);
$t->attach($frame['sci'],1,2,4,5,$z,$z);
$t->set_row_spacings(8);
$t->set_col_spacings(8);
$t->resize(2, 4);
$y = new GtkStyle();
$y->fg[GTK_STATE_NORMAL] = new GdkColor('#000000');
$y->fg[GTK_STATE_ACTIVE] = new GdkColor('#000000');
$y->fg[GTK_STATE_PRELIGHT] = new GdkColor('#000000');
$y->fg[GTK_STATE_SELECTED] = new GdkColor('#FFFFFF');
$y->fg[GTK_STATE_INSENSITIVE] = new GdkColor('#808080');
$y->bg[GTK_STATE_NORMAL] = new GdkColor('#D4D0C8');
$y->bg[GTK_STATE_ACTIVE] = new GdkColor('#C8C3B8');
$y->bg[GTK_STATE_PRELIGHT] = new GdkColor('#E1DED7');
$y->bg[GTK_STATE_SELECTED] = new GdkColor('#000080');
$y->bg[GTK_STATE_INSENSITIVE] = new GdkColor('#D4D0C8');
$y->font = gdk::font_load('--Verdana-normal-r-normal--18--96-96-p-0-iso8859-1');
$w->set_style($y->copy());
$prompt->set_style($y->copy());
$separator->set_style($y->copy());
foreach ($frame as $x)
$x->set_style($y->copy());
$y->font = gdk::font_load('--Lucida Console-normal-r-normal--18--96-96-p-0-iso8859-1');
$entry->set_style($y->copy());
foreach ($q as $x)
$x->set_style($y->copy());
$w->show_all();
$entry->grab_focus();
return $w;
}
//CALCULATOR FUNCTIONS
//Constants
define('pi', pi());
define('e', exp(1));
//Returns an string containing a character, or its name if it's not printable
function pchar($c) {
$c %= 256;
if ($c < 0)
$c += 256;
if ($c >= 32)
return chr($c);
else {
$names = array('NUL','SOH','STX','ETX','EOT','ENQ','ACK','BEL','BS' ,'TAB','LF' ,'VT' ,'NP' ,'CR' ,'SO' ,'SI' ,'DLE','DC1','DC2','DC3','DC4','NAK','SYN','ETB','CAN','EM' ,'EOF','ESC','FS' ,'GS' ,'RS' ,'US');
return $names[$c];
}
}
//CALCULATOR
function Calculate() {
global $q, $entry;
@eval('$x=' . $entry->get_text() . ';');
$r = round($x);
$q['raw']->set_text($x);
$q['int']->set_text($r);
$q['uint']->set_text($r >= 0 ? $r : 4294967296 + $r);
$q['hex']->set_text(sprintf('%X', $r));
$q['oct']->set_text(sprintf('%o', $r));
$q['bin']->set_text(sprintf('%b', $r));
$q['char']->set_text(pchar($r));
$q['float']->set_text(sprintf(is_infinite((float) $x) ? 'INF' : '%f', $x));
$q['sci']->set_text(sprintf(is_infinite((float) $x) ? 'INF' : '%e', $x));
}
//MAIN
form_Main();
Calculate();
Gtk::main();
?>
[/code]</code>
Looks like neither was :) Ok, I think I got how it's done:
<?php
//PHP-GTK calculator for geeks by Wiseman
//GTK COMMON CODE
if (!extension_loaded('gtk')) dl('php_gtk.'.PHP_SHLIB_SUFFIX);
function delete_event() {
return false;
}
function destroy() {
Gtk::main_quit();
}
//BEGIN WINDOW DEFINITIONS
function form_Main() {
global $q, $entry;
$w = new GtkWindow(GTK_WINDOW_DIALOG);
$w->set_name('Main');
$w->set_title('GeekCalc');
$w->set_usize(512, 280);
$w->connect('destroy', 'destroy');
$w->connect('delete-event', 'delete_event');
$w->set_border_width(2);
$w->set_position(GTK_WIN_POS_CENTER);
$w->set_policy(false, false, false);
$box1 = new GtkVBox();
$w->add($box1);
$box2 = new GtkHBox();
$box1->pack_start($box2);
$prompt = new GtkLabel('PHP:');
$box2->pack_start($prompt, false, true, 0);
$entry = new GtkEntry();
$box2->pack_start($entry, true, true, 0);
$entry->connect('activate', 'Calculate');
$separator = new GtkHSeparator();
$box1->pack_start($separator);
$t = new GtkTable(4, 2, true);
$box1->pack_start($t);
foreach (array('raw' => 'Result', 'int' => 'Decimal', 'uint' => 'Unsigned 32', 'hex' => 'Hexadecimal', 'oct' => 'Octal', 'bin' => 'Binary', 'char' => 'Character', 'float' => 'Float', 'sci' => 'Scientific') as $k => $v) {
$frame[$k] = new GtkFrame($v);
$q[$k] = new GtkLabel('-' . $k . '-');
$q[$k]->set_usize(246, -1);
$frame[$k]->add($q[$k]);
}
$z = GTK_FILL;
$t->attach($frame['raw'],0,2,0,1,$z,$z);
$t->attach($frame['int'],0,1,1,2,$z,$z);
$t->attach($frame['uint'],1,2,1,2,$z,$z);
$t->attach($frame['hex'],0,1,2,3,$z,$z);
$t->attach($frame['oct'],1,2,2,3,$z,$z);
$t->attach($frame['bin'],0,1,3,4,$z,$z);
$t->attach($frame['char'],1,2,3,4,$z,$z);
$t->attach($frame['float'],0,1,4,5,$z,$z);
$t->attach($frame['sci'],1,2,4,5,$z,$z);
$t->set_row_spacings(8);
$t->set_col_spacings(8);
$t->resize(2, 4);
$y = new GtkStyle();
$y->fg[GTK_STATE_NORMAL] = new GdkColor('#000000');
$y->fg[GTK_STATE_ACTIVE] = new GdkColor('#000000');
$y->fg[GTK_STATE_PRELIGHT] = new GdkColor('#000000');
$y->fg[GTK_STATE_SELECTED] = new GdkColor('#FFFFFF');
$y->fg[GTK_STATE_INSENSITIVE] = new GdkColor('#808080');
$y->bg[GTK_STATE_NORMAL] = new GdkColor('#D4D0C8');
$y->bg[GTK_STATE_ACTIVE] = new GdkColor('#C8C3B8');
$y->bg[GTK_STATE_PRELIGHT] = new GdkColor('#E1DED7');
$y->bg[GTK_STATE_SELECTED] = new GdkColor('#000080');
$y->bg[GTK_STATE_INSENSITIVE] = new GdkColor('#D4D0C8');
$y->font = gdk::font_load('-*-Verdana-normal-r-normal--18-*-96-96-p-0-iso8859-1');
$w->set_style($y->copy());
$prompt->set_style($y->copy());
$separator->set_style($y->copy());
foreach ($frame as $x)
$x->set_style($y->copy());
$y->font = gdk::font_load('-*-Lucida Console-normal-r-normal--18-*-96-96-p-0-iso8859-1');
$entry->set_style($y->copy());
foreach ($q as $x)
$x->set_style($y->copy());
$w->show_all();
$entry->grab_focus();
return $w;
}
//CALCULATOR FUNCTIONS
//Constants
define('pi', pi());
define('e', exp(1));
//Returns an string containing a character, or its name if it's not printable
function pchar($c) {
$c %= 256;
if ($c < 0)
$c += 256;
if ($c >= 32)
return chr($c);
else {
$names = array('NUL','SOH','STX','ETX','EOT','ENQ','ACK','BEL','BS' ,'TAB','LF' ,'VT' ,'NP' ,'CR' ,'SO' ,'SI' ,'DLE','DC1','DC2','DC3','DC4','NAK','SYN','ETB','CAN','EM' ,'EOF','ESC','FS' ,'GS' ,'RS' ,'US');
return $names[$c];
}
}
//CALCULATOR
function Calculate() {
global $q, $entry;
@eval('$x=' . $entry->get_text() . ';');
$r = round($x);
$q['raw']->set_text($x);
$q['int']->set_text($r);
$q['uint']->set_text($r >= 0 ? $r : 4294967296 + $r);
$q['hex']->set_text(sprintf('%X', $r));
$q['oct']->set_text(sprintf('%o', $r));
$q['bin']->set_text(sprintf('%b', $r));
$q['char']->set_text(pchar($r));
$q['float']->set_text(sprintf(is_infinite((float) $x) ? 'INF' : '%f', $x));
$q['sci']->set_text(sprintf(is_infinite((float) $x) ? 'INF' : '%e', $x));
}
//MAIN
form_Main();
Calculate();
Gtk::main();
?>
Presenting "splice", a useful UNIX command (probably requires a 4.4BSD-based system):
/*
* splice is a program intended to be placed in a pipeline. It reads all
* input from stdin, opens your favorite text editor ($VISUAL, $EDITOR,
* or vi) on that input, then prints your manually changed version of
* the text on stdout.
*
* This is done by forking and reopening stdin and stdout as /dev/tty
* before invoking the text editor.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <paths.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#define MAX_EDITOR_ARGS 30
char *editor_args[MAX_EDITOR_ARGS+2]; /* 1 for filename arg, 1 for NULL */
int nargs = 0;
char tmppath[] = "/tmp/tmp.XXXXXXXXXX";
int fd = -1;
char *strndup(const char *src, size_t len)
{
char *s;
s = malloc(len+1);
if (s == NULL) err(1, NULL);
memcpy(s, src, len);
s[len] = '\0';
return s;
}
void string_to_args(const char *str)
{
const char *p = str, *space;
for (;;)
{
if (nargs == MAX_EDITOR_ARGS)
errx(1, "too many editor arguments");
while(*p == ' ')
p++;
if (*p == '\0')
break;
space = strchr(p, ' ');
if (space == NULL)
space = &p[strlen(p)];
editor_args[nargs++] = strndup(p, space - p);
p = space;
}
editor_args[nargs] = NULL;
}
void save_stdin(void)
{
char buf[BUFSIZ];
int bytesread;
fd = mkstemp(tmppath);
if (fd == -1)
err(1, "cannot open temporary file");
while ((bytesread = read(STDIN_FILENO, buf, BUFSIZ)) > 0)
write(fd, buf, bytesread);
close(fd);
}
void replicate_tmpfile(void)
{
char buf[BUFSIZ];
int bytesread;
fd = open(tmppath, O_RDONLY|O_NOFOLLOW, 0);
if (fd == -1)
err(1, "cannot reopen temporary file");
while ((bytesread = read(fd, buf, BUFSIZ)) > 0)
write(STDOUT_FILENO, buf, bytesread);
close(fd);
}
void unlink_tmpfile(void)
{
if (unlink(tmppath) == -1)
warn("cannot unlink temporary file");
}
void setup_editor_args(void)
{
const char *edname;
edname = getenv("VISUAL");
if (edname == NULL) edname = getenv("EDITOR");
if (edname == NULL) edname = "vi";
/*
* Split up the editor command into arguments,
* e.g. "mg" and "-n".
*/
string_to_args(edname);
}
int start_editor(void)
{
pid_t pid;
int status;
/* To the editor arguments, add the temporary filename to edit. */
editor_args[nargs++] = tmppath;
editor_args[nargs] = NULL;
switch (vfork())
{
case -1:
unlink_tmpfile();
err(1, "vfork");
case 0:
/* Reopen the terminal as stdin and stdout. */
fd = open(_PATH_TTY, O_RDWR);
if (fd == -1)
{
warn("cannot open " _PATH_TTY);
_exit(1);
}
if (dup2(fd, STDIN_FILENO) == -1)
{
warn("can't dup2 to stdin");
_exit(1);
}
if (dup2(fd, STDOUT_FILENO) == -1)
{
warn("can't dup2 to stdout");
_exit(1);
}
close(fd);
execvp(editor_args[0], editor_args);
/* execvp only returns if there is an error. */
warn("%s", editor_args[0]);
_exit(1);
}
pid = wait(&status);
if (pid == -1)
err(1, "wait");
return WIFEXITED(status) ? WEXITSTATUS(status) : 1;
}
int main(void)
{
int ret;
setup_editor_args();
save_stdin();
ret = start_editor();
if (ret != 0)
warnx("non-zero return value from editor");
replicate_tmpfile();
unlink_tmpfile();
return ret;
}
age
>>54
Nice. FYI, you might want to try perror if you're finding err isn't always available.
>>56
I wrote my own portable implementation of err() and friends for those situations. It's about 75 lines of code. I could post it here if anyone cares.
BTW, since nobody said anything encouraging: congrats, >>53. It's nothing personal, I just don't think most of us here like PHP enough to run that.
>>58
Thanks. I don't actually use it as I have a command line one, but I did that to learn PHP-GTK and see what could be done with it.
BTW, PHP is not the source of all evil. Problem is it's too easy to learn, and too easy to do it wrong. There are a lot of shitty "coders" out there writing sucky code I wouldn't touch, but any decent programmer can do a good job with PHP. Its advantages are productivity and simplicity. I've found PHP great for web applications (including complex ones; I'm currently maintaining a 200K lines one, 85% of its code doesn't suck), as well as command line scripts which are far more readable and sometimes simpler than Perl (which I also know).
For example, here's another 4 KB contender:
A script I wrote to find duplicate files in my collections, even when they are in different subdirectories and have different names. It's pretty fast (only compares file groups with the same size, only reads each of these once), and even shows fancy character mode progress bars. You use it like this: go to the root directory of your <whatever> collection, say images, and run it. It'll generate a file, "dupfiles.log", with all duplicate files (using relative paths), one line per group, 2 or more files per line, quoted names separated with a space. Now you can either run a very simple script and delete arbitrarily all files per line but one, or edit this file by hand, delete one entry per line - the one you want to keep, and then run a very simple script to delete everything that's still listed there.
The script was nicer, had more comments, reusable progress bar (I use them in other scripts), localization, and a configuration file, but I had to cut that out for the 4 KB version which sill retains most of the comments and the progress bar (only it's built in and uglier).
<?php
echo "DUPFILES v1.11.4K by Wiseman\n\n";
define(CONWIDTH, 80);
define(BARLEN, 32);
define(SEP, DIRECTORY_SEPARATOR);
/* Draws a text progress bar, $pct=percentage (float ok), $lab=text printed left of it (trimmed if necessary).
You can update it by calling to Progress again. To finish the progress bar, call ProgressEnd($lab). */
function Progress($pct, $lab) {
global $lablen;
//Label
if ($lablen) {
//Decide whether to trim the label or not
if (strlen($lab) > ($lablen - 1))
$lab = substr($lab, 0, $lablen - 2) . '|';
//Print label and extra spaces
echo $lab, str_repeat(' ', $lablen - strlen($lab));
}
//Bar
$i = floor($pct * BARLEN / 100);
echo '[', str_repeat('#', $i), str_repeat(' ', BARLEN - $i), ']';
//Take the cursor back
echo str_repeat("\x08", $lablen + BARLEN + 2);
}
/* Finishes a progress bar. $lab=text printed left of it. */
function ProgressEnd($lab) {
global $lablen;
//Label
if ($lablen) {
//Decide whether to trim the label or not
if (strlen($lab) > ($lablen - 1))
$lab = substr($lab, 0, $lablen - 2) . '|';
//Print label and extra spaces
echo $lab, str_repeat(' ', $lablen - strlen($lab));
}
//Bar
echo '[', str_repeat('+', BARLEN), ']';
//End of line
echo "\n";
}
/* Scan directories recursively, inserting files into $Fsize. Prints bars.
$filebase Filename base
$pctbase Base of progress bar done
$pctarea Percentage of bar assigned to it
*/
function ScanDirectory($filebase, $pctbase, $pctarea) {
global $Fsize;
Progress($pctbase, $filebase);
//Glob stuff
if (!($dir = glob('*', GLOB_MARK | GLOB_NOSORT)))
return;
//Process files
foreach ($dir as $k => $file)
if (substr($file, -1, 1) != SEP) {
//Add to $Fsize by size
$Fsize[filesize($file)][] = '"' . $filebase . $file . '"';
//Quotes are to prevent glitches with spaces
//Remove from $dir
unset($dir[$k]);
}
//Process directories and update progress bar
if (count($dir) > 0)
$pctadd = $pctarea / count($dir); //Amount to add for every subdir
foreach ($dir as $subdir) {
chdir($subdir);
ScanDirectory($filebase . $subdir, $pctbase, $pctadd);
chdir('..');
$pctbase += $pctadd;
}
}
/* Scan $Fsize and build $Fcheck on files of matching sizes */
function SizeToChecksum() {
global $Fsize, $Fcheck;
$pct = 0;
$pctadd = 100 / count($Fsize);
Progress(0, 'Analyzing...');
foreach ($Fsize as $k => $a) {
if (count($a) > 1) {
$pctadd2 = $pctadd / count($a);
foreach ($a as $file) {
Progress($pct, 'Matching size ' . $k . ' = ' . $file);
$Fcheck[substr(`md5sum $file`, 0, 32)][] = $file;
$pct += $pctadd2;
}
Progress($pct, 'Scanning list');
} else
$pct += $pctadd;
}
}
/* Generate a report of $Fcheck, $file=File to be written */
function GenerateReport($file) {
global $Fcheck;
$sgroups = 0;
$sfiles = 0;
$finit = FALSE;
foreach ($Fcheck as $a) {
if (count($a) > 1) {
if (!$finit) {
$f = fopen($file, 'w');
echo "Generating report...\n";
$finit = TRUE;
}
fwrite($f, join(' ', $a) . "\n");
$sgroups++;
$sfiles += count($a);
}
}
if ($finit) {
fclose($f);
echo "File dupfiles.log generated\n";
}
echo "$sgroups groups of duplicate files\n";
if ($sgroups) {
printf("%d matching files (%.2f per group)\n", $sfiles, $sfiles / $sgroups);
echo $sfiles - $sgroups, ' duplicate files';
}
}
//MAIN
if ($argc != 1) {
echo "Help wouldn't fit 4 KB lol";
die(1);
}
$lablen = CONWIDTH - BARLEN - 3;
echo "=1/2=: Exploring files and comparing sizes\n";
ScanDirectory('.' . SEP, 0, 100);
ProgressEnd('Completed');
if (count($Fsize) == 0) {
echo "No files\n";
exit;
}
echo "=2/2=: Calculating checksum for equal size files\n";
SizeToChecksum();
ProgressEnd('Completed');
if (count($Fcheck) == 0) {
echo "No files of the same size (therefore no duplicates)\n";
exit;
}
GenerateReport('dupfiles.log');
?>
To get this to run on my machine, I had to change line 81 to:
$Fcheck[substr(`md5 $file`, 0, 32)][] = $file;
Don't really understand why you're not just using PHP's own md5_file()
, though. Also, I found the log report much more legible if we change line 102 to:
fwrite($f, join('=', $a) . "\n\n");
The script seems to work, but there's a glitch; if there's two or more sets of matching files in the same directory, the script reports all of those files as matching each other.
It's a good start, though. I was planning on writing something like this for myself one of these days.
>>61
Actually, I don't remember why I used an external command. Perhaps I measured their performance and found my md5sum utility faster.
As for the log, I join them with spaces because that way you can edit the log file as I suggested (deleting the file you want to keep in every line) and then run a command on all these lines as is. To do that I use another script.
> there's a glitch; if there's two or more sets of matching files in the same directory, the script reports all of those files as matching each other.
This never happened to me, and I've been using it on 10000+ file collections for over a year; could you post the files you've used to see if I can reproduce it? Thanks.
Hmm. No, because now it's not finding dupes at all... ?
Twelve:~ Albright$ mkdir duck
Twelve:~ Albright$ cd duck
Twelve:~/duck Albright$ echo "Banana">banana.text
Twelve:~/duck Albright$ cp banana.text banana-copy.text
Twelve:~/duck Albright$ echo "Apple">apple.text
Twelve:~/duck Albright$ cp apple.text apple-copy.text
Twelve:~/duck Albright$ echo "Cheese">cheese.text
Twelve:~/duck Albright$ echo "asdf">asdf.text
Twelve:~/duck Albright$ echo "askljasdjklsda">askl.text
Twelve:~/duck Albright$ mv ../dupes.php ./
Twelve:~/duck Albright$ php -f dupes.php
DUPFILES v1.11.4K by Wiseman
=1/2=: Exploring files and comparing sizes
Completed [++++++++++++++++++++++++++++++++]
=2/2=: Calculating checksum for equal size files
Completed [++++++++++++++++++++++++++++++++]
0 groups of duplicate files
Twelve:~/duck Albright$ mkdir asdf
Twelve:~/duck Albright$ cp * asdf/
cp: asdf is a directory (not copied).
Twelve:~/duck Albright$ ls
apple-copy.text asdf.text banana.text
apple.text askl.text cheese.text
asdf banana-copy.text dupes.php
Twelve:~/duck Albright$ ls asdf
apple-copy.text askl.text cheese.text
apple.text banana-copy.text dupes.php
asdf.text banana.text
Twelve:~/duck Albright$ php -f dupes.php
DUPFILES v1.11.4K by Wiseman
=1/2=: Exploring files and comparing sizes
Completed [++++++++++++++++++++++++++++++++]
=2/2=: Calculating checksum for equal size files
Completed [++++++++++++++++++++++++++++++++]
0 groups of duplicate files
Maybe because I'm using tiny files here? I'll play with it a bit more when I have some time.
Twelve:~/duck Albright$ ls
Birmanstrofe.jpg batgun22qt.jpg
CalgaryDT.jpg dupes.php
ChineseNewYearAucklandNewZealand.jpg dupfiles.log
aye.sized.jpg
Twelve:~/duck Albright$ cp Birmanstrofe.jpg kitty.jpg
Twelve:~/duck Albright$ cp aye.sized.jpg aye.jpg
Twelve:~/duck Albright$ mkdir goose
Twelve:~/duck Albright$ cp batgun22qt.jpg goose/
Twelve:~/duck Albright$ cp CalgaryDT.jpg goose/
Twelve:~/duck Albright$ cd goose
Twelve:~/duck/goose Albright$ cp CalgaryDT.jpg canada.jpg
Twelve:~/duck/goose Albright$ cd ..
Twelve:~/duck Albright$ php -f dupes.php
DUPFILES v1.11.4K by Wiseman
=1/2=: Exploring files and comparing sizes
Completed [++++++++++++++++++++++++++++++++]
=2/2=: Calculating checksum for equal size files
Completed [++++++++++++++++++++++++++++++++]
0 groups of duplicate files
=/
Here is a tiny perl program for creating 10 character random alphanumeric passwords with mixed case.
#!/usr/bin/perl
@a=(0..9,a..z,A..Z);
for(1..10){print@a[rand@a]}
print"\n"
>>65
shorter:
#!/usr/bin/perl
$a.=(0..9,a..z,A..Z)[rand 62]for(0..9);
die$a
Time for some Perl golf!
#!/usr/bin/perl
die map{(0..9,a..z,A..Z)[rand 62]}(1..10)
Shows how much I know about perl after using it for years. I did not know what map was.
That's the best part about Perl - you NEVER STOP LEARNING IT.
>>68
You should learn a Lisp; there's probably other neat things you don't know, too.
>>70
some of us spend thousands on speech therapy to unlearn our lisps, you insensitive clod
>>71
slashdot memes? In my /code/?
>>73
in your code!
Not even close to 4K, I was just really bored this evening... Too lazy to add command line arguments, however.
import urllib, urllib2, re
def babelfish(langpair, text):
url="http://babelfish.altavista.com/tr?lp="+langpair+"&trtext="+urllib.quote(text.encode('utf-8'))
html = urllib2.urlopen(urllib2.Request(url,None,{'Accept-charset':'utf-8'})).read()
m = re.compile("white class.s..div.style.padding.10px..([^<]*)</div",re.U).search(html)
return m.groups()[0].decode('utf-8').replace(u'\n',u' ')
def log(f, num, text, encoding='utf-8'):
out = (unicode(num)+u': '+text+u"\r\n")
print out.strip().encode('ascii','replace')
f.write(out.encode(encoding))
f.flush()
def mutate(text, steps, langpairs, outfile):
t = unicode(text)
f = open(outfile,"wb")
n = 1
log(f, 0, t)
history = [t]
br = False
while not br:
for lp in langpairs:
t = babelfish(lp, t)
log(f, n, t)
if n==steps: break
n += 1
if t in history:
br = True
break
history.append(t)
if n==steps: break
if br: log(f, n, u"[loop found]")
f.close()
mutate("Hay guys what's going on in this thread?", 20, ['en_ja','ja_en'], "nonsense.txt")
opens a tab with w3m running in the first open konsole and switches to that tab, or starts konsole with w3m if no konsole is running.
first, create ~/.kde/share/apps/konsole/w3m.desktop with the following contents:
[Desktop Entry]
Encoding=UTF-8
Type=KonsoleApplication
Name=w3m
Comment=Web Browser
Exec=w3m -v
Cwd=
then, you can use this perl script:
#!/usr/bin/perl
my $kpid=`dcop|grep konsole`;
$kpid=~s/\n.*//g;
if($kpid eq "")
{
`konsole --type w3m`
}
my $w3msession=`dcop $kpid konsole newSession w3m`;
$w3msession=~s/\n.*//g;
`dcop $kpid konsole activateSession $w3msession`;
hmm, it's difficult for me.
there are many kind of programming language.
so, i don't know how kind do i chose.
r2_jane@yahoo.co.jp
The maximum post size is set too low. I get "Text field too long" even though my whole post is less than 4K.
>>78
Maximum comment size is to 4096 characters exactly. Break it up if you have to.
>>79
Why don't you set it higher, then? What was wrong with 9K?
#!/usr/bin/perl
use CGI;
use CGI::Carp qw(fatalsToBrowser);
my $query=new CGI;
my $task=$query->param("task");
my $text=$query->param("text");
do_post($text) if $text;
unless (-e "index.xhtml") {
build_main_page();
}
print "Status: 303 Go West\n",
"Location: index.xhtml\n",
"Content-type: application/xhtml+xml; charset=utf-8\n\n",
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n",
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd\">\n",
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n",
"<head><title>redirect</title></head><body>\n",
"<p><a href=\"index.xhtml\">go to index.xhtml</a></p></body></html>\n";
sub do_post($) {
$text=shift;
$text=~s/[\x00-\x08\x0b\x0c\x0e-\x1f]//g;
$text=~s/&/&/g;
$text=~s/\</</g;
$text=~s/\>/>/g;
$text=~s/"/"/g;
$text=~s/'/'/g;
$text=~s/,/,/g;
$text=~s/&(\#[0-9]+;)/&$1/g;
$text=~s/&(\#x[0-9a-f]+;)/&$1/gi;
$text=~s/&\#([0-9]+);/$1<=1114111?"&#$1;":""/ge;
$text=~s/&\#x([0-9a-f]+);/hex($1)<=1114111?"&#x$1;":""/gei;
if(length($text)>4096) {
too_long_error();
} else {
my $filename="data/".int(rand(20));
open POSTFILE,">$filename";
print POSTFILE $text;
close POSTFILE;
}
build_main_page();
}
sub too_long_error() {
print "Content-type: application/xhtml+xml; charset=utf-8\n\n",
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n",
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd\">\n",
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n",
"<head><title>error!</title></head>\n<body>\n",
"<p>your text is too long.</p></body></html>\n";
}
sub build_main_page() {
open MAINPAGE,">index.xhtml";
print MAINPAGE "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n",
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd\">\n",
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n",
"<head><title>a web 3.0 page</title></head>\n",
"<body>\n",
"<form action=\"web3.0.pl\" method=\"post\">\n",
"<p><textarea name=\"text\" cols=\"64\" rows=\"10\"></textarea><br/>\n",
"<input type=\"submit\" value=\"submit\" /></p></form>\n";
@posts=glob("data/*");
for(@posts) {
open POSTFILE,"<$_";
read POSTFILE,$text,4096;
close POSTFILE;
print MAINPAGE "<hr><p>$text</p>\n";
}
print MAINPAGE "</body>\n</html>\n";
close MAINPAGE;
}
>>81
oh, the my $task=$query->param("task");
line isn't needed anymore
>>81
Nice, but if you call it .xhtml it'll send as a content-type of application/xhtml+xml, which some browsers don't support. (I'm thinking of Lynx and w3m here, there might be another major browser that doesn't support that content type, but I'm drawing a blank).
>>83
w3m and lynx do support xhtml sent as application/xhtml+xml.
Just tested. Lynx 2.8.5.rel2 and w3m 0.5.1 both offer to save the file. Maybe your server isn't set up to actually send .xhtml as application/xhtml+xml?
>>85
http://web3.hollosite.com/
works in lynx 2.8.5rel.4 and w3m 0.5.1 for me...
http://img122.imageshack.us/my.php?image=lynx0ob.png
http://img118.imageshack.us/my.php?image=w3m5ju.png
>>86
Are you using FreeBSD? It looks like their w3m port has a patch to make this work. I didn't look at Lynx, but I figure either it has a similar patch or it was fixed between 2.8.5rel.2 and 2.8.5rel.4.
Someone should step up to maintain w3m and collect these fixes. Nobody is really maintaining it right now, it seems.
Speaking of XHTML, the <hr>
that script outputs is wrong.
> Speaking of XHTML, the <hr> that script outputs is wrong.
i thought i posted about that when i fixed it on web3.hollosite.com... for anyone who can't figure out how to fix it, just replace it with <hr/>
I've been learning Perl recently, and I made this small program to encrypt/decrypt text and files using one-time pads (more on one-time pads here, if there's interest: http://en.wikipedia.org/wiki/One-time_pad)
Don't expect this code to be very good, but I would love any constructive criticisim (or destructive, whatever)
#!/usr/bin/perl -w
use strict;
=pod
-g output-file num: generates keytext file of length num. makes file of length 1024
if num is omitted.
-e file-to-encrypt output-file a-keyfile : encrypts file-to-encrypt with a-keyfile. if
a-keyfile is omitted, script uses file 'keyfile'.
-d file-to-decrypt output-file a-keyfile : decrypts file-to-decrypt with a-keyfile. if
a-keyfile is omitted, script uses file 'keyfile'.
=cut
if (not @ARGV)
{
print "try supplying some arguments : )\nview the source for a guide.\n";
exit(0);
}
sub rand_char{
return chr(rand 255);
}
sub crypt($$$){
my($arg,$letter,$keyletter)=@_;
return
($arg eq "-e" )?chr(($letter+$keyletter)%255):
($arg eq "-d" )?chr(($letter-$keyletter)%255):
undef;
}
if($ARGV[0] eq '-ga' || $ARGV[0] eq '-g')
{
my $keytext='';
my $length=($ARGV[2])?$ARGV[2]:1024;
$keytext.=rand_char while $length--;
open KEYFILE, ">$ARGV[1]" or die "couldn't open $ARGV[1] for output: $!";
print KEYFILE $keytext;
}
wow, I already fucked that up. here's the bottom half of the code
if($ARGV[0] eq '-e'||$ARGV[0] eq '-ea'||$ARGV[0] eq '-d'||$ARGV[0] eq '-da')
{
open INPUT, "<$ARGV[1]" or die "couldn't open $ARGV[1] for input: $!";
open OUTPUT, ">$ARGV[2]" or die "couldn't open $ARGV[2] for output: $!";
open KEY, ($ARGV[3])?"<$ARGV[3]":"<keyfile";
my @input=split //, join("\n", <INPUT>);
my @key=split //, <KEY>;
foreach (@input)
{
my $letter=ord($_);
my $keyletter=ord(shift @key);
print OUTPUT &crypt($ARGV[0],$letter,$keyletter);
}
close INPUT;
close OUTPUT;
close KEY;
}
Your "one-time pad" is trivially breakable if you generate it like that. Seriously. It is far weaker than even DES. You need a file of real, cryptographic-strength random data, and that's non-trivial to generate.
Also, you're taking a layman's description of one-time pads too literally if you're using + and - to encrypt. Just use a proper XOR and you won't need separate encryption and decryption modes, either.
Also, my @input=split //, join("\n", <INPUT>);
is a bug. You want my @input=split //, join("", <INPUT>);
Cryptographically you're also missing a whole lot of important features, such as a check that you have enough pad to encrypt the whole data, and a method to make sure you never re-use any part of the pad.
.
None of you are expert programmers. I have read the SICP, I know the abstract bullshite. I believe I am the Sussman's love child. Not enough of you are using Lisp (Possibly none of you, I do not check lesser languages on lesser boards). If you all achieved satori, you could become expert programmers like me, and sometimes shaft the paying customers, but have a lot of fun.
I have one word for all of you; the forced indentation of code.
>>94
Fuck off back to /prog/, animal.
I am from /prog/
GREETINS folks ;]
I am from Prague too!
COMRADES, WE SHALL HAVE OUR REVENGE
[code]
#!/usr/bin/perl
use strict;
use warnings;
my $sleep = 2000+int(rand(1500)); #Some days are better for fishing than others
open(FISH, "fish.data") || die("Couldn't open fish.data $!");
my @fish = <FISH>;
my $fish = @fish;
close(FISH);
foreach my $typeOfFish (@fish) {
chomp $typeOfFish;
}
while (1) {
my $thisIsTheFloorGrid = int(rand(80)) +1;
my $typeOfFish = @fish[int(rand($fish))];
system("xmessage A $typeOfFish appears in grid $thisIsTheFloorGrid");
sleep $sleep+int(rand(800));
}
[/code]
http://www.dilbert.com/comics/dilbert/archive/dilbert-20070930.html
I am taking 100GET to tell >>99 to next time read the notice at the top of the board, there is no retarded BBCode here you idiot!
That's great. Carpet fishing.
>>100
Which is very unfortunate. I haven't been able to get my ``EXPERT BBCODE'' fix for a few days.
The averaging solution to Laplace's equation. More specifically, it's a 1000V and a -1000V wire near each other in a conducting pipe and I find the voltage in the pipe. While ago though, I've to look it up to see if that's right. Used symmetry to speed it up. You can change the shape and the wire's voltage and get rid of the symmetry. Graphs the result. It's in Matlab. Am I cool yet?
``
m=201;
n=201;
a = 0.5;
x = 0:1/200:a;
y = 0:1/200:a;
s = zeros(m,n);
[u1,u2] = meshgrid(y.^2,x.^2); % shape
out = find(u1+u2 >= a^2); % points outside the circle
e = 1;
while e<1000,
e = e + 1;
s = ([s(2,:) ; s(1:end-1,:)] ...
+ [s(2:end,:) ; zeros(1,n)] ...
+ [zeros(m,1) s(:,1:end-1)] ...
+ [s(:,2:end) zeros(m,1)])/4; % averaging
s(out) = 0; % outside pipe
s(1,5) = 10; % the 1000V wire
s(:,1) = 0; % y = 0
end
s1 = [flipud(s) ; s(2:end,:)];
s2 = [fliplr(-s1) s1(:,2:end)]; % symmetry across the y-axis
mesh(s2)
``
> what does anon think?Unlike Blum Blum Shub, the algorithm in its native form is not suitable for cryptography.
Monads in Javascript
// Monad stuff
function bindM(m ,k)
{
return function (s) {
tmp = m(s);
a = tmp[0]; s_ = tmp[1];
return k(a)(s_);
}
}
function thenM(m,k) { return bindM(m,function(_){return k;}); }
function returnM(v) { return function (s) { return [v,s]; } }
function evalS(m,s) { return m(s)[0]; }
function getS(s) { return [s,s]; }
function putS(s) { return function(_) { return [null,s]; } }
function doM(m) {
if (arguments.length == 1) return m;
else if (arguments.length % 2 && arguments.length >= 2) {
var rest = Array.prototype.slice.call(arguments).slice(2);
return arguments[1](m, doM.apply(this, rest));
}
else throw ("doM: Error: Arguments mismatch.");
}
function mapM(k,l) {
if (l.length > 0) return doM(
k(l[0])
, bindM
, function (item) { return doM(
mapM(k,l.slice(1))
, bindM
, function (rest) {
if (rest)
return returnM(item.concat(rest));
else
return returnM(item);
}
); }
);
else
return returnM(null);
}
// Parse stuff
function parse(parser, input) { return evalS(parser, input); }
function throwInt(msg,input) {
var e = new Error();
e.message = [msg,input];
e.name = 'PARSE_ERROR'; throw e;
}
/// Combinators
function choice_(m,k) {
return function (s) {
try {
return m(s);
}
catch (e) {
switch (e.name) {
case 'PARSE_ERROR':
if (e.message[1].length != s.length) throw e;
else return k(s);
break;
default:
throw e;
}
}
}
}
function try_(m) {
return function (s) {
try {
return m(s);
}
catch (e) {
switch (e.name) {
case 'PARSE_ERROR':
e.message[1] = s; // Pretend we haven't consumed input
throw e;
break;
default:
throw e;
}
}
}
}
var letter_ = doM(
getS
, bindM
, function (input) {
if (input.length == 0)
return throwInt("Unexpected end of input, expected letter",input);
if (input.match(/^[a-z]/i))
return doM( putS(input.slice(1)) ,thenM, returnM(input[0]) );
else
return throwInt("Expected letter ([a-zA-Z])",input);
}
);
function char_(c) {
return doM(
getS
, bindM
, function (input) {
if (input.length == 0)
return throwInt("Unexpected end of input, expected '" + c + "'",input);
if (input[0] == c)
return doM( putS(input.slice(1)) ,thenM, returnM(c) );
else
return throwInt("Expected character '" + c + "'",input);
}
);
}
function string_(str) {
return mapM(char_,str);
}
// Run a parser
function run(parser,string) {
print("Parse output:");
try {
print(parse(parser,string));
}
catch (e) {
switch (e.name) {
case 'PARSE_ERROR':
print("Parse failed: " + e.message[0] + ", input: " + e.message[1]);
break;
default:
throw e;
}
}
}
// Example parsers
// Parse some parentheses
function parens(s) {
return choice_( doM( char_('(')
, thenM
, parens
, thenM
, char_(')')
, thenM
, parens
)
, returnM(null)
)(s);
}
var testOr = choice_( string_("(a)")
, string_("(b)") );
var testOr1 = doM( char_('(')
, thenM
, choice_( char_('a') , char_('b') )
, thenM
, char_(')')
);
var testOr2 = choice_( try_( string_("(a)") )
, string_("(b)")
);
var testOr3 = choice_( doM( try_( string_("(a") )
, thenM
, char_(')')
, thenM
, returnM("(a)")
)
, string_("(b)")
);
function nesting(s) {
return choice_(
doM(
char_('(')
, thenM
, nesting
, bindM
, function (n) {
return doM(
char_(')')
, thenM
, nesting
, bindM
, function (m) {
return returnM(Math.max(n+1, m));
}
);
})
, returnM(0)
)(s);
}
>>108
Usage: var nestcount = run(nesting,"((()))");
//Coded by drwho
// Knight's Tour program where moves are base on on horizontal and vertical
// arrays and are accessed by a random number generator. This does only 64
// moves but can be increased. the 0 on the board is the night
// I didn't know how to get C to print out both characters and integers
// or else I would have made the knight k (%c didn't work and just displays
// weird shit). Question? I idle in #4-ch on synirc so come by
// http://en.wikipedia.org/wiki/Knight's_tour
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
int main(int argc, char *argv[])
{
int j, currentrow, currentcolumn, lastmover, lastmovec, counta, moves, check;
static movenumber;
int horizontal[8]={2,1,-1,-2,-2,-1,1,2};
int vertical[8]={-1,-2,-2,-1,1,2,2,1};
int board[8][8]={
{2,3,4,4,4,4,3,2},
{3,4,6,6,6,6,4,3},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{3,4,6,6,6,6,4,3},
{2,3,4,4,4,4,3,2}
};
currentrow = 3;
currentcolumn = 3;
board[currentrow][currentcolumn] = 0;
moves = 0;
check = 0;
//time seed
srand ( time(NULL) );
for (counta = 1; counta < 65; counta++){
printf("Knights Round Program\n");
// random move number with time seed
movenumber = rand() % 8;
currentrow += horizontal[movenumber];
currentcolumn += vertical[movenumber];
if(currentrow > 8 || currentrow < 0 || currentcolumn > 8 || currentcolumn < 0){
currentrow = lastmover;
currentcolumn = lastmovec;
}
check = board[currentrow][currentcolumn];
if(check == 0){ board[lastmover][lastmovec]; }
else{board[currentrow][currentcolumn] = 0;}
// The Board
printf("\n");
for(j=0;j<8;j++){printf("%d", board[0][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[1][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[2][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[3][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[4][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[5][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[6][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[7][j]);}
printf("\n");
printf("Row: %d | Column: %d\n", currentrow, currentcolumn);
if(currentrow != lastmover && currentcolumn != lastmovec){moves++;}
lastmover = currentrow;
lastmovec = currentcolumn;
printf("Moves: %d\n", moves);
if(counta == 64){
printf("Knights Round Program\n");
printf("\n");
for(j=0;j<8;j++){printf("%d", board[0][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[1][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[2][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[3][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[4][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[5][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[6][j]);}
printf("\n");
for(j=0;j<8;j++){printf("%d", board[7][j]);}
printf("\n");
printf("Row: %d | Column: %d\n", currentrow, currentcolumn);
printf("Moves: %d\n", moves);
system("PAUSE");
return 0;
}
//Time Delay
sleep(1000);
system("cls");
}
}
//Coded by drwho
// Update: Thanks to a friend from 2600 I was able to shorten the code for the
// chess board. Now that is real hacking!
// Knight's Tour program where moves are base on on horizontal and vertical
// arrays and are accessed by a random number generator. This does only 64
// moves but can be increased. the 0 on the board is the night
// I didn't know how to get C to print out both characters and integers
// or else I would have made the knight k (%c didn't work and just displays
// weird shit). Question? I idle in #4-ch on synirc so come by
// http://en.wikipedia.org/wiki/Knight's_tour
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
int main(int argc, char *argv[])
{
int j, i, currentrow, currentcolumn, lastmover, lastmovec, counta, moves, check;
static movenumber;
int horizontal[8]={2,1,-1,-2,-2,-1,1,2};
int vertical[8]={-1,-2,-2,-1,1,2,2,1};
int board[8][8]={
{2,3,4,4,4,4,3,2},
{3,4,6,6,6,6,4,3},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{3,4,6,6,6,6,4,3},
{2,3,4,4,4,4,3,2}
};
currentrow = 3;
currentcolumn = 3;
board[currentrow][currentcolumn] = 0;
moves = 0;
check = 0;
//time seed
srand ( time(NULL) );
for (counta = 1; counta < 65; counta++){
printf("Knights Round Program\n");
// random move number with time seed
movenumber = rand() % 8;
currentrow += horizontal[movenumber];
currentcolumn += vertical[movenumber];
if(currentrow > 8 || currentrow < 0 || currentcolumn > 8 || currentcolumn < 0){
currentrow = lastmover;
currentcolumn = lastmovec;
}
check = board[currentrow][currentcolumn];
if(check == 0){ board[lastmover][lastmovec]; }
else{board[currentrow][currentcolumn] = 0;}
// The Board
printf("\n");
for(i=0;i<8;i++) { for(j=0;j<8;j++){printf("%d", board[i][j]);} printf("\n"); }
printf("\n");
printf("Row: %d | Column: %d\n", currentrow, currentcolumn);
if(currentrow != lastmover && currentcolumn != lastmovec){moves++;}
lastmover = currentrow;
lastmovec = currentcolumn;
printf("Moves: %d\n", moves);
if(counta == 64){
printf("Knights Round Program\n");
printf("\n");
for(i=0;i<8;i++) { for(j=0;j<8;j++){printf("%d", board[i][j]);} printf("\n"); }
printf("\n");
printf("Row: %d | Column: %d\n", currentrow, currentcolumn);
printf("Moves: %d\n", moves);
system("PAUSE");
return 0;
}
//Time Delay
sleep(1000);
system("cls");
}
}
> #include <windows.h>
http://www.tilander.org/aurora/2008/01/include-windowsh.html
>>1
Why not just implement an interpreter for lisp or something. That's as useful as you can get because you can implement any other program in that.
ok I hav it giv me a sec XDD
[code]
mysqld > /dev/usr/in > out.py
out.py < in.tt > ee.ttt
dc -e "5 6 * + +" > ff.rrrr
cat ee.ttt ff.rrrr > src.c
gcc -Wall -O3 src.c -o exe
[/code]
ders my code XDD u need the /devusr/in file tho XDDD
>source code must be 4 kb
>not the resulting executable
lol cucks.