OK, so in the spirit of Code-Golf, I\'m trying out something new here: Code-Bowling.
In golf, you try to get the lowest score (smallest application, mos
/*
* TODO: write manpage
*/
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define ERROR_MAX 2048 /* arbitrary, must account for argv[0] */
#define MSG_SIZE (5+9+1) /* +1 for newline, +1 for NUL */
#if defined(linux) || defined(BSD) && BSD > 199300L
extern char const *__progname;
# define progname __progname
#else
static char *progname;
#endif
typedef enum _Progerr {
IO_ERR = 1,
RND_ERR = 2
} progerr_t;
static const char GREET_START[5] = "Good"; /* XXX move to Makefile? */
static const char *TIMES_OF_DAY[5] = {
"Morning",
"Afternoon",
"Evening",
"Night",
NULL
};
int main()
{
char errbuf[ERROR_MAX];
char msgbuf[MSG_SIZE];
char *slash;
const char **time_of_day;
int fd, rnd;
size_t greet_len;
#ifndef progname
/* we want proper error messages */
progname = argv[0];
if ((slash = strrchr(progname, '/')) != NULL)
progname = slash+1;
#endif
/* get REAL randomness; can't trust rand(3).
* avoid stdio, it's slow. */
#ifdef DEBUG
write(STDERR_FILENO, "getting random data\n", sizeof("getting random data\n")-1);
#endif
if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
if ((fd = open("/dev/random", O_RDONLY)) == -1)
rnd = rand(); /* last resort, for MSYS etc. */
}
if (fd >= 0 && read(fd, &rnd, sizeof(int)) != sizeof(int)) {
close(fd);
goto rngerr;
}
/* higher bits of rand() have better entropy */
assert(sizeof(int) >= 4); /* should be compile-time assert */
rnd = (rnd >> 24) & 0x03;
for (time_of_day = TIMES_OF_DAY; *time_of_day && rnd; time_of_day++, rnd--)
;
if (!time_of_day)
goto rngerr;
sprintf(msgbuf, "%s %s", GREET_START, *time_of_day);
greet_len = strlen(msgbuf);
msgbuf[greet_len] = '\n';
if (write(STDOUT_FILENO, msgbuf, greet_len+1) == -1)
goto write_err;
return 0;
rngerr:
sprintf(errbuf, "%s: cannot get random data\n", progname);
write(STDERR_FILENO, errbuf, strlen(errbuf));
return (int)RND_ERR;
write_err:
sprintf(errbuf, "%s: cannot write to stdout\n", progname);
write(STDERR_FILENO, errbuf, strlen(errbuf));
return (int)IO_ERR;
}
I wrote a tri-lingual frankensource program that can be interpreted with bash, compiled with gcc and interpreted with python without alterations to the code (if interpreted with bash, it invokes itself as C and python to accomplish the task). It also uses the load time of google as a source of random numbers.
#if 0
"""ls" > /dev/null
echo /* >/dev/null
# Save as 'whatever.sh.c' (.sh is negotiable, but .c is a must, lest gcc will cry)
# Run with bash (i.e. bash 'whatever.sh.c')
gcc -std=c99 $0 -o /tmp/codebowling 2>/dev/null
/tmp/codebowling
/tmp/codebowling `python $0`
rm -rf /tmp/codebowling
exit;
echo */ >/dev/null
#endif
#include <stdlib.h>
#include <stdio.h>
char* strings[] = {
"Morning\n", "Evening\n", "Afternoon\n", "Night\n"
};
int main(int argc, char* argv[]) {
if(argc == 1) printf("Good ");
else if(argc == 2) {
int what = atoi(argv[1]);
printf(strings[what]);
}
return EXIT_SUCCESS;
}
#if 0
/*
"""
#*/
from urllib import urlopen
import time, math
t1 = time.time()
str = urlopen('http://www.google.com').read();
t2 = time.time()
dt = t2 - t1;
print int(100+100*math.sin(100000*dt))%4
#endif
I think this set some records in WTF-iness. It's one function that compiles a human-readable assembly into BrainF***, and then another function that interprets it.
Of course, the human-readable assembly is missing some features, so there's some hack-ish insertion of BF code manually. And the code is just generally full of WTFs.
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
public class CodeBowling {
public static void main(String[] args) throws IOException{
//An extended version of BrainF*ck, with a command for jumping a rand(int) to the right
//I've heard that assembly languages always run faster, so this should be really efficient!
String readable="";
readable+="set 0 G\n";
readable+="set 1 o\n";
readable+="set 2 o\n";
readable+="set 3 d\n";
readable+="set 4 _\n";
readable+="set 5 M\n";
readable+="set 9 o\n";
readable+="set 13 r\n";
readable+="set 17 n\n";
readable+="set 21 i\n";
readable+="set 25 n\n";
readable+="set 29 g\n";
readable+="set 6 A\n";
readable+="set 10 f\n";
readable+="set 14 t\n";
readable+="set 18 e\n";
readable+="set 22 r\n";
readable+="set 26 n\n";
readable+="set 30 o\n";
readable+="set 34 o\n";
readable+="set 38 n\n";
readable+="set 7 E\n";
readable+="set 11 v\n";
readable+="set 15 e\n";
readable+="set 19 n\n";
readable+="set 23 i\n";
readable+="set 27 n\n";
readable+="set 31 g\n";
readable+="set 8 N\n";
readable+="set 12 i\n";
readable+="set 16 g\n";
readable+="set 20 h\n";
readable+="set 24 t\n";
//Begin execution.
readable+="print 0\n";
readable+="print 1\n";
readable+="print 2\n";
readable+="print 3\n";
readable+="sub 4 63\n";
readable+="print 4\n";
//VERY IMPORTANT
//JUMP COMMANDS PERMANTENTLY SHIFT THE MEMORY.
//DO NOT FOLLOW THEM BY ANY OTHER COMMANDS.
readable+="rand\n";
readable+="rand\n";
readable+="rand";
String bf=compile(readable);
//Prints out the random greeting; the assembly does not include this function.
//A request has been filed to the other developer to add this feature to the
//compiler ASAP.
bf+=">>>>>[.>>>>]";
execute(bf);
}
static void execute(String program){
InputStream is=null;
try {
is = new ByteArrayInputStream(program.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Scanner scn=new Scanner(is);
List<Character> acceptedChars=Arrays.asList('<','>','.',',','+','-','[',']','J');
int brack=0;
Stack<Integer> brackStack=new Stack<Integer>();
Map<Integer,Integer> brackMap=new HashMap<Integer,Integer>();
int pos=0;
StringBuilder sb=new StringBuilder();
scn.useDelimiter("");
int warnings=0;
while(scn.hasNext()){
char nextChar=scn.next().charAt(0);
if(acceptedChars.contains(nextChar)){
sb.append(nextChar);
if(nextChar=='['){
brack++;
brackStack.push(pos);
}
if(nextChar==']'){
brack--;
brackMap.put(pos, brackStack.peek());
brackMap.put(brackStack.pop(), pos);
}
} else if(warnings<3){
System.out.println("Warning: unrecognized character '"+((nextChar=='\r'||nextChar=='\n')?"newline":nextChar)+"'");
warnings++;
if(warnings==3)
System.out.println("Too many warnings, suppressing output.");
}
pos++;
}
if(brack!=0){
System.out.println("Error: unbalanced brackets.");
System.exit(1);
}
char[] pgrm=sb.toString().toCharArray();
//Begin execution
int Codeloc=0,Memloc=0,lim=pgrm.length;
ArrayList<Integer> mem=new ArrayList<Integer>();
scn=new Scanner(System.in);
scn.useDelimiter("");
while(Codeloc<lim){
try{
switch(pgrm[Codeloc]){
case '+':
mem.set(Memloc,mem.get(Memloc)+1);
break;
case '-':
mem.set(Memloc,mem.get(Memloc)-1);
break;
case '>':
Memloc++;
break;
case '<':
Memloc--;
break;
case '[':
if(mem.get(Memloc)==0){
Codeloc=brackMap.get(Codeloc);
} else {
Codeloc=Codeloc;//0 //brackStack.peek() //Codeloc++;;;
}
break;
case ']':
Codeloc=brackMap.get(Codeloc)-1;
break;
case '.':
System.out.print((char)(int)mem.get(Memloc));
break;
case ',':
mem.set(Memloc,(int)scn.next().charAt(0));
break;
case 'J':
java.util.Random r=new java.util.Random();
Memloc+=r.nextBoolean()?1:0;
}
Codeloc++;
} catch (java.lang.IndexOutOfBoundsException e){
//i++;
//if(i>20){
// System.exit(1);
//}
mem.add(0);
}
}
}
static String compile(String readable) throws IOException{
String program="";
BufferedReader is=null;
try {
is = new BufferedReader((Reader)new StringReader(readable));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Stack continueLoopingWhileNotEqualToZeroLocations=new Stack();
while(is.ready()){
String command=is.readLine();
try{
int a=1/((command==null)?0:1);
} catch (Exception e) {
break;
}
StringTokenizer st=new StringTokenizer(command);
String type=st.nextToken();
if(type.equals("set")){ // "set 4 c" sets memory location 4 to a "c".
Object temp=new Integer(st.nextToken());
int location=(Integer)temp;
for(int i=0;i<location;i++){
program+=">";
}
program+="[-]";
temp=new Character(st.nextToken().charAt(0));
char character=(Character)temp;
for(char i=0;i<character;i++){
program+="+";
}
for(int i=location;i>0;i--){
program+="<";
}
} else if(type.equals("add")){ // "add 4 10" increments memory location 4 by 10.
Object temp=new Integer(st.nextToken());
int location=(Integer)temp;
for(int i=0;i<location;i++){
program+=">";
}
temp=new Integer(st.nextToken());
int diff=(Integer)temp;
for(char i=0;i<diff;i++){
program+="+";
}
for(int i=location;i>0;i--){
program+="<";
}
} else if(type.equals("sub")){ // "sub 4 10" decrements memory location 4 by 10.
Object temp=new Integer(st.nextToken());
int location=(Integer)temp;
for(int i=0;i<location;i++){
program+=">";
}
temp=new Integer(st.nextToken());
int diff=(Integer)temp;
for(char i=0;i<diff;i++){
program+="-";
}
for(int i=location;i>0;i--){
program+="<";
}
} else if(type.equals("addFrom")){ // "addFrom 4 5 7 9" adds the value of location 4 to locations 5, 7, and 9, and erases 4.
Object temp=new Integer(st.nextToken());
int location=(Integer)temp;
for(int i=0;i<location;i++){
program+=">";
}
program+="[-";
int a=location;
int b;
while(st.hasMoreTokens()){
b=Integer.valueOf(st.nextToken());
int diff=b-a;
if(diff>0){
for(int i=0;i<diff;i++){
program+=">";
}
} else {
for(int i=0;i<diff;i++){
program+="<";
}
}
program+="+";
a=b;
}
int diff=location-a;
if(diff>0){
for(int i=0;i<diff;i++){
program+=">";
}
} else {
for(int i=0;i<diff;i++){
program+="<";
}
}
program+="]";
} else if(type.equals("subFrom")){ // "subFrom 4 5 7 9" subtracts the value of location 4 to locations 5, 7, and 9, and erases 4.
Object temp=new Integer(st.nextToken());
int location=(Integer)temp;
for(int i=0;i<location;i++){
program+=">";
}
program+="[-";
int a=location;
int b;
while(st.hasMoreTokens()){
b=Integer.valueOf(st.nextToken());
int diff=b-a;
if(diff>0){
for(int i=0;i<diff;i++){
program+=">";
}
} else {
for(int i=0;i<diff;i++){
program+="<";
}
}
program+="-";
a=b;
}
int diff=location-a;
if(diff>0){
for(int i=0;i<diff;i++){
program+=">";
}
} else {
for(int i=0;i<diff;i++){
program+="<";
}
}
program+="]";
} else if(type.equals("print")){// "print 3" prints the value of 3, cast to a char.
int point=Integer.valueOf(st.nextToken());
for(int i=0;i<point;i++){
program+=">";
}
program+=".";
for(int i=0;i<point;i++){
program+="<";
}
} else if(type.equals("read")){// "read 3" grabs one char from the input, and assigns it to position 3.
int point=Integer.valueOf(st.nextToken());
for(int i=0;i<point;i++){
program+=">";
}
program+=",";
for(int i=0;i<point;i++){
program+="<";
}
} else if(type.equals("while")){//"while 5" will loop as long as 5 is not zero.
int continueLoopingWhileNotEqualToZeroLocation=(Integer)new Integer(st.nextToken());
for(int i=0;i<continueLoopingWhileNotEqualToZeroLocation;i++){
program+=">";
}
program+="[";
for(int i=0;i<continueLoopingWhileNotEqualToZeroLocation;i++){
program+="<";
}
((Stack<Integer>)continueLoopingWhileNotEqualToZeroLocations).push(continueLoopingWhileNotEqualToZeroLocation);
} else if(type.equals("endwhile")){
int l=((Stack<Integer>)continueLoopingWhileNotEqualToZeroLocations).pop();
for(int i=l/2;i<-((l+1)/2);i--){
program+=">";
}
} else if(type.equals("rand")){
program+="J";
} else {
System.out.println("UNRECOGNIZED COMMAND "+type);
int a=1/0; //Kills the program.
}
}
return program;
}
}
This JavaScript piece comes with a text generator:
function cth(i) {
return i > 16 ? cth(i >> 4) + cth(i & 15) : "" + (i < 10 ? i : String.fromCharCode(55 + i))
}
function nc(s) {
return c += s
}
var w = [],
s = [],
c = 0,
t = new Date().getTime()
s[0] = cth(nc(71)) s[1] = cth(nc(40)) s[2] = cth(nc(-11))
s.splice(1, 0, s.slice(1, 2)[0])
w.push(unescape("%" + s.join("%")))
s[0] = cth(nc(-23)) s[2] = cth(nc(37)) s[3] = cth(nc(-4)) s[4] = cth(nc(-5)) s[5] = cth(nc(-2))
s.splice(5, 0, s.slice(3, 4)[0])
w.push(unescape("%" + s.join("%")))
s.splice(0, 3)
s.unshift(cth(nc(-2))) s.unshift(s[s.length - 1].replace(/(.)(.)/, "$2$1")) s.unshift(cth(nc(-32)))
w.push(unescape("%" + s.join("%")))
s = w[0].split(/[^aeiou]/i) s[0] = "After"
s = s.join("n")
w.push(s)
s = String(69676874).replace(/(..)/g, "%$1")
w.push("N" + unescape(s))
t /= c
alert(w[0] + " " + w[1 + (t & 3)])
Yes, this isn't a long code, but it's still pointless to have.
Java+Spring: All interfaces are injectable for unit testing!
package stackoverflow.codebowling;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ByteArrayResource;
import java.io.*;
import java.util.Random;
import java.util.logging.Logger;
public class Main {
/*
TODO: Add javadoc
*/
static public final Logger logger = Logger.getLogger(Main.class.getName());
public static void main(String[] args) throws IOException {
ByteArrayResource byteArrayResource =
new ByteArrayResource(spring_config_xml.getBytes());
XmlBeanFactory beanFactory = new XmlBeanFactory(byteArrayResource);
MessageWriter messageWriter = beanFactory.getBean("MessageWriterBean", MessageWriter.class);
try {
Writer writer = new PrintWriter(System.out);
messageWriter.writeMessage(writer);
writer.flush();
} catch(IOException ex) {
logger.severe(ex.getMessage());
throw ex;
}
}
/*
Using a visitor pattern to avoid casting or case statements.
If you see a case statement your are probably not doing real OOP
*/
static abstract public class TimeOfDay {
public abstract void visit(TimeOfDayVisitor visitor);
static final class Morning extends TimeOfDay {
@Override
public void visit(TimeOfDayVisitor visitor) {
visitor.morning(this);
}
}
static final class Afternoon extends TimeOfDay {
@Override
public void visit(TimeOfDayVisitor visitor) {
visitor.afternoon(this);
}
}
static final class Evening extends TimeOfDay {
@Override
public void visit(TimeOfDayVisitor visitor) {
visitor.evening(this);
}
}
static final class Night extends TimeOfDay {
@Override
public void visit(TimeOfDayVisitor visitor) {
visitor.night(this);
}
}
static public final TimeOfDay[] ALL = {
new Morning(),
new Afternoon(),
new Evening(),
new Night()
};
static public interface TimeOfDayVisitor {
public void morning(TimeOfDay timeOfDay);
public void afternoon(TimeOfDay timeOfDay);
public void evening(TimeOfDay timeOfDay);
public void night(TimeOfDay timeOfDay);
}
}
static public interface MessageWriter {
void writeMessage(Writer writer) throws IOException;
}
static public class MessageWriterImpl implements MessageWriter {
private TimeOfDayChooser timeOfDayChooser;
private TimeOfDayGreetingsFormatter timeOfDayGreetingsFormatter;
public void writeMessage(Writer writer) throws IOException {
TimeOfDay timeOfDay = timeOfDayChooser.choose();
writer.write(timeOfDayGreetingsFormatter.format(timeOfDay));
}
public void setTimeOfDayChooser(TimeOfDayChooser timeOfDayChooser) {
this.timeOfDayChooser = timeOfDayChooser;
}
public void setTimeOfDayGreetingsFormatter(TimeOfDayGreetingsFormatter timeOfDayGreetingsFormatter) {
this.timeOfDayGreetingsFormatter = timeOfDayGreetingsFormatter;
}
}
static public interface TimeOfDayGreetingsFormatter {
String format(TimeOfDay timeOfDay);
}
static public class TimeOfDayGreetingsFormatterImpl implements TimeOfDayGreetingsFormatter {
public String format(TimeOfDay timeOfDay) {
final StringBuilder builder = new StringBuilder();
builder.append("Good ");
timeOfDay.visit(new TimeOfDay.TimeOfDayVisitor() {
public void morning(TimeOfDay timeOfDay) {
builder.append("Morning");
}
public void afternoon(TimeOfDay timeOfDay) {
builder.append("Afternoon");
}
public void evening(TimeOfDay timeOfDay) {
builder.append("Evening");
}
public void night(TimeOfDay timeOfDay) {
builder.append("Night");
}
});
return builder.toString();
}
}
static public interface TimeOfDayChooser {
TimeOfDay choose();
}
static public class RandomTimeOfDayChooserImpl implements TimeOfDayChooser {
// *** injected by Spring
private RandomService randomService;
public synchronized TimeOfDay choose() {
int range = TimeOfDay.ALL.length;
int index = randomService.rand(range);
return TimeOfDay.ALL[index];
}
public void setRandomService(RandomService randomService) {
this.randomService = randomService;
}
}
static public class ChaoticTimeOfDayChooserImpl implements TimeOfDayChooser {
// *** injected by Spring
private RandomService randomService;
// *** this is initialized in the setter for randomService
private int currentIndex;
public synchronized TimeOfDay choose() {
int range = TimeOfDay.ALL.length;
this.currentIndex = this.currentIndex + 1 + randomService.rand(range - 1);
return TimeOfDay.ALL[this.currentIndex];
}
public void setRandomService(RandomService randomService) {
this.randomService = randomService;
int range = TimeOfDay.ALL.length;
this.currentIndex = randomService.rand(range);
}
}
static public interface RandomService {
int rand(int range);
}
static public class RandomServiceImpl implements RandomService {
// *** initialized by Spring
private long seed;
// *** initialized by setSeed
private Random random;
public int rand(int range) {
return (int)(random.nextInt(range));
}
/*
A seed of < 0 indicates a random seed. For testing, set a positive long value
which will guarantee reproducible results.
*/
public void setSeed(long seed) {
this.seed = seed;
if (seed >= 0) {
this.random = new Random(seed);
} else {
this.random = new Random();
}
}
}
static public final String spring_config_xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<beans xmlns=\"http://www.springframework.org/schema/beans\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xmlns:aop=\"http://www.springframework.org/schema/aop\"\n" +
" xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\">\n" +
" <bean id=\"MessageWriterBean\" class=\"stackoverflow.codebowling.Main.MessageWriterImpl\">\n" +
" <property name=\"timeOfDayChooser\" ref=\"RandomTimeOfDayChooserBean\" />\n" +
" <property name=\"timeOfDayGreetingsFormatter\" ref=\"TimeOfDayGreetingsFormatterBean\" />\n" +
" </bean>\n" +
" <bean id=\"RandomTimeOfDayChooserBean\" class=\"stackoverflow.codebowling.Main.RandomTimeOfDayChooserImpl\">\n" +
" <property name=\"randomService\" ref=\"RandomServiceBean\" />\n" +
" </bean>\n" +
" <bean id=\"ChaoticTimeOfDayChooserBean\" class=\"stackoverflow.codebowling.Main.ChaoticTimeOfDayChooserImpl\">\n" +
" <property name=\"randomService\" ref=\"RandomServiceBean\" />\n" +
" </bean>\n" +
" <bean id=\"RandomServiceBean\" class=\"stackoverflow.codebowling.Main.RandomServiceImpl\">\n" +
" <property name=\"seed\" value=\"-1\" />\n" +
" </bean>\n" +
" <bean id=\"TimeOfDayGreetingsFormatterBean\" class=\"stackoverflow.codebowling.Main.TimeOfDayGreetingsFormatterImpl\" />\n" +
"</beans>\n";
}