NUMBER) RETURN BOOLEAN IS L_LIMITE_INFERIOR NUMBER := 875106; L_DIVISOR NUMBER := 4;BEGIN RETURN (P_NUMERO >= L_LIMITE_INFERIOR) AND (P_NUMERO MOD L_DIVISOR = 0); EXCEPTION WHEN OTHERS THEN BEGIN DBMS_OUTPUT.PUT_LINE(SQLERRM); END; END;Finalmente, a implementacao do procedimento CALCULA_NUMERO_BONITO_DISTINTO:PROCEDURE CALCULA_NUMERO_BONITO_DISTINTO(P_PERGAMINHO_ID NUMBER) IS L_ORDEM NUMBER; L_LETRA CHAR; L_UNIDADE NUMBER; L_NUMERO NUMBER; I NUMBER;BEGIN I := 1; L_ORDEM := 1; FOR REGISTRO IN (SELECT PALAVRA FROM PALAVRAS WHERE PERGAMINHO_ID = P_PERGAMINHO_ID) LOOP L_NUMERO := 0; FOR I IN 1 .. LENGTH(REGISTRO.PALAVRA) LOOP L_LETRA := SUBSTR(REGISTRO.PALAVRA, I, 1); L_UNIDADE := GOOGLE_DEV_DAY_BRASIL_2011.LETRA_TO_UNIDADE(L_LETRA); L_NUMERO := L_NUMERO + (L_UNIDADE * POWER(20, I - 1)); END LOOP; IF GOOGLE_DEV_DAY_BRASIL_2011.IS_NUMERO_BONITO(L_NUMERO) THEN INSERT INTO NUMEROS(NUMERO_ID, PERGAMINHO_ID, ORDEM, NUMERO) VALUES(NUMEROS_SEQ.NEXTVAL, P_PERGAMINHO_ID, L_ORDEM, L_NUMERO); L_ORDEM := L_ORDEM + 1; END IF; I := I + 1; END LOOP; UPDATE PERGAMINHOS P SET P.NUMERO_BONITO_DISTINTO = ( SELECT COUNT(DISTINCT NUMERO) FROM NUMEROS WHERE PERGAMINHO_ID = P.PERGAMINHO_ID) WHERE P.PERGAMINHO_ID = P_PERGAMINHO_ID; EXCEPTION WHEN OTHERS THEN BEGIN DBMS_OUTPUT.PUT_LINE(SQLERRM); END; END;ConcluindoAgora com todos os procedimentos e funcoes implementadas, segue o pacote GOOGLE_DEV_DAY_BRASIL_2011:Package:CREATE OR REPLACE PACKAGE GOOGLE_DEV_DAY_BRASIL_2011 IS -- AUTHOR : SAKAMOTO -- SITE : MyTraceLog - Registro de um DBA -- URL : http://mytracelog.blogspot.com -- CREATED : 14/08/2011 16:42:22 -- PURPOSE : PROVINHA DE PROGRAMACAO - GOOGLE DEVELOPER DAY BRASIL 2011 -- VERSION : 1.0 SEPARADOR CONSTANT CHAR := ' '; FUNCTION COUNT_PALAVRAS(P_PERGAMINHO VARCHAR2, P_SEPARADOR VARCHAR2) RETURN NUMBER; FUNCTION LETRA_TO_UNIDADE(P_LETRA CHAR) RETURN NUMBER; FUNCTION IS_NUMERO_BONITO(P_NUMERO NUMBER) RETURN BOOLEAN; PROCEDURE PERGAMINHO_TO_PALAVRAS(P_PERGAMINHO_ID NUMBER); PROCEDURE CALCULA_PREPOSICAO(P_PERGAMINHO_ID NUMBER); PROCEDURE CALCULA_VERBO(P_PERGAMINHO_ID NUMBER); PROCEDURE CALCULA_VERBO_PRIMEIRA_PESSOA(P_PERGAMINHO_ID NUMBER); PROCEDURE PALAVRAS_TO_LISTA_VOCABULARIO(P_PERGAMINHO_ID NUMBER); PROCEDURE CALCULA_NUMERO_BONITO_DISTINTO(P_PERGAMINHO_ID NUMBER);END GOOGLE_DEV_DAY_BRASIL_2011;Package Body:CREATE OR REPLACE PACKAGE BODY GOOGLE_DEV_DAY_BRASIL_2011 IS -- AUTHOR : SAKAMOTO -- SITE : MyTraceLog - Registro de um DBA -- URL : http://mytracelog.blogspot.com -- CREATED : 14/08/2011 16:42:22 -- PURPOSE : PROVINHA DE PROGRAMACAO - GOOGLE DEVELOPER DAY BRASIL 2011 -- VERSION : 1.0/*********************************************************************************/ FUNCTION COUNT_PALAVRAS(P_PERGAMINHO VARCHAR2, P_SEPARADOR VARCHAR2) RETURN NUMBER IS L_TOTAL_PALAVRAS NUMBER; L_EXPRESSAO_REGULAR VARCHAR2(4);BEGIN L_EXPRESSAO_REGULAR := '[^' || P_SEPARADOR || ']'; EXECUTE IMMEDIATE 'SELECT LENGTH(REGEXP_REPLACE(:1,:2,NULL))+1 FROM DUAL' INTO L_TOTAL_PALAVRAS USING P_PERGAMINHO, L_EXPRESSAO_REGULAR; RETURN L_TOTAL_PALAVRAS; EXCEPTION WHEN OTHERS THEN BEGIN DBMS_OUTPUT.PUT_LINE(SQLERRM); END;END;/*********************************************************************************/FUNCTION LETRA_TO_UNIDADE(P_LETRA CHAR) RETURN NUMBER IS L_UNIDADE NUMBER;BEGIN SELECT DECODE(P_LETRA, 'd',0, 'c',1, 'x',2, 'k',3, 'j',4, 's',5, 'm',6, 'v',7, 'r',8, 'l',9, 'g',10, 'f',11, 't',12, 'w',13, 'p',14, 'q',15, 'z',16, 'n',17, 'b',18, 'h',19) INTO L_UNIDADE FROM DUAL; RETURN L_UNIDADE; EXCEPTION WHEN OTHERS THEN BEGIN DBMS_OUTPUT.PUT_LINE(SQLERRM); END;END;/*********************************************************************************/FUNCTION IS_NUMERO_BONITO(P_NUMERO NUMBER) RETURN BOOLEAN IS L_LIMITE_INFERIOR NUMBER := 875106; L_DIVISOR NUMBER := 4;BEGIN RETURN(P_NUMERO >= L_LIMITE_INFERIOR) AND (P_NUMERO MOD L_DIVISOR = 0); EXCEPTION WHEN OTHERS THEN BEGIN DBMS_OUTPUT.PUT_LINE(SQLERRM); END; END;/*********************************************************************************/PROCEDURE PERGAMINHO_TO_PALAVRAS(P_PERGAMINHO_ID NUMBER) IS L_PERGAMINHO VARCHAR2(4000); L_TOTAL_PALAVRAS NUMBER; L_PALAVRA VARCHAR2(4000); L_INICIO NUMBER;BEGIN EXECUTE IMMEDIATE 'SELECT PERGAMINHO FROM PERGAMINHOS WHERE PERGAMINHO_ID = :1' INTO L_PERGAMINHO USING P_PERGAMINHO_ID; L_TOTAL_PALAVRAS := GOOGLE_DEV_DAY_BRASIL_2011.COUNT_PALAVRAS(L_PERGAMINHO, GOOGLE_DEV_DAY_BRASIL_2011.SEPARADOR); L_PERGAMINHO := L_PERGAMINHO || GOOGLE_DEV_DAY_BRASIL_2011.SEPARADOR; L_INICIO := 1; FOR I IN 1 .. L_TOTAL_PALAVRAS LOOP L_PALAVRA := SUBSTR(L_PERGAMINHO, L_INICIO, INSTR(L_PERGAMINHO, GOOGLE_DEV_DAY_BRASIL_2011.SEPARADOR, 1, I) - L_INICIO); L_INICIO := INSTR(L_PERGAMINHO, GOOGLE_DEV_DAY_BRASIL_2011.SEPARADOR, 1, I) + 1; INSERT INTO PALAVRAS(PALAVRA_ID, PERGAMINHO_ID, ORDEM, PALAVRA) VALUES(PALAVRAS_SEQ.NEXTVAL, P_PERGAMINHO_ID, I, L_PALAVRA); END LOOP; EXCEPTION WHEN OTHERS THEN BEGIN DBMS_OUTPUT.PUT_LINE(SQLERRM); END;END;/*********************************************************************************/PROCEDURE CALCULA_PREPOSICAO(P_PERGAMINHO_ID NUMBER) IS L_EXPRESSAO_REGULAR VARCHAR2(32) := '^[^w]{4}[^wvkbps]$';BEGIN EXECUTE IMMEDIATE 'UPDATE PERGAMINHOS P SET P.PREPOSICAO = ( SELECT COUNT(*) FROM PALAVRAS WHERE PERGAMINHO_ID = P.PERGAMINHO_ID AND REGEXP_LIKE(PALAVRA,:1) ) WHERE