在没有定义函数的情况下检查布尔表达式中的素数

时间:2014-05-01 20:49:03

标签: oracle plsql

通过为IF语句提供一些布尔表达式,可以完成以下PL / SQL代码吗?

declare
   N int := extract(year from sysdate);
begin
   if INSERT_YOUR_BOOLEAN_EXPRESSION_HERE then
      dbms_output.put_line('Current year is prime number.');
   else
      dbms_output.put_line('Current year is not prime number.');
   end if;
end;

显然,您无法定义自己的功能 只允许使用标准的Oracle 11g PL / SQL函数 该代码应在2014-9999年期间正常运行。


编辑:
答案被接受了,但问题没有按照需要解决 那么,让我们继续吧。

让我们在不久的将来将时间间隔缩短到256年:2014-2269
您是否能够在Oracle服务器之外找到另一种解决方案,更聪明,更紧凑,没有外部依赖性? 在这项任务中取得成功需要一些好主意。


编辑#2:
当前记录长度为41个符号:not regexp_like(rpad(1,N,1),'^(11+)\1+$')
现在可能有人可以提供更加出色的解决方案吗? 我会留下足够的印象来奖励一个特大号的赏金)) 打败当前记录至少1个符号。

5 个答案:

答案 0 :(得分:5)

好的,这是另一个解决方案:

declare
N int := extract(year from sysdate);
begin
if not regexp_like(rpad('1', N, '1'),'^1?$|^(11+?)\1+$')
then
   dbms_output.put_line('Current year is prime number.');
else
   dbms_output.put_line('Current year is not prime number.');
end if;
end;

最好是32767(PL / SQL中varchar2的大小)

答案 1 :(得分:2)

第二次尝试 - 40个字符

regexp_instr(rpad(2,N+1),'2(  +)\1+$')=0

基于@vav的回答,稍作修改。用not regexp_like...替换regexp_count...=0可以保存一个字符。其他变化是装饰性的 - 用2代替字符1以区分字符和反向引用;使用N + 1(默认的rpad参数)和空格只是为了显示稍微不同的方法。 regexp_count也可以在这里工作,但该函数比其他正则表达式函数更新。

首次尝试 - 54个字符

这是一个完全不可行的解决方案,恰好使用非常少量的字符表达式(54),并且绝不像高尔夫代码。

declare
   N int := extract(year from sysdate);
begin
   if httpuritype('goo.gl/qMu5eR').getClob like'% '||n||' %' then
      dbms_output.put_line('Current year is prime number.');
   else
      dbms_output.put_line('Current year is not prime number.');
   end if;
end;

答案 2 :(得分:2)

在一个屏幕上完成所有操作,无需连接互联网:

declare
   N int := extract(year from sysdate);
begin
   if case
   when least(
            mod(N, 2),  mod(N, 3),  mod(N, 5),  mod(N, 7),  mod(N, 11) 
           ,mod(N, 13), mod(N, 17), mod(N, 19), mod(N, 23), mod(N, 29)
           ,mod(N, 31), mod(N, 37), mod(N, 41), mod(N, 43), mod(N, 47)
           ,mod(N, 53), mod(N, 59), mod(N, 61), mod(N, 67), mod(N, 71)
           ,mod(N, 73), mod(N, 79), mod(N, 83), mod(N, 89), mod(N, 97)
           )
 = 0 then 'NOT PRIME'     
ELSE 'PRIME'
end = 'PRIME' then
  dbms_output.put_line('Current year is prime number.');
else
  dbms_output.put_line('Current year is not prime number.');
end if;
end;

如果你可以保持在2269以下,请评论最后2行mod。 它可以在一定程度上扩展,它与O(sqrt(n))一致。

答案 3 :(得分:1)

试试这个:

declare
   N int := extract(year from sysdate);
begin
   if case
     when N in
       (2017, 2027, 2029, 2039, 2053, 
        2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 
        2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 
        2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 
        2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 
        2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 
        2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 
        2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 
        2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 
        2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 
        2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 
        2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 
        2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 
        3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 
        3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 
        3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 
        3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 
        3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 
        3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 
        3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 
        3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 
        3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 
        3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 
        3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 
        3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 
        4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 
        4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 
        4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 
        4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 
        4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 
        4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 
        4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 
        4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 
        4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 
        4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 
        4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 
        4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 
        5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 
        5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 
        5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 
        5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 
        5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 
        5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 
        5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 
        5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 
        5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 
        5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 
        5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939,
        5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 
        6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 
        6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 
        6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 
        6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 
        6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 
        6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 
        6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 
        6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 
        6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 
        6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 
        6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 
        7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 
        7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 
        7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 
        7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 
        7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 
        7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 
        7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 
        7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 
        7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 
        7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 
        7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 
        8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 
        8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 
        8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 
        8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 
        8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 
        8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 
        8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 
        8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 
        8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 
        8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 
        8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 
        9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 
        9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 
        9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 
        9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 
        9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 
        9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 
        9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 
        9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 
        9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 
        9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 
        9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973)
     then 'PRIME'
     ELSE 'NOT PRIME'
   end = 'PRIME' then
      dbms_output.put_line('Current year is prime number.');
   else
      dbms_output.put_line('Current year is not prime number.');
   end if;
end;

分享并享受。

答案 4 :(得分:0)

declare
   N int := extract(year from sysdate);
begin
   if mod(n,2)<>0 and mod(n,3)<>0 and mod(n,5)<>0 and mod(n,7)<>0 
   and mod(n,11)<>0 and mod(n,13)<>0 and mod(n,17)<>0 and mod(n,19)<>0
   and mod(n,23)<>0 and mod(n,29)<>0 and mod(n,31)<>0 and mod(n,37)<>0
   and mod(n,41)<>0 and mod(n,43)<>0 and mod(n,47)<>0 then 
      dbms_output.put_line('Current year is prime number.');
   else
      dbms_output.put_line('Current year is not prime number.');
   end if;
end;

这适用于2014-2269区间

UPD:我发现的最小比较数为:

when mod(n,10) in (1,3,7,9) and mod(n,3)<>0
and mod(n,7)<>0 and mod(n,11)<>0 and mod(n,13)<>0
and mod(n,17)<>0 and mod(n,19)<>0 and mod(n,23)<>0
and mod(n,29)<>0 and mod(n,31)<>0 and mod(n,37)<>0
and mod(n,41)<>0 and mod(n,43)<>0 and mod(n,47)<>0