FFFF/Implementation

From Esolang
Jump to navigation Jump to search

This is an implementation of FFFF in Python by User:RainbowDash.

from fractions import Fraction
import sys

def reduce_pair(a, b=None):
    """Convert inputs to Fraction, optionally divide by b, return as [numerator, denominator]."""
    if isinstance(a, (list, tuple)) and len(a) == 2:
        f = Fraction(a[0], a[1])
    else:
        f = Fraction(a)

    if b is None:
        return [f.numerator, f.denominator]

    if isinstance(b, (list, tuple)):
        if len(b) == 2:
            f /= Fraction(b[0], b[1])
        elif len(b) == 1:
            f /= Fraction(b[0])
        else:
            raise ValueError(f"Cannot divide by multi-element list: {b}")
    else:
        f /= Fraction(b)

    return [f.numerator, f.denominator]

def simplify_fraction(pair, debug=False):
    """Simplify pair to integer if divisible, otherwise return as 'a/b' string."""
    # check if input is a single int
    if isinstance(pair, int):
        return str(pair)

    # assume input is a pair [a, b]
    a, b = pair
    if b == 0:
        raise ValueError("Denominator cannot be zero!")
    if debug:
        if a % b == 0:
            return str(a // b)
        else:
            return f"{a}/{b}"
    return f"{a}/{b}"

def load_program(filename):
    try:
        with open(filename, "r") as f:
            return f.read()
    except FileNotFoundError:
        print(f"File not found: {filename}")
        sys.exit(1)


def parse_program(prgm, array2d):
    """Parse lines, fill array2d and return initial value a."""
    a = 1
    for line in prgm.splitlines():
        if not line.strip():
            continue
        parts = line.split()
        if len(parts) == 1:
            if "/" in parts[0]:
                a = [int(x) for x in parts[0].split("/")]
            else:
                a = int(parts[0])
        else:
            src = [int(x) for x in parts[0].split("/")]
            dst = [int(x) for x in parts[2].split("/")]
            array2d[src[1]][src[0]] = dst
    return a


def main():
    if len(sys.argv) < 2:
        print("Usage: python script.py <filename.ffff>")
        sys.exit(1)

    filename = sys.argv[1]
    program = load_program(filename)

    ROWS, COLS = 1000, 1000
    array2d = [[1 for _ in range(COLS)] for _ in range(ROWS)]

    DEBUG_SIMPLIFY_PRINT = False
    a = parse_program(program, array2d)
    print(simplify_fraction(a, debug=DEBUG_SIMPLIFY_PRINT))

    fract = reduce_pair(a, int(input("> ")))
    fract = reduce_pair(fract, array2d[fract[1]][fract[0]])
    print(simplify_fraction(fract, debug=DEBUG_SIMPLIFY_PRINT))

    while True:
        fract = reduce_pair(fract, int(input("> ")))
        fract = reduce_pair(fract, array2d[fract[1]][fract[0]])
        print(simplify_fraction(fract, debug=DEBUG_SIMPLIFY_PRINT))


if __name__ == "__main__":
    main()