Skip to content

Instantly share code, notes, and snippets.

@Kuniwak
Created January 24, 2014 11:23
Show Gist options
  • Select an option

  • Save Kuniwak/8595658 to your computer and use it in GitHub Desktop.

Select an option

Save Kuniwak/8595658 to your computer and use it in GitHub Desktop.
CodeIQ「数列の四則演算」問題の回答。 https://codeiq.jp/magazine/2014/01/4799/
var StopIteration = Error('STOP_ITERATION');
var util = {
array: {
clone: function(arr) {
var clone = [];
Array.prototype.push.apply(clone, arr);
return clone;
}
},
object: {
getValues: function(obj) {
var values = [];
var idx = 0;
for (var key in obj) {
values[idx++] = obj[key];
}
return values;
},
getCount: function(obj) {
var count = 0;
for (var key in obj) {
++count;
}
return count;
}
},
math: {
randomInt: function(a) {
return Math.floor(Math.random() * a);
}
}
};
/**
* @constructor
*/
var IncrementalNumSeq = function(opt_len) {
this.assertLength_(opt_len);
var len = opt_len || 0;
this.nums_ = new Array(len);
};
IncrementalNumSeq.MAX_LENGTH = 1023;
/**
* @enum {string}
*/
IncrementalNumSeq.Operator = {
ADDITION: '+',
SUBTRACTION: '-',
MULTIPLICATION: '*',
DEVISION: '/',
JOIN: ''
};
IncrementalNumSeq.getOperatorByIndex = (function() {
var operators = util.object.getValues(IncrementalNumSeq.Operator);
return function(idx) {
return operators[idx];
};
})();
IncrementalNumSeq.prototype.assertLength_ = function(len) {
if (!isFinite(len) && len !== undefined && len !== null) {
throw Error('Sequence length must be finite but come: ' + len);
}
else if (len < 0) {
throw Error('Sequence length must be positive or zero but come: ' + len);
}
};
IncrementalNumSeq.prototype.equals = function(incNumSeq) {
var aLen = this.nums_.length;
var bLen = incNumSeqGen_.nums_.length;
if (aLen !== bLen) {
return false;
}
for (var idx = 0; idx < aLen; idx++) {
if (this.nums_[idx] !== incNumSeq.nums_[idx]) {
return false;
}
}
return true;
};
IncrementalNumSeq.prototype.fill = function(val) {
this.set(function() {
return val;
});
return this;
};
IncrementalNumSeq.prototype.set = function(func, opt_this) {
for (var idx = 0, len = this.nums_.length; idx < len; idx++) {
this.nums_[idx] = func.call(opt_this, this.nums_[idx], idx);
}
return this;
};
IncrementalNumSeq.prototype.reverse = function() {
this.nums_.reverse();
return this;
};
IncrementalNumSeq.prototype.reduce = function(func, start, opt_this) {
return this.nums_.reduce(func, start, opt_this);
};
IncrementalNumSeq.prototype.map = function(func, opt_this) {
return this.nums_.map(func, opt_this);
};
IncrementalNumSeq.prototype.evaluate = function(opSeq) {
var expr = this.toExprString(opSeq);
return eval(expr);
};
IncrementalNumSeq.prototype.clone = function() {
var clone = new this.constructor();
clone.nums_ = util.array.clone(this.nums_);
return clone;
};
IncrementalNumSeq.prototype.toExprString = function(opSeq) {
return this.reduce(function(prev, curr, idx) {
return (opSeq[idx] || '') + curr + prev;
}, '');
};
IncrementalNumSeq.prototype.toString = function() {
return '<' + this.nums_.join(', ') + '>';
};
/**
* @constructor
*/
var IncrementalNumSeqGenerator = function(len, opt_lower, opt_upper) {
this.len = len;
this.lower = opt_lower || 0;
this.upper = opt_upper || IncrementalNumSeqGenerator.MAX_LENGTH;
};
IncrementalNumSeqGenerator.MAX_LENGTH = 1023;
IncrementalNumSeqGenerator.prototype.next = function() {
var finish = false;
var finisher = Error();
if (!this.numSeq_) {
this.numSeq_ = new IncrementalNumSeq(this.len);
this.numSeq_.fill(this.lower);
return this.numSeq_;
}
try {
this.numSeq_ = this.numSeq_.clone();
this.numSeq_.set(function(num) {
if (finish) {
throw finisher;
}
if (num < this.upper) {
finish = true;
return num + 1;
}
else {
return this.lower;
}
}, this);
}
catch (e) {
if (e !== finisher) {
throw e;
}
}
if (finish) {
return this.numSeq_;
}
else {
throw StopIteration;
}
};
/**
* @constructor
*/
var OperatorSeqGenerator = function(len) {
var maxOperatorsIdx = util.object.getCount(IncrementalNumSeq.Operator) - 1;
this.incNumSeqGen_ = new IncrementalNumSeqGenerator(len, 0, maxOperatorsIdx);
};
OperatorSeqGenerator.prototype.next = function() {
return this.incNumSeqGen_.next().map(function(opIdx) {
return IncrementalNumSeq.getOperatorByIndex(opIdx);
});
};
var SEQ_LEN = 4;
var incNumSeqGen = new IncrementalNumSeqGenerator(SEQ_LEN, 0, 9);
var opGen = new OperatorSeqGenerator(SEQ_LEN - 1);
var incrementalNumSeqToNumberString = function(incNumSeq) {
return incNumSeq.reduce(function(prev, curr) {
return curr + prev;
}, '');
};
for (var start = 1000; start >= 0; start--) {
incNumSeqGen.next();
}
while (true) {
try {
var incNumSeq = incNumSeqGen.next();
}
catch (e) {
if (e === StopIteration) {
console.log('Complete.');
break;
}
else {
throw e;
}
}
while (true) {
try {
var opSeq = opGen.next();
}
catch (e) {
if (e === StopIteration) {
break;
}
else {
throw e;
}
}
// Expression must contained an four arithmetic operations.
if (!opSeq.join('')) {
continue;
}
var expected = incrementalNumSeqToNumberString(incNumSeq.clone().reverse());
if (String(incNumSeq.evaluate(opSeq)) === expected) {
console.log('HIT: ' + incNumSeq.toExprString(opSeq) + ' = ' + expected);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment