clear_functions()
cur.execute("""
SET @base_value = 2,
@extracting_column = 2,
@number_of_columns = 40,
@number_of_layers = 5,
@active_side = 2;
""")
cur.execute(f"""
CREATE FUNCTION numbering_formula
(
layer INT,
side INT,
column_ INT
)
RETURNS int
BEGIN
DECLARE loop_ INT;
DECLARE a_upper INT;
DECLARE ch0 INT;
DECLARE ch1 INT;
DECLARE extra INT;
DECLARE a_lower INT;
DECLARE cdb0 INT;
DECLARE cde0 INT;
DECLARE cdb1 INT;
DECLARE cde1 INT;
IF NOT (1 <= layer AND layer <= @number_of_layers AND (side = 1 OR side = 2) AND 1 <= column_ AND column_ <= @number_of_columns AND column_ != @extracting_column) THEN
RETURN -1;
END IF;
SET side = CASE WHEN @active_side = 1 THEN side else flip_side(side) END;
SET loop_ = CASE WHEN abs(column_ - @extracting_column) <= @base_value THEN layer - 1 ELSE layer + abs(column_ - @extracting_column) - @base_value - 1 END;
IF abs(column_ - @extracting_column) <= @base_value THEN
SET a_upper = lower_area(loop_ + 1);
SET ch0 = circ_horz(loop_, @extracting_column);
SET ch1 = circ_horz(loop_, flip_column(@extracting_column));
SET extra = (CASE WHEN side = 1 THEN 0 ELSE ch0 + ch1 END) + (CASE WHEN column_ > @extracting_column THEN 0 ELSE ch0 END);
RETURN a_upper - 2*(ch0 + ch1) + extra + abs(column_ - @extracting_column);
ELSE
SET a_lower = lower_area(loop_);
SET cdb0 = circ_diag_before(layer, side, column_, loop_, @extracting_column);
SET cde0 = circ_diag_exists(layer, side, column_, loop_, @extracting_column);
SET cdb1 = circ_diag_before(layer, side, 2*@extracting_column - column_, loop_, @extracting_column);
SET cde1 = circ_diag_exists(layer, side, 2*@extracting_column - column_, loop_, @extracting_column);
RETURN a_lower + 2*(cdb0 + cdb1) + (CASE WHEN side = 1 THEN 0 ELSE cde0 + cde1 END) + (CASE WHEN column_ > @extracting_column THEN 0 ELSE cde1 END) + 1;
END IF;
END
""")
cur.execute("""
CREATE FUNCTION flip_side
(
side INT
)
RETURNS INT
BEGIN
RETURN CASE WHEN side = 1 THEN 2 ELSE 1 END;
END
""")
cur.execute("""
CREATE FUNCTION flip_column
(
column_ INT
)
RETURNS INT
BEGIN
RETURN @number_of_columns - column_ + 1;
END
""")
cur.execute("""
CREATE FUNCTION lower_area
(
loop_ INT
)
RETURNS INT
BEGIN
RETURN 2 * (area_diag(loop_, @extracting_column) +
area_diag(loop_, flip_column(@extracting_column)) +
area_horz(loop_, @extracting_column) +
area_horz(loop_, flip_column(@extracting_column)));
END
""")
cur.execute("""
CREATE FUNCTION area_diag
(
loop_ INT,
extracting_column INT
)
RETURNS INT
BEGIN
IF extracting_column + @base_value > @number_of_columns THEN
RETURN 0;
END IF;
RETURN bin2(loop_) - bin2(loop_ + extracting_column + @base_value - @number_of_columns) - bin2(loop_ - @number_of_layers) + bin2(loop_ + extracting_column + @base_value - @number_of_columns - @number_of_layers);
END
""")
cur.execute("""
CREATE FUNCTION bin2
(
n INT
)
RETURNS INT
BEGIN
RETURN CASE WHEN n > 0 THEN n*(n-1) DIV 2 ELSE 0 END;
END
""")
cur.execute("""
CREATE FUNCTION min_
(
a INT,
b INT
)
RETURNS INT
BEGIN
RETURN CASE WHEN a < b THEN a ELSE b END;
END
""")
cur.execute("""
CREATE FUNCTION max_
(
a INT,
b INT
)
RETURNS INT
BEGIN
RETURN CASE WHEN a < b THEN b ELSE a END;
END
""")
cur.execute("""
CREATE FUNCTION area_horz
(
loop_ INT,
extracting_column INT
)
RETURNS INT
BEGIN
RETURN min_(@base_value, @number_of_columns - extracting_column)*min_(loop_, @number_of_layers);
END
""")
cur.execute("""
CREATE FUNCTION circ_horz
(
loop_ INT,
extracting_column INT
)
RETURNS INT
BEGIN
RETURN CASE WHEN loop_ < @number_of_layers THEN min_(@base_value, @number_of_columns - extracting_column) ELSE 0 END;
END
""")
cur.execute("""
CREATE FUNCTION circ_diag_before
(
layer INT,
side INT,
column_ INT,
loop_ INT,
extracting_column INT
)
RETURNS INT
BEGIN
IF column_ < extracting_column THEN
SET column_ = flip_column(column_);
SET extracting_column = flip_column(extracting_column);
END IF;
RETURN max_(0, min_(layer - 1, @number_of_columns - column_));
END
""")
cur.execute("""
CREATE FUNCTION circ_diag_exists
(
layer INT,
side INT,
column_ INT,
loop_ INT,
extracting_column INT
)
RETURNS INT
BEGIN
IF column_ < extracting_column THEN
SET column_ = flip_column(column_);
SET extracting_column = flip_column(extracting_column);
END IF;
RETURN cast(column_ <= @number_of_columns AS INT);
END
""")
Comments
0 B
|👍
/👎