Skip to content

Instantly share code, notes, and snippets.

@halan
Last active November 19, 2016 01:18
Show Gist options
  • Save halan/dd2091d5e3723c1ba68ce886ecca8eed to your computer and use it in GitHub Desktop.
Save halan/dd2091d5e3723c1ba68ce886ecca8eed to your computer and use it in GitHub Desktop.
module.exports = (distribuicao) => {
const pulaLinha = (linha, coluna) => [linha+1, coluna]
const pulaLinhaIniciaColuna = (linha, coluna) => [linha+1, 0]
const pulaLinhaColuna = (linha, coluna) => [linha+1, coluna+1]
const pulaLinhaDiminuiColuna = (linha, coluna) => [linha+1, coluna-1]
const voltaLinhaContinuaColuna = (linha, coluna) => [linha-1, coluna]
const voltaLinhaVoltaColuna = (linha, coluna) => [linha-1, coluna-1]
const volta2LinhasUltimaColuna = (linha, coluna) => [linha-2, coluna]
const continuaLinhaAndaColuna = (linha, coluna) => [linha, coluna+1]
// Aqui no meio são funções puras, podem ser refatoradas com composição
// const isFinal = (linha, coluna) => {
// const ultimaLinha = (linha === distribuicao.length-1)
// const ultimaColuna = (coluna === distribuicao[linha].length-1)
// return (ultimaLinha && ultimaColuna)
// }
const atualizaPosition = (linha, tam) =>
({linha: linha-1, coluna: tam < 3 ? tam : tam-1})
const quandoEntreDuaseCincoLinhas = (linha, coluna, position) => (
coluna ?
[pulaLinhaDiminuiColuna(linha, coluna), position] :
quandoEntreDuaseCincoLinhasComColuna(linha, distribuicao[linha-1].length-1)
)
const quandoEntreDuaseCincoLinhasComColuna = (linha, tam) => (
tam < 3 ? // esse condicional pode ir pra dentro de uma função pra chamar o voltaLinhaContinuaColuna
[voltaLinhaContinuaColuna(linha, tam), atualizaPosition(linha, tam)] :
[voltaLinhaContinuaColuna(linha-1, tam-1), atualizaPosition(linha, tam)]
)
const quandoMaiorQueCinco = (linha, coluna) => (
coluna ?
pulaLinhaDiminuiColuna(linha, coluna) :
volta2LinhasUltimaColuna(linha, distribuicao[linha-2].length-1)
)
const pulaLinhaOuColuna = (linha, coluna) =>
!coluna ? pulaLinha(linha, coluna) : pulaLinhaColuna(linha, coluna)
const pulaLinhaVaiParaColuna = (linha, tam) =>
voltaLinhaContinuaColuna(linha-1, tam)
const quandoUmaOuDuasLinhas = (linha, coluna, positions) => {
switch(coluna) {
case 0:
return continuaLinhaAndaColuna(linha, coluna)
case 1:
return pulaLinhaIniciaColuna(linha, coluna)
default:
//if(coluna === distribuicao[linha].length-1) { // Ou coloca um else nesse cara, ou não precisa dele.
return pulaLinhaDiminuiColuna(positions.linha, positions.coluna)
//}
}
}
//-----------------------------------------------
//
const getNextElement = ([[linha, coluna], positions]) => {
switch(true) {
//case isFinal(linha, coluna): // em tese podemos apagar essa condição, o default do switch vai dar conta
// return [false, positions]
case !linha:
return [pulaLinhaOuColuna(linha, coluna), positions]
case linha === 1 || linha === 2:
return [quandoUmaOuDuasLinhas(linha, coluna, positions), positions]
case linha > 2 && linha < 5:
return quandoEntreDuaseCincoLinhas(linha, coluna, positions) // <-- essa é a única que atualiza positions!
case linha >= 5:
return [quandoMaiorQueCinco(linha, coluna), positions]
default:
return [false, positions]
}
}
const flatten = arr =>
arr.reduce( (result, subarr) =>
[...result, ...subarr], [])
const print = arr => arr.forEach( v => console.log(v) )
const getValue = ([x, y]) => distribuicao[x][y]
const start = [0,0]
const posicaoInicial = { linha: 0, coluna: 0 }
const initialState = { result: [], params: [start, posicaoInicial] }
const step = ({
result,
params: [next, position]
})=> ({ // dá pra fazer melhor, mandando o segundo parâmetro e utilizando ele dentro do cálculo, imagino que isso pode simplificar algumas funções
result: [...result, getValue(next)],
params: getNextElement([next, position])
})
const solved = flatten(distribuicao)
.reduce(step, initialState).result
print(solved)
}
@halan
Copy link
Author

halan commented Nov 19, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment