title: Generate an understandable sentence

text:
# Question
Title: Generate an understandable sentence
**Problem:**

Generate a sentence that can be read and understood. It must contain a subject, verb, and object, and tenses and plurals must match. The program must also be able to generate several different sentences to qualify.

**Rules:**

* Hard-coding the sentences is not permitted, and nor is reading them directly from a file (i'm looking at you, unclemeat)
* You can have any number of word lists
* Submit an example sentence or 2 that have been generated by your program
* Any language is accepted
* It's a , so the most upvoted answer wins

# Answer
# Bash

```
fgrep '/* ' /usr/src/linux* -r | cut -d '*' -f 2 | head -$((RANDOM)) | tail -1

```

Requirements: linux kernel source installed in /usr/src

This pulls random comments out of the kernel source. Whether the sentences are actually **understandable** is open to debate.

Examples of actual output:

* `end of packet for rx`
* `I don't know what to do`
* `256 byte packet data buffer.`
* `The rest of this junk is to help gdb figure out what goes where`
* `Convert page list back to physical addresses, what a mess.`
* `???`
* `Only Sun can take such nice parts and fuck up the programming interface`
> 90 votes

# Answer
## Matlab

```
why

```

example of outputs:

```
>> why
The programmer suggested it.
>> why
To please a very terrified and smart and tall engineer.
>> why
The tall system manager obeyed some engineer.
>> why
He wanted it that way.

```

\[This is one of Matlab's easter eggs\]

**EDIT:** you can see the code of this function here: why.m
> 102 votes

# Answer
# PHP

Given enough time, this will produce all literature, past, present and future. *The rules didn't mention that no other text may be produced.*

The string `'TOS...'` provides a logarithmic scale frequency of the letters to more closely match English. This is used to generate a larger string with the approximate relative letter frequencies.

```
$a = ord('A');
$s = '';

foreach (str_split('TOSRWQPPUALRQTTRGUUUQMMLMFZ') as $i=>$f)
{
    if (!ctype_alpha($c = chr($a + $i)))
        $c = ' ';
    $s .= str_repeat($c, round(exp((ord($f) - $a) / 3.976)));
}

$l = strlen($s) - 1;
for (;;)
    echo substr($s, mt_rand(0, $l), 1);

```

Running it, I have discovered such literary gems as:

* `GO NOW` \- *You* as a subject is implied.
* `IM AOK` \- I'm A-OK
* `IM FDR` \- I'm F(ranklin) D(eleano) R(oosevelt)

Also, numerous invectives to concisely express displeasure with the current situation. \[Some letters redacted.\]

* `F**K`
* `S**T`

As well, the following using the fine-tuned scaling:

* `IS IT ON`
* `I AM STU`
* `I SEE HTML`
> 51 votes

# Answer
# C

```
char*strerror(),i;main(){for(;--i;)puts(strerror(i));}

```

Example output:

> Software caused connection abort
> Interrupted system call should be restarted

There are also plenty of valid sentences output that do not have a subject, verb and object:

> Timer expired
> File exists
> 43 votes

# Answer
# Java

Pulls the intro sentence from a random Wikipedia article:

```
import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

public class RandomSentence {
    public static void main (String[] args) throws Exception {
        String sentence;
        do {
            InputStream in = new URL("https://en.wikipedia.org/wiki/Special:Random").openStream();
            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);
            String intro = doc.getElementsByTagName("p").item(0).getTextContent();
            sentence = intro.replaceAll("\\([^(]*\\) *", "").replaceAll("\\[[^\\[]*\\]", "").split("\\.( +[A-Z0-9]|$)")[0];
        } while (sentence.endsWith(":") || sentence.length() < 30 || sentence.contains("?"));
        System.out.println(sentence + ".");
    }
}

```

Sometimes you get unlucky; I try to minimize this by setting a minimum sentence length and filtering out sentences that end with ":" (all disambiguation pages start that way) or contain a "?" (there seem to be many articles with unresolved unknown info marked by question marks). Sentence boundaries are a period followed by whitespace followed by a number or capital letter.

I also filter out text in parentheses (the result is still a valid sentence) to try and remove some periods that aren't sentence boundaries. I filter out square braces to remove source citation numbers. Examples:

> * Idle Cure was an arena rock band from Long Beach, California.
> * Self-focusing is a non-linear optical process induced by the change in refractive index of materials exposed to intense electromagnetic radiation.
> * TB10Cs4H3 is a member of the H/ACA-like class of non-coding RNA molecule that guide the sites of modification of uridines to pseudouridines of substrate RNAs.
> * The Six-headed Wild Ram in Sumerian mythology was one of the Heroes slain by Ninurta, patron god of Lagash, in ancient Iraq.
> * Sugar daddy is a slang term for a man who offers to support a typically younger woman or man after establishing a relationship that is usually sexual.
> * Old Bethel United Methodist Church is located at 222 Calhoun St., Charleston, South Carolina.
> * Douglas Geers is an American composer.

If you notice any grammar issues, well, that's your fault for not being a diligent Wikipedia editor! ;-)
> 37 votes

# Answer
Soooo... Since this is , I had some fun with `eval` and with functions. Basically I generate a random number and then execute a random function based on that number (in your face, `switch`!) via `eval`.

# PHP, ~9k valid outputs

```
<?php

//Subjects
function s1(){ echo "I "; $m = rand(1,20); eval ("v".$m."(0);");}
function s2(){ echo "You "; $m = rand(1,20); eval ("v".$m."(0);");}
function s3(){ echo "He "; $m = rand(1,20); eval ("v".$m."(1);");}
function s4(){ echo "She "; $m = rand(1,20); eval ("v".$m."(1);");}
function s5(){ echo "We "; $m = rand(1,20); eval ("v".$m."(0);");}
function s6(){ echo "They "; $m = rand(1,20); eval ("v".$m."(0);");}

//Verbs
function v1($n){ echo "want"; if($n==1)echo"s"; echo " to "; $z = rand(1,10); eval ("a".$z."();");}
function v2($n){ echo "need"; if($n==1)echo"s"; echo " to "; $z = rand(1,10); eval ("a".$z."();");}
function v3($n){ echo "ha"; if($n==1){echo"s";}else{echo"ve";} echo " to "; $z = rand(1,10); eval ("a".$z."();");}
function v4($n){ echo "wanted to "; $z = rand(1,10); eval ("a".$z."();");}
function v5($n){ echo "needed to "; $z = rand(1,10); eval ("a".$z."();");}
function v6($n){ echo "had to "; $z = rand(1,10); eval ("a".$z."();");}
function v7($n){ echo "eat"; if($n==1)echo"s"; echo " "; $w = rand(1,20); eval ("o".$w."();");}
function v8($n){ echo "think"; if($n==1)echo"s"; echo " about "; $w = rand(1,20); eval ("o".$w."();");}
function v9($n){ echo "ate "; $w = rand(1,20); eval ("o".$w."();");}
function v10($n){ echo "thought about "; $w = rand(1,20); eval ("o".$w."();");}
function v11($n){ echo "draw"; if($n==1)echo"s"; echo " "; $w = rand(1,20); eval ("o".$w."();");}
function v12($n){ echo "drew "; $w = rand(1,20); eval ("o".$w."();");}
function v13($n){ echo "smell"; if($n==1)echo"s"; echo " like "; $w = rand(1,20); eval ("o".$w."();");}
function v14($n){ echo "shot "; $w = rand(1,20); eval ("o".$w."();");}
function v15($n){ echo "destroy"; if($n==1)echo"s"; echo " "; $w = rand(1,20); eval ("o".$w."();");}
function v16($n){ echo "destroyed "; $w = rand(1,20); eval ("o".$w."();");}
function v17($n){ echo "melt"; if($n==1)echo"s"; echo " "; $w = rand(1,20); eval ("o".$w."();");}
function v18($n){ echo "saw "; $w = rand(1,20); eval ("o".$w."();");}
function v19($n){ echo "ha"; if($n==1){echo"s";}else{echo"ve";} echo " "; $w = rand(1,20); eval ("o".$w."();");}
function v20($n){ echo "had "; $w = rand(1,20); eval ("o".$w."();");}

//Auxiliaries
function a1(){ echo "punch "; $w = rand(1,20); eval ("o".$w."();");}
function a2(){ echo "drive "; $w = rand(1,20); eval ("o".$w."();");}
function a3(){ echo "mount "; $w = rand(1,20); eval ("o".$w."();");}
function a4(){ echo "see "; $w = rand(1,20); eval ("o".$w."();");}
function a5(){ echo "have "; $w = rand(1,20); eval ("o".$w."();");}
function a6(){ echo "eat "; $w = rand(1,20); eval ("o".$w."();");}
function a7(){ echo "stun "; $w = rand(1,20); eval ("o".$w."();");}
function a8(){ echo "kiss "; $w = rand(1,20); eval ("o".$w."();");}
function a9(){ echo "Ted "; $w = rand(1,20); eval ("o".$w."();");} //See "How I met Your Mother" for further informations :)
function a10(){ echo "blow "; $w = rand(1,20); eval ("o".$w."();");}

//Objects
function o1(){ echo "a cow!<br>";}
function o2(){ echo "a meatball!<br>";}
function o3(){ echo "a car!<br>";}
function o4(){ echo "shoes!<br>";}
function o5(){ echo "pigs!<br>";}
function o6(){ echo "a telephone!<br>";}
function o7(){ echo "some bottles of water!<br>";}
function o8(){ echo "a laptop!<br>";}
function o9(){ echo "my shorts!<br>";} //Quote needed
function o10(){ echo "anchovies!<br>";}
function o11(){ echo "an alarm clock!<br>";}
function o12(){ echo "every second!<br>";}
function o13(){ echo "until the end!<br>";}
function o14(){ echo "sitting!<br>";}
function o15(){ echo "a sword!<br>";}
function o16(){ echo "fire!<br>";}
function o17(){ echo "the dust!<br>";}
function o18(){ echo "in the bedroom!<br>";}
function o19(){ echo "a poor ant!<br>";}
function o20(){ echo "a pencil!<br>";}

//Testing
$n = rand(1,6); eval ("s".$n."();");
$n = rand(1,6); eval ("s".$n."();");
$n = rand(1,6); eval ("s".$n."();");
$n = rand(1,6); eval ("s".$n."();");

?>

```

**Some outputs...**

```
She draws a sword!
They thought about sitting!
You eat my shorts!
He wanted to Ted a cow!
You want to mount a poor ant!
She smells like anchovies!
He wanted to have shoes!
They wanted to see a pencil!

```
> 34 votes

# Answer
# PHP + Project Gutenberg

I wrote a PHP script that turns a plain text document into a set of word bigrams, which it then uses to generate random sentences. Here are some of the better examples it generated from the entire plain text version of Patrick Henry's "Give Me Liberty Or Give Me Death" speech, including the Project Gutenberg small print:

> * The Project Gutenberg Etext of nations, and slavery!
> * We apologize for the 200th anniversary of this Small Print!
> * YOU DON'T HAVE NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR INCIDENTAL DAMAGES, But for me, death!

You can try it out for yourself here. Refresh the page for a new batch of sentences.

If you want to run the source code yourself, don't forget to load `$src_text` with your chosen plain text.

```
<html>
<head>
<title>Give Me Liberty Or Give Me Death</title>
<style>
body { margin:4em 6em; text-align:center; background-color:#feb; }
h1 { font-weight:normal; font-size:2em; margin-bottom:2em; }
blockquote { font-style:italic; }
</style>
</head>
<body>
<h1>A collection of quotes randomly generated from Patrick Henry's speech
<a href="http://www.gutenberg.org/ebooks/6">Give Me Liberty Or Give Me Death</a>
(and its accompanying Project Gutenberg blurb).</h1>
<?php

/* Give Me Liberty Or Give Me Death */
/* Plain text available from http://www.gutenberg.org/ebooks/6 */
$src_text = file_get_contents('libertyordeath.txt');

$bigrams = array();
$openers = array();
$loc = 0;
$new_sentence = true;
$last = false;
while (preg_match('/\'?\w+[^\s\[\]\*\(\)"#@]*/',$src_text,$matches,PREG_OFFSET_CAPTURE,$loc)) {
  $w = $matches[0][0];
  $loc = $matches[0][1]+strlen($w);
  $bareword = preg_replace('/\W/','',$w);
  if ($last) {
    if (!isset($bigrams[$last][$w])) $bigrams[$last][$w] = 1;
    else $bigrams[$last][$w]++;
  }
  if (!isset($bigrams[$bareword])) $bigrams[$bareword] = array();
  $last = $bareword;
  if ($new_sentence && preg_match('/^[A-Z]/',$w)) {
    if (!isset($openers[$w])) $openers[$w] = 1;
    else $openers[$w]++;
    $new_sentence = false;
  }
  if (ends_sentence($w)) {
    $new_sentence = true;
    $last = false;
  }
}

/* Now generate ten random sentences */

for ($ns=0; $ns<10; $ns++) {

  echo "<blockquote><p>";

  /* Choose a starting word */

  $sum = 0;
  foreach ($openers as $w=>$c) $sum += $c;
  $r = mt_rand(0,$sum);
  foreach ($openers as $w=>$c) {
    $r -= $c;
    if ($r<=0) break;
  }

  /* Barf out additional words until end of sentence reached */

  while(1) {
    echo "$w ";
    if (ends_sentence($w)) break;
    $bareword = preg_replace('/\W/','',$w);
    $sum = 0;
    foreach ($bigrams[$bareword] as $w=>$c) $sum += $c;
    $r = mt_rand(0,$sum);
    foreach ($bigrams[$bareword] as $w=>$c) {
      $r -= $c;
      if ($r<=0) break;
    }
  }

  echo "</p></blockquote>\n";
}

function ends_sentence($w) {
  if (!preg_match('/[\.\?!]$/',$w)) return false;
  if (preg_match('/^(\w|St|Mr|Ms|Mrs|Messrs|i\.e|e\.g|etc|Rd)\./i',$w)) return false;
  return true;
}

?>
</body>
</html>

```
> 33 votes

# Answer
**Python**

This entry selects words from whole system dictionary. It takes advantage of the fact that you can make most nouns into verbs and vice-versa. It uses a few heuristics to classify words and avoid obvious impossibilities.

It produces a few nearly sane statements:

```
The snigger westernizes the bacteriologist.
A drizzle stoked the sentiments.

```

Many insane ones:

```
Tipper's orthopaedic knitwear plates a payroll.
A fibula teletypewritered a yogi.
The protozoan's spiralling skydive coats this veterinarian

```

And a lot of stuff that sounds like Monty Python making lewd innuendos:

```
That rolling indictment tarries some bang's bulge.
Some inflammatory tush's intermarriage sextants some postman.
Some pentagon's manufacturer squeaked the wolverine.
A disagreeable participant is entertaining my optimized spoonful.

```

Version 3 has been modified to take any text file as input:

```
$ man python | python words.py
The disabled comma-separated source is using those wizards at exit.
$ cat COPYING | python words.py  #GPL
My user accord actions a gnu of software.
$ cat pg2591.txt | python words.py #Grimm's Fairy Tales
Some bargain receives my threepence.
Any wrong worms your world.
$ cat words.py | python words.py #self reflection
Your filter_possesive not_nouned those prepositions.
$ ls /usr/bin | python words.py  #directory lists
Their dropbox funziped an arch.

```

Code *(version 3)*:

```
import random
import string
import sys
import re

#words = open("/usr/share/dict/words").readlines()
words = re.sub("[]:;.,:?!<>{}()|=\"`[]",' ',sys.stdin.read(),flags=re.M).split()
words = list(set(words))

articles=('','a ','the ','some ','this ','that ','my ','any ','your ','their ',
             'all ','more '
             'an ') #an must be last
pl_articles=('','some ','those ','many ','the ','these ')
prepositions = ('of','by','to','for','from','in','with','on','which','when','at',
                     'into','as','if','near')
conjunctions = ('and','or','but')
verbs = ('is','are','was', 'be','do','came','been','had','have')
pronouns_s = ('he','she','it','we','you')
pronouns_o = ('him','her','them')

possesive=False
modifiers=0
use_prep = None

MAX_MODIFIERS=2

def is_modifier(w):
    return ("'" in w or
        w[-2:] in ('ry','ed','er','ic','al')  or
        w[-3:] in ('ing','est','ble','ous') or
        w[-4:] in ('less','ical','mmon') )

def is_verb(w):
    return (w in verbs or
        w[-2:] in ('ed',) or
        w[-3:] in ('ing','ize') )

def is_article(w):
    return w+' ' in articles or w+' ' in pl_articles

def is_conjunction(w):
    return w in conjunctions

def filter_possesive(w,always=False):
    global possesive
    #allow only one
    result = True if "'" in w else False
    if result:
        if always: return False
        if not possesive:
            possesive = True
            return False
    return result

def is_preposition(w):
    global use_prep
    if w in prepositions:
        use_prep = w
        return True
    return False

def is_adverb(w):
    return w[-2:]=='ly'

def is_gerund(w):
    return w[-3:]=='ing'

def is_plural(w):
    return w[-1]=='s'

def not_verb(w):
    return (w in ('you','they','our','yes') or
              w[-4:] in ('ness','such') or
              w in pronouns_o or w in pronouns_s
              )

def not_noun(w):
    return (w in verbs)

def getword():
    while True:
        w=words[random.randrange(len(words))].rstrip()
        if w[0] in string.ascii_uppercase: continue
        if is_article(w) or is_preposition(w):  continue
        if filter_possesive(w): continue
        #print w
        return w

def get_article():
    return articles[random.randrange(len(articles)-1)]

#print '--s--'
substr=''
conjunction = False
while True:
    w=getword()
    if is_modifier(w):
        if modifiers < MAX_MODIFIERS:
            substr+=w+' '
            modifiers+=1
        else: continue
    elif is_adverb(w) or is_plural(w) or not_noun(w): continue
    else:
        if is_conjunction(w):
            conjunction = w
            continue
        substr= substr+w+' '
        if conjunction:
            substr+=conjunction+' '
            conjunction = False
            continue
        if w in pronouns_s:
            substr = w+' '
            art=''
        else:
            art = get_article()
            if art is 'a ' and substr[0] in 'aeiou': art='an '
        substr= string.capwords(art+substr,'.')
        break

#print '--v--'
verbstr=''
while True:
    w=getword()
    if not_verb(w) or filter_possesive(w,True): continue
    elif is_adverb(w): verbstr+=w+' '
    elif is_gerund(w):
        verbstr+='is '+w+' '
        break
    elif is_verb(w):
        verbstr= verbstr+w+' '
        break
    elif is_modifier(w) or is_conjunction(w): continue
    else:
        if not is_plural(w):
            w=w+'ed' if w[-1]!='e' else w+'d'
        verbstr= verbstr+w+' '
        break

#print '--o--'
obstr=''
conjunction = False
while True:
    w=getword()
    if is_modifier(w):
        if modifiers<MAX_MODIFIERS:
            obstr+=w+' '
            modifiers+=1
        else: continue
    elif is_adverb(w) or not_noun(w) or w in pronouns_s: continue
    else:
        if is_conjunction(w):
            conjunction = w
            continue
        obstr = obstr+w
        if conjunction:
            obstr+=' '+conjunction+' '
            conjunction = False
            continue
        if is_plural(w):
            art = pl_articles[random.randrange(len(pl_articles))]
        else:
            art = articles[random.randrange(len(articles)-1)]
            if art is 'a ' and obstr[0] in 'aeiou': art='an '
        if w in pronouns_o:
            obstr=w
        else:
            obstr= art+obstr
        break

#print '--p--'
while use_prep:
    w=getword()
    if (is_modifier(w) or is_preposition(w) or
         is_gerund(w) or not_noun(w) or is_conjunction(w)):
        continue
    obstr+=' '+use_prep+' '+w
    use_prep=None

print substr+verbstr+obstr+'.'

```
> 29 votes

# Answer
## Bash

Inspired by the Matlab answer. Assumes you have `aptitude` installed.

```
r=$[ RANDOM % 7 ]
a=''
for i in `seq $r`; do a=$a'v'; done
if [ $r -ne 0 ]; then a='-'$a; fi
aptitude $a moo

```

Possible outputs (screenshot from this wikipedia article)
> 25 votes

# Answer
# Python:

```
import random
l = ['Buffalo']
while random.randint(0,5) > 0:
    l.append('buffalo')
print ' '.join(l) + '.'

```

## Samples:

* Buffalo buffalo buffalo.
* Buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo.

Unfortunately, it has somewhat poor handling of punctuation and capitalization, but then again those weren't listed as requirements.

Also, here is a reference.
> 24 votes

# Answer
## Rust + Toki Pona

Any language is accepted, so I wrote a program in Rust that generates some sentences in Toki Pona.

Toki Pona is an attempt to create a minimal natural language, and it has a super simple and regular grammar. That's a very useful property for this contest!

```
use std::rand;

#[deriving(Rand)]
struct Phrase { a: Option<~GNominal>, b: ~Sujet, c: ~Predicat }

#[deriving(Rand)]
enum Sujet { A(~GNominal), B(~SCompose) }

#[deriving(Rand)]
enum Predicat { C(~GVerbal), D(~PCompose) }

#[deriving(Rand)]
struct SCompose { a: ~Sujet, b: ~Sujet }

#[deriving(Rand)]
struct PCompose { a: ~Predicat, b: ~Predicat }

#[deriving(Rand)]
struct GNominal { a: ~nom::Nom, b: Multi<~adjectif::Adjectif> }

#[deriving(Rand)]
struct GVerbal { a: ~verbe::Verbe, b: Multi<~adjectif::Adjectif>, c: Multi<~ODirect> }

#[deriving(Rand)]
struct ODirect { a: ~GNominal}

#[deriving(Rand)]
enum Multi<T> { Zero, One(T), Two((T,T)) }

mod nom {
    #[deriving(Rand)]
    #[deriving(ToStr)]
    pub enum Nom {akesi,ala,ale,anpa,ante,ijo,ike,ilo,insa,jaki,jan,jo,kala,kalama,kama,kasi,ken,kili,kiwen,ko,kon,kule,kulupu,lape,lawa,len,lete,linja,lipu,luka,lupa,ma,mama,mani,meli,mi,mije,moku,moli,monsi,mun,musi,mute,nanpa,nasin,nena,nimi,noka,oko,olin,ona,pakala,pali,palisa,pana,pilin,pimeja,pini,pipi,poka,poki,pona,seli,selo,sewi,sijelo,sike,sina,sinpin,sitelen,sona,soweli,suli,suno,supa,suwi,tan,tawa,telo,tenpo,toki,tomo,tu,unpa,uta,utala,walo,wan,waso,wawa,weka,wile}
}

mod verbe {
    #[deriving(Rand)]
    #[deriving(ToStr)]
    pub enum Verbe {ante,awen,ijo,ike,jaki,jan,jo,kalama,kama,ken,kepeken,kule,kute,lape,lawa,lete,lili,lon,lukin,moku,moli,musi,mute,nasa,olin,open,pakala,pali,pana,pilin,pimeja,pini,pona,seli,sin,sitelen,sona,suli,suwi,tawa,telo,toki,tu,unpa,utala,wan,wawa,weka,wile,}
}

mod adjectif {
    #[deriving(Rand)]
    #[deriving(ToStr)]
    pub enum Adjectif {ala,ale,anpa,ante,awen,ike,insa,jaki,jan,jelo,kama,kin,kiwen,kon,kule,kute,kulupu,lape,laso,lawa,lete,lili,linja,loje,luka,lukin,mama,meli,mi,mije,moli,monsi,mun,musi,mute,nasa,ni,olin,ona,pali,pimeja,pini,poka,pona,sama,seli,sewi,sike,sin,sina,suli,suwi,taso,tawa,toki,tomo,unpa,uta,walo,wan,wawa,weka,wile,}
}

impl ToStr for Phrase {
    fn to_str(&self) -> ~str {
        self.a.as_ref().map_or(~"", |g| format!("{:s} la ", g.to_str()))
        + format!("{:s} li {:s}", self.b.to_str(), self.c.to_str())
    }
}

impl ToStr for Sujet {
    fn to_str(&self) -> ~str {
        match *self {
            A(ref v) => v.to_str(),
            B(ref v) => v.to_str(),
        }
    }
}

impl ToStr for Predicat {
    fn to_str(&self) -> ~str {
        match *self {
            C(ref v) => v.to_str(),
            D(ref v) => v.to_str(),
        }
    }
}

impl ToStr for SCompose {
    fn to_str(&self) -> ~str {
        format!("{:s} en {:s}", self.a.to_str(), self.b.to_str())
    }
}

impl ToStr for PCompose {
    fn to_str(&self) -> ~str {
        format!("{:s} li {:s}", self.a.to_str(), self.b.to_str())
    }
}

impl ToStr for GNominal {
    fn to_str(&self) -> ~str {
        format!("{:s} {:s}", self.a.to_str(), self.b.to_str())
    }
}

impl ToStr for GVerbal {
    fn to_str(&self) -> ~str {
        format!("{:s} {:s} {:s}", self.a.to_str(), self.b.to_str(), self.c.to_str())
    }
}

impl ToStr for ODirect {
    fn to_str(&self) -> ~str {
        format!("e {:s}", self.a.to_str())
    }
}

impl<T: ToStr> ToStr for Multi<~T> {
    fn to_str(&self) -> ~str {
        match *self {
            Zero => ~"",
            One(ref v) => v.to_str(),
            Two((ref v,ref w)) => format!("{:s} {:s}", v.to_str(), w.to_str()),
        }
    }
}

fn main() {
    let phrase = rand::random::<Phrase>();
    println!("{:s}\n{:?}", phrase.to_str(), phrase);
}

```

I don't speak Toki Pona, but I found the syntax of Toki Pona as a set of BNF rules on Wikipedia. I created one struct or enum for each BNF rule, and I annotated them with `deriving(Rand)`, which gives me a way to generate a random `Phrase` struct for free! Then, I implemented `ToStr` for each of these structs to convert them to a string.

I intentionnaly left the struct names in french, because the BNF rules I found are in french, and also because it reinfoces the multilingual nature of my submission!

## Sample outputs

Some outputs and their translations, that I did based on the BNF rules and a Toki Pona dictionary. I'm sure these translations are mostly wrong, but Toki Pona actually leaves a lot of room for the interpretation of a sentence.

> nasin mi tawa la jan li jaki

*While on my trip, someone polluted*

> monsi li jaki li jan ike musi

*The butt is dirty and is a funny bad person*

> sina li tawa ale jelo e kili tawa e insa

*You moved the fruit and the center to the yellow universe*

## Issues

* I don't check if a verb is transitive or not, thus some sentences are grammatically incorrect.
* Some structs are recursive, and when a rule can be repeated I randomly choose to output 0, 1 or 2 elements. This can lead to veeeeeery long generated sentences, containing thousands of words...
* I cannot really verify the validity of the output, I rely entirely on the BNF syntax, the dictionary, and my own wild guesses :)
> 16 votes

# Answer
# Python

```
import this

```

```
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

```
> 14 votes

# Answer
## Prolog

Use prolog's backtracking and a generative grammar approximating English grammar to generate *all* possible sentences.

This version has a fairly limited vocabulary and sentence structure, but it should be pretty easy to extend.

The code:

```
% Define the vocabulary
verb(V) :- V = 'eats' | V = 'fights' | V = 'finds'.
subj_pronoun(P) :- P = 'he' | P = 'she' | P = 'it'.
obj_pronoun(P) :- P = 'him' | P = 'her' | P = 'it'.
name(N) :- N = 'alice' | N = 'bob'.
noun(N) :- N = 'cat' | N = 'door' | N = 'pen'.
article(H) :- H = 'the' | H = 'a'.

% Grammar
subject_phrase_short(H) :- subj_pronoun(H)
                         | name(H).
% Subordinate clause. Don't use verb_phrase here to avoid recursive clauses.
sub_clause([Which, Verb|T], Rest) :- Which = 'which', verb(Verb),
                                     object_noun_phrase_short(T, Rest).
subject_phrase([H|T], Rest) :- subject_phrase_short(H), Rest = T.
object_noun_phrase_short([A, N | T], Rest) :- article(A), noun(N), Rest = T
                                            | obj_pronoun(A), Rest = [N|T].
object_phrase(L, Rest) :- object_noun_phrase_short(L, Rest)
                        | object_noun_phrase_short(L, Rest1), sub_clause(Rest1, Rest).
verb_phrase([H|T], Rest) :- verb(H), object_phrase(T, Rest).
sentence(S) :- subject_phrase(S, Rest), verb_phrase(Rest, []).

```

Run this query:

```
sentence(L).

```

to generate all possible sentences in this language.

Some sample outputs:

```
L = [he, eats, the, cat] ;
L = [she, finds, a, door] ;
L = [alice, fights, the, door] ;
L = [he, fights, the, cat, which, eats, the, pen] ;
L = [alice, eats, him, which, finds, the, cat] ;

```

(EDIT: Allow object subordinate clauses).
> 14 votes

# Answer
# Python

As you know, you can do anything in python with few `import`s. This simple task can be accomplished with this 2 lines python script.

```
import random

print ("I like the number "+str(random.uniform(0,1)))

```

The number of sentences generated by this script is quate huge: `10^12` different sentences. If reading a sentece takes you ~0.5 sec, then reading them all will take more than 15000 years!

Some sample sentences:

* `I like the number 0.444371877853`
* `I like the number 0.358614422548`

Yet all the generated sentences contains a subject, a verb and an object.

UPDATE:

I received some critiques about some sophisticated words that this complex tool may produce. Here is a slightly longer version which should be in agreement with most of the wordlists.

```
import random

print ('I like the number'+''.join([' '+{'0':'zero','.':'point','1':'one','2':'two','3':'three','4':'four','5':'five','6':'six','7':'seven','8':'eight','9':'nine'}[digit] for digit in str(random.uniform(0,1))])+'.')

```

Here are some sample sentences:

* `I like the number zero point six three five nine zero eight one five eight four two four.`
* `I like the number zero point four nine zero eight four four three two zero six two seven.`
> 12 votes

# Answer
Playing with the Mathematica internal dictionary:

```
res = {};
SeedRandom[42 + 1];
Do[
  (While[
    If[(c = Flatten@WordData[RandomChoice[WordData[All]], "Examples"][[All, 2]]) != {},
     StringPosition[(c1 = RandomChoice@c), "'" | "-" | "\\" | "`"] != {}, True, True]];
   sp = ToLowerCase /@ StringSplit[c1, (WhitespaceCharacter .. | ",")];
   toChange = RandomSample[Range@#, RandomInteger[IntegerPart[{#/2, #}]]] &@Length@sp;
   If[StringPosition[ToString@WordData[sp[[#]], "Definitions"],  "WordData"] == {},
    sp[[#]] = RandomChoice@ WordData[All, RandomChoice@WordData[sp[[#]], "PartsOfSpeech"]]]
             & /@ toChange;
   AppendTo[res, StringJoin@Riffle[sp, " "]];)
  ,
  {10}];
res

```

You get lucky, say, 70% of the time. It generates things like:

> a amygdaloid electric circuit
> yonder Parkia was unrestrictive though ragged
> his longanimous society
> Doctor of Education unintelligible reply to kibbutz
> little musical theater against Julius Caesar
> an Tai nuthatch
> mow down in sportive center contra thy niggardliness
> the required extrinsic detergents
> sans necromantic sorcerer
> these vena pectoralis opposite mine latria trophy wife trend-setting investors brown
> what man-portable field of fire
> umbra charmingly whereunto my answer
> another screw-loose debris storm scentless aslant Aral Sea complex waffle
> for professed delight mongoloid type metal

but sometimes:

> mine adoption pro least battle of Lutzen would cash draw in during whiles Hejira of the cleaver
> nine common shiner subduction genus Seiurus heartwarming her audience

Oh well, its use of English is better than mine.
> 10 votes

# Answer
# VBA/Excel

\[edit 2\]

Have taught it how to conjugate verbs, examples below are simple past tense:

> The moderate wild cocaine slid abreast of the historic instant decision. The regional safe chapter snapped inside of the numerous random entity. The yellow right domain removed behind the magnetic fragile gender. The physical fatal pollution began past the dead poor sensation. The cognitive brave theater went to the front of the fragile aware literature. The conventional actual output resisted away from the favorite immune site. The fixed economic twin recognized out of the evil human necessity.

The relevant code follows, excluding a bunch of boring ancillary parsing and looping functions. The main parts that are missing are the various word lists (by parts of speech) which do pluralization, tenses, conjugations, etc.

All of the word roots are picked randomly, but I force them to be arranged in a particular sentence pattern:

```
Debug.Print getWords("ad adj adj nns vpa1s pl ad adj adj nns")

```

... which is what I used to generate the output above. It follows the general form of, "The quick red fox jumped over the lazy brown dog."

```
Function getWords(strStruc As String) As String
    Dim i As Long
    Dim s As Long
    Dim strIn As String
    Dim strOut As String

    getWords = ""
    s = numElements(strStruc)
    For i = 1 To s
        strIn = parsePattern(strStruc, i)
        Select Case strIn
            Case ",", ";", ":", """" 'punctuation
                strOut = strIn
                getWords = Trim(getWords)
            Case "ai", "ad" 'indefinite article, definite article
                strOut = getArticle(strIn)
            Case "adj" 'adjective
                strOut = getWord("adj", 1)
            Case "nns" 'noun nominative singular
                strOut = getWord("n", 1)
            Case "nnp" 'noun nominative plural
                strOut = getWord("n", 2)
            Case "nps" 'noun posessive singular
                strOut = getWord("n", 3)
            Case "npp" 'noun posessive plural
                strOut = getWord("n", 4)
            Case "vpr1s" 'Present 1st Person Singular
                strOut = getWord("v", 1)
            Case "vpr2s" 'Present 2nd Person Singular
                strOut = getWord("v", 2)
            Case "vpr3s" 'Present 3rd Person Singular
                strOut = getWord("v", 3)
            Case "vi" 'Infinitive
                strOut = getWord("v", 4)
            Case "vpp" 'Present Participle
                strOut = getWord("v", 5)
            Case "vi" 'Imperative/Subjunctive
                strOut = getWord("v", 6)
            Case "vpa1s" 'Past Tense First Person
                strOut = getWord("v", 7)
            Case "vpa2s" 'Past Tense Second Person
                strOut = getWord("v", 8)
            Case "vpa3s" 'Past Tense Third Person
                strOut = getWord("v", 9)
            Case "vppr1s" 'Present Progressive First Person Singular
                strOut = getWord("v", 10)
            Case "vppr2s" 'Present Progressive Second Person Singular
                strOut = getWord("v", 11)
            Case "vppr3s" 'Present Progressive Third Person Singular
                strOut = getWord("v", 12)
            Case "vppe1s" 'Present Perfect First Person Singular
                strOut = getWord("v", 13)
            Case "vppe2s" 'Present Perfect Second Person Singular
                strOut = getWord("v", 14)
            Case "vpp3s" 'Present Perfect Third Person Singular
                strOut = getWord("v", 15)
            Case "vi1s" 'Imperfect First Person Singular
                strOut = getWord("v", 16)
            Case "vi2s" 'Imperfect Second Person Singular
                strOut = getWord("v", 17)
            Case "v13s" 'Imperfect Third Person Singular
                strOut = getWord("v", 18)
            Case "vsf" 'Simple Future
                strOut = getWord("v", 19)
            Case "vfp" 'Future Progressive
                strOut = getWord("v", 20)
            Case "vc" 'Conditional
                strOut = getWord("v", 21)
            Case "vcp" 'Conditional Perfect
                strOut = getWord("v", 22)
            Case "vci" 'Conditional Imperfect
                strOut = getWord("v", 23)
            Case "pl" 'location prepositions
                strOut = getWord("pl", 1)
        End Select
        getWords = getWords & strOut & " "
    Next i
End Function

```

\[begin original post\]

Still a work in progress, need to add logic for tenses and noun/verb pluralization, viz.:

> Your average travel our supposed dose nor a temperature boost beyond my tomato.

... which is parsable, but doesn't make much sense.

> The programming enable their dirty fisherman far our pork cast instead no sentence.

Right. Not really a sentence, but better than some JavaScript error messages.

> His appeal lift every live question that my lady outline top her English.

The innuendo routine is almost top-notch tho' ...

Code to follow anon. Does this contest have a deadline?

\[edit 1\]

Code that generated the above.

```
Function getWord(sht As Worksheet) As String
    Dim i As Long
    Dim freq As Long
    Dim c As Long
    Dim f As Double
    Dim fSum As Double

    c = 4
    fSum = WorksheetFunction.Count(sht.Columns(c))
    f = Rnd() * fSum
    i = 2
    Do
        If i >= f Then Exit Do
        i = i + 1
    Loop
    getWord = sht.Cells(i, 1).Value
End Function
Function PCase(str As String) As String
    PCase = UCase(Left(str, 1)) & Right(str, Len(str) - 1)
End Function
Sub doMakeSentences01()
    Dim shtIn As Worksheet
    Dim shtOut As Worksheet
    Dim strSheet As String
    Dim rIn As Long
    Dim rOut As Long
    Dim cFreq As Long
    Dim c As Long
    Dim strPattern As String
    Dim w As Long
    Dim strOut As String
    Dim strIn As String
    Dim strWord As String

    cFreq = 4
    Set shtOut = Sheets("Output")
    rOut = shtOut.Range("A65536").End(xlUp).Row + 1

    strPattern = "anvajncanvian"
    For rOut = rOut To rOut + 1000
        strOut = ""
        For w = 1 To Len(strPattern)
            Set shtIn = Sheets(Mid(strPattern, w, 1))
            strWord = getWord(shtIn)
            If w = 1 Then strWord = PCase(strWord)
            strOut = strOut & strWord & " "
        Next w
        strOut = Trim(strOut) & "."
        shtOut.Cells(rOut, 1).Value = strOut
    Next rOut
End Sub

```
> 8 votes

# Answer
# Perl 5

OK, the guts of the program is just this:

```
use v5.14;
my %pad = (
    ...
);
sub pad { shift =~ s(\{(.+?)\}){pad($pad{$1}[rand(@{$pad{$1}})])}rogue }
say ucfirst pad '{START}';

```

It's basically a "madlib" engine. To actually generate interesting sentences, you need to populate `%pad` with some data. Here's an example `%pad`...

```
my %pad = (
  START => ['{complex}.'],
  complex => [
    '{simple}',
    '{simple}, and {simple}',
    '{simple}, and {complex}',
    '{simple}, but {simple}',
    '{simple}, yet {simple}',
    'even though everybody knows {simple}, {simple}',
    'not only {simple}, but also {simple}',
  ],
  simple => [
    '{thing} {verb}s {thing}',
    '{thing} {verb}s {adverb}',
    '{thing} is {adjective}',
    '{things} {verb} {thing}',
    '{things} {verb} {adverb}',
    '{things} are {adjective}',
    '{thing} {past_verb} {thing}',
    '{things} {past_verb} {thing}',
  ],
  thing => [
    'the {adjective} gorilla',
    'the {adjective} mailbox',
    'Archbishop Desmond Tutu',
    'the beef salad sandwich',
    'the {adjective} stegosaur',
    'the summit of Mt Everest',
    'Chuck Norris',
    'the cast of television\'s "Glee"',
    'a {adjective} chocolate cake',
  ],
  things => [
    '{adjective} shoes',
    'spider webs',
    'millions of {adjective} eels',
    '{adjective} children',
    '{adjective} monkeys',
    '{things} and {things}',
    'the British crown jewels',
  ],
  verb => [
    'love',
    'hate',
    'eat',
    'drink',
    'follow',
    'worship',
    'respect',
    'reject',
    'welcome',
    'jump',
    'resemble',
    'grow',
    'encourage',
    'capture',
    'fascinate',
  ],
  past_verb => [  # too irregular to derive from {verb}
    'loved',
    'ate',
    'followed',
    'worshipped',
    'welcomed',
    'jumped',
    'made love to',
    'melted',
  ],
  adverb => [
    'greedily',
    'punctually',
    'noisily',
    'gladly',
    'regularly',
  ],
  adjective => [
    'enormous',
    'tiny',
    'haunted',
    'ghostly',
    'sparkling',
    'highly-decorated',
    'foul-smelling',
    '{adjective} (yet {adjective})',
    'expensive',
    'yellow',
    'green',
    'lilac',
    'tall',
    'short',
  ],
);

```

Here's some samples of the wisdom I've discovered from that `%pad`. These sentences have not been edited for length, punctuation, grammar, etc, though I have culled some uninteresting ones and rearranged the order in which the sentences appear - they are no longer in the order they were generated, but instead I'm trying to use them to tell a story: a story I hope you will find both touching and thought-provoking.

* Spider webs are short.
* Spider webs fascinate regularly.
* Short monkeys are sparkling, but spider webs drink greedily.
* Sparkling (yet foul-smelling) monkeys followed the tiny (yet sparkling) gorilla.
* The summit of Mt Everest welcomed the highly-decorated stegosaur.
* Not only the summit of Mt Everest is expensive, but also the cast of television's "Glee" followed the sparkling gorilla.
* The cast of television's "Glee" resembles the lilac mailbox.
* The expensive mailbox is tall, and the expensive stegosaur jumps Chuck Norris, yet green shoes jumped the beef salad sandwich.
* The beef salad sandwich loved Chuck Norris.
* Millions of sparkling eels are green (yet ghostly).
> 6 votes

# Answer
## Ms Word

I'm not sure if this is acceptable, but since html is, I think this should be also acceptable.

```
 =rand(1,1)

```

Sample sentences:

> On the Insert tab, the galleries include items that are designed to coordinate with the overall look of your document.
>
> You can use these galleries to insert tables, headers, footers, lists, cover pages, and other document building blocks.

you can also specify any number of sentences and paragraphs.
> 5 votes

# Answer
A work in progress using JSoup and simpleNLG

```
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import simplenlg.framework.NLGFactory;
import simplenlg.lexicon.Lexicon;
import simplenlg.phrasespec.SPhraseSpec;
import simplenlg.realiser.english.Realiser;

/**
 * Scapes words from Wiktionary then assembles them into sentences
 *
 * @author pureferret
 *
 */
public class SentenceBuilder {
    static ArrayList<String> ListOfWordTypes= new ArrayList<>(Arrays.asList("Noun","Verb","Adjective","Adverb","Proper noun","Conjunction"));
    private static String RandomWiktWord ="http://toolserver.org/~hippietrail/randompage.fcgi?langname=English";
    /**
     * @param args
     */
    public static void main(String[] args) {
        Lexicon lexicon = Lexicon.getDefaultLexicon();
        NLGFactory nlgFactory = new NLGFactory(lexicon);
        Realiser realiser = new Realiser(lexicon);

        ArrayList<String> nounList = new ArrayList<String>();
        ArrayList<String> verbList = new ArrayList<String>();
        ArrayList<String> adjeList = new ArrayList<String>();
        ArrayList<String> adveList = new ArrayList<String>();
        ArrayList<String> pnouList = new ArrayList<String>();
        ArrayList<String> conjList = new ArrayList<String>();

        String word= null;
        String wordType = null;

        try {
            newDoc:
            while( nounList.size()<1 ||
                    verbList.size()<1 ||
//                  adjeList.size()<2 ||
//                  adveList.size()<2 ||
                    pnouList.size()<1){
                Document doc = Jsoup.connect(RandomWiktWord).get();
                Element bodyElem = doc.body();
                word = bodyElem.select("h1>span[dir=auto]").get(0).ownText();
                int wtIdx = 0;
                while(wtIdx<bodyElem.select("div#mw-content-text span.mw-headline").size()){
                    wordType = bodyElem.select("div#mw-content-text span.mw-headline").get(wtIdx).id()
                            .replace("_", " ");
                    wtIdx++;
                    switch (wordType) {
                    case "Proper noun":
                        pnouList.add(word);
                        continue newDoc;
                    case "Noun":
                        nounList.add(word);
                        continue newDoc;
                    case "Verb":
                        verbList.add(word);
                        continue newDoc;
                    case "Adjective":
                        adjeList.add(word);
                        continue newDoc;
                    case "Adverb":
                        adveList.add(word);
                        continue newDoc;
                    case "Conjunction":
                        conjList .add(word);
                        continue newDoc;
                    default:
                        break;
                    }
                }
            }
                SPhraseSpec p = nlgFactory.createClause();
                p.setSubject(pnouList.get(0));
                p.setVerb(verbList.get(0));
                p.setObject(nounList.get(0));

                String output2 = realiser.realiseSentence(p); // Realiser created earlier.
                System.out.println(output2);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.err.println(word + " is a " + wordType);
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
            System.err.println(word + " is a " + wordType);
        }
    }

}

```

**Issues:**

* Sentences are too simple
* Occasionally 404s (without good handling!)
* Only generates one sentence at a time
* Uses a switch case!

Sample outputs:

> Popoloca prickethes runner beans.
> Tropic of Capricorn beams up bodles.
> Beijing synonymiseds pillow boxes.
> Chukchis enculturateds influencing.
> 4 votes

# Answer
## PHP

```
<?php
  $trends = file_get_contents('http://www.google.com/trends/hottrends/widget?pn=p1&tn=30');
  preg_match_all("/widget-title-in-list'>(.+?)</", $trends, $m);

  $q = urlencode($m[1][array_rand($m[1])]);
  $page = file_get_contents("http://www.google.com/search?q=$q&btnI=1");
  preg_match_all('/[A-Z]([\w,]+ ){2,}[\w, ]+?[.!]/', strip_tags($page), $m);

  echo $m[0][array_rand($m[0])];

```

This fetches the 30 most trending google searches, performs an "I Feel Lucky" search, and then displays a random sentence from that page with at least 3 words.

Examples:

*"She was considered a medal favourite in the event."*

*"Kate graduated from high school a year early."*

*"April 15, 2014, to promote compliance with the policy on biographies of living people."*

*"On behalf of Bryan, we, his family, would like to thank everyone for the outpouring of love, prayers and support."*

*"This article is about the American basketball player."*

*"Sorry, your browser either has JavaScript disabled or does not have any supported player."*
> 4 votes

# Answer
# JavaScript (ES6)

```
var t='';for(f of [_=>foo,_=>null.a,_=>0..toString(0)])try{f()}catch(e){t+=e.message+'\n';}t

```

Running it in the console produces

```
foo is not defined
null has no properties
radix must be an integer at least 2 and no greater than 36

```
> 3 votes

# Answer
**Python 2.7**

```
python2.7 -c "import urllib2, pprint; pprint.pprint([str(x[:x.find('<')]) for x in unicode(urllib2.urlopen('http://codegolf.stackexchange.com/questions/21571/generate-an-understandable-sentence').read(), 'utf8').split('<p>') if x.find('<') >= 1][1].split('.')[0])"

```

output:

> Generate a sentence that can be read and understood
> 3 votes

# Answer
## Shell Scripting

This script will always display the title of the first question that is currently on top of this site. My assumption is the question title will always be human readable. And it will change dynamically. So whenever a new question comes and when the script is executed, it will give the latest question title.

```
curl "codegolf.stackexchange.com" -s |  w3m -dump -T text/html > foo.txt
awk 'f;/more tags/{f=1}' foo.txt > foo1.txt
sed '8q;d' foo1.txt

```

**Trial 1 output**

```
Find words containing every vowel

```

**Trial 2 output**

```
Hello World 0.0!

```

## EDIT

Not using any files. Without files, I can use the below script.

```
value1=$(curl "codegolf.stackexchange.com" -s |  w3m -dump -T text/html)
echo "$value1" | grep -A 8 "more tags" | tail -1

```

**Output**

```
Generate an understandable sentence

```
> 2 votes

# Answer
# Yet another Python script

The answer of user3058846 isn't bad, but it displays every sentences, every time. Here, I propose a script that output a random sentence from the *Zen of Python*:

```
from random import choice
import subprocess
proc = subprocess.Popen(('python', '-c', 'import this'), stdout=subprocess.PIPE,)
# Get output of proc, split by newline
sentences = [x for x in proc.communicate()[0].splitlines() if x != '']
print(choice(sentences))

```

In one line, for fans:

```
from random import choice;import subprocess;print(choice([x for x in subprocess.Popen("python -c 'import this'",shell=True,stdout=subprocess.PIPE).communicate()[0].split('\n') if x]))

```

<sup><sub>(Boooh, dirty.)</sub></sup>

Examples:

```
>>> a()  # <--- a is just the oneline above
Explicit is better than implicit.
>>> a()
Although never is often better than *right* now.
>>> a()
Errors should never pass silently.
>>> a()
Special cases aren't special enough to break the rules.

```

---

## Another fun way in Python

Thanks to @TheDoctor pour the idea :-) Silent the import output and then play with the pseudo-encrypted dict in the module.

```
import sys, random
_stdout, sys.stdout = sys.stdout, open('/tmp/trash', 'w')  # silent the stdout just for the import
import this
sys.stdout = _stdout
lst = []
for x in this.s:
    if x in this.d:
        lst.append(this.d[x])
    else:
        lst.append(x)

# Then, example from the interpreter
>>> random.choice(''.join(lst).split('\n'))
'Beautiful is better than ugly.'
>>> random.choice(''.join(lst).split('\n'))
'Although never is often better than *right* now.'
>>>

```
> 2 votes

# Answer
# Python 3

Guaranteed to generate grammatical output! (Usually.)

```
import re
from urllib.request import urlopen
from random import random, choice as pick

letters = "abcdefghijklmnopqrstuvwxyz"
wordregex = re.compile(r'a href="/wiki/([a-z_]+)"')
subjects = {1:("I","we"), 2:("you",), 3:("they",)}
objects = {1:("me","us"), 2:("you",), 3:("him","her","it","them")}
patterns = ["{0} {1} {2}.",
            "Why do {0} {1} {2}?",
            "It's because {0} {1} {2}, of course.",
            "Did {0} {1} {2}?",
            "{0} will not {1} {2}!",
            ]

wiktionaryurl = "http://en.wiktionary.org/w/index.php?" + \
              "title=Category:English_{0}&pagefrom={1}"

def getWord(category):
    subset = pick(letters) + pick(letters)
    url = wiktionaryurl.format(category, subset)
    try:
        response = urlopen(url)
    except:
        print("An error occurred while connecting to the Internet!")
        return "fail"
    page = str(response.read())
    word = pick(wordregex.findall(page))
    word = word.replace("_", " ")
    return word

for i in range(10):
    verb = getWord("transitive_verbs")
    subjPerson = pick([1,2,3])
    subj = pick(subjects[subjPerson])
    if random() > 0.4:
        # Use a plural noun for the object
        obj = getWord("plurals")
    else:
        # Use a pronoun for the object
        objPerson = pick([1,2,3])
        while subjPerson == objPerson and subjPerson in (1,2):
            objPerson = pick([1,2,3])
        obj = pick(objects[objPerson])
    sentence = pick(patterns).format(subj, verb, obj)
    sentence = sentence[0].upper() + sentence[1:]
    print(sentence)

```

To make it perfectly grammatical, delete the underscore from `wordregex`. This will disallow multi-word entries that lead to bad sentences such as "We zip up you."

Sample run:

```
We appropriate journals.
I will not masticate you!
Did you lower me?
Why do I sag estoppels?
They will not proofread you!
It's because you unbeguile mucosae, of course.
Why do I flack zakuski?
You will not visit junkpiles!
Did they goat us?
Why do we prefix nolids?

```

Favorite output so far:

```
They you her.

```

Look it up: http://en.wiktionary.org/wiki/you#Verb.
> 2 votes

# Answer
# Python

Result:

```
$ python mksentence.py
infringement lecture attainment
Produce more? (Y/N)y
impeachment recoup ornament
Produce more? (Y/N)y
maladjustment edit discouragement
Produce more? (Y/N)y
embellishment guest punishment
Produce more? (Y/N)y
settlement section escapement
Produce more? (Y/N)y
segment withhold recruitment
Produce more? (Y/N)

```

I used the word list from here Find words containing every vowel

Some more rules can be added. For example, if a word ending with "ness" and the word also exist in set without the suffix, then it's a noun.

Source code:

```
#!/usr/bin/env python
# vim: set fileencoding=utf-8 ts=4 sw=4 tw=72 :

from __future__ import (unicode_literals, absolute_import,
                        division, print_function)

import random

if __name__ == "__main__":
    filename = 'corncob_lowercase.txt'
    noun = set()
    verb = set()
    whole_words_set = {word.rstrip() for word in open(filename)}

    for word in whole_words_set:
        if word.endswith('ment'):
            noun.add(word)
        elif word.endswith('ing'):
            if word[:-3] in whole_words_set:
                verb.add(word[:-3])
            elif word[:-3]+"e" in whole_words_set:
                verb.add(word[:-3]+"e")
    noun_list = list(noun)
    verb_list = list(verb)
    while True:
        sentence = "%s %s %s" % (random.choice(noun_list),
                                 random.choice(verb_list),
                                 random.choice(noun_list))
        print(sentence)
        if input("Produce more? (Y/N)").lower() == "n":
            break

```
> 0 votes

# Answer
## Bash

Trying to run a program that exists but is not installed gives this (in Linux Mint 13).

```
$ say
The program 'say' is currently not installed.  To run 'say' please ask your administrator to install the package 'gnustep-gui-runtime'

```
> 0 votes

# Answer
# Python 3

Another take at *The Zen of Python*, inspired by Maxime's answer.

```
import codecs
import os
import sys
import random

stdout = sys.stdout
sys.stdout = open(os.devnull, 'r+')

import this

sys.stdout.close()
sys.stdout = stdout

zen = codecs.decode(this.s, 'rot-13').splitlines()

print(random.choice(zen))

```
> 0 votes

---
Tags: popularity-contest
---


title: Implement ROT-47... in ROT-47

text:
# Question
Title: Implement ROT-47... in ROT-47
Challenge: Implement ROT-47 in code that works as both itself and as the ROT-47 version of itself.

### Scoring:

Your score is calculated as a percentage of **used, ROT-47 eligible bytes in total of both versions of the program** divided by **total bytes (all characters) of both versions**.

A **used, ROT-47 eligible byte** is any character that would be converted by the ROT-47 cipher that is not **part of a comment** or ignored by the compiler/interpreter. For example, any character in a brainfuck program that is not `+-<>[],.`  is not considered a used byte, and any character in a C program including and after `//` or inside `/* */` is not considered a used byte. All special symbols in APL are not considered used, as are all characters in a Whitespace program (sorry).

Ties will be broken by the program with the most upvotes. If there is still a tie, then the shortest program wins.

Example scoring:

### C: 62/64 = 96.875%

Notice there is a space in this program. Obviously also, this program is not a valid entry because it doesn't even compile, but I wanted to show how scoring works.

```
main(){printf("Hello World!");}

```

# Answer
> 28 votes
# Ruby, 100% (74 characters)

Input on STDIN, output on STDOUT.

```
Vj=s=gets;puts(s.tr'!-~','P-~!-O');Vj;'lDl86EDjAFEDWD]ECVP\OV[V!\OP\~VXj;'

```

The second line is the first line ROT-47'd. Therefore, when ROT-47ing the whole program, it becomes:

```
';lDl86EDjAFEDWD]ECVP\OV[V!\OP\~VXj';jV=s=gets;puts(s.tr'!-~','P-~!-O');jV

```

My strategy here is based upon the fact that:

* `V` is `'` when ROT-47'd
* `j` is `;` when ROT-47'd
* Therefore, `Vj=...Vj;` turns into `';l...';`, which is essentially a no-op

+ Now you can create any arbitrary code that does anything normally and no-ops when ROT-47'd. This is because `Vj=...Vj;` can support running any code as you could do `Vj=0;{INSERT ANY CODE};Vj;`, and that will become `'...';` when ROT-47'd. You just have to be careful not to use `V` in that code, since that will break it.
* Similar logic can be used in reverse to produce the second half (`jV` instead of `Vj`)

# Answer
> 16 votes
# C - 54.6%

```
Y;BW;XL;jNj;AW(){XL^Y;};main(int i,char**v){char*x=v[1];while(*x){if(*x>32&&*x<128)*x=(*x+15)%94+32;putchar(*x++);}}//Y^Nj>2:?W:?E :[492CYYGXL492CYIlG,`.jH9:=6WYIXL:7WYImbaUUYIk`agXYIlWYIZ`dXThcZbajAFE492CWYIZZXjNN

```

When ROT-47-translated, we get

```
*jq(j){j;};jp(WXL){/*jNj>2:?W:?E :[492CYYGXL492CYIlG,`.jH9:=6WYIXL:7WYImbaUUYIk`agXYIlWYIZ`dXThcZbajAFE492CWYIZZXjNN^^*/};main(int i,char**v){char*x=v[1];while(*x){if(*x>32&&*x<128)*x=(*x+15)%94+32;putchar(*x++);}}

```

Both programs compile, and ROT-47-translate the first argument:

```
$ ./a "hello world"
96==@ H@C=5

```

# Answer
> 10 votes
## GolfScript, 120 / 120 bytes = 100%

```
{:&&32>&&+254<*{7+7+94%33+}*}%LiUUbamUUZadckYLfZfZhcTbbZNYNT

```

or, in ROT-47:

```
LiUUbamUUZadckYLfZfZhcTbbZNYNT{:&&32>&&+254<*{7+7+94%33+}*}%

```

No comments or string abuse. The undefined command `LiUUbamUUZadckYLfZfZhcTbbZNYNT` (which equals the rest of the code in ROT-47) is a no-op, but it still gets executed by the interpreter, so I believe it counts as used.

This was actually a pretty easy challenge in GolfScript. The main difficulty was in avoiding the digit `1`, which is mapped by ROT-47 into the GolfScript command ```. The commands `.`, `-`, `,`, `\`, `[`, `/`, `]` and `^` also had to be avoided, but that was fairly easy in this case, since the task required no array building.

### Bonus:

Here's a GolfScript period-2 quine (i.e. a program that prints a second program that prints the first program again) where the two programs are the ROT-47 transforms of each other:

```
{`'0$~'+.{7+7+94%33+}%@!{0$@@;}*}0$~L1V_SOVZ]LfZfZhcTbbZNToPL_SoojNYN_SO

```

This program outputs itself ROT-47 encoded, yielding another GolfScript program:

```
L1V_SOVZ]LfZfZhcTbbZNToPL_SoojNYN_SO{`'0$~'+.{7+7+94%33+}%@!{0$@@;}*}0$~

```

which, in turn, also outputs itself ROT-47 encoded, yielding the previous program again. Thus, this program is also a rotating quine.

# Answer
> 6 votes
# python, 96.1% (?)

According to your definition, strings count as used code?

```
V=input();print("".join([chr(33+(ord(V[i])+14)%94)for i in range(len(V))]));V
'l:?AFEWXjAC:?EWQQ];@:?W,49CWbbZW@C5WD,:.XZ`cXThcX7@C : :? C2?86W=6?WDXX.XXj'

```

---
Tags: code-challenge, cryptography
---


title: Noughts and Crosses (aka Tic-Tac-Toe)

text:
# Question
Title: Noughts and Crosses (aka Tic-Tac-Toe)
Write a **`Notes and Crosses`** application.

User interface is optional.
You can output the computers move in text: eg `1x1` (meaning center square)

The computer must play an intelligent (extra marks for optimal) game.
Apart from its first move which should be random.

Player computer take turns at first move.
First player to win two games in a row wins.

Score:

* Lowest strokes wins.
* If equal best computer move algorithm (as I see fit)
* If equal submitted date.

# Answer
c99 -- 1229 characters (and needs nucrses)

```
#include <ncurses.h>
#include <string.h>
#define R return
#define A char
#define M mvprintw
#define I int
#define O "%c wins a game, press any key to %s."
A*s=" XOCHT";FILE *r;
I W(A*b){I i,p,q,r,w[]={0,1,2,0,3,6,0,2,3,3,3,1,1,1,4,2};if(!memchr(b,0,9))
R 3;for(i=0;i<16;i++){p=w[i/2];q=w[i/2+8];r=i%2+1;if((b[p]==r)&&(b[p+q]==r)
&&(b[p+q+q]==r))R r;}R 0;};
I C(A*b, I s){A c[9];for(I i=0;i<9;i++){memcpy(c,b,9);if(c[i]==0)c[i]=s;
if(s==W(c))R i;}R -1;};I P(A*b){I i;while(b[i=fgetc(r)%9]);R i;};
I D(A*b){A*p=" |-+";I i=0,j;for(;i<5;i++)for(j=0;j<5;j++)
mvaddch(i,j,p[2*(i%2)+j%2]);for(i=0;i<9;i++)mvaddch(2*(i/3),2*(i%3),
b[i]?s[b[i]]:'1'+i);refresh();};
I G(A m){I u=1,i,j;A b[9];memset(b,0,9);M(1,9,"Computer %c",s[m]);M(2,9,
"Human %c",s[m%2+1]);do{M(4,9,"Up %c",s[u]);D(b);if(u==m){if((i=C(b,m))<0&&(i=C
(b,m%2+1))<0)i=P(b);b[i]=m;}else{do{M(6,0,"your move ");refresh();scanw("%d",&i
);}while(i>10||i<1||b[i-1]!=0);b[i-1]=m%2+1;};u=u%2+1;}while(0==W(b));M(8,0,O,
s[W(b)],"continue");D(b);getch();M(8,0,"%44c",*s);R W(b)==3?5:u==m?4:3;}
I main(I c,A**v){A d=0, m=v[1][0]-'x'?2:1;r=fopen("/dev/random","r");
initscr();for(;;){c=G(m);if(c==d&&c-5)break;else M(4,25,"Previous winner %c",
s[c]),d=c;m=m%2+1;}M(9,0,O,c,"quit");getch();endwin();}

```

It gives away characters for the users convenience by using curses and having actual English prompts and informative lines. The obvious macro golfs have been made, but there are probably some comma and conditional operator improvements still available.

Is it smart? Well, it takes one move wins and blocks one move losses, but is otherwise quite random. (I may take the weekend to repair my interrupted CS education and learn about A\* trees...) The "random first move" condition is met automatically as no one has the option to win at that point. Despite this obviously deficient AI I have yet to beat it when it holds X, so I have not defeated it by the "two in a row" rules.

Structurally we have a *"is there a winner"* function and a *"can I win with a single play"* function which works by coping the board and trying each position in turn with the `isWon` function. The single `canWin` function serves first to search for winning opportunities (by passing the computer's symbol) and then to search for things than need blocking (by passing the human's).

It declares `C`omputer, `H`uman, or `T`ie the winner on each game and only `C` or `H` for the series.

**Now respects the spec as to winning conditions** And plays well enough that you have to let it win or Ctrl-C to get out.

The version below differs from the above in prompts as well as macroization, but still represents the approach.

```
#include <ncurses.h>
#include <string.h>

char*s/*ymbols*/=" XOCHT";
FILE *r/*dev/random*/;

/* return the index of the side that wins, 0 if un-won or 3 if cat's game */
int W/*on*/(char*b){
  int i,p,q,r,w/*inning matrix*/[]={0,1,2,0,3,6,0,2,
                    3,3,3,1,1,1,4,2};
  if(!memchr(b,0,9))return 3; /* detect cat games by lack of open positions */
  for(i=0;i<16;i++){
    p=w[i/2];   /* starting position of the winning sequence to check */
    q=w[i/2+8]; /* step size of the winning sequence to check */
    r=i%2+1;  /* winning value to check */
    if( (b[p]==r) &&
    (b[p+q]==r) &&
    (b[p+q+q]==r) )
      return r;
  }
  return 0;
};
/* returns the first square in which the current side can win or -1 if none*/
int C/*an win?*/(char*b, int s/*ide to play*/){
  char c[9];
  for(int i=0;i<9;i++){
    memcpy(c,b,9);
    if(c[i]==0)c[i]=s;
    if(s==W(c))return i;
  }
  return -1;
};
/* returns a random unoccupied square */
int P/*ick a random move*/(char*b){
  /* assumes a move is possible and will loop forever if this
     condition is violated */
  int i;
  while(b[i=fgetc(r)%9])
    ;
  return i;
};
int D/*raw the board*/(char*b){
  char*p=" |-+";
  int i=0,j;
  for(;i<5;i++)
    for(j=0;j<5;j++)
      mvaddch(i,j,p[2*(i%2)+j%2]);
  for(i=0;i<9;i++)
    mvaddch(2*(i/3),2*(i%3),b[i]?s[b[i]]:'1'+i);
  refresh();
};

/* Play a single game with the computer taking s[m] and return the winner
 *
 *  3 -- computer
 *  4 -- human
 *  5 -- tie
 */
int G(char m){
  int u/*p*/=1,i,j;
  char b/*oard*/[9];
  memset(b,0,9); /* initalized to 0 (empty) */
  mvprintw(1,9,"Computer uses %c",s[m]);
  mvprintw(2,9,"Human uses %c",s[m%2+1]);
  /* main loop */
  do {
    mvprintw(4,9,"To play %c",s[u]);
    D(b);
    if(u==m){
      // my turn to move
      if( (i=C(b,m))<0 &&    /* move to win */
      (i=C(b,m%2+1))<0 ) /* 2%2+1 == 1,  1%2+1 == 2 so, the other side */
    i=P(b);
      b[i]=m;
    } else {
      // user's turn
      /* get user selection */
      do {
    mvprintw(6,0,"your move:\n");
    refresh();
    scanw("%d",&i);
      } while (i>10||i<1||b[i-1]!=0);
      b[i-1]=m%2+1;
    };
    u=u%2+1; /* Here u is switched to the *next* player, so if the
        game is one u denotes the *loser*  */
  } while(0==W(b));
  /* Print out the winner */
  mvprintw(8,0,"%c wins a game, press any key to continue.",s[W(b)]);
  D(b);
  getch();
  mvprintw(8,0,"%44c",*s);
  return W(b)==3?5:u==m?4:3;
}

/* first argument is required and expected to be x or o
 *
 * x always goes first
 */
int main(int c,char**v){
  char d=0, /* previous winner, starts on an impossible value */
    m=v[1][0]-'x'?2:1; /* select my symbol by index into s */
  /* /dev/random intialization */
  r=fopen("/dev/random","r");
  /* curses intialization */
  initscr(); /* start curses */
  for(;;){
    c=G(m);
    if (c==d&&c-5) // same *player* wins two in a row
      break;
    else
      mvprintw(4,25,"Previous winner %c",s[c]),d=c;
    m=m%2+1;
  }
  mvprintw(9,0,"Final winner is %c, press any key to quit.",c);
  getch();
  endwin();
}

```
> 2 votes

# Answer
## Bash, 591 670, 812 <sub>(excluding `#!/bin/bash`)</sub>

x is computer. x goes first and then alternates with o for each new game. x never looses so game ends when x wins twice in a row. UI is a simple 3x3 board. Positions are numbers from 0 to 8. Occupied positions are x's or o's. x (now) plays a boring game. Although x never looses, it will randomly pick between a set of best moves to be a little bit interesting.

The code:

```
W()for q in 1 28 55 3 12 21 4 20;{ [[ w**3 -eq B[f=q/8]*B[g=q%8]*B[g+g-f] ]]&&$r;}
B(){ local -i p R t=9 S;for((;p<9;p++)){ [[ B[p] -eq p ]]&&{ B[p]=w;W&&$e 98&&$r $p;R+=S[B[p]=p]=98-$(M+=-1;w=w^3;B);t=$((S[p]<S[t]?t:p));V=R/M;};};$e $V;$r $t;}
T()(for q in {1..9};{ $e -en ${P[B[q-1]]}${N[q%3]};};W=${P[w^=3]};q=$([ $w = 9 ]&&for((;B[q]!=q;)){ read -sn1 -p? q;}&&$e $q&&$r;[ $M = 9 ]&&$e $RANDOM||(B>1;$e $?))%9;B[q]=w;M+=-1;$e $W..$q;W&&$e $W!&&$r $w;[ $M = 0 ]&&$e Ty||T);P=({0..8} o x);N="\n";e=echo;r=return;declare -i V=49 q w=9 M=9 B=({0..8});for((;(J&(J=K))<9;w^=3)){ T;K=$?;};$e Won

```

I have just noticed that I use W as a function and variable. Bash does not seem to mind.

Dialogue is minimal:

```
? means it is waiting for o to play.
  means it is thinking about next move.
x! means X wins.
Ty means a Tie.

W determines if $w won.

```

It uses a code in $q to identify lines of positions to test. Let a line of positions be F, G, and H. Code is 8F+G. H can be derived from F and G: H=G+(G-F). eg. From 28, F=3, G=4, H=5. If board positions B\[F\]+B\[G\]+B\[H\]=3\*w then $w has won

```
B $1 finds best move for player $1.
T controls a game and gets user move if $w is 0 or computer's move.

```

Full source code:

```
# Players
#   o is opponent
#   x is computer
#   Player symbols are stored in Player array.

# Board B has 9 board positions numbered 0 to 8
#   0-8=unoccupied
#   9=o in position
#   10=x in position

# Winning line encoding
#   if a winning row is positions f,g, and h then these are encoded as f*8+g
#   h is derived as g+(g-f)

Win()
  for q in 1 28 55 3 12 21 4 20;{                        # for each code
    [[ w**3 -eq B[f=q/8]*B[g=q%8]*B[g+g-f] ]] && return  # w won if 3 in row
  }

# F=49
# F sets a resolution for determining value of a move.
# Since AVG=sum(Score[*])/M then larger scores mean better fixed point real number.
# Score is 0 to 2F. Larger F, larger score accuracy.
#   F is set to largest number such that 2F is 2 digits.

# A move probability to win is returned in AVG.
#   AVG=0  o wins this move (if they play rationally)
#   AVG<F  means o more likely to win
#   AVG=F  means most likely a tie
#   AVG>F  means x more likely to win
#   AVG=2F means x wins

# p must be integer or it does not get initialised to 0
# R must be integer and it gets initialised to 0
# t needs a starting default value of 9 if there are no empty positions

Best(){  # here we have to silently play lots of games to choose best move
  local -i p R t=9 Score                         # save board and move count
  for((; p<9; p++)){
    [[ B[p] -eq p ]] && {                        # empty position
      B[p]=w                                     # occupy it
      Win && echo 98 && return $p                # if w won then restore board, set score to 2F
      R+=Score[B[p]=p]=98-$(M+=-1; w=w^3; Best)  # restore board, inc move & what is opponents best move?
      t=$((Score[p]<Score[t]?t:p))               # if score is better then restart list with this position
      AVG=R/M                                    # average scores
    }
  }
  echo $AVG                                      # set score
  return $t                                      # return first best position
}

# Take Turns.
#   Starting with other player (w^3), take turns and count down remaining turns.
#   Get a move from opponent or computer. Ensure opponent move is legal.
#   If there is a winner, return winner (9=o 10=x).
#   If game over, return tie (0)
#   Else take next turn
#   Changes w, W, M, B, p

Turn()(
  for q in {1..9};{
    echo -en ${Players[B[q-1]]}${N[q%3]}  # show position or player and newline every 3rd
  }
  W=${Players[w^=3]}                      # W is symbol of other player
  # if o, get move. else if game start, random move. else get best move for x
  q=$([ $w = 9 ]&&for((;B[q]!=q;)){ read -sn1 -p? q;}&&echo $q&&$r;[ $M = 9 ]&&echo $RANDOM||(Best>1;echo $?))%9
  B[q]=w                                  # move and occupy board position
  M+=-1                                   # dec move count
  echo $W..$q                             # show move
  Win        && echo $W! && return $w     # w has won
  [ $M = 0 ] && echo Ty  || Turn          # return 0 tie after 9 moves and no winner or another turn
)

# Play a game.
#   Board can be configured as you like. Ensure M represents number of moves remaining.
#   AVG is used by Best to return value of best move.

# Loop for competition to declare winner after 2 wins in a row.
#   Turn returns 9=o win, 10=x win, and 0=tie
#   w is non-starting player: 9=o 10=x
#   w swaps between 9 and 10 for subsequent games

# AVG is a global used to calculate/store average value of a move.
#   Since Best() is called in a subshell, it will always be 49.

# q is a globally used integer
# M is number of moves remaining. Starts at 9 and when 0 board is full and game over.

Players=({0..8} o x); N="\n";e=echo;r=return
declare -i AVG=49 q w=9 M=9 B=({0..8})  # player=H, empty board, 9 moves to go

for((; (J&(J=K))<9;w^=3)){              # start with X (9^3); while tie or not 2 in a row
  Turn
  K=$?                                  # K=who one
}
echo Won                                # I should cheat and just say x won to save more characters

```
> 2 votes

# Answer
# Javascript 271

This is not a real entry in this competition, but i just wanted to share this interesting algorithm with the other (potentional) competitors.

```
b=[[8,8,8,8],[8,0,0,0],[8,0,2,0],[8,0,0,0]]
m=[2,2]
for(n=0;n<4;n++){
i=prompt(m).split(",")
r=+i[0]
c=+i[1]
b[r][c]=1
if(!b[r][c+1]){b[r][c+1]=2;m=[r,c+1]}
else if(!b[r][c-1]){b[r][c-1]=2;m=[r,c-1]}
else if(!b[r-1][c]){b[r-1][c]=2;m=[r-1,c]}
else{b[r+1][c]=2;m=[r+1,c]}}

```

It takes input of the form `r,c` where r is the row and c is the collumn, and it outputs in the same format. It does not output the last move since it's not a choice. This algorithm is sooooo simple that you can probably implement it in less than 100 chars if you do it right! It works as follows:

1: The computer takes the first move `(2,2)`
2: The user makes any move
3: The computer checks if he can make a move on the square to the right of the user, if he can't he checks for the left, if he can't he checks for the square above and if he still can't he puts it on the square below.
4: Go to step 2

Try to beat it!
> 1 votes

# Answer
# Java 1801 1691 1467

So yeah, this is definitely a revival, but as a new participant on codegolf I hope you won't hold it against me.

**Edit:** Changed from multidimensional array to single dimension array, also stripped out a bunch of unnecessary parenthesis. Next step will be to write a different "brain" for the computer. Even as it is, although not perfect, it does pretty well. I'm probably going to set up a version that has the computer play itself, for kicks. When I do, you can find it in my github.

**Edit2:** Replaced `q` and `b` methods with a single `d` method that performs all the work of `q` and `b` based on a flag passed in that chooses the "mode", `1` for win or block (prior `q` method), `0` for future-move-win choice (prior `b` method). Saved more than two hundred characters, hurray.

I spent some time golfing in Java, and this is what I came up with:

```
import java.util.*;class W{public static void main(String[]a){(new W()).t();}void p(String k,int i){System.out.print(k+(i<1?"":"\n"));}int[]M;int P;int c(){int m,a,b,i;for(a=b=i=0;i<3;i++){a=M[i*3];b=M[i];m=a==M[i*3+1]&&M[i*3+1]==M[i*3+2]&&a>0?a:b==M[i+3]&&M[i+3]==M[i+6]&&b>0?b:0;if(m>0){return m;}}m=M[4];return M[0]==m&&m==M[8]||b==m&&m==a?m:0;}void g(){for(int i=0;i<9;)p(w(M[i]),i++%3/2);p("",1);}int x(int i){return(new Random()).nextInt(i);}String w(int i){return(i<1)?".":((2*i-3)*P<0)?"X":"O";}int y(){return(new Scanner(System.in)).nextInt();}void Z(){int i;do{i=x(9);}while(!s(i,1));}int o(int a,int b,int c,int z,int x){return a==b&&c==x&&a==z?2:a==x&&b==c&&b==z?0:a==c&&b==x&&c==z?1:-1;}int d(int z,int y,int k){int i=0,j;for(;i<3;i++){if((j=o(M[i*3],M[i*3+1],M[i*3+2],z*k,z*(1-k)))>=0?s(k>0?i*3+j:i*3+2-j/2,y):(j=o(M[i],M[i+3],M[i+6],z*k,z*(1-k)))>=0?s(k>0?i+3*j:i+(2-j/2)*3,y):0>1)return 1;}if((i=o(M[0],M[4],M[8],z*k,z*(1-k)))>=0?s(k>0?i*4:8-(i/2)*4,y):(i=o(M[2],M[4],M[6],z*k,z*(1-k)))>=0?s(k>0?i*2+2:6-(i/2)*2,y):0>1)return 1;return 0;}void z(){if(!(d(1,1,1)>0||d(2,1,1)>0||s(4,1)||d(1,1,0)>0))Z();}boolean s(int i,int z){if(M[i]<1){p(w(z)+" to "+i%3+","+i/3,1);return(M[i]=z)==z;}return 0>1;}void t(){while(1>0){M=new int[9];int m=9,x;if(x(2)<1){P=1;Z();g();m--;}else P=-1;do{do{p("x?",0);x=y();p("y?",0);}while(!s(y()*3+x,2));m--;g();x=c();if(x>0||m<1)break;z();g();m--;x=c();}while(m>0&&x<1);if(x<1)p("No winner!",1);else p(w(x)+" wins!",1);}}}

```

Ungolfed, with comments (and perhaps some longer variables/method names):

```
import java.util.*;
public class TicTacToeGolf {
    public static void main(String[] args) {
        (new TicTacToeGolf()).start();
    }
    /** Wrap System.out.print to avoid all that typing */
    void p(String k, int i){
        System.out.print(k +((i<1)?"":"\n"));
    }
    /** Game board */
    int[][] gg;int P;
    /** Check all possibilities for winner, return 0 for no winner, 1 for X, 2 for O */
    int c(){
        for(int[]i:gg)
            if((i[0]==i[1])&&(i[1]==i[2])&&i[0]>0)
                return i[0];
        for(int i=0;i<3;i++)
            if ((gg[0][i]==gg[1][i])&&(gg[1][i]==gg[2][i])&&gg[0][i]>0)
                return gg[0][i];
        int m=gg[1][1];
        return (((gg[0][0]==m)&&(m==gg[2][2])||(gg[0][2]==m)&&(m==gg[2][0]))?m:0);
    }
    /** Print game board */
    void g(){
        for(int[]i:gg){
            for(int j:i)
                p(w(j),0);
            p("",1);
        }p("",1);
    }
    /** Generate a random value */
    int x(int i) {
        return (new Random()).nextInt(i);
    }
    /** Convert 1 to X, 2 to O */
    String w(int i) {
        return (i<1)?".":((2*i-3)*P<0)?"X":"O";
    }
    /** Get a number from the input */
    int y() {
        return (new Scanner(System.in)).nextInt();
    }
    /** Pick the next move for the computer */
    void Z() {
        int i,j;
        do{
            i=x(3);
            j=x(3);
        }while(!s(i,j,1));
    }
    /** Check for win or board condition for player z based on an ordered set of values a,b,c having one space with player x */
    int o(int a, int b, int c, int z, int x) {
        return (a==b&&c==x&&a==z)?2:(a==x&&b==c&&b==z)?0:(a==c&&b==x&&c==z)?1:-1;
    }
    /** Check for win over rows, cols, and grids for user z, place for user y based on findings.
     *  Means will block z if z != y */
    int q(int z,int y){
        int i=0,j;
        // check for win or block
        for (;i<3;i++){
            j=o(gg[i][0],gg[i][1],gg[i][2],z,0);
            if (j>=0){s(i,j,y);return 1;}
            j=o(gg[0][i],gg[1][i],gg[2][i],z,0);
            if (j>=0){s(j,i,y);return 1;}
        }
        i=o(gg[0][0],gg[1][1],gg[2][2],z,0);
        if (i>=0){s(i,i,y);return 1;}
        i=o(gg[0][2],gg[1][1],gg[2][0],z,0);
        if (i>=0){s(i,2-i,y);return 1;}
        return 0;
    }
    /** Check for placement options over rows, cols, and grids for user z, place for user y based on findings.
     *  Means will block z if z != y */
    int b(int z,int y){
        int i=0,j;
        // check for placement or block
        for (;i<3;i++){
            j=o(gg[i][0],gg[i][1],gg[i][2],0,z);
            if (j>=0){s(i,2-j/2,y);return 1;}
            j=o(gg[0][i],gg[1][i],gg[2][i],0,z);
            if (j>=0){s(2-j/2,i,y);return 1;}
        }
        i=o(gg[0][0],gg[1][1],gg[2][2],0,z);
        if (i>=0){s(2-i/2,2-i/2,y);return 1;}
        i=o(gg[0][2],gg[1][1],gg[2][0],0,z);
        if (i>=0){s(2-i/2,i/2,y);return 1;}
        return 0;
    }
    /** Pick the next move for the computer, smartly */
    void z() {
        // Check for win
        if (q(1,1)>0)return;
        // Check for block
        if (q(2,1)>0)return;
        // check for best
        if (s(1,1,1))return; // try to take center.
        // take whatever would win the subsequent turn if the other person is stupid.
        if (b(1,1)>0)return;
        Z(); // take anything.
    }
    /** Check if move is possible, if so do it, otherwise return false */
    boolean s(int i, int j, int z){
        if (gg[i][j]<1){
            p(w(z)+" to "+j+","+i,1);
            return (gg[i][j]=z)==z;
        }
        return 0>1;
    }
    /** Play the game, Computer gets first  move. */
    void start() {
        while(true){
            gg = new int[3][3];
            int moves=9,x;
            if (x(2)<1) { // Computer starts.
                P=1;
                Z();
                g();
                moves--;
            }else P=-1;
            do{
                do{
                    p("x?",0);
                    x=y();
                    p("y?",0);
                }while(!s(y(),x,2));
                moves--;
                g();
                if (c()>0||moves==0)
                    break;
                z();
                g();
                moves--;
            }while(moves>0&&c()==0);
            if(c()<1) p("No winner!",1);
            else p(w(c()) + " wins!",1);
        }
    }
}

```

**Some usage notes:**

* 50/50 chance for who takes first turn.
* Move of "X" or "O" announced before displaying the game board.
* Choice of cell is specified as column, then row, indexed from 0.
* Entering something outside `[0,2]` will cause a index exception and end the game.
* If computer goes first, takes a random move (no preference for any board location).
* Computer will take one move wins, block one move losses, plays conservatively (prefers center if available), tries to set up a two-turn win (hope other player doesn't block), and if that fails? Picks a random spot. So doesn't play a perfect game, but plays a great game. I can force a win due to the random start possibilities, but computer will force a win as well if I start badly.
* Wins are detected immediately.
* Impossible-to-win is *not* detected; you must play every game to the end or let the other player win.
* At the end of each game, a new game begins, again with a randomly chosen starting player.
* Took a few hits to character length by including a usable UI.
* Use `Ctrl+c` to end.

Example game (with computer starting, so first placement is random):

```
$ java W
X to 1,2
...
...
.X.

x?1
y?1
O to 1,1
...
.O.
.X.

X to 2,2
...
.O.
.XX

x?0
y?2
O to 0,2
...
.O.
OXX

X to 2,0
..X
.O.
OXX

x?2
y?1
O to 2,1
..X
.OO
OXX

X to 0,1
..X
XOO
OXX

x?0
y?0
O to 0,0
O.X
XOO
OXX

X to 1,0
OXX
XOO
OXX

No winner!

```

There's definitely room for improvement. One place is likely replacing the multi-dimensional array with a one-dimensional array*(done)*, and replacing the more complex decision logic with either a reduced form of the same*(done)*, or a more concise best-choice solver.

Play around with it and let me know what you think. I've got this hosted over on my github so feel free to fork, clone, and create pull requests with improvements.
> 1 votes

---
Tags: code-golf, tic-tac-toe
---


title: Cross-matching regular expressions

text:
# Question
Title: Cross-matching regular expressions
Your task here is to write two regular expressions, each of which matches the other one but does not match itself.

Both regular expressions should have this form:

```
/pattern/optional-flags

```

This is also the form in which they should be matched.

The shortest solution wins. The solution length is counted as the sum of characters in both regular expressions including slashes and flags.

Use a regex syntax standard of your choice, or specify a programming language, when it makes a difference.

Have fun!

# Answer
## PRCE with the A modifier: 9 chars

```
/A$/
/.A/A

```

Although this is a variant on Doorknob's `/modifier$/` answer, I think this innovation qualifies it as a separate answer rather than a comment on his: the modifier does double-duty. Rather than being there solely for the other regex to match, it anchors.

The first regex matches any string ending in a literal `A`. The second regex matches any string whose second character is a literal `A`, using an anchor-to-start flag.

Online demo
> 7 votes

# Answer
# 4+6=score of 10

First regex:

```
/i$/

```

Second regex:

```
/^.i/i

```

Hooray for flag abuse! :-P

The first one matches anything that ends with `i` (therefore, any regex with the `i` flag).

The second one matches anything with a second character of `i`.

Alternative version: `/i$/g` and `/g$/i`.
> 18 votes

# Answer
## JavaScript regexes, score: 18

First regex:

```
/^[^a]+$/

```

Second regex:

```
/^[^b]+$/

```

JavaScript test:

```
var regex1 = "/^[^a]+$/";
var regex2 = "/^[^b]+$/";
alert(/^[^a]+$/.test(regex2)); // true: regex1 matches regex2
alert(/^[^b]+$/.test(regex1)); // true: regex2 matches regex1
alert(/^[^a]+$/.test(regex1)); // false: regex1 doesn't match regex1
alert(/^[^b]+$/.test(regex2)); // false: regex2 doesn't match regex2

```

Test online: http://jsfiddle.net/99Sx6/
> 6 votes

# Answer
## Ruby regex, 15

Regular expressions:

```
/.{9}/
/^.{06}$/

```

Just counting characters...

Online version

```
r1 = '/.{9}/'
r2 = '/^.{06}$/'

p r1 =~ /^.{06}$/ #0:   r2 matches r1
p r2 =~ /.{9}/    #0:   r1 matches r2
p r1 =~ /.{9}/    #nil: r1 doesn't match r1
p r2 =~ /^.{06}$/ #nil: r2 doesn't match r2

```
> 5 votes

# Answer
# 4 + 6 = 10

First regex:

```
/i$/

```

Second regex:

```
/\/$/i

```

`i$` matches something that ends with `i`, the second one. `/$` matches something that ends with `/`, the first one.
> 5 votes

# Answer
# 5 + 5 = 10

Regex #1:

```
/0.$/

```

Regex #2:

```
/^.0/

```

The `0`s in both regexes can be replaced with any non-metacharacter and the regex still works.

`0.$` matches anything whose second last character is `0`, and `^.0` matches anything whose second character is `0`.
> 4 votes

# Answer
# Score: 5 + 5 = 10

Took me half-an-hour to figure out but I am really happy that I did :)

### 1st is: `/j.$/`

### 2nd is: `/^.j/`

The 1st matched a `j` occurring in the second position starting from the right. The 2nd matches a `j` occurring at the second-position starting from left.

I haven't tested but I think that these RegExs are really versatile as the `j` can be replaced with any `\w` character (or more?) and still should work fine.

P.S. This should (hopefully) work in any language. Though, if it does not work in any, please inform in the comments below :)

Test
> 3 votes

# Answer
## JavaScript regexes, score: 13

First regex:

```
/\d/

```

Second regex:

```
/^[^0]+$/

```

Explanation: the first regex matches everything that contains a digit, and the second regex matches everything that doesn't contain a `0`.

JavaScript test:

```
var regex1 = "/\d/";
var regex2 = "/^[^0]+$/";
alert(/\d/.test(regex2)); // true: regex1 matches regex2
alert(/^[^0]+$/.test(regex1)); // true: regex2 matches regex1
alert(/\d/.test(regex1)); // false: regex1 doesn't match regex1
alert(/^[^0]+$/.test(regex2)); // false: regex2 doesn't math regex2

```

Test online: http://jsfiddle.net/5VYjC/1/
> 2 votes

# Answer
**12 chars** ;) JS regex

```
/\d/
/0?\/$/g

```
> 2 votes

# Answer
### PCRE using modifier x: 11 chars

```
/\s/
/ s.$/x

```

The first matches any string with a whitespace character, but doesn't contain whitespace. The second contains whitespace, but it's ignored because of the `x` modifier; it matches any string whose penultimate character is `s`.

### PCRE and other engines using character classes: 11 chars

```
/\w+w/
/\Ww/

```

The first matches any string with a "word" character (letter, digit, underscore) followed by a literal `w`; the second matches any string with a non-word character followed by a literal `w`.

### PCRE and other engines using character classes and word boundary anchor: 11 chars

```
/\w\w/
/\bw/

```

The first matches any string with two consecutive "word" characters; the second any string with a non-word character or start of string followed by a literal `w`.
> 1 votes

# Answer
# ECMAScript (11 bytes):

```
/^\1?d/
/\d/

```

# Other REGEXP Engines (14 bytes):

```
/^\\\\1?d/
/\d/

```

The 1st matches \d\[..\] or \1d\[..\].

The second matches any string with a number.

**EDIT:**

Originally, this answer was posted as being compatible with all engines, but it was proven to be wrong.

There was a problem with references to the capturing groups (for example, in php).
> -1 votes

---
Tags: code-golf, regular-expression
---