Last active
November 20, 2023 21:38
-
-
Save evilthreads669966/ce93c099cb30b3d44254ef5ce54bb27f to your computer and use it in GitHub Desktop.
fraction math
This file contains 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 java.util.* | |
import java.util.concurrent.ConcurrentHashMap | |
import java.util.concurrent.Executors | |
import java.util.concurrent.Future | |
import java.util.concurrent.ThreadPoolExecutor | |
import kotlin.math.abs | |
fun main(){ | |
while(true){ | |
println("Enter for example 1/2 + 2/5") | |
println("Supports + - * /") | |
val input = readlnOrNull()?.trim() | |
if(input.isNullOrBlank()) continue | |
var parts = input.split(" ") | |
val result = evaluateFractionExpression(parts) | |
if(result == null) continue | |
result.reduce() | |
println("The answer is: $result") | |
} | |
} | |
fun evaluateFractionExpression(parts: List<String>): Fraction?{ | |
val leftFractionParts = parts[0].split("/") | |
val leftNumerator = leftFractionParts[0].toIntOrNull() | |
val leftDenominator = leftFractionParts[1].toIntOrNull() | |
if(leftNumerator == null) return null | |
if(leftDenominator == null) return null | |
val leftFraction = Fraction(leftNumerator,leftDenominator) | |
val rightFractionParts = parts[2].split("/") | |
val rightNumerator = rightFractionParts[0].toIntOrNull() | |
val rightDenominator = rightFractionParts[1].toIntOrNull() | |
if(rightNumerator == null) return null | |
if(rightDenominator == null) return null | |
val rightFraction = Fraction(rightNumerator, rightDenominator) | |
when(parts[1]){ | |
"+" -> return leftFraction + rightFraction | |
"-" -> return leftFraction - rightFraction | |
"*" -> return leftFraction * rightFraction | |
"/" -> return leftFraction / rightFraction | |
else -> return null | |
} | |
} | |
fun slope(first: Point, second: Point): Fraction{ | |
val rise = second.y - first.y | |
val run = second.x - first.x | |
val fraction = Fraction(rise, run) | |
fraction.reduce() | |
return fraction | |
} | |
data class Fraction (var numerator: Int, var denominator: Int): Comparable<Fraction>{ | |
companion object{ | |
@JvmStatic | |
fun sort(fractions: Collection<Fraction>): List<Fraction>{ | |
val lcm = lcm(fractions.map { it.denominator }) | |
val copy = mutableListOf<Fraction>() | |
fractions.forEach { copy.add(it.copy()) } | |
copy.forEach { | |
it.numerator = it.numerator * (lcm / it.denominator) | |
it.denominator = lcm | |
} | |
return copy.sortedBy { it.numerator } | |
} | |
} | |
fun reduce(){ | |
try{ | |
val gcf = gcf(sortedSetOf(abs(denominator.toLong()),abs(numerator.toLong()))).gcf.toInt() | |
denominator = denominator / gcf | |
numerator = numerator /gcf | |
}catch (e: NumberZeroException){ } | |
} | |
fun add(fraction: Fraction): Fraction{ | |
var lcm = lcm(listOf(denominator, fraction.denominator)) | |
numerator = numerator * (lcm / denominator) | |
fraction.numerator = fraction.numerator * (lcm / fraction.denominator) | |
val result = Fraction(numerator + fraction.numerator, lcm) | |
return result | |
} | |
fun subtract(fraction: Fraction): Fraction{ | |
var lcm = lcm(listOf(denominator, fraction.denominator)) | |
numerator = numerator * (lcm / denominator) | |
fraction.numerator = fraction.numerator * (lcm / fraction.denominator) | |
val result = Fraction(numerator - fraction.numerator, lcm) | |
result.reduce() | |
return result | |
} | |
fun multiply(fraction: Fraction): Fraction{ | |
val result = Fraction(numerator * fraction.numerator, denominator * fraction.denominator) | |
result.reduce() | |
return result | |
} | |
fun divide(fraction: Fraction): Fraction{ | |
val result = Fraction(numerator * fraction.denominator, denominator * fraction.numerator) | |
result.reduce() | |
return result | |
} | |
override fun compareTo(other: Fraction): Int { | |
val lcm = lcm(listOf(denominator, other.denominator)) | |
numerator = numerator * (lcm / denominator) | |
other.numerator = other.numerator * (lcm / other.denominator) | |
if(numerator > other.numerator) | |
return 1 | |
else if(numerator < other.numerator) | |
return -1 | |
else | |
return 0 | |
} | |
operator fun plus(fraction: Fraction): Fraction = add(fraction) | |
operator fun minus(fraction: Fraction): Fraction = subtract(fraction) | |
operator fun times(fraction: Fraction): Fraction = multiply(fraction) | |
operator fun div(fraction: Fraction): Fraction = divide(fraction) | |
override fun toString(): String { | |
return "$numerator/$denominator" | |
} | |
} | |
fun Collection<Fraction>.reduce() = forEach { it.reduce() } | |
fun Collection<Fraction>.sort(): List<Fraction> = Fraction.sort(this) | |
@Throws(NumberZeroException::class, NegativeNumberException::class) | |
fun gcf(numbers: SortedSet<Long>): FactorResult<Long> { | |
numbers.forEach { | |
if(it == 0L) throw NumberZeroException() | |
if(it < 0L) throw NegativeNumberException() | |
} | |
val factors = ConcurrentHashMap<Long, MutableList<Long>>() | |
numbers.forEach { num -> | |
factors[num] = mutableListOf() | |
} | |
var pool = Executors.newFixedThreadPool(numbers.size) as ThreadPoolExecutor | |
val tasks = mutableListOf<Future<*>>() | |
numbers.forEach { num -> | |
val task = pool.submit { | |
for (i in 1..num) { | |
if (num % i == 0L) { | |
synchronized(factors){ | |
factors[num]!!.add(i) | |
} | |
} | |
} | |
} | |
tasks.add(task) | |
} | |
tasks.forEach { it.get() } | |
if (numbers.size == 1) { | |
factors[numbers.first()]!! | |
return FactorResult(factors[numbers.first()]!!.last(), factors[numbers.first()]!!, factors) | |
} | |
val commonFactors = Collections.synchronizedList(mutableListOf<Long>()) | |
numbers.drop(1) | |
tasks.clear() | |
if(pool.maximumPoolSize < factors[factors.keys.first()]!!.size) | |
pool.maximumPoolSize = factors[factors.keys.first()]!!.size | |
factors[factors.keys.first()]!!.forEach { factor -> | |
val task = pool.submit { | |
var count = 0 | |
numbers.forEach { num -> | |
if (factors[num]!!.contains(factor)) | |
count++ | |
} | |
if (count == numbers.size) | |
synchronized(commonFactors){ | |
commonFactors.add(factor) | |
} | |
} | |
tasks.add(task) | |
} | |
tasks.forEach { it.get() } | |
val result = FactorResult<Long>(commonFactors.max(), commonFactors, factors) | |
return result | |
} | |
fun lcm(numbers: List<Int>): Int{ | |
var lcm: Int = numbers.max() | |
while(true){ | |
var isMultiple = false | |
for(number in numbers) { | |
println("$lcm $number") | |
if(lcm % number != 0) { | |
lcm++ | |
continue | |
}else{ | |
if(!isMultiple) | |
isMultiple = true | |
} | |
} | |
if(isMultiple){ | |
println(lcm) | |
return lcm | |
} | |
} | |
} | |
class FactorResult<T: Number>(val gcf: T, val commonFactors: List<T>, val factors: Map<T,List<T>>) | |
class NumberZeroException: Exception("Do not enter the number zero") | |
class NegativeNumberException: Exception("Do not enter negative numbers") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment