Pattern finder

by Vasily Liaskovsky

HTML

<textarea class="one" rows="4">
 + 
+++
 + 
</textarea>
<textarea class="two" rows="4">
+ +   ++++  + ++  + + +
+ ++ +++ + +++ ++ + +++
+ ++ + + ++ + + + + ++ 
</textarea>
<div class="result"></div>

CSS

.one, .two, .result{
  padding: 0;
  font-family: monospace;
  width: 100%;
  font-size: 1rem;
}

JavaScript

function indexOf(pattern, input){
	if(pattern.length !== input.length) throw 'Works only for same number of lines';
	var counts = [].concat(...input.map((s,i) => allMatches(pattern[i],s))).reduce((r,e) => (r[e] = (r[e] || 0) + 1, r), {}); //find all matches for all lines and flatten
  var stops = Object.keys(counts).filter(k => counts[k] === pattern.length); //get only those that span across all the lines
  return stops[0] || -1; //first found or -1 if empty
}
function allMatches(substr, str){
	var result = [], index = 0;
  while(~(index = str.indexOf(substr, index))) // ~(-1) is falsy
  	result.push(index++);
  return result;
}
function readContent(element){
	return (element.value || element.textContent).split(/[\r\n]+/).filter(s => s.length); //get all non-empty lines
}
function showResult(pattern, input){
	var chars = Array(input[0].length).fill('\xa0'); // &nbsp;
	chars[indexOf(pattern, input)] = '^';
  document.querySelector('.result').textContent = chars.join('');
}
function updater(){
	showResult(	readContent(document.querySelector('.one')),
							readContent(document.querySelector('.two'))
	);
}
document.querySelector('.one').addEventListener('input', updater);
document.querySelector('.two').addEventListener('input', updater);
updater();