Ответы пользователя по тегу Алгоритмы
  • Алгоритм решения данной задачи?

    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;

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