-
-
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"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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