Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save lastrafda/0c2f44041671aac1ad77ffdc4a64cfdc to your computer and use it in GitHub Desktop.
Save lastrafda/0c2f44041671aac1ad77ffdc4a64cfdc to your computer and use it in GitHub Desktop.
Código escrito durante o live coding "Resolvendo Problemas com Programação Funcional"
/*
* Links para o live coding:
* Parte I: https://www.youtube.com/watch?v=11HGQkaOT8c
* Parte II: https://www.youtube.com/watch?v=pFYIDtgkYb0
*/
/*
* Primeiro problema
*/
/*
* Transformar uma lista de pares [{name: a, answer: b}]
* em um mapa {a: b, ...}
* com todos os pares da lista
*/
import { compose, map, mergeAll } from "ramda"
type FerIn = {
name: string
answer: string
}
type FerOut = Record<string, string>
const inputExample: FerIn[] = [
{ name: 'first', answer: 'a' },
{ name: 'second', answer: 'e' },
]
const outputExample: FerOut = { first: 'a', second: 'e' }
const ferSolver = compose(
mergeAll,
map<FerIn, FerOut>(({ name, answer }) => ({ [name]: answer }))
)
console.log(
ferSolver(inputExample)
) // => { first: 'a', second: 'e' }
/*
* Segundo problema
*/
/*
* Dada uma lista de inteiros e um número n,
* devolver o uma lista com todos os pares de números
* x,y da lista tal que x*y = n
*
* resolver em O(n)!
*/
import { zipObj, repeat, length, reduce, append, divide, ifElse, prop, toString } from "ramda"
// exemplo de entrada
const listExample = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const nExample = 12
// exemplo de saída
const expected = [[2, 6], [3, 4], [4, 3], [6, 2]]
const brunoSolver = (list: number[], n: number) => {
const hashMap = zipObj(list, repeat(true, length(list))) as Record<number, boolean>
return reduce<number, number[][]>(
(acc, val) => ifElse(
prop(toString(divide(n, val))),
() => append([val, divide(n, val)], acc),
() => acc
)(hashMap),
[],
list,
)
}
brunoSolver(listExample, nExample) // => [ [ 2, 6 ], [ 3, 4 ], [ 4, 3 ], [ 6, 2 ] ]
/*
* Terceiro problema
*/
/*
* Transformar o tipo input no de output
*/
import { lensPath, view, set, zipObj, map, path, find, propEq, indexBy, indexOf, append, compose, Lens, reduce, equals } from "ramda"
export type CaioInput = {
properties: {
name: string
enabled: boolean
version: number
product: string
}
geometry: {
coordinates: number[][][]
"type": string
}
}
export const caioInput: CaioInput[] = [
{
properties: {
name: 'test',
enabled: true,
version: 0,
product: 'ibuyer',
},
geometry: {
"type": 'Polygon',
coordinates: [
[
[30, 30],
[-30, 30],
[-30, -30],
[30, -30],
[30, 30],
],
],
},
},
{
properties: {
name: 'test',
enabled: true,
version: 0,
product: 'marketplace',
},
geometry: {
type: 'Polygon',
coordinates: [
[
[90, 90],
[-90, 90],
[-90, -90],
[90, -90],
[90, 90],
],
],
},
}
]
export type Coordinate = {
lat: number
lng: number
}
export type Layer = {
product: string
polygons: Coordinate[][]
}
export type CaioOutput = {
layers: Layer[]
}
export const caioOutput: CaioOutput =
{
layers: [
{
product: 'loftGo',
polygons: [
[
{ lat: 30, lng: 30 },
{ lat: -30, lng: 30 },
{ lat: -30, lng: -30 },
{ lat: 30, lng: -30 },
{ lat: 30, lng: 30 },
],
],
},
{
product: 'loftMarket',
polygons: [
[
{ lat: 90, lng: 90 },
{ lat: -90, lng: 90 },
{ lat: -90, lng: -90 },
{ lat: 90, lng: -90 },
{ lat: 90, lng: 90 },
],
],
}
]
}
/*
* Funçoes auxilias
*/
const getPolygon = map(zipObj(['lat', 'lng']))
const getProdName = (name: string) => path([name])({
ibuyer: 'loftGo',
marketplace: 'loftMarket'
})
const getLayerIdx = (prodName: string, layers: Layer[]) =>
indexOf(
find(propEq('product', prodName), layers),
layers)
/*
* Lentes
*/
const layersLens = lensPath(['layers'])
const coordLens = lensPath(['geometry', 'coordinates', 0])
const productLens = lensPath(['properties', 'product'])
const initialAns: CaioOutput = {
layers: []
}
const caioSolver = (initAns: CaioOutput, input: CaioInput) => {
const layers = view(layersLens, initAns) as Layer[]
const prodName = getProdName(view(productLens, input)) as string
const layerIdx = getLayerIdx(prodName, layers)
const polygon = getPolygon(view(coordLens, input))
if (layerIdx > -1) {
const polygonsLens = compose(
layersLens,
lensPath([layerIdx, 'polygons'])
) as Lens
const polygons = view(polygonsLens, initAns) as Coordinate[][]
return set(polygonsLens,
append(polygon, polygons),
initAns
)
}
else {
const layer = { product: prodName, polygons: [polygon] }
return set(
layersLens,
append(layer, layers),
initAns
)
}
}
const answer = reduce(caioSolver, initialAns, caioInput)
console.log(
equals(answer, caioOutput)
) // => true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment