Обнаружить тепловые волны


48

Фон

Королевский нидерландский метеорологический институт определяет волну жары * как серию не менее 5 последовательных дней с погодой ≥25 ° C («летняя погода»), так что по крайней мере 3 из этих дней составляют ≥30 ° C («тропическая погода») ).

Тропическая погода не должна измеряться последовательно: например, 30, 25, 30, 26, 27, 28, 32, 30это 8-дневная волна тепла с 4 днями тропической погоды.

* (Ну, по голландским меркам.)

Вызов

Учитывая непустой список натуральных чисел, представляющих измерения температуры по Цельсию за последующие дни, решите, содержит ли этот список волну тепла (согласно приведенному выше определению).

Самый короткий ответ в байтах побеждает.

Контрольные примеры

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]

2
Гарантируется ли температура ниже 100 градусов по Цельсию?
FryAmTheEggman

3
@FryAmTheEggman Ну, в Нидерландах, да :), но я не хочу, чтобы ваш ответ злоупотреблял этим фактом, поэтому нет.
Линн

1
@ HatWizard Да, все в порядке. «Crash / Don't Crash» тоже хорошо, например.
Линн

2
Эй, Линн, это был большой вызов, и он до сих пор остается таким :-)
Роланд Шмитц

1
@RolandSchmitz Спасибо! Я рад удивлен креативными ответами, которые пришли из него так поздно в жизни испытания. 🎉
Линн

Ответы:



19

Желе , 15 байт

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

Монадическая ссылка, принимающая список чисел, который возвращается, 1если бы еще была обнаружена тепловая волна 0.

Попробуйте онлайн! или посмотрите набор тестов .

Как?

Критерием является наличие серии из более чем четырех значений, больших или равных 25, из которых более двух должны быть больше или равных 30.

Если мы разделим на пять, то критериями станет наличие серии из более чем четырех значений, больших или равных пяти, из которых более двух должны быть больше или равны шести.

Если мы вычтем пять из этих значений, критерием станет наличие серии из более чем четырех значений, больших или равных нулю, из которых более двух должны быть больше или равны единице.

Если мы возьмем знак этих значений (получая -1, 0 или 1), критериями станет наличие серии из более чем четырех значений, не равных -1, из которых более двух должны быть равны одному.

Если мы добавим одно к этим значениям (получим 0, 1 или 2), критериями станет наличие серии из более чем четырех значений, не равных нулю, из которых более двух должны быть равны двум.

Произведение списка, содержащего любые нули, равно нулю, а произведение списка, содержащего более двух двойок (и остальных), больше четырех. Это означает, что критериями в этом скорректированном списке становится то, что минимум продукта и длина больше 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

C (лязг) , 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, а также Удо Борковски и Матису за их идеи.

Как работает, если? Каждая последовательность чисел повторяется с операцией уменьшения, начинающейся с уменьшающего значения 1. Если число> = 25 видно, уменьшение умножается на 2. Если видно число> = 30, уменьшение умножается на 2 и на 3 = 6. Если видно, что число <25, уменьшение начинается снова с 1. Если уменьшение делится на 864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3, то обнаруживается тепловая волна, и результат Операция по модулю 0, что приводит к уменьшению значения 0 и возвращаемому значению true.

Попробуйте онлайн!


Добро пожаловать в PPCG.
Мухаммед Салман

Добро пожаловать в PPCG! Очень хороший первый ответ в комплекте с набором тестовых примеров! Не могли бы вы добавить объяснение, чтобы мы поняли магию?
JayCe

Это действительно элегантное решение, молодец :)
Линн


7

APL (Dyalog Classic) , 21 20 байт

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

Попробуйте онлайн!

использования ⎕io←1

25 30⍸x 0, если x <25, 1, если 25≤x <30, или 2 в противном случае

мы вычисляем кумулятивные продукты из них, начиная (или эквивалентно: заканчивая) во всех возможных местах, отбрасываем первые 4 продукта и выявляем наличие продуктов ≥8 (что составляет 2 3 )


6

Japt , 19 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.

Я надеюсь, что все обсуждения в комментариях были сделаны правильно.
Побрился на один байт благодаря Шегги .

Попробуйте онлайн!


Я думал, что это сработает короче, когда я его читаю, но смог обработать только 18 байт .
Лохматый

@ Shaggy Я тоже так думал, но не мог найти и более короткую версию. Большое спасибо за указатель!
Нить

1
Похоже, мы выигрываем этот момент :)
Shaggy

Разве не-ASCII символы не считаются несколькими байтами?
Судо

1
@sudo Все эти символы однобайтовые. Например, будет 3 байта, но ¨это один байт. Используемые выше символы были выбраны для языка игры в гольф именно по той причине, что все они представляют собой один байт.
Нить

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
mazzy

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%

Принимает input как аргументы командной строки и выводит 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 в

↑a← матрица, образованная

e⊆⍨25≤e←⎕ серия последовательных элементов, которые ≥ 25


Ваш первый тест комментируется без необходимости - он работает.
НГН

@ngn Спасибо, что заметили это, исправлено
Kritixi Lithos

4

Котлин , 57 байт

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

(-1 байт, заменяя явный параметр v-> неявным параметром it )

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

(-16 байт с использованием операции any {}, как видно из решения 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 байт, спасибо Линн: заменил r> 0 && v <25 на 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}

Это лямбда-выражение принимает List и возвращает true для тепловой волны или false в противном случае.

Благодаря волшебному номеру 864 и Удо Борковски и Матису за их идеи.

Как работает, если? Каждая последовательность чисел повторяется с любой операцией {}, начинающейся с уменьшенного значения 1. Уменьшение умножается на 2 и умножается на 3 (2 * 3 = 6), если число больше или равно 30. Если число <25 видно, что уменьшение начинается снова с 1. Если уменьшение делится на 864 = 2 * 2 * 2 * 2 * 2 * 3 * 3 * 3, то обнаруживается тепловая волна, и результат операции по модулю равен 0, что приводит к истинное возвращаемое значение во внутренней лямбде, вызванное операцией any {}, которая затем останавливает итерацию и возвращает значение true.

Попробуйте онлайн!


Хорошее объяснение :)
JayCe

Я думаю, что ваш счетчик байтов должен отражать все объявление функции, а не только тело функции. Как сейчас, мне кажется, это фрагмент кода.
Джонатан Фрех

@ jonathan-frech, я изменил тело функции на более длинное лямбда-выражение, включая фигурные скобки, которые не являются обязательными, как в Java. Это справедливо?
Роланд Шмитц

@RolandSchmitz Глядя на другие представления Kotlin и лямбда-функции Java, я предполагаю, что не учитывается число байтов объявления функции; Это означает, что ваше первоначальное представление наиболее вероятно. Извините за мой комментарий, мне это показалось странным, так как я нахожу, что это выглядит очень сниппетом, поскольку это не допустимая языковая конструкция без объявления типа.
Джонатан Фрех

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


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

Рубин , 89 байт

->a{(0..a.size).map{|i|(b=a[i..-1].take_while{|t|t>24}).size>4&&b.count{|t|t>29}>2}.any?}

Попробуйте онлайн!


Я полагаю, что это не удастся, потому что во втором истинном случае +30 дней - это не все в течение пяти дней.
Стьюи Гриффин

Очень хорошо. Вы можете сбрить несколько байтов each_consподходом - попробуйте онлайн!
benj2240

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

R , 111 93 71 67 66 байт

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

Попробуйте онлайн!

Бесстыдный порт ответов Ролана Шмитца . -4 байта благодаря Роланду и -1 благодаря Джузеппе.

TIO ссылки на функциональную версию.

Предыдущая версия извлекала последовательные дни> 25, используя rleи сохраняя колоссальные 18 байтов благодаря Giuseppe!


если вы используете 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 , потому что иногда непечатная ползучесть ...
Giuseppe

Это фантастика! Вероятно, есть еще более короткий способ использовать математику Джонатана Аллана ...
JayCe

Хорошо, вы даже можете сохранить еще несколько байтов, если упростите внутреннюю часть с (i * 2 * (1+ (2 * (j> 29)))) до (i * (2 + 4 * (j> 29)) ))
Роланд Шмитц

@RolandSchmitz очень верно!
JayCe

3

Swift 4 , 50 байт

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

Попробуйте онлайн!

Выражение замыкания возвращает 0 для тепловой волны или> 0 в противном случае.

Создано в сотрудничестве с Роландом Шмитцем и Матисом.

Как работает, если? Каждая последовательность чисел повторяется с операцией уменьшения, начинающейся с уменьшающего значения 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 байта благодаря Линн

Как работает, если? Каждая последовательность чисел повторяется с операцией уменьшения, начинающейся с уменьшающего значения 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 байта; это может относиться ко многим решениям, использующим этот подход на разных языках :)
Линн

@ Линн Большое спасибо. Я обновил решение соответственно.
Удо Борковски,



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.