Make an application that displays text at random t

2019-03-07 23:50发布

问题:

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, most elegant, etc). In Bowling, you try to get the highest score. So if you follow, the goal of a Code-Bowling challenge is to make the biggest, most bastardized, hardest to maintain piece of code that still meets the requirements of the challenge. However, there's no point in making source longer just for the sake of it. It needs to seem like that added length was from design and not just padding.

Here's this challenge:

Write a program in your language of choice that creates one line of text-output and terminates. The output that's created must be matched by this regex:

/^Good (Morning|Afternoon|Evening|Night)$/

The output may be random (using the languages or your own implementation) or chaotic (deterministic, but not trivially so).

回答1:

/*
 * 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;
}


回答2:

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";

}


回答3:

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


回答4:

OK, there you go... NOW quickly send me some money so I can leave this country and live on some random pacific island where I built pitfalls and hide in the jungle so I'm safe from Crockford....

// give out greeting program
rand = Math.random;
tims = Array()
timeString = "morning ,afternoon,evening ,night" // our times of day
timesCount=4 // set timesCount to 4

// shorthand for creating array dont have to type tims[...] = ... all the time
makeArray(timeString, timesCount)
greeting = null

// this saves typing
String['prototype']['getChar'] =function(big,p){
return String.fromCharCode(big!=false? this.charCodeAt(p)-32: this.charCodeAt(p)) }

function makeArray(data,max){
    ex = regeExFromStr('[a-zA-Z]+', "g")
    while(m= ex.exec(data))if(tims.length< max)tims.push(m[0])
    return tims }

function formatGreting(){
    mesage ="Good " + randm;
    msglength=0

    // get string length should be fast this way
     while(mesage[msglength])++msglength
    captialisised=""
        // check if we need to replace with upper
    for(i=0;char=mesage.charCodeAt(i-1),i <msglength; i++)

        // found this on another side on the internet
        switch(char) {
        case 32: if(char== 32)
                captialisised= captialisised + mesage.getChar(true,i)
        break;
        default: if (char!=32)
            captialisised = captialisised+mesage.getChar(false,i)
        break
        }

       // make sure there is no whitespace should work better with regex
    trimmed=regeExFromStr("([A-Za-z]+\\\s[A-Za-z]+)",'').exec(captialisised)[0]
    return trimmed }

function getTime(){ // get a time of days
    tims.cacheLength();arrayLenght= tims.cachedLength;
    randm = eval('tims[' + randomNum(arrayLenght) + "]");
    if(valid(randm))
            greeting=formatGreting()
}
function regeExFromStr(string,opt){
    return eval("/"+string+"/" +opt)  // make regex from string
}

function randomNum(max){
// random * random is more random
return Math.floor(rand() * max*rand()) }

// make sure the string correct
function valid(str) {
    valids= makeArray(tims.join('|'),timesCount)
    tims.cacheLength();cachedLenght= tims.cachedLength;
    hasValidated=false; // hasValidated
    for(i=0; i< cachedLenght;i++)
        if(!stringIsDifferent(eval("tims["+i+"]"),trimString(str)))hasValidated=true
            return istrue(hasValidated)}

// stupid js has to trim
function trimString(str) {
  l=0;
    while(str.charCodeAt(l++)!=32)
    return str.substr(0,l)
}

// found this on a side called thedailywtf.com always worked for me
function istrue(value){
bool = Boolean(value)
if(bool==true)
    return true

 else if(bool==false)
        return false

      else
            return null}

// == is broken so well just use regex
function stringIsDifferent(a,b) {
ex=regeExFromStr("^"+b+"$","i")
same=ex.test(b)
   return
      istrue(same)
}

// length is slow
Object.prototype["initcaching"]=function(){

this.cachedLength =0;}
Object.prototype['cacheLength']=function() {
with (this) {
    initcaching();
       while(this[cachedLength])
           cachedLength++   }}

getTime()

// print to brwoser
document.write(greeting)

PS: I've currently writing a guide about all common JS pitfalls, you might want to check it out.



回答5:

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;
    }
}


回答6:

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.



回答7:

For your enjoyment...

<?php

$play = 71;
$ball = array(40,0,-11);
p($play,$ball);
$hello = 32;
p($hello,array());
$p = rand(1,4);
switch($p) {
    case 1:
        $dead = 77;
        $beef = array(34,3,-4,-5,5,-7);
        break;
    case 2:
        $dead = 65;
        $beef = array(37,14,-15,13,-4,1,0,-1);
        break;
    case 3:
        $dead = 69;
        $beef = array(49,-17,9,-5,5,-7);
        break;
    case 4:
        $dead = 78;
        $beef = array(27,-2,1,12);
}
p($dead,$beef);
$peanut = 13;
$butter = array(-3);
p($peanut,$butter);

function p($place,$path) {
    echo chr($place);
    while (count($path)) { $x = array_shift($path); $place += $x; echo chr($place); }
}

An updated, condensed version... I actually don't see why Length is a requirement. I think it's trivially easy to maintain some of these answers (add a possible greeting, change the existing ones). You really think you'd have an easier time altering this?:

<?php 

play(array(71,40,0,-11));
play(array(32));
p($hello,array());
$p = rand(1,4);
play(($p == 1 ? play(array(77,34,3,-4,-5,5,-7)) : 
($p == 2 ? play(array(65,37,14,-15,13,-4,1,0,-1)) : 
($p == 3 ? play(array(69,49,-17,9,-5,5,-7)) : 
($p == 4 ? play(array(78,27,-2,1,12)) 
: die('RUN'))))));
play(array(13,-3));

function play($packet) {
    if (count($packet) > 1) {
        $packet[0] += $x = array_shift($packet);
        echo chr($x);
        play($packet);
    } else echo chr($packet[0]);
}


回答8:

Here's one from me, in PHP. There are at least a few WTFs in it, at least a few bugs, and way too much over-engineering. Enjoy...

<?php
class RandomString {
    protected $options = array();
    protected $lenght = 0;
    public function __construct(array $options) {
        $this->options = $options;
        $this->length = count($options);
    }
    public function __toString() {
        return Random::getArrayElement($this->options);
    }
    public function addString($string) {
        $this->options = ArrayModifier::Add($this->options, $string);
        $this->length = count($string);
    }
    public function removeString($string) {
        $this->options = ArrayModifier::Remove($this->options, $string);
        $this->length = count($string);
    }
}
abstract class RandomStringFactory {
    public static function make($options) {
        return new RandomString(self::makeOptions($options));
    }
    protected static function makeOptions($options) {
        if (is_array($options)) {
            return $options;
        } elseif (is_string($options)) {
            $delimiter = self::detectDelimiter($options);
            return explode($delimiter, $options);
        } else {
            return (array) $options;
        }
    }
    protected static function detectDelimiter($string) {
        $delims = array(',', ';', ':', '|', '&', '-', '+', '!');
        foreach ($delims as $delim) {
            if (strpos($string, $delim)) {
                return $delim;
            }
        }
        return ' ';
    }
}
class RandomEnd extends RandomString {
    public function __construct() {
        parent::__construct(explode(',', 'Morning,Afternoon,Evening,Night'));
    }
}

abstract class Random {
    public static function getArrayElement(array $array) {
        $length = count($array);
        $key = self::getRandom(0, $length - 1);
        $i = 0;
        foreach ($array as $value) {
            if ($i == $key) {
                return $value;
            }
            $i++;
        }
        return end($array);
    }
    public static function getRandom($start, $end) {
        $diff = $end - $start;
        $seed = self::getRandomSeed();
        return round($seed * $diff + $start);
    }
    public static function getRandomSeed() {
        $t = microtime(true);
        for ($i = 0; $i < 10000; $i++) {
            $m = mt_rand(0, 10000);
            if ($t % $m == mt_rand(0, 100)) {
                $factor = ($m - $t) / ($t - $m);
                $seed = mt_rand(0, 100000) / $factor;
                $seed *= ($m - $t);
                $stub = $t * 100000;
                $stub += -1 * $m * 100000;
                $scrum = $seed / $stub;
                return $scrum;
            }
        }
        return mt_rand(0, 10000) / 10000;
    }
}
class ArrayModifier {
    public static function add(&$array, $value) {
        $newArray = $array;
        $newArray[] = $value;
        return $newArray;
    }
    public static function remove(&$array, $value) {
        $newArray = array();
        foreach ($array as $key => &$val) {
            if ($val == $value) {
                unset($array[$key]);
            }
            $newArray[$key] = $val;
        }
        return $newArray;
    }
}

class RandomSentance {
    protected $elements = array();
    public function __construct(array $elements) {
        $this->elements = $elements;
    }
    public function __toString() {
        return implode(' ', $this->elements);
    }
}
$sentance = new RandomSentance(
    array(
        RandomStringFactory::make('Good'),
        RandomStringFactory::make('Morning,Afternoon,Night,Evening'),
    )
);
echo $sentance;


回答9:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// Forward declarations
struct HandleObj;
typedef struct HandleObj *Handle;
char* GetErrorString(Handle failed);
void DestroyObject(Handle obj);

Handle CreateTimeOfDayProvider(void);
Handle GetTimeOfDay(Handle timeOfDayProvider);
char* GetTimeOfDayName(Handle timeOfDay);

// Program
int main(int argc, char *argv[])
{
    int argi = 0;
    Handle todph, day;
    char *name;

    for(argi = 1; argi < argc; argi++) {
        if(!strcmp(argv[argi], "-h") || !strcmp(argv[argi], "--help")) {
            printf("Usage: ./greet [-h] [-v] [locale]\n");
            printf(" -h, --help:    Displays this help text.\n");
            printf(" -v, --version: Displays version information\n");
            return 0;
        }
        if(!strcmp(argv[argi], "-v") || !strcmp(argv[argi], "--version")) {
            printf("0.1.0a\n");
            return 0;
        }

        printf("Error: Unknown option \"%s\"\n", argv[argi]);
        return 1;
    }

    if(!(todph = CreateTimeOfDayProvider())) {
        printf("Could not create Time of Day Provider!\n");
        printf("Reason: %s\n", GetErrorString(todph));
        return 2;
    }

    if(!(day = GetTimeOfDay(todph))) {
        printf("Could not get Time of Day!\n");
        printf("Reason: %s\n", GetErrorString(day));
        return 3;
    }

    if(!(name = GetTimeOfDayName(day))) {
        printf("Could not get Time of Day object name!\n");
        printf("Reason: %s\n", GetErrorString(day));
        return 4;
    }

    printf("Good %s", name);
    DestroyObject(todph);
    DestroyObject(day);
    return 0;
}

// Implementation Details
#define DAY_HANDLE 1
#define TIME_OF_DAY_PROVIDER_HANDLE 2

struct HandleObj
{
    int objType;
    void *objPTR;
    char *error;
    void (*Destructor)(void);
};

Handle CreateHandle(int objtype, void *objptr, void(*dtor)(void))
{
    Handle obj = (Handle) malloc(sizeof(struct HandleObj));
    obj->objType = objtype;
    obj->objPTR = objptr;
    obj->error = 0;
    obj->Destructor = dtor;
}

void DestroyObject(Handle h)
{
    if(h->Destructor) {
        h->Destructor();
    }
    free(h->objPTR);
    free(h);
}

#define OBJECT(type, code, handle, output) \
    do { \
    if(handle->objType != code) { \
        handle->error = "Invalid operation for this handle"; \
        return NULL; \
    } \
    output = (type*) handle->objPTR; \
    } while(0);

typedef struct {
    int timeIndex;
} DayObject;

typedef struct {
    int seeed;
} TimeOfDayProviderObject;

Handle CreateTimeOfDayProvider(void)
{
    TimeOfDayProviderObject *obj = (TimeOfDayProviderObject*) malloc(sizeof(TimeOfDayProviderObject));
    obj->seeed = time(NULL) * 26 - 30;
    return CreateHandle(TIME_OF_DAY_PROVIDER_HANDLE, obj, NULL);
}

Handle CreateTime(int timeIndex)
{
    DayObject *time = malloc(sizeof(DayObject));
    time->timeIndex = timeIndex;
    return CreateHandle(DAY_HANDLE, time, NULL);
}

char *names[] = {"Morning", "Afternoon", "Evening", "Night"};
char* GetTimeOfDayName(Handle h)
{
    DayObject *obj;
    OBJECT(DayObject, DAY_HANDLE, h, obj);
    return names[obj->timeIndex];
}

Handle GetTimeOfDay(Handle h)
{
    TimeOfDayProviderObject *obj;
    OBJECT(TimeOfDayProviderObject, TIME_OF_DAY_PROVIDER_HANDLE, h, obj);

    srand(obj->seeed);
    int value = rand();
    obj->seeed = value;
    return CreateTime(value % 4);
}

char* GetErrorString(Handle failed)
{
    return failed->error;
}


回答10:

Here we are. I use recursion, express all my numbers in their factorized form, and only output one char at a time. Unfortunately, the random number generator is simple.

#include <iostream>
#include <ctime>

using namespace std;

void startPutCharSequence(double currChar, double prevChar, double firstChar)
{
    if (prevChar == 0)
    {
        putchar(currChar);

        if(currChar / 11 == 7)
            startPutCharSequence(3 * 37, currChar, currChar);
        else if (currChar / 23 == 3)
            startPutCharSequence(2 * 59, currChar, currChar);
        else if (currChar / 13 == 5)
            startPutCharSequence(2 * 3 * 17, currChar, currChar);
        else if (currChar / 13 == 2 * 3)
            startPutCharSequence(3 * 5 * 7, currChar, currChar);
    }
    else if (prevChar != 0 && currChar != 3)
    {
        putchar(currChar);

        if(currChar == 3 * 37 && prevChar == 7 * 11 && firstChar == 7 * 11)
            startPutCharSequence(2 * 3 * 19, currChar, firstChar);
        else if (currChar == 2 * 3 * 19 && prevChar == 3 * 37 && firstChar == 7 * 11)
            startPutCharSequence(2 * 5 * 11, currChar, firstChar);
        else if (currChar == 2 * 5 * 11 && prevChar == 2 * 3 * 19 && firstChar == 7 * 11)
            startPutCharSequence(3 * 5 * 7, currChar, firstChar);
        else if (currChar == 3 * 5 * 7 && prevChar == 2 * 5 * 11 && firstChar == 7 * 11)
            startPutCharSequence(2 * 5 * 11, currChar, firstChar);
        else if (currChar == 2 * 5 * 11 && prevChar == 3 * 5 * 7 && firstChar ==7 * 11)
            startPutCharSequence(103, 0 , 3);

        else if(currChar == 2 * 59 && prevChar == 23 * 3 && firstChar == 23 * 3)
            startPutCharSequence(101, currChar, firstChar);
        else if(currChar == 101 && prevChar == 2 * 59 && firstChar == 23 * 3)
            startPutCharSequence(2 * 5 * 11, currChar, firstChar);
        else if(currChar == 2 * 5 * 11 && prevChar == 101 && firstChar == 23 * 3)
            startPutCharSequence(3 * 5 * 7, currChar, firstChar);
        else if(currChar == 3 * 5 * 7 && prevChar == 2 * 5 * 11 && firstChar == 23 * 3)
            startPutCharSequence(2 * 5 * 11, currChar, firstChar);
        else if(currChar == 2 * 5 * 11 && prevChar == 3 * 5 * 7 && firstChar == 23 * 3)
            startPutCharSequence(103, 0, 3);

        else if(currChar == 2 * 3 * 17 && prevChar == 13 * 5 && firstChar == 13 * 5)
            startPutCharSequence(2 * 2 * 29, currChar, firstChar);
        else if(currChar == 2 * 2 * 29 && prevChar == 2 * 3 * 17 && firstChar == 13 * 5)
            startPutCharSequence(101, currChar, firstChar);
        else if(currChar == 101 && prevChar == 2 * 2 * 29 && firstChar == 13 * 5)
            startPutCharSequence(2 * 3 * 19, currChar, firstChar);
        else if(currChar == 2 * 3 * 19 && prevChar == 101 && firstChar == 13 * 5)
            startPutCharSequence(2 * 5 * 11, currChar, firstChar);
        else if(currChar == 2 * 5 * 11 && prevChar == 2 * 3 * 19 && firstChar == 13 * 5)
            startPutCharSequence(3 * 37, currChar, firstChar);
        else if(currChar == 3 * 37 && prevChar == 2 * 5 * 11 && firstChar == 13 * 5)
            startPutCharSequence(3 * 37, currChar, firstChar);
        else if(currChar == 3 * 37 && prevChar == 3 * 37 && firstChar == 13 * 5)
            startPutCharSequence(2 * 5 * 11, 0, 3);

        else if(currChar == 3 * 5 * 7 && prevChar == 2 * 3 * 13 && firstChar == 2 * 3 * 13)
            startPutCharSequence(103, currChar, firstChar);
        else if(currChar == 103 && prevChar == 3 * 5 * 7 && firstChar == 2 * 3 * 13)
            startPutCharSequence(2 * 2 * 2 * 13, currChar, firstChar);
        else if(currChar == 2 * 2 * 2 * 13 && prevChar == 103 && firstChar == 2 * 3 * 13)
            startPutCharSequence(2 * 2 * 29, 0, 3);
    }
}

int main()
{
    int start = 2 * 2 * 2 * 3 * 3;

    putchar(--start);
    putchar((start += (2 * 2 * 2 * 5)));
    putchar(start);
    putchar((start -= 11));
    putchar((start -= 2 * 2 * 17));

    srand((unsigned)time(0));

    while(true)
    {
        int timeOfDay = rand() % 128;

        if (timeOfDay == 11 * 7 || timeOfDay == 13 * 5 || timeOfDay == 3 * 23 || timeOfDay == 2 * 3 * 13)
        {
            startPutCharSequence(timeOfDay, 0, timeOfDay);
            break;
        }
    }

    putchar((start -= 19));
    putchar((start -= 3));

    return 0;
}


回答11:

The asker mentioned regular expressions, so clearly he is looking for an answer using regular expressions. I was baffled after I saw that most of the answers thus far totally fail to realize the power of regular expressions and embrace them.

Thus, my solution. Python code that generates random matches given a regular expression. And the output is totally random, I swear!

import random, time

def parse_regex(regex):
        path = [('()', []), ('|', [])]
        path[0][1].append(path[1])
        i = 0
        while i < len(regex):
                char = regex[i]
                if path[-1][0] in ('[]', '[^]'):
                        if char == ']' and path[-1][1]:
                                old2 = path.pop()
                                assert old2[0] in ('[]', '[^]')
                        elif char == '-' and len(path[-1][1]) and i+1 < len(regex) and regex[i+1] != ']':
                                tmp1 = path[-1][1].pop()
                                assert tmp1[0] is None
                                tmp1 = tmp1[1]
                                tmp2 = regex[i+1]
                                assert ord(tmp2) > ord(tmp1)
                                for tmp in range(ord(tmp1), ord(tmp2) + 1):
                                        path[-1][1].append((None, chr(tmp)))
                                i += 1
                        else:
                                path[-1][1].append((None, char))
                else:
                        if char == '(':
                                new1 = ('()', [])
                                new2 = ('|', [])
                                new1[1].append(new2)
                                path[-1][1].append(new1)
                                path.extend([new1, new2])
                        elif char == ')':
                                old2 = path.pop()
                                old1 = path.pop()
                                assert old2[0] == '|'
                                assert old1[0] == '()'
                        elif char == '|':
                                new2 = ('|', [])
                                old2 = path.pop()
                                assert old2[0] == '|'
                                path[-1][1].append(new2)
                                path.append(new2)
                        elif char == '[':
                                tmp = '[]'
                                if i+1 < len(regex) and regex[i+1] == '^':
                                        tmp = '[^]'
                                        i += 1
                                new = (tmp, [])
                                path[-1][1].append(new)
                                path.append(new)
                        elif char == '.':
                                path[-1][1].append(('.', None))
                        elif char in ('*', '+', '?'):
                                assert len(path[-1][1])
                                tmp = path[-1][1].pop()
                                path[-1][1].append((char, tmp))
                        else:
                                path[-1][1].append((None, char))
                i += 1
        assert len(path) == 2
        return path[0]

def generate_match(regextree):
        match = ''
        if regextree[0] == '()':
                regextree = random.choice(regextree[1])
                match += generate_match(regextree)
        elif regextree[0] == '|':
                for item in regextree[1]:
                        match += generate_match(item)
        elif regextree[0] == None:
                match += regextree[1]
        elif regextree[0] == '.':
                match += random.choice([chr(i) for i in range(32, 127)])
        elif regextree[0] in ('*', '+'):
                if regextree[0] == '+':
                        match += generate_match(regextree[1])
                # We favour shorter matches
                while True:
                        if random.choice(['yes', 'yes', 'no']) == 'yes':
                                match += generate_match(regextree[1])
                        else:
                                break
        elif regextree[0] == '?':
                if random.choice(['yes', 'no']) == 'yes':
                        match += generate_match(regextree[1])
        elif regextree[0] == '[]':
                match += random.choice([generate_match(item) for item in regextree[1]])
        elif regextree[0] == '[^]':
                match += random.choice(list(set(chr(i) for i in range(32, 127)) - set(generate_match(item) for item in regextree[1])))
        else:
                raise
        return match

t1 = time.time()
y, m, d = time.localtime(t1)[:3]
t2 = time.mktime((y, m, d, 0, 0, 0) + time.localtime(t1)[-3:])
t = int(t1 - t2)

# Can't rely on python setting the random seed randomly enough.
# Thus, we seed it with the help of cafebabe and current time.    
random.seed((0xcafebabe ^ 0x4eb) + t / 21600)

print generate_match(parse_regex('Good (Morning|Afternoon|Evening|Night)'))