Last active
August 29, 2015 14:17
-
-
Save MarksCode/29b3290a352af81e9e7a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*********************************************************************/ | |
/* Program: Markov ChainMaker */ | |
/* Author: Ron Marks */ | |
/* */ | |
/* This programs applies Markov chains to textual input in order to */ | |
/* generate not-quite-random sentences and words. */ | |
/* */ | |
/* */ | |
/* Input: */ | |
/* Text file as args0 */ | |
/* Example: https://gist.github.com/MarksCode/6150b1dd4721b9a1c85f */ | |
/* Example: java ChainMaker Moby.txt */ | |
/* */ | |
/* Output: */ | |
/* Chain outputs words of text file using markov chain rule */ | |
/* Char outputs characters of text file using markov chain rule */ | |
/*********************************************************************/ | |
import java.util.*; | |
import java.io.*; | |
class ChainMaker{ | |
/***************/ | |
/* MAIN METHOD */ | |
/***************/ | |
public static void main(String[] args) throws FileNotFoundException { | |
MarkovChain m = new MarkovChain(); | |
m.training(args[0]); | |
m.generate(50, " "); | |
MarkovChar mc = new MarkovChar(); | |
mc.training(args[0]); | |
mc.generate(150, ""); | |
} | |
} | |
/**************************/ | |
/* Chain Interface */ | |
/* */ | |
/* by Ron Marks (romarks) */ | |
/**************************/ | |
// Interface is contract to make sure rules are met when calling listed methods | |
interface Chain { | |
public void training(String filename) throws FileNotFoundException; | |
public void generate(int iterations, String delimeter); | |
} | |
/**************************/ | |
/* MarkovChain Class */ | |
/**************************/ | |
class MarkovChain implements Chain { | |
private HashMap<String, List<String>> map = new HashMap<String, List<String>>(); | |
/*******************/ | |
/* Training Method */ | |
/* Creates hashmap */ | |
/* Input: File */ | |
/*******************/ | |
public void training(String filename) throws FileNotFoundException { | |
File file = new File(filename); | |
Scanner type = new Scanner(file); | |
String w1 = ""; | |
String w2 = ""; | |
// Checking there is a word to scan | |
if (!type.hasNext()){ | |
System.out.println("Not Enough Words"); | |
System.exit(0); | |
} | |
String w3 = type.next(); | |
// Making combination String out of 1st and 2nd words for key | |
String comb = w1 + " " + w2; | |
// Making an ArrayList with 3rd word and putting it and key in my HashMap | |
List<String> vals = new ArrayList<String>(); | |
vals.add(w3); | |
map.put(comb, vals); | |
// Loop keeps going as long as there are words to scan | |
while(type.hasNext()){ | |
w1 = w2; | |
w2 = w3; | |
w3 = type.next(); | |
comb = w1 + " " + w2; | |
// Checking if map contains key already | |
if(map.containsKey(comb)){ | |
vals = map.get(comb); | |
vals.add(w3); | |
} else{ | |
vals = new ArrayList<String>(Arrays.asList(w3)); | |
map.put(comb, vals); | |
} | |
} | |
} | |
/**********************/ | |
/* Generate Method */ | |
/* Prints things */ | |
/* Input: Iterations, */ | |
/* seperator string */ | |
/**********************/ | |
public void generate(int iterations, String delim) { | |
String a1 = ""; | |
String a2 = ""; | |
int i = 0; | |
String key = a1 + " " + a2; | |
Boolean contKey = map.containsKey(key); | |
Random rand = new Random(4); | |
// Loop goes for iteration number or until key isn't found in HashMap | |
while(i<iterations && contKey){ | |
List<String> words = map.get(key); | |
int randNum = rand.nextInt(words.size()); | |
String val = words.get(randNum); | |
// Prints out the chosen value and seperator string | |
System.out.printf(val + delim); | |
a1 = a2; | |
a2 = val; | |
key = a1 + " " + a2; | |
contKey = map.containsKey(key); | |
i++; | |
} | |
System.out.printf("..."); | |
System.out.println(); | |
System.out.println("--"); | |
} | |
} | |
/*******************************/ | |
/* MarkovChar Class */ | |
/*******************************/ | |
class MarkovChar extends MarkovChain{ | |
// Creating HashMap for Strings and Characters | |
private HashMap<String, List<Character>> cMap = new HashMap<String, List<Character>>(); | |
/*******************/ | |
/* Training Method */ | |
/* Creates hashmap */ | |
/* Input: File */ | |
/*******************/ | |
public void training(String filename) throws FileNotFoundException { | |
File file = new File(filename); | |
Scanner inType = new Scanner(file); | |
char c1 = '\u0000'; | |
char c2 = '\u0000'; | |
if (!inType.hasNext()){ | |
System.out.println("Not Enough Chars"); | |
System.exit(0); | |
} | |
// Creating combination of first 2 characters | |
String cComb = c1+""+c2; | |
List<Character> cvals = new ArrayList<Character>(); | |
inType.useDelimiter(""); | |
String blah = inType.next(); | |
// Scanning for next char in document and changing it based on its value | |
char c3 = blah.charAt(0); | |
if(c3 == '\n'){ | |
c3 = ' '; | |
} | |
if(c3 == ')'){ | |
c3 = ' '; | |
} | |
if(c3 == '('){ | |
c3 = ' '; | |
} | |
cvals.add(c3); | |
// Adding first bit to HashMap | |
cMap.put(cComb, cvals); | |
// Starting loop for rest of HashMap | |
while(inType.hasNext()){ | |
c1 = c2; | |
c2 = c3; | |
cComb = c1 + "" + c2; | |
blah = inType.next(); | |
c3 = blah.charAt(0); | |
if(c3 == '\n'){ | |
c3 = ' '; | |
} | |
if(c3 == ')'){ | |
c3 = ' '; | |
} | |
if(c3 == '('){ | |
c3 = ' '; | |
} | |
// Checking if HashMap already contains key | |
if(cMap.containsKey(cComb)){ | |
cvals = cMap.get(cComb); | |
cvals.add(c3); | |
} else{ | |
cvals = new ArrayList<Character>(); | |
cvals.add(c3); | |
cMap.put(cComb, cvals); | |
} | |
} | |
} | |
/***********************/ | |
/* Generate Method */ | |
/* Prints based on */ | |
/* hashmap constructed */ | |
/* Input: Iterations, */ | |
/* seperating string */ | |
/***********************/ | |
public void generate(int iterations, String sep){ | |
char p1 = '\u0000'; | |
char p2 = '\u0000'; | |
int i = 0; | |
String key = p1 + "" + p2; | |
Boolean contChar = cMap.containsKey(key); | |
Random rand = new Random(4); | |
// Checks for iterations gone through and if map contains key, then prints out a random value for corresponding key | |
while(i<iterations && contChar){ | |
List<Character> myChars = cMap.get(key); | |
int randNum = rand.nextInt(myChars.size()); | |
char newChar = myChars.get(randNum); | |
System.out.printf(newChar + "" + sep); | |
p1 = p2; | |
p2 = newChar; | |
key = p1 + "" + p2; | |
contChar = cMap.containsKey(key); | |
i++; | |
} | |
System.out.printf("..."); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment