Last active
November 12, 2023 18:17
-
-
Save tommysullivan/e038bbc9dbe721d7a9c96b3d5ca818e2 to your computer and use it in GitHub Desktop.
parecel cost decision
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
import { sum, uniq } from "lodash" | |
const previousLandValue = 250000 | |
const previousHomeValue = 450000 | |
const previousAcreage = 20 | |
const parcelAcreage = 3 | |
const currentAcreage = previousAcreage - parcelAcreage | |
const multiplierForTwoParcelsIntrinsicValue = 1.15 | |
const parcelViewMultiplier = 1.1 | |
const parcelInaccessibilityMultiplier = 0.9 | |
const costOfGravelPerFoot =(0.86 + 3.85) / 2 | |
const pavementCostPerFoot = (3 + 4) / 2 | |
const drivewayCostUnknownsMultiplier = 1.3 | |
const nettingCostPerSquareFoot = 1 //TODO: Consider whether netting that plants can grow thru would be sufficient / worth it and add that | |
//Derived Quantities | |
const parcelLandValue = parcelAcreage / previousAcreage * previousLandValue * multiplierForTwoParcelsIntrinsicValue * parcelViewMultiplier * parcelInaccessibilityMultiplier | |
const currentLandValue = currentAcreage / previousAcreage * previousLandValue * multiplierForTwoParcelsIntrinsicValue | |
const drivewaySegments = { | |
1: { sharedBy: ["deb"], lengthInFeet: 1000 }, | |
2: { sharedBy: ["deb", "sweni"], lengthInFeet: 6000 }, | |
3: { sharedBy: ["deb", "sweni", "pam"], lengthInFeet: 9000 }, | |
4: { sharedBy: ["deb", "sweni", "pam", "cabin"], lengthInFeet: 9000 }, | |
5: { sharedBy: ["deb", "sweni", "pam", "cabin", "ladies"], lengthInFeet: 5000 }, | |
6: { sharedBy: ["deb", "sweni", "pam", "cabin", "ladies", "drena"], lengthInFeet: 1000 }, | |
} | |
type SegmentId = keyof typeof drivewaySegments | |
const numPeoplePayingForSegmentId = (segmentId:SegmentId) => drivewaySegments[segmentId].sharedBy.length | |
//P1 | |
const parcelWideningCost = 3000 | |
const parcelGravelCost = drivewaySegments[1].lengthInFeet * costOfGravelPerFoot | |
const parcelPavementFeet = 200 | |
const parcelPavementCost = parcelPavementFeet * pavementCostPerFoot | |
//P2 | |
const p2EstimatedWideningCost = 5000 //widening the area by the drive and putting some retaining wall, potential widening of sharp turn by pump | |
const p2PavementFeet = | |
150 //by the water pump | |
+ 150 //up the hill | |
const p2GravelFeet = | |
p2PavementFeet + | |
250 //area in front of our house i want nice gravel from sweni sign until around the corner | |
const p2GravelCost = p2GravelFeet * costOfGravelPerFoot | |
const p2PavementCost = p2PavementFeet * pavementCostPerFoot | |
//P3 | |
const p3WideningCost = 8000 //straightaway, has trees, not easy to get to, steep wall needs more retaining wall costs | |
const p3PavementFeet = 600 //large hill up to pams | |
const p3PavementCost = p3PavementFeet * pavementCostPerFoot | |
//P4 - goes from cabin drive to bottom of the ladies bump | |
const p4WideningCost = 500 | |
const p4PavementLengthInFeet = 500 | |
const lengthFromMirrorToLadiesHouse = 200 | |
const p4GravelCost = (p4PavementLengthInFeet + lengthFromMirrorToLadiesHouse) * costOfGravelPerFoot | |
const p4PavementCost = p4PavementLengthInFeet * pavementCostPerFoot | |
const drivewayOutcomes = [ | |
{ | |
description: "Pave hilly parts, smooth and add gravel the rest, widened to 15ft", | |
segmentCosts: [ | |
{ id: 1, cost: (parcelWideningCost + parcelGravelCost + parcelPavementCost)}, | |
{ id: 2, cost: (p2EstimatedWideningCost + p2GravelCost + p2PavementCost)}, | |
{ id: 3, cost: (p3WideningCost + p3PavementCost)}, | |
{ id: 4, cost: (p4WideningCost + p4GravelCost + p4PavementCost)}, | |
] | |
} | |
] | |
const drivewayPeople = uniq(Object | |
.values(drivewaySegments) | |
.flatMap(s => s.sharedBy)) | |
type DrivewayOutcomes = typeof drivewayOutcomes | |
type DrivewayOutcome = DrivewayOutcomes[0] | |
type DrivewayPerson = (typeof drivewayPeople)[0] | |
const drivewayCostsPerOutcome = | |
(a:DrivewayOutcomes) => | |
a.map( | |
o => | |
({ | |
description: o.description, | |
cost: Object.fromEntries( | |
drivewayPeople.map( | |
person => | |
[person, drivewayCostPerPersonOutcome(person)(o)] | |
) | |
), | |
total: sum(drivewayPeople.map(p => drivewayCostPerPersonOutcome(p)(o))) | |
}) | |
) | |
const drivewayCostPerPersonOutcome = | |
(p:DrivewayPerson) => | |
(o:DrivewayOutcome) => | |
{ | |
const costs = segmentIdsForPerson(p) | |
.map( | |
sId => { | |
const segment = o.segmentCosts.find( | |
sc => | |
sc.id == sId | |
) | |
if(segment == undefined) return 0; | |
return segment.cost / numPeoplePayingForSegmentId(segment.id as any) * drivewayCostUnknownsMultiplier | |
} | |
) | |
return sum(costs) | |
} | |
const segmentIdsForPerson = | |
(person:DrivewayPerson):SegmentId[] => | |
Object.entries(drivewaySegments).filter(([, segment]) => segment.sharedBy.includes(person)).map(([id,]) => id) as unknown as SegmentId[] | |
console.log(drivewayCostsPerOutcome(drivewayOutcomes)) | |
console.log(JSON.stringify(drivewayOutcomes, null, 3)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
to run:
yarn i
npx ts-node calc.ts
output: