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 9, 2016

@suissa roda aí, deu certo os positions.

@suissa
Copy link

suissa commented Nov 9, 2016

Q DOIDERA! \o/

@rhnasc
Copy link

rhnasc commented Nov 9, 2016

Functional implementation in elm:

https://gist.github.com/rhnasc/ae91ffebc3f6cbf044b0a637a231c435

import Html exposing (text)
import Array

arr =
  Array.fromList [ Array.fromList ["1s2"]
  , Array.fromList ["2s2", "2p6"]
  , Array.fromList ["3s2", "3p6", "3d10"]
  , Array.fromList ["4s2", "4p6", "4d10", "4f14"]
  , Array.fromList ["5s2", "5p6", "5d10", "5f14"]
  , Array.fromList ["6s2", "6p6", "6d10"]
  , Array.fromList ["7s2", "7p6"]
  ]

arr_i coords =
 case coords of
  (x,y) -> case Array.get x arr of
             Just a -> case Array.get y a of
                         Just b -> b
                         Nothing -> "y out of bound"
             Nothing -> "x out of bound"

next_iteration tuple = 
 case tuple of
   (0,0) -> (1,0)
   (x,0) -> (ceiling((x+1)/2),floor((x+1)/2))
   (x,y) -> (x+1,y-1)

iterations list =
 case List.head list of
   Just (6,1) -> list
   Just tuple -> iterations[next_iteration tuple] ++ list
   _ -> iterations [(0,0)]

main = text <| toString <| List.map arr_i ( List.reverse ( iterations [] ) )

["1s2","2s2","2p6","3s2","3p6","4s2","3d10","4p6","5s2","4d10","5p6","6s2","4f14","5d10","6p6","7s2","5f14","6d10","7p6"]

@halan
Copy link
Author

halan commented Nov 11, 2016

@rhnasc

import Html exposing (text, Html)
import Array

type alias Coord = (Int, Int)
type alias Line = Array.Array String
type alias Distribution = Array.Array Line

arr : Distribution
arr =
    [ ["1s2"]
    , ["2s2", "2p6"]
    , ["3s2", "3p6", "3d10"]
    , ["4s2", "4p6", "4d10", "4f14"]
    , ["5s2", "5p6", "5d10", "5f14"]
    , ["6s2", "6p6", "6d10"]
    , ["7s2", "7p6"]
  ]
    |> Array.fromList
    |> Array.map Array.fromList

arr_i : Coord -> String
arr_i coords =
 case coords of
  ( x, y ) ->
    case Array.get x arr of
      Just a ->
        case Array.get y a of
          Just b -> b
          Nothing -> "y out of bound"
      Nothing -> "x out of bound"

next_iteration : Coord -> Coord
next_iteration tuple =
 case tuple of
     (0,0) ->
       (1,0)
     (x,0) ->
       ( ceiling( (x+1) / 2 )
       , floor( (x+1) / 2 )
       )
     (x,y) ->
       (x+1,y-1)

iterations : List Coord -> List Coord
iterations list =
 case List.head list of
   Just (6,1) ->
     list
   Just tuple ->
     iterations[next_iteration tuple] ++ list
   _ ->
     iterations [(0,0)]


main =
  iterations []
    |> List.reverse
    |> List.map arr_i
    |> toString
    |> text

@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