# Background

The Royal Netherlands Meteorological Institute defines a heat wave* as a series of at least 5 consecutive days of ≥25°C weather (“summery weather”), such that at least 3 of those days are ≥30°C (“tropical weather”).

The tropical weather doesn't have to be measured consecutively: for example: 30, 25, 30, 26, 27, 28, 32, 30 is a 8-day long heat wave with 4 days of tropical weather.

*(Well, by Dutch standards.)

# Challenge

Given a non-empty list of positive integers representing Celsius temperature measurements from successive days, decide whether that list contains a heat wave (as per the above definition).

The shortest answer in bytes wins.

# Test cases

Falsey:

[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]


Truthy:

[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]

• Is the temperature guaranteed to be below 100 Celsius? – FryAmTheEggman Apr 23 '18 at 21:38
• @FryAmTheEggman Well, in the Netherlands, yes :), but I don't want your answer to abuse this fact, so no. – Lynn Apr 24 '18 at 6:42
• @HatWizard Yes, that’s okay. “Crash / don’t crash” is also fine, for example. – Lynn Jun 11 '18 at 14:43
• Hey @Lynn this was a great challenge and still is :-) – Roland Schmitz Jun 19 '18 at 20:01
• @RolandSchmitz Thank you! I'm happily surprised by the creative answers that came out of it so late into the challenge's lifetime. 🎉 – Lynn Jun 20 '18 at 8:25

# K (ngn/k), 3832 30 bytes

{+/7<,/4_'*\'|:',\+/x>/:24 29}


Try it online!

# [JavaScript (ES6)], 49 bytes

a=>a.reduce((b,c)=>b>0&c<25?1:b*(c<30?2:6)%864,1)


Try it online!

The arrow function returns 0 for a heatwave or >0 else.

(Port of the Swift solution to JavaScript)

How does if work? Each sequence of numbers is iterated with a reduce operation starting at the reduce value 1. If a number >= 25 is seen the reduce is multiplied by 2. If a number >= 30 is seen the reduce is multiplied by 2 and by 3 = 6. If a number < 25 is seen the reduce starts again at 1. If the reduce is divisible by 864=2*2*2*2*2*3*3*3 then a heatwave is found, and the result of the modulo operation is 0 which results in a reduce value of 0. Only when a heat wave was found the reduce can become 0. Once the reduce value is 0 it will be 0 for all future reduces, i.e. also for the end result.

• Nice! Even one byte less compared to the Swift solution. – Roland Schmitz Jun 11 '18 at 18:40

# Java (JDK 10), 60 bytes

h->h.stream().reduce(1,(r,v)->r*25>r*v?1:r*(v<30?2:6)%864)<1


(-1 byte thanks Lynn: replaced r>0&&v<25 with r*25>r*v)

h->h.stream().reduce(1,(r,v)->r>0&&v<25?1:r*(v<30?2:6)%864)<1


The lambda expression returns true for a heatwave or false else.

Thanks to the magic number 864 and to Udo Borkowski and Mathis for their ideas.

How does if work? Each sequence of numbers is iterated with a reduce operation starting at the reduce value 1. If a number >= 25 is seen the reduce is multiplied by 2. If a number >= 30 is seen the reduce is multiplied by 2 and by 3 = 6. If a number < 25 is seen the reduce starts again at 1. If the reduce is divisible by 864=2*2*2*2*2*3*3*3 then a heatwave is found, and the result of the modulo operation is 0 which results in a reduce value of 0 and in a return value of true.

Try it online!

# Ruby, 50 48 bytes

->a{b=1;a.any?{|r|1>b=[b*2,1,b*6][5<=>r/5]%864}}


Try it online!

Thanks to Roland Schmitz and Udo Borkowski for the idea and the magic number 864. And again to Roland for saving 2 bytes.

• This is a great solution, especially the part with the spaceship and the negative array index. – Roland Schmitz Jun 15 '18 at 5:34
• You could save 2 more bytes by rearranging and combining the expressions of the inner lambda: ->a{b=1;a.any?{|r|1>b=[b*2,1,b*6][5<=>r/5]%864}} – Roland Schmitz Jun 15 '18 at 6:14
• Thanks for the idea with the any{} operation, which gave me -16 Bytes in the Kotlin solution – Roland Schmitz Jun 15 '18 at 22:06

# Perl 5-pa, 52 bytes

map{$_<25?$w=$h=0:$w++;$h+=$_>29;$\|=$w>4&&$h>2}@F}{  Try it online! # Java 8, 91 bytes h->{int e=0,a=0,t=0;for(int i:h)t=(e=i<25?0:e+1)>4&(a=i<25?0:i<30?a:a+1)>2?1:t;return t>0;}  Hopefully we'll have a heat wave here in The Netherlands soon, since it's currently 13 °C again (even though it was 24 °C this weekend..) Try it online. Explanation: h->{ // Method with integer-array parameter and boolean return-type int e=0, // Amount of subsequent 25+ days, starting at 0 a=0, // Amount of 30+ days in the current 'heat wave', starting at 0 t=0; // Result-flag, starting at 0 for(int i:h) // Loop over the input-array t= // Change the flag to: (e=i<25? // If the current temperature is below 25 °C 0 // Reset e to 0 : // Else (temperature is 25+ °C): e+1) // Increase e by 1 >4 // Validate if e is at least 5 now &(a=i<25? // If the current temperature is below 25 °C 0 // Reset a to 0 :i<30? // Else if the current temperature is [25,29] °C a // Leave a the same : // Else (temperature is 30+ °C): a+1) // Increase a by 1 >2? // Validate if a is at least 3 now: // If there is a 'heat wave': 1 // Change the flag t to 1 : // Else: t; // Leave the flag t unchanged return t>0;} // Return whether the flag t is 1 now  # J, 35 bytes 1#.(1,2~:/\24<])(2<1#.29<]*4<#);.1]  Try it online! Returns 0 for Falsy and positive integer for Truthy I feel it's too descriptive, so it's certainly golfable. ## Explanation: I split x u;.1 ythe input list of values into sublists that are smaller or greater/equal to 25. x is a binary mask denoting the intervals, y is the input list (1,2~:/\24<]) finds if each item is greater or equal to 25; then marks the boundaries of the intervals and prepends 1 to the list for the start.  (1,2~:/\24<]) 1 1 25 30 25 30 25 25 25 25 25 25 25 25 40 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 ((1,2~:/\24<])<;.1]) 1 1 25 30 25 30 25 25 25 25 25 25 25 25 40 1 1 ┌───┬──────────────────────────────────────┬───┐ │1 1│25 30 25 30 25 25 25 25 25 25 25 25 40│1 1│ └───┴──────────────────────────────────────┴───┘  (2<1#.29<]*4<#) Checks if the length # of the sublist is at least 5 and sets all items to 0 if not by multiplying the list by the result of the check; then checks if there are 3 or more items that are greater or equal to 30.  ((1,2~:/\24<])(2<1#.29<]*4<#);.1]) 1 1 25 30 25 30 25 25 25 25 25 25 25 25 40 1 1 0 1 0  1#. adds up the partial results # ><>, 64 bytes 00>l3(?^$:1+{:64*)?v~~~~
^<v?)4:+1$~$?)+fe<
)?v^>$:@2 ;n< 0<  Keeps track of the current number of summer days and tropical days, resets when a regular day is encountered. For every summer day it checks if the requirements for a heat wave is met. # Julia 0.6, 49 bytes T->reduce((x,y)->y>24?(2+4(y>29))x%864:x>0,1,T)<1  Try it online! The popular reduce solution from Udo Borkowski. The final <1 limits the output to true/false. We can remove it for 47 bytes, but the output will then be either false or 0 (varying) for, well, false, and a non-zero number for true. Alternate version (equivalent) based on G B's Ruby implementation (1 byte longer): T->(x=1;any(y->(x=y>24?(2+4(y>29))x%864:x>0)<1,T))  Try it online! Explanation for either version: function u_explained(temps) x = 1 for y in temps if y > 24 val = 2 + (y > 29 ? 4 : 0) #2 for 25 to 29, 6 for 30 and above x = val * x #If we've reached 5 "summery" days (2^5) of which at least 3 are # "tropical" (3^3), then x will be a multiple of 2^5*3^3 # If we've reached there, make x 0. Else, keep as is. x = x % 864 else #found non-summery day, reset non-zero values into 1 (true), but keep 0 as 0 (false) x = x > 0 end end return x == 0 end  Older solution: ### 75 bytes T->(l=endof(T))>4&&any(prod(1+sign(T[i:j]÷5-5))>7 for i=1:l-4 for j=i+4:l)  Try it online! (+13 bytes to fix buggy behaviour for test cases 2 and 9) Julia port of Jonathan Allan's brilliant Jelly solution. Probably not optimal, I just found the method used so neat that I had to try it. # APL(NARS), 100 char, 200 bytes ∇r←f w;c;C;k;i;x r←i←c←C←0⋄k←≢w →0×⍳k<i+←1⋄→3×⍳∼25>x←i⊃w⋄c←C←0⋄→2 c+←1⋄C+←x≥30⋄→2×⍳∼(c≥5)∧C≥3 r←1 ∇  I find useful traslate program construct if() with "→LineNumber×⍳∼" test:  f¨(,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) 0 0 0 0 0 0 0 0 0 0 0 0 f¨(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) 1 1 1 1 1 1 1 1 1 1 1 1  If it is better I write less test space someone say that to me... • Why do you localise your variables? The program will certainly work without ;c;C;k;i;x – Adám Feb 17 '19 at 17:20 • They are local v – user58988 Feb 18 '19 at 22:57 • @Adám They are local variables, if they are defined out that function, and are not declared local in the function, I suppose they could change what not have to change (a variable out the function) – user58988 Feb 18 '19 at 23:05 • So what? This is code golf. Code quality is of no importance at all. – Adám Feb 18 '19 at 23:15 • @Adám yes formally correct and without possible Undefined Behaviour is a prerequisite of one function they came first than codegolf – user58988 Feb 18 '19 at 23:35 # Powershell, 75 73 bytes. -2 bytes thanks to Veskah. based on Javascript by @Arnauld $a=$b=0;$args|?{if($_-ge25){++$a-ge5-band($b+=$_-ge30)-ge3}else{$a=$b=0}}


returns an array or $null. Save as get-heatWave.ps1 and test with script https://regex101.com/r/lXdvIs/2 $t = @(
@(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)
)

$f = @( @(30), @(31, 29, 29, 28, 24, 23, 29, 29, 26, 27, 33, 20, 26, 26, 20, 30), @(29, 29, 29, 47, 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) ) "Should be$true"
$t | % { [bool](.\get-heatWave.ps1 @_) } "Should be$false"
\$f | % {
[bool](.\get-heatWave.ps1 @_)
}


# C# (Visual C# Compiler), 114 bytes

using System.Linq;s=>s.Select((a,b)=>s.Skip(b).TakeWhile(c=>c>24)).Any(a=>a.Count()>4&&a.Where(b=>b>29).Count()>2)


Try it online!

# 05AB1E, 18 bytes

.γ25@}ʒg5@}30@O3@à


Explanation:

.γ   }              # Group the (implicit) input-list by sections of:
25@               #  >= 25
ʒ   }         # Then only leave groups of:
g5@          #  At least 5 items
30@      # Check for each remaining value if its >= 30 (1 if truthy; 0 if falsey)
O     # And get the amount of truthy values per group by taking the sum
3@   # Check if that amount is >= 3 for each
à  # And check if any are truthy by taking the maximum
# (which is output implicitly as result)


# C# (.NET Core), 81 bytes

Without LINQ.

a=>{int b=0;foreach(int i in a){b+=i<25?-b:i>29?11:1;if(b>34)return 1;}return 0;}


Try it online!