@xZand

Алгоритм решения данной задачи?

Всем привет, пытаюсь решить данную задачку на javascript -Ссылка, но не получается описать алгоритм решения. Как правильно сравнить ключи объекта edgeTypesId, и стоит ли пушить в результирующий массив те объекты, который не прошли условия? Стоит ли ставить условие "если первые 10 элементов априори не имеют выемки, а только top: null, то проходится по массиву фильтром и пушить только такие элементы?

Буду благодарен за помощь. Очень нужно понять, как решаются такие задачи. И с чего вообще начать. PS: Буду еще более благодарен, если по пунктам опишите весь процесс решения задачи(именно алгоритм) что бы понять где ошибка и как решать.
  • Вопрос задан
  • 262 просмотра
Пригласить эксперта
Ответы на вопрос 1
agoalofalife
@agoalofalife
Team Lead
Понравилась задача, расскажу как сделал в итоге я.
Программа работает слева -> направо, сверху -> вниз.
Первый кусок, нам известен.
Берем правую сторону первого элемента, находим его связь, далее для следующего элемента надо найти элемент противоположной стороны.
Для примера правая сторона вот такая:
`left: { edgeTypeId: 38, type: 'outside' }`
Надо искать где edgeTypeId :38 и type:'inside'.
Элемент который будет найден, надо обратить внимание, на его сторону, и получить противоположный.
К примеру мы нашли 38 и inside, оно лежало в элементе с id:33, сторона: top, нам надо искать след элемент который будет в bottom, так как он противоположный.

И так проходим всю строку до конца.
Находим нижний элемент первого элемента первого ряда, и далее так же как и было выше, ищем связь для противоположной стороны.
Прикреплю код, его можно сделать более читабельным, но решение рабочие для этой задачи.
Осторожно код

function solvePuzzle(pieces) {
	// initial
	let result = [pieces[0].id];
	let next = {
			edgeTypeId: pieces[0].edges.bottom.edgeTypeId,
			type: pieces[0].edges.bottom.type,
	};


	for(let rowIndex = 0, step = -10;rowIndex < 10;rowIndex++, step += 10) {
		if (rowIndex !== 0) {
			next = getDownPiece(result[step], pieces)
			result.push(next.id)
			next = next.edges.bottom
		}
		for(let i = 0;i < 9;i++) {
			next = findNextEdge(next, pieces, i === 8);
			result.push(next.id)
		}
   }
  return result;
}


function findNextEdge(previousEdge, pieces, isLast = false) {
	let typeOpposite = getTypeOpposite(previousEdge.type);
	let result = {};	
	for (var i = 0; i < pieces.length; i++) {
		let nextEdge = Object.entries(pieces[i].edges).find(function(edge) {
			let [, nextEdgeCandidate] = edge
			return nextEdgeCandidate !== null && previousEdge.edgeTypeId === nextEdgeCandidate.edgeTypeId && nextEdgeCandidate.type === typeOpposite;
		});
		if (nextEdge !== undefined) {
			[typeSide] = nextEdge
			if (isLast === false) {
				result = Object.assign(pieces[i].edges[getOppositePosition(typeSide)], {id:pieces[i].id})
			} else if(isLast){
				result = Object.assign(pieces[i].edges[typeSide], {id:pieces[i].id})
			}
		}
	}
	return result;
}

function findConnectedEdge(leftEdge, pieces) {
	let typeOpposite = getTypeOpposite(leftEdge.type);
	return pieces.find(function(piece){
		return Object.entries(piece.edges).find(function(edge) {
			let [, rightEdgeCandidate] = edge
			return rightEdgeCandidate !== null && leftEdge.edgeTypeId === rightEdgeCandidate.edgeTypeId && rightEdgeCandidate.type === typeOpposite;
		});
	});
}

function getTypeOpposite(type){
  return type === 'inside' ? 'outside':'inside';
}
function getOppositePosition(position) {
	if (position === 'bottom') {
		return 'top';
	} else if(position === 'top') {
		return 'bottom'
	} else if (position === 'left') {
		return 'right';
	} else {
		return 'left';
	}
}

function getDownPiece(idUpPiece, pieces) {
	return findConnectedEdge(pieces.find(edge => {
	  return edge.id === idUpPiece;
	}).edges.left, pieces)
}

// Не удаляйте эту строку
window.solvePuzzle = solvePuzzle;

Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы