检测热浪


48

背景

荷兰皇家气象学院将热浪 * 定义为≥25°C天气(“夏季天气”)至少连续 5 天的一系列,至少 3天为30℃以上(“热带天气”) )。

不必连续测量热带天气:例如:30, 25, 30, 26, 27, 28, 32, 30是8天长的热浪和4天热带天气。

*(按荷兰标准。)

挑战

给定一个非空的正整数列表,该整数表示连续几天的摄氏温度测量值,请确定该列表是否包含热浪(按照上述定义)。

以字节为单位的最短答案将获胜。

测试用例

虚假:

[30]
[29, 29, 29, 47, 30]
[31, 29, 29, 28, 24, 23, 29, 29, 26, 27, 33, 20, 26, 26, 20, 30]
[23, 31, 29, 26, 30, 24, 29, 29, 25, 27, 24, 28, 22, 20, 34, 22, 32, 24, 33]
[23, 24, 25, 20, 24, 34, 28, 32, 22, 20, 24]
[24, 28, 21, 34, 34, 25, 24, 33, 23, 20, 32, 26, 29, 29, 25, 20, 30, 24, 23, 21, 27]
[26, 34, 21, 32, 32, 30, 32, 21, 34, 21, 34, 31, 23, 27, 26, 32]
[29, 24, 22, 27, 22, 25, 29, 26, 24, 24, 20, 25, 20, 20, 24, 20]
[23, 33, 22, 32, 30]
[28, 21, 22, 33, 22, 26, 30, 28, 26, 23, 31, 22, 31, 25, 27, 27, 25, 28]
[27, 23, 42, 23, 22, 28]
[25, 20, 30, 29, 32, 25, 22, 21, 31, 22, 23, 25, 22, 31, 23, 25, 33, 23]

真相:

[30, 29, 30, 29, 41]
[1, 1, 25, 30, 25, 30, 25, 25, 25, 25, 25, 25, 25, 25, 40, 1, 1]
[31, 34, 34, 20, 34, 28, 28, 23, 27, 31, 33, 34, 29, 24, 33, 32, 21, 34, 30, 21, 29, 22, 31, 23, 26, 32, 29, 32, 24, 27]
[26, 29, 22, 22, 31, 31, 27, 28, 32, 23, 33, 25, 31, 33, 34, 30, 23, 26, 21, 28, 32, 22, 30, 34, 26, 33, 20, 27, 33]
[20, 31, 20, 29, 29, 33, 34, 33, 20]
[25, 26, 34, 34, 41, 28, 32, 30, 34, 23, 26, 33, 30, 22, 30, 33, 24, 20, 27, 23, 30, 23, 34, 20, 23, 20, 33, 20, 28]
[34, 23, 31, 34, 34, 30, 29, 31, 29, 21, 25, 31, 30, 29, 29, 28, 21, 29, 33, 25, 24, 30]
[22, 31, 23, 23, 26, 21, 22, 20, 20, 28, 24, 28, 25, 31, 31, 26, 33, 31, 27, 29, 30, 30]
[26, 29, 25, 30, 32, 28, 26, 26, 33, 20, 21, 32, 28, 28, 20, 34, 34]
[34, 33, 29, 26, 34, 32, 27, 26, 22]
[30, 31, 23, 21, 30, 27, 32, 30, 34, 29, 21, 31, 31, 31, 32, 27, 30, 26, 21, 34, 29, 33, 24, 24, 32, 27, 32]
[25, 33, 33, 25, 24, 27, 34, 31, 29, 31, 27, 23]

2
温度是否保证低于100摄氏度?
FryAmTheEggman '18

3
@FryAmTheEggman好吧,在荷兰,是:),但我不想您的回答滥用这一事实,所以不。
林恩

1
@HatWizard是的,没关系。例如,“崩溃/不崩溃”也可以。
林恩

2
嘿@Lynn,这是一个巨大的挑战,仍然是:-)
Roland Schmitz

1
@RolandSchmitz谢谢!我很高兴为挑战的一生中出现的创意答案感到惊讶。🎉–
林恩

Answers:



19

果冻,15 字节

:5_5Ṡ‘ẆP«LƊ€>4Ṁ

单子链接接受一个数字列表,1否则如果检测到热浪则返回0

在线尝试!或查看测试套件

怎么样?

标准是存在大于或等于25的四个以上值的游程,其中两个以上必须大于或等于30。

如果我们将其除以五,则该标准将存在大于或等于五个的四个以上值的游程,其中两个以上必须大于或等于六。

如果我们从这些值中减去五个,则该标准将成为存在四个以上大于或等于零的值的游标,其中两个以上的值必须大于或等于一。

如果我们采用这些值的符号(得到-1、0或1),则该条件将存在四个以上不等于-1的值,其中两个以上必须等于1。

如果我们在这些值上加上一个(得到0、1或2),则该条件将存在四个以上不等于零的值,其中两个以上必须等于二。

包含任何零的列表的乘积为零,并且包含两个以上(两个为1)的列表的乘积大于4。这意味着此调整后列表上的条件变为产品的最小值和长度大于4。

:5_5Ṡ‘ẆP«LƊ€>4Ṁ - Link: list of numbers
:5              - integer divide by five (vectorises)
  _5            - subtract five (vectorises)
    Ṡ           - sign {negatives:-1, zero:0, positives:1} (vectorises)
     ‘          - increment (vectorises)
      Ẇ         - all sublists
          Ɗ€    - last three links as a monad for €ach:
       P        -   product
         L      -   length
        «       -   minimum
            >4  - greater than four? (vectorises) -- 1 if so, else 0
              Ṁ - maximum -- 1 if any are 1, else 0

9

Haskell73 72 71 69 67 66字节

any(\a->sum[1|x<-a,x>29,take 4a<a]>2).scanl(\a t->[0|t>24]>>t:a)[]

感谢@flawr和@Laikoni每个提供两个字节,而@xnor提供一个字节!

在线尝试!

等长:

any(\a->take 4a<a&&sum a>2).scanl(\a t->[0|t>24]>>sum[1|t>29]:a)[]

在线尝试!


9

C(clang),64字节

h;o(*t){for(h=1;*t;++t)h=h&&*t<25?1:h*(*t<30?2:6)%864;return!h;}

函数o()对于热波返回1,否则返回0。

感谢神奇的数字864以及Udo Borkowski和Mathis的想法。

如果工作怎么办?从减少值1开始,通过减少操作对每个数字序列进行迭代。如果看到一个数字> = 25,则将减少数乘以2。如果看到一个数字> = 30,则将减少数乘以2,然后将3 = 6.如果看到小于25的数,则缩减从1开始。如果缩减可以被864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3整除,则发现热波,并且求和的结果取模运算为0,这将导致减少值0和返回值true。

在线尝试!


欢迎来到PPCG。
穆罕默德·萨勒曼

欢迎来到PPCG!测试用例套件非常不错的第一个答案!您能添加一个解释以便我们理解魔术吗?
JayCe

那是一个非常优雅的解决方案,做得很好:)
Lynn


7

APL(Dyalog Classic)21 20字节

184↓⍉×\25 30⍸↑,⍨\⎕

在线尝试!

用途 ⎕io←1

25 30⍸x 如果x <25,则为0;如果25≤x<30,则为1;否则,为2

我们从所有可能的位置开始(或等价地:终止于)所有位置的累积乘积,丢弃前4个乘积,并检测出≥8的乘积(即2 3


6

Japt19 18字节

ô<25 d_ʨ5©3§Zè¨30
ô                  // Partition the input at every item
 <25               // where the value is less than 25.
     d_            // Then, return whether any resulting subarray
       ʨ5         // is at least five items long
          ©        // and
           3§      // has at least three items
             Zè¨30 // with a value of at least 30.

我希望我能正确地获得评论中的所有讨论。
由于减少了一个字节 Shaggy

在线尝试!


以为当我读完这篇文章时,它的工作时间会缩短,但只能管理18个字节
Shaggy

@Shaggy我也这么认为,但是我也找不到较短的版本。非常感谢您的指导!
Nit

1
看来我们目前正在赢得这一
奖项

非ASCII字符不算作多个字节吗?
sudo

1
@sudo这些符号都是单字节的。例如,将为3个字节,但¨为1个字节。上面使用的符号之所以被选作高尔夫语言,正是因为它们都是一个字节。
Nit

5

PowerShell,121字节

param($a)$b="";($a|%{if($_-ge25){$b+="$_ "}else{$b;$b=""}})+$b|?{(-split$_).count-ge5-and(-split$_|?{$_-ge30}).count-ge3}

在线尝试!验证所有测试用例

PowerShell没有等价的a .some.every类似物,因此需要手动滚动。

我们将输入$a作为整数数组。将辅助变量$b设置为空字符串。然后,遍历中的每个整数$a。在循环中,如果整数-greaterthanor eQUAL到25,把它添加到我们的潜力字符串$b,否则放$b的管道,并将其设置为空字符串。

一旦超出循环范围,就用数组将管道结果串联起来$b,然后将它们放在Where-Object子句中|?{...}。此翻出那些具有的元件长度的字符串-ge5(基于空白分裂)和临时工大于的计数30-ge3。这些字符串留在管道上,因此真实值是非空的(请参见“验证所有测试用例”链接以了解真实/错误)。


尝试使用$args ,而不是param($a)$a
MAZZY

-2字节...{$a=-split$_;$a.count-ge5-and($a|?{$_-ge30}).count-ge3}
mazzy

109个字节的数组。另存$args|%{if($_-ge25){$b+=$_}else{,$b;$b=@()}}-E{,$b}-B{,($b=@())}|?{$_.count-ge5-and($_|?{$_-ge30}).count-ge3}get-heatWave.ps1。测试脚本regex101.com/r/lXdvIs/2
疯狂的

103字节$b=@();$args|%{if($_-ge25){$b+=$_}else{,$b;$b=@()}}-E{,$b}|?{$_.count-ge5-and($_|?{$_-ge30}).count-ge3}
mazzy

怎么-E办?我对此不熟悉。
AdmBorkBork

5

果冻17 16字节

:5_5Ṡṣ-ḤS«LƊ€Ṁ>4

在线尝试!

这个怎么运作

:5_5Ṡṣ-ḤS«LƊ€Ṁ>4  Main link. Argument: T (array of temperatures)

:5                Divide each item of T by 5 (integer division).
  _5              Subtract 5 from each quotient.
    Ṡ             Take the signs.
                  This maps (-oo,25) to -1, [25,30) to 0, and [30,+oo) to 1.
     ṣ-           Split at occurrences of -1.
       Ḥ          Double, replacing 1's with 2's.
           Ɗ€     Map the three links to the left over each chunk.
        S             Take the sum.
          L           Take the length.
         «            Take the minimum of the results.
             Ṁ    Take the maximum.
              >4  Test if it's larger than 4.
                  Note that the sum is larger than 4 if and only if there are more
                 than two 2's, which correspond to temperatures in [30,+oo).



4

05AB1E,20个字节

Œʒ24›DPsO4›*}29›O2›Z

在线尝试!

说明

Π                    # push sublists of input
 ʒ          }         # filter, keep the lists where:
           *          # the product of:
     DP               # the product and
       sO4›           # the sum compared using greater-than to 4
  24›                 # for the elements greater than 24
                      # is true
                      # the result is:
                   Z  # the maximum from the remaining lists where
                O     # the sum of 
             29›      # the elements greater than 29
                 2›   # is greater than 2

4

批处理,119字节

@set h=0
@for %%t in (0 %*)do @if %%t lss 25 (set/as=5,t=3)else set/a"t+=!!t*(29-%%t)>>9,s-=!!s,h+=!(s+t+h)
@echo %h%

将输入作为命令行参数,并为热浪输出1,否则为0。


4

Python,67字节

f=lambda l:l>l[:4]and(min(l)>24<sorted(l)[~2]-5)|f(l[1:])|f(l[:-1])

在线尝试!

由于指数增长,在较长的测试用例上超时。通过重复切掉第一个或最后一个元素来查找连续的子列表。通过查看第三大数值来检查3天≥30°C sorted(l)[~2]。通过利用真实/错误或错误终止,基本情况可能会更短。




4

APL(Dyalog Unicode),29个字节

∨/(5≤≢¨a)∧3≤+/30≤↑ae⊆⍨25e←⎕

在线尝试!

∨/没有这样的元素

(5≤≢¨a)5 < 每个系列中的天数(a包含所有可能的天数)

3≤+/30≤+/3≤≥30 in的元素总数

↑a← 由...形成的矩阵

e⊆⍨25≤e←⎕ ≥25的一系列连续元素


您的第一个测试被不必要地评论了-它起作用。
ngn

@ngn感谢您发现问题,已解决
Kritixi Lithos

4

Kotlin,57个字节

{var r=1;it.any{r*=2;if(it>29)r*=3;if(it<25)r=1;r%864<1}}

(通过将隐式参数it替换为显式参数v->,从而得到-1个字节)

{var r=1;it.any{v->r*=2;if(v>29)r*=3;if(v<25)r=1;r%864<1}}

(使用any {}操作可得到-16个字节,如Ruby解决方案中GB所示

{it.stream().reduce(1){r,v->if(r*25>r*v)1 else(r*if(v<30)2 else 6)%864}<1}

(-1字节感谢Lynn:用r * 25> r * v替换了r> 0 && v <25)

{it.stream().reduce(1){r,v->if(r>0&&v<25)1 else(r*if(v<30)2 else 6)%864}<1}

此lambda表达式接受一个List,并在热浪中返回true,否则返回false。

感谢神奇的数字864以及Udo Borkowski和Mathis的想法。

如果工作怎么办?每个数字序列都以从减小值1开始的any {}操作进行迭代。如果数字大于或等于30,则将reduce乘以2并乘以3(2 * 3 = 6)。如果数字<25可以看到减少再次从1开始。如果减少可以被864 = 2 * 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3整除,则发现热波,并且模运算的结果为0,结果为从any {}操作调用的内部lambda中的true返回值,然后该操作将停止迭代并返回true值。

在线尝试!


很好的解释:)
JayCe

我认为您的字节数应该反映整个函数的声明,而不仅仅是函数的主体。就目前而言,在我看来,这只是一个片段。
乔纳森·弗雷希

@ jonathan-frech,我将函数体更改为稍长的lambda表达式,包括括号,它们不是Java中那样可选的。这公平吗?
罗兰·施米兹

@RolandSchmitz在查看其他Kotlin提交和Java lambda函数提交时,我认为不包括函数声明字节数;意味着您的原始提交很有可能是有效的。对不起,我的评论对我来说似乎很奇怪,因为我发现它看起来非常简洁,因为没有类型声明,它不是有效的语言构造。
乔纳森·弗雷希

3

不可思议,34个字节

(/>@(& <2!> '<29#0)*> '<24#0).cns5

用法示例:

((/>@(& <2!> '<29#0)*> '<24#0).cns5) [25 33 33 25 24 27 34 31 29 31 27 23]

说明

详细版本:

(some x\\(and <2 (fltr <29) x) (every <24) x) . (cns 5)

取5个连续项目的重叠序列,然后检查序列中是否有所有项目> 25且超过2个项目> 30。


嘿,这无关紧要,但是您网站上的Facebook链接已死。
mbomb007 '18


3

Stax,23 个字节

Æ7)║▄░Ä╟═╙hⁿ╧\ßY8÷K▌µ½x

在staxlang.xyz上运行和调试它!这需要很长时间才能运行,因此我禁用了自动运行。

解压缩(28个字节)和说明

:efc%4>nc{24>f=a{29>f%2>|&|&
:e                              Set of all contiguous subarrays
  f                             Filter, using the rest of the program as a predicate:
   c                              Copy subarray on the stack
    %4>                           Five or more elements?
                        |&        AND
       nc                         Copy subarray twice to top
         {   f                    Filter:
          24>                       Greater than 24?
              =                   Equals the original subarray?
                          |&      AND
               a                  Move subarray to top
                {   f             Filter:
                 29>                Greater than 30?
                     %2>          Length greater than two?
                                  Implicit print if all three conditions are met

这将打印所有可以算作热波的子数组,当且仅当不存在子数组时,才会出错。



3

外壳,19个字节

Vo≥3#≥30fo≥5Lġ(±≥25

在线尝试!

使用filter(f)比使用逻辑和(&)检查要短一个字节,而且摆脱掉± -花费2个字节:(

说明

V(≥3#≥30)f(≥5L)ġ(±≥25)  -- example input: [12,25,26,27,28,29,18,24,32]
               ġ(    )  -- group by
                ( ≥25)  -- | greater or equal to 25: [0,1,2,3,4,5,6,0,0,8]
                (±   )  -- | sign: [0,1,1,1,1,1,1,0,0,1]
                        -- : [[12],[25,26,27,28,29,30],[18,24],[32]]
         f(   )         -- filter by
          (  L)         -- | length: [1,6,2,1]
          (≥5 )         -- | greater or equal to 5: [0,2,0,0]
                        -- : [[25,26,27,28,29,30]]
V(      )               -- does any element satisfy
 (  #   )               -- | count occurences where
 (   ≥30)               -- | | elements greater or equal to 30
 (      )               -- | : [1]
 (≥3    )               -- | greater or equal to 3: [0]
                        -- : 0


3

R111 93 71 67 66字节

!Reduce(function(i,j)"if"(j<25,!!i,(i*(2+4*!j<30))%%864),scan(),1)

在线尝试!

罗兰· 施米茨Roland Schmitz)的无耻港口 答案。感谢Roland -4个字节,感谢Giuseppe -1。

TIO链接到功能版本。

先前的版本使用rleGiuseppe 提取了连续25天以上的数据,并节省了18个字节!


如果使用F代替T,则可以执行此操作F=F|"if"(cond,(expr),0),然后返回F以保存6位字节。您周围也有一对不必要的括号,(1-z[i]):0但是我认为这可能1-z[i]:1还是可以节省另外几个字节……
朱塞佩

^当我想到另一个主意时,我正要提交上述评论,我设法找到了一个100字节以下的解决方案!它function(x,z=rle(x>24)$l){for(i in 1:sum(z|1))F=F|z[i]>4&sum(x[sum(z[1:i])+1-z[i]:1]>29)>2;F}不过是从PPCG小心粘贴到TIO因为有时unprintables在...蠕变
朱塞佩

这是太棒了!利用乔纳森·艾伦(Jonathan Allan)的数学,可能还有更短的方法……
JayCe

很好,如果将内部部分从(i * 2 *(1+(2 *(j> 29))))简化为(i *(2 + 4 *(j> 29)),甚至可以节省更多字节))
罗兰·施米兹

@RolandSchmitz非常真实!
JayCe

3

斯威夫特4,50字节

{$0.reduce(1){$0>0&&$1<25 ?1:$0*($1<30 ?2:6)%864}}

在线尝试!

对于热浪,闭合表达式返回0,否则返回> 0。

Roland Schmitz合作创建和Mathis。

如果工作怎么办?从减少值1开始,通过减少操作对每个数字序列进行迭代。如果看到一个数字> = 25,则将减少数乘以2。如果看到一个数字> = 30,则将减少数乘以2,然后将3 = 6.如果看到一个小于25的数字,则缩减从1重新开始。如果缩减可以被864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3整除,则会发现一个热波,并且求和的结果模运算为0,这将导致归约值0。仅当发现热浪时,归约值才能变为0。归约值一旦为0,则所有将来的归约值(即最终结果)也将为0。


3

Python 2中66个 63字节

lambda a:reduce(lambda b,c:(b*(6,2)[c<30]%864,1)[b*25>b*c],a,1)

在线尝试!

-3字节感谢Lynn

如果工作怎么办?从减少值1开始,通过减少操作对每个数字序列进行迭代。如果看到一个数字> = 25,则将减少数乘以2。如果看到一个数字> = 30,则将减少数乘以2,然后将3 = 6.如果看到一个小于25的数字,则缩减从1重新开始。如果缩减可以被864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3整除,则会发现一个热波,并且求和的结果模运算为0,这将导致归约值0。仅当发现热浪时,归约值才能变为0。归约值一旦为0,则所有将来的归约值(即最终结果)也将为0。

更具可读性,但更长的版本如下所示:

lambda a:reduce((lambda b,c: 1 if b>0 and c<25 else b*(2 if c<30 else 6)%864), a, 1)

删除多余的空格/括号和更换x if cond else y(y,x)[cond]

lambda a:reduce(lambda b,c:(b*(6,2)[c<30]%864,1)[b>0and c<25],a,1)

林恩建议缩短病情 b>0and c<25

b>0and c<25-> b*25>0 and b*c<b*25->b*25>0 and b*25>b*c ->b*25>b*c

导致

lambda a:reduce(lambda b,c:(b*(6,2)[c<30]%864,1)[b*25>b*c],a,1)

您也必须包括进口声明:)
穆罕默德·萨尔曼

1
实际上,您不需要导入reduce from functools,它是Python 2中内置功能
林恩

1
您可以检查b*25>b*c并保存3个字节。这可能适用于采用不同语言的采用这种方法的许多解决方案:)
Lynn

@琳恩非常感谢。我相应地更新了解决方案。
Udo Borkowski

2

Pyth,23个字节

f&glT5&>T]25gePPT30SM.:

在这里尝试

f&glT5&>T]25gePPT30SM.:
f                  SM.:Q   Get the sorted subsequences of the (implicit) input...
 &qlT5                     ... with at least 5 elements...
      &>T]25               ... all at least 25...
            gePPT30        ... where the third to last is at least 30.


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.