Skip to content

Instantly share code, notes, and snippets.

@JochemKuijpers
Last active October 12, 2018 19:56
Show Gist options
  • Save JochemKuijpers/208acec59dc17e2b5afd84eb3922b150 to your computer and use it in GitHub Desktop.
Save JochemKuijpers/208acec59dc17e2b5afd84eb3922b150 to your computer and use it in GitHub Desktop.
Letter Clock generator
import java.util.*;
public class Main {
public static void main(String[] args) {
int targetRows = 16;
int width = 16;
long tries = 0;
double bestScore = 0;
List<String> words = new ArrayList<>();
List<String> result = new ArrayList<>();
while (true) {
tries++;
System.out.printf("\rattempt: #%d", tries);
words.clear();
result.clear();
double score = generateWords(words);
int length = 0;
String currentRow = "";
for (String word : words) {
// ignore space at the beginning of the word if the word starts a new row
boolean postfixWhitespace = word.endsWith(" ");
if (currentRow.length() == 0 && word.startsWith(" ")) {
word = word.substring(1);
}
if (postfixWhitespace) {
word = word.substring(0, word.length() - 1);
}
// place the next word on this row with as much overlap as possible
for (int i = word.length(); i >= 0; i--) {
// but if that isn't possible, move to the next row.
if (currentRow.length() + (word.length() - i) > width) {
result.add(currentRow);
length += currentRow.length();
currentRow = "";
i = 0;
if (word.startsWith(" ")) {
word = word.substring(1);
}
}
// find as much overlap as possible (by i decreasing form word.length() to 0)
if (currentRow.endsWith(word.substring(0, i))) {
currentRow += word.substring(i);
break;
}
}
// add whitespace if the current word ended with whitespace
if (currentRow.length() < width && postfixWhitespace) {
currentRow += " ";
}
}
result.add(currentRow);
length += currentRow.length() * 0.1;
score += length;
if (result.size() <= targetRows) {
if (score > bestScore) {
bestScore = score;
System.out.printf("\nFound a solution! %2d characters, %2d rows, score: %8.2f\n", length, result.size(), score);
for (String line : result) {
for (int c : line.chars().toArray()) {
System.out.print((char) c + " ");
}
System.out.print('\n');
}
System.out.println("- - - - - - - - - - - - - - - -\n");
}
}
}
}
private static double generateWords(List<String> words) {
Random random = new Random(System.nanoTime());
double score = 0.0;
// greeting
words.add(" GOEDE ");
List<String> orderedDayParts = Arrays.asList("MORGEN", "MIDDAG", "AVOND", "NACHT");
List<String> dayParts = new ArrayList<>(orderedDayParts);
Collections.shuffle(dayParts);
score += scoreShuffledList(orderedDayParts, dayParts);
words.addAll(dayParts);
words.addAll(Arrays.asList(" ", " HET ", " IS "));
// day
words.addAll(Arrays.asList("MA", "DI", "WO", "DO", "VR", "ZA", "ZO"));
words.add(" ");
// day of month
List<String> orderedDom = Arrays.asList("10", "11", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31");
List<String> dom = new ArrayList<>(orderedDom);
Collections.shuffle(dom);
score += scoreShuffledList(orderedDom, dom);
words.addAll(dom);
words.add(" ");
// month
List<String> orderedMonths = Arrays.asList("JAN", "FEB", "MAA", "APR", "MEI", "JUN", "JUL", "AUG", "SEP", "OKT", "NOV", "DEC");
List<String> months = new ArrayList<>(orderedMonths);
Collections.shuffle(months);
score += scoreShuffledList(orderedMonths, months);
words.addAll(months);
words.add(" ");
// weather
if (random.nextBoolean()) {
words.addAll(Arrays.asList(" HET ", " WEER ", " IS "));
} else {
words.addAll(Arrays.asList(" HET ", " WEER: "));
}
List<String> weather = Arrays.asList("REGENACHTIG", "ONBEWOLKT"); // BEWOLKT is a substring of ONBEWOLKT
words.addAll(weather);
// 5/10/15
words.addAll(Arrays.asList(" HET ", " IS "));
if (random.nextBoolean()) {
List<String> minutes = Arrays.asList("VIJF", "TIEN", "KWART");
Collections.shuffle(minutes);
words.addAll(minutes);
} else {
words.add("VIJFTIEN");
}
words.add(" ");
// past/to
List<String> pastto = Arrays.asList("VOOR", "OVER");
Collections.shuffle(pastto);
words.addAll(pastto);
words.add(" HALF ");
// uren
List<String> orderedHours = Arrays.asList("EEN", "TWEE", "DRIE", "VIER", "VIJF", "ZES", "ZEVEN", "ACHT", "NEGEN", "TIEN", "ELF", "TWAALF");
List<String> hours = new ArrayList<>(orderedHours);
Collections.shuffle(hours);
score += scoreShuffledList(orderedHours, hours);
words.addAll(hours);
return score;
}
private static double scoreShuffledList(List<String> orderedList, List<String> shuffledList) {
// compute the number of items in original place
double score = 0.0;
for (int i = 0; i < orderedList.size(); i++) {
int difference = Math.abs(i - shuffledList.indexOf(orderedList.get(i)));
score -= Math.pow(difference, 1.5) + 10 * difference;
}
score /= orderedList.size();
return score;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment