A Pen by Sher Minn Chong on CodePen.
Created
July 4, 2015 15:19
-
-
Save piratefsh/91e76ebad9cdc0786930 to your computer and use it in GitHub Desktop.
Cryptoarithmetic Solver
This file contains 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
article | |
header | |
.container | |
h1 Cryptoarithmetic Solver | |
section | |
.container | |
h2 Puzzle | |
form#puzzle-form | |
.form-group | |
input#puzzle.form-control(type="text", placeholder="Puzzle", value="ODD+ODD==EVEN") | |
.form-group | |
input.pull-left.btn.btn-primary.btn-solve(type="submit") | |
section.solution | |
.container | |
h2 Solution | |
.well | |
ul#solutions | |
This file contains 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
$(function(){ | |
var $solutionsContainer = $('.solution').hide(); | |
var $btn = $('.btn-solve'); | |
var $solutions = $('#solutions').html(""); | |
$('#puzzle-form').submit(function(event){ | |
event.preventDefault(); | |
var puzzle = $('#puzzle', event.target).val(); | |
$btn.val('Solving...'); | |
// solve | |
var solutions = solve(puzzle); | |
$btn.val("Submit"); | |
// display results | |
$solutionsContainer.show(); | |
$solutions.html(""); | |
for(var s of solutions){ | |
$solutions.append('<li>' + s + '</li>'); | |
} | |
if(solutions.length == 0){ | |
$solutions.html('No solution') | |
} | |
}); | |
}); | |
function solve(puzzle){ | |
var chars = uniqueChars(puzzle).join(""); | |
var combinations = Combinatorics.permutation([0,1,2,3,4,5,6,7,8,9], chars.length); | |
var results = []; | |
var compiled = compile(puzzle); | |
if(!compiled){ | |
return []; | |
} | |
while(c = combinations.next()){ | |
if(compiled.apply(null, c)){ | |
var filled = replace(puzzle, chars, c.join("")); | |
results.push(filled); | |
} | |
} | |
console.log(results); | |
return results; | |
} | |
// returns unique alphabets in text | |
function uniqueChars(text){ | |
var set = new Set(text.match(/[A-Z]/g)).values(); | |
var arr = []; | |
for (s of set){ arr.push(s)} | |
return arr; | |
} | |
// compile puzzle | |
function compile(puzzle){ | |
var params = uniqueChars(puzzle).join(","); | |
// get leading digits | |
var leadingPattern = /\b([A-Z])[A-Z]/g; | |
var leadingDigits = []; | |
while((results = leadingPattern.exec(puzzle))){ | |
leadingDigits.push(results[1]); | |
} | |
var leadingDigitsStr = "[" + leadingDigits.join(",") + "]" | |
// compile expression | |
var tokens = puzzle.split(/([A-Z]+)/g); | |
var exp = tokens.map(compileWord).join(" "); | |
// put together function | |
var func = "(function f(" + params | |
+ "){ if(" + leadingDigitsStr + ".indexOf(0) == -1){ " | |
+ "return " + exp + "} " | |
+ "else {return false}})"; | |
var fn; | |
// catch eval errors | |
try{ | |
fn = eval(func); | |
} | |
catch(err){ | |
alert(err.message); | |
return false; | |
} | |
return fn; | |
} | |
function compileWord(word){ | |
if(/[A-Z]/g.test(word)){ | |
var digits = []; | |
for(var i = 0; i < word.length; i++){ | |
var zeroes = Math.pow(10, word.length - 1 - i) | |
var digit = word[i] + '*' + zeroes; | |
digits.push(digit); | |
} | |
return "(" + digits.join('+') + ")"; | |
} | |
else{ | |
return word; | |
} | |
} | |
// replaces chars in intab with chars in outtab | |
function replace(text, intab, outtab){ | |
intab = intab.split(""); outtab = outtab.split(""); | |
var table = {}; | |
for(var i in intab){ | |
table[intab[i]] = outtab[i]; | |
} | |
var translated = text.split(""); | |
translated.map(function(curr, index, arr){ | |
if(curr in table) arr[index] = table[curr]; | |
}); | |
return translated.join(""); | |
} | |
function test(){ | |
console.log(replace('ODD+ODD==EVEN', 'ODEVN', '12345')); | |
var f = compile('ODD+ODD==EVEN'); | |
console.log(f(0, 1, 2, 3, 4)); | |
var g = compile('MEE+YOU==OKAY'); | |
console.log(g(0, 1, 2, 3, 4)); | |
} |
This file contains 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
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="https://rawgit.com/dankogai/js-combinatorics/master/combinatorics.js"></script> |
This file contains 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
$space: 20px | |
header, section | |
margin-bottom: $space |
This file contains 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
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment