Detectar ondas de calor


48

fundo

O Instituto Meteorológico Real da Holanda define uma onda de calor * como uma série de pelo menos 5 dias consecutivos com tempo ≥25 ° C (“clima de verão”), de modo que pelo menos três desses dias sejam ≥30 ° C (“clima tropical” )

O clima tropical não precisa ser medido consecutivamente: por exemplo: 30, 25, 30, 26, 27, 28, 32, 30é uma onda de calor de 8 dias com 4 dias de clima tropical.

* (Bem, pelos padrões holandeses.)

Desafio

Dada uma lista não vazia de números inteiros positivos representando medições de temperatura Celsius de dias sucessivos, decida se essa lista contém uma onda de calor (conforme a definição acima).

A resposta mais curta em bytes vence.

Casos de teste

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]

Verdade:

[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
A temperatura é garantida abaixo de 100 graus Celsius?
FryAmTheEggman

3
@FryAmTheEggman Bem, na Holanda, sim :), mas eu não quero sua resposta para abusar desse fato, então não.
21418 Lynn

11
@ HatWizard Sim, tudo bem. "Bater / não travar" também é bom, por exemplo.
Lynn

2
Hey @Lynn, este foi um grande desafio e ainda é :-)
Roland Schmitz

11
@RolandSchmitz Thank you! Estou felizmente surpreso com as respostas criativas que surgiram tão tarde na vida do desafio. Lyn
Lynn

Respostas:



19

Gelatina , 15 bytes

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

Um link monádico que aceita uma lista de números que retorna 1se outra onda de calor foi detectada 0.

Experimente online! ou veja a suíte de testes .

Quão?

O critério é a existência de uma execução com mais de quatro valores maiores ou iguais a 25, dos quais mais de dois devem ser maiores ou iguais a 30.

Se dividirmos por cinco, o critério se torna a existência de uma execução com mais de quatro valores maiores ou iguais a cinco, dos quais mais de dois devem ser maiores ou iguais a seis.

Se subtrairmos cinco desses valores, o critério se tornará a existência de uma execução com mais de quatro valores maiores ou iguais a zero, dos quais mais de dois devem ser maiores ou iguais a um.

Se tomarmos o sinal desses valores (obtendo -1, 0 ou 1), o critério se tornará a existência de uma execução de mais de quatro valores diferentes de -1, dos quais mais de dois devem ser iguais a um.

Se adicionarmos um a esses valores (obtendo 0, 1 ou 2), o critério se tornará a existência de uma execução de mais de quatro valores diferentes de zero, dos quais mais de dois devem ser iguais a dois.

O produto de uma lista que contém zeros é zero e o produto de uma lista que contém mais de dois pares (sendo o restante) é maior que quatro. Isso significa que os critérios nessa lista ajustada passam a ser o mínimo do produto e o comprimento maior que 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

Haskell , 73 72 71 69 67 66 bytes

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

Obrigado a @flawr e @Laikoni por dois bytes cada e @xnor por um byte!

Experimente online!

Comprimento igual:

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

Experimente online!


9

C (clang) , 64 bytes

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

A função o () retorna 1 para uma onda de calor ou 0 mais.

Graças ao número mágico 864 e a Udo Borkowski e Mathis por suas idéias.

Como funciona se? Cada sequência de números é iterada com uma operação de redução iniciando no valor de redução 1. Se um número> = 25 for visto, a redução será multiplicada por 2. Se um número> = 30 for visto, a redução será multiplicada por 2 e por 3 = 6. Se um número <25 for visto, a redução será iniciada novamente em 1. Se a redução for divisível por 864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3, uma onda de calor será encontrada e o resultado da A operação do módulo é 0, o que resulta em um valor reduzido de 0 e em um valor de retorno verdadeiro.

Experimente online!


Bem-vindo ao PPCG.
Muhammad Salman

Bem-vindo ao PPCG! Primeira resposta muito boa, completa com o conjunto de casos de teste! Você poderia adicionar uma explicação para entendermos a mágica?
Jayce

Essa é uma solução muito elegante, bem feito :)
Lynn


7

APL (Dyalog Classic) , 21 20 bytes

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

Experimente online!

usa ⎕io←1

25 30⍸x é 0 se x <25, 1 se 25≤x <30 ou 2 caso contrário

calculamos produtos cumulativos a partir de (ou equivalente: terminando em) todos os locais possíveis, descartamos os 4 primeiros produtos e detectamos a presença de produtos ≥8 (que é 2 3 )


6

Japonês , 19 18 bytes

ô<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.

Espero ter conseguido todas as discussões nos comentários corretamente.
Raspou um byte graças a Shaggy .

Experimente online!


Pensei que isso funcionaria mais curto quando eu estava lendo, mas só conseguia gerenciar 18 bytes .
Shaggy

@ Shaggy também pensei, mas também não consegui encontrar uma versão mais curta. Muito obrigado pelo ponteiro!
Nit

11
Parece que estamos ganhar um presente no momento :)
Shaggy

Os caracteres não ASCII não contam como vários bytes?
Sudo

11
@sudo Esses símbolos são todos de byte único. Por exemplo, seria 3 bytes, mas ¨é um byte. Os símbolos usados ​​acima foram escolhidos para o idioma do golfe exatamente pelo motivo de serem todos um único byte.
Nit

5

PowerShell , 121 bytes

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

Experimente online! ou Verifique todos os casos de teste

O PowerShell não tem o equivalente a .someou .everyou algo parecido, portanto, isso é feito manualmente.

Tomamos entrada $acomo uma matriz de números inteiros. Defina a variável auxiliar $bcomo a sequência vazia. Em seguida, percorra todos os números inteiros em $a. Dentro do loop, se o número inteiro for de -gacordo com a equalidade 25, adicione-o à nossa cadeia de caracteres em potencial $b, caso contrário, coloque $bno pipeline e defina-o como a string vazia.

Uma vez fora do loop, concatene os resultados do pipeline com array $be coloque-os em uma Where-Objectcláusula |?{...}. Isso extrai as strings que possuem um comprimento de elemento -ge5(com base na divisão em espaço em branco) e uma contagem de temperaturas acima do que 30é -ge3. Essas cadeias são deixadas no pipeline, portanto, um valor de verdade não está vazio (consulte o link "verificar todos os casos de teste" para obter a distinção de verdade / falsey).


tente usar em $args vez disso param($a)e$a
mazzy

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

109 bytes com matrizes. salvar $args|%{if($_-ge25){$b+=$_}else{,$b;$b=@()}}-E{,$b}-B{,($b=@())}|?{$_.count-ge5-and($_|?{$_-ge30}).count-ge3}como get-heatWave.ps1. Script de teste regex101.com/r/lXdvIs/2
mazzy

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

O que -Efaz? Eu não estou familiarizado com isso.
AdmBorkBork

5

Geléia , 17 16 bytes

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

Experimente online!

Como funciona

: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 bytes

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

Experimente online!

Explicação

Π                    # 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

Lote, 119 bytes

@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%

Recebe a entrada como argumentos da linha de comando e gera 1 para uma onda de calor, caso contrário, 0.


4

Python , 67 bytes

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

Experimente online!

Tempo limite nos casos de teste mais longos devido ao crescimento exponencial. Localiza sublistas contíguas cortando repetidamente o primeiro ou o último elemento. A verificação dos 3 dias ≥30 ° C é feita com o terceiro maior valor sorted(l)[~2]. Os casos base podem talvez ser mais curtos, aproveitando a verdade / falsey ou terminando com erro.




4

APL (Dyalog Unicode) , 29 bytes

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

Experimente online!

∨/existe algum elementos de tal modo que

(5≤≢¨a)5 <a contagem de dias em cada série (a tem todas as séries possíveis de dias)

e

3≤+/30≤ 3 ≤ o total +/ número de elementos que são ≥ 30 em

↑a← a matriz formada por

e⊆⍨25≤e←⎕ a série de elementos consecutivos ≥ 25


Seu primeiro teste é comentado desnecessariamente - ele funciona.
NGN

Graças @ngn para detectar que, fixa
Kritixi Lithos

4

Kotlin , 57 bytes

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

(-1 byte substituindo o parâmetro explícito v-> pelo parâmetro implícito it )

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

(-16 bytes usando a operação any {}, como visto na Ruby Solution por GB )

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

(-1 byte graças a Lynn: substituído r> 0 && v <25 por r * 25> r * v)

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

Essa expressão lambda pega uma lista e retorna true para uma onda de calor ou false.

Graças ao número mágico 864 e a Udo Borkowski e Mathis por suas idéias.

Como funciona se? Cada sequência de números é iterada com qualquer operação {} iniciando no valor de redução 1. A redução é multiplicada por 2 e multiplicada por 3 (2 * 3 = 6) se o número for maior ou igual a 30. Se um número <25 é visto que o redutor começa novamente em 1. Se o redutor é divisível por 864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3, uma onda de calor é encontrada e o resultado da operação do módulo é 0, o que resulta em um valor de retorno verdadeiro no lambda interno chamado a partir de qualquer operação {} , que para de iterar e retorna o valor true.

Experimente online!


Boa explicação :)
Jayce

Eu acho que sua contagem de bytes deve refletir toda a declaração da função, não apenas o corpo da função. Como é agora, parece-me um trecho.
Jonathan Frech

@ jonathan-frech, mudei o corpo da função para uma expressão lambda um pouco mais longa, incluindo chaves que não são opcionais como em Java. Isso é justo?
Roland Schmitz

@RolandSchmitz Olhando para outros envios de Kotlin e envios de função Java lambda, acho que não incluindo a declaração de função contagem de bytes é aceita; o que significa que seu envio original provavelmente é válido. Desculpe pelo meu comentário, me pareceu estranho, pois acho que parece muito snippet-esk, pois não é uma construção de idioma válida sem a declaração de tipo.
Jonathan Frech

3

Maravilha , 34 bytes

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

Exemplo de uso:

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

Explicação

Versão detalhada:

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

Faça sequências sobrepostas de 5 itens consecutivos e verifique se alguma das sequências tem todos os itens> 25 e mais de 2 itens> 30.


Ei, isso não tem relação, mas o link do facebook em seu site está morto.
precisa saber é o seguinte


3

Stax , 23 bytes

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

Execute e depure-o em staxlang.xyz!Como demora muito para executar, desabilitei a execução automática.

Descompactado (28 bytes) e explicação

: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

Isso imprimirá todos os subarrays que podem ser contados como ondas de calor, que serão falsas se e somente se não existirem.



3

Casca , 19 bytes

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

Experimente online!

O uso de filter ( f) é um byte mais curto do que o de verificação com um lógico e ( &) , também seria muito bom se livrar do± 2 bytes :(

Explicação

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

R , 111 93 71 67 66 bytes

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

Experimente online!

Porto desavergonhado de Roland Schmitz respostas . -4 bytes graças a Roland e -1 graças a Giuseppe.

Links do TIO para a versão funcional.

A versão anterior extraiu dias consecutivos> 25, usando rlee salvando 18 bytes, graças a Giuseppe!


se você usar em Fvez de T, poderá fazer F=F|"if"(cond,(expr),0)e retornar Fpara salvar bytes de 6 ish. Você também tem um par desnecessária de parênteses em torno (1-z[i]):0mas eu acho que poderia ser apenas 1-z[i]:1uma maneira de salvar um outro par de bytes ...
Giuseppe

^ Eu estava prestes a enviar o comentário acima quando outra idéia me ocorreu e consegui encontrar uma solução de menos de 100 bytes! É 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}, mas tenha cuidado colar a partir PPCG em TIO porque fluência às vezes unprintables em ...
Giuseppe

Isto é fantástico! Há provavelmente uma maneira ainda mais curto alavancar matemática de Jonathan Allan ...
Jayce

Bom, você pode até salvar mais alguns bytes, se simplificar a parte interna de (i * 2 * (1+ (2 * (j> 29)))) para (i * (2 + 4 * (j> 29)) ))
Roland Schmitz

@RolandSchmitz very true!
JayCe

3

Swift 4 , 50 bytes

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

Experimente online!

A expressão de fechamento retorna 0 para uma onda de calor ou> 0 mais.

Criado em colaboração com Roland Schmitz e Mathis.

Como funciona se? Cada sequência de números é iterada com uma operação de redução iniciando no valor de redução 1. Se um número> = 25 for visto, a redução será multiplicada por 2. Se um número> = 30 for visto, a redução será multiplicada por 2 e por 3 = 6. Se um número <25 for visto, a redução será iniciada novamente em 1. Se a redução for divisível por 864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3, uma onda de calor será encontrada e o resultado da A operação do módulo é 0, o que resulta em um valor reduzido de 0. Somente quando uma onda de calor foi encontrada, a redução pode se tornar 0. Quando o valor reduzido for 0, será 0 para todas as reduções futuras, ou seja, também para o resultado final.


3

Python 2 , 66 63 bytes

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

Experimente online!

-3 bytes graças a Lynn

Como funciona se? Cada sequência de números é iterada com uma operação de redução iniciando no valor de redução 1. Se um número> = 25 for visto, a redução será multiplicada por 2. Se um número> = 30 for visto, a redução será multiplicada por 2 e por 3 = 6. Se um número <25 for visto, a redução será iniciada novamente em 1. Se a redução for divisível por 864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3, uma onda de calor será encontrada e o resultado da A operação do módulo é 0, o que resulta em um valor reduzido de 0. Somente quando uma onda de calor foi encontrada, a redução pode se tornar 0. Quando o valor reduzido for 0, será 0 para todas as reduções futuras, ou seja, também para o resultado final.

Uma versão mais legível, mas mais longa, tem a seguinte aparência:

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

A remoção adicional espaços / parêntese e substituindo x if cond else ypor (y,x)[cond]

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

Lynn sugeriu reduzir a condição 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

resultando em

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

Você tem que incluir a declaração de importação também :)
Muhammad Salman

11
Você realmente não precisa importar as reduções de functools, é um recurso incorporado no Python 2 !
Lynn

11
Você pode verificar se b*25>b*ce salvar 3 bytes; este pode aplicar-se a muitas das soluções que tomam esta abordagem em diferentes línguas :)
Lynn

@ Lynn Muito obrigado. Eu atualizei a solução de acordo.
Udo Borkowski

2

Pitão, 23 bytes

f&glT5&>T]25gePPT30SM.:

Experimente aqui

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.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.