Слон, корова и козел. Расширение стандартного функционала SAP HANA недокументированными функциями
HANA – это мощный инструмент для решения различных задач. В этой статье приводится пример решения простой математической задачи различными способами.
Введение.
Однажды, читая SCN я наткнулся на интересную статью по решению математической задачки с помощью SAP HANA. Оригинальная статья –
Я же хочу немного прокомментировать предложенные решения и слегка их дополнить.
Постановка задачи.
У Вас есть 100$, потратив их полностью (1), вы хотите купить ровно 100 игрушек (2).
Есть всего три варианта покупки: Слон за 10$, Корова за 3$, и Козел за 0.5$ (3).
Сколько необходимо купить слонов, коров и козлов, чтобы они удовлетворяли всем (трём) условиям.
Предложенное решение.
Первый и, пожалуй, самый очевидный способ поиска решения, который пришёл в голову коллегам – это сделать три вложенных цикла и если все условия выполнены – добавить сообщение в таблицу из которой потом выбирается результат.
CREATE TABLE PRACTICE_TEST.MY_LOG
(LOG_ENTRY varchar(100));
--procedure to make entries in log tables
CREATE PROCEDURE PRACTICE_TEST.PROC_MY_LOG
(IN v_in_msg VARCHAR (100) )
LANGUAGE SQLSCRIPT
AS
BEGIN
INSERT INTO PRACTICE_TEST.MY_LOG ( LOG_ENTRY) VALUES (:v_in_msg);
END;
--dropping any other procedure with similar name (just in case)
DROP PROCEDURE PRACTICE_TEST.PROC_PUZZLE_OUTPUT;
--Creating the actual stored procedure to process the business logic
CREATE PROCEDURE PRACTICE_TEST.PROC_PUZZLE_OUTPUT
LANGUAGE SQLSCRIPT
AS
ELEPHANT_COUNT integer;
COW_COUNT integer;
GOAT_COUNT integer;
ELEPHANT integer;
CNTR integer;
v_msg varchar(100);
Begin
ELEPHANT_COUNT := 1;
CNTR := 0;
v_msg := '';
While ELEPHANT_COUNT < 10
DO
COW_COUNT := 1;
While COW_COUNT < 100
DO
GOAT_COUNT := 1;
while GOAT_COUNT < 100
Do
CNTR := CNTR + 1;
if MOD(:cntr, 1000) = 0 then
v_msg := 'CNTR RUN COUNT = '||:CNTR;
call PRACTICE_TEST.PROC_MY_LOG(:v_msg);
end if;
if ((:ELEPHANT_COUNT + :COW_COUNT + :GOAT_COUNT) = 100) AND ((:ELEPHANT_COUNT * 10) + (:COW_COUNT * 3) + (:GOAT_COUNT * 0.5) = 100)
THEN
v_msg := 'CNTR RUN COUNT = '||:CNTR || 'Goat Loop : Elephant count = '||:ELEPHANT_COUNT||' Cow count = '||:COW_COUNT||'Goat count = '||:GOAT_COUNT;
call PRACTICE_TEST.PROC_MY_LOG(:v_msg);
end if;
GOAT_COUNT := :GOAT_COUNT + 1;
END While;
COW_COUNT := :COW_COUNT + 1;
End While;
ELEPHANT_COUNT := :ELEPHANT_COUNT + 1;
end while;
End;
--deleting the log entries for previous runs
truncate table PRACTICE_TEST.MY_LOG;
--running the procedure having business logic
call PRACTICE_TEST.PROC_PUZZLE_OUTPUT;
--Checking the results in the log
SELECT * from PRACTICE_TEST.MY_LтоOG ASC;
Задача вроде решена, и даже с использованием HANA, но не использована вся её мощь. Да и решение получилось свойственное скорее языкам подобным C++или JAVA. Просто переложили логику на SQL-script. Примем время работы этого варианта- (1) за точку отсчёта.
Второй вариант - более интересный.
Формируется «вспомогательная» таблица со значениями от 1 до 100, а далее при запросе три раза JOIN к себе же, ну а в WHERE – условия, которые необходимы для решения задачи:
DROP TABLE COACH.HELPER;
DROP PROCEDURE COACH.INIT_GAME;
CREATE COLUMN TABLE "COACH"."HELPER" ("ID" INTEGER CS_INT NOT NULL);
CREATE PROCEDURE COACH.INIT_GAME() LANGUAGE SQLSCRIPT AS
v_count INT;
BEGIN
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти
Обсуждения 3
Комментарий от
Олег Башкатов
| 09 сентября 2013, 16:20
Предварительное упрощение условий должно быть, в любом случае (хоть это и SAP HANA).
ведь вся задача - это решение системы
C = (20 - 19*E/5);
G = 100 - E - C;
C,G,E - целые неотрицательные числа.
решение которой сводится к перебору значений E кратным 5, то есть всего два значения: 0 и 5.
то есть в итоге ответа два:
E=0;С=20;G=80
E=5;С=1;G=94
Комментарий от
Надежда Быкова
| 10 сентября 2013, 12:03
Олег Башкатов 09 сентября 2013, 16:20
Вы заметили, что автор статьи, на которую Вы ссылаетесь, решил задачу, вообще говоря, неверно :-) (нашел только 1 решение, а их два)?
Предварительное упрощение условий должно быть, в любом случае (хоть это и SAP HANA).
ведь вся задача - это решение системы
C = (20 - 19*E/5);
G = 100 - E - C;
C,G,E - целые неотрицательные числа.
решение которой сводится к перебору значений E кратным 5, то есть всего два значения: 0 и 5.
то есть в итоге ответа два:
E=0;С=20;G=80
E=5;С=1;G=94
Комментарий от
Олег Башкатов
| 10 сентября 2013, 14:23
Надежда Быкова 10 сентября 2013, 12:03
Автор статьи использовал в алгоритме решения одно необъявленное условие - в наборе игрушек должна быть хотя бы одна игрушка каждого вида. Кстати, в одном из своих комментариев он сделал замечание по поводу двойного решения системы.
Ответ получается однозначно.
Суть моего комментария: нельзя брать и "вслепую перебирать решения", какие бы вычислительные мощности не были.