Идет дождь? Не могу сказать


10

Это капли дождя:

! | . " :

Это частицы облаков:

( ) _ @ $ &

Я хочу, чтобы вы, при наличии блока текста, убедились, идет ли дождь. Идет дождь, если где-то над каждой дождевой каплей находится облачная частица. На каждую каплю дождя должна быть одна частица облака. Выведите истинное или ложное значение, обозначающее ваши выводы.

Допустимые примеры

(@@@@@@)
 ( $ &  )
Q   (  )
..  .  !
 : .
  |"   !
    .

()()()
......

@_$ &
errrr
h_r-5
.:. .
 "

Неверные примеры

!
()

$$$$$
(   )
:::::
.....

Это поэтому выигрывает самая короткая программа в персонажах .


2
«Должна быть одна облачная частица для каждой капли дождя»
Blue

@feersum Второй неверный пример - пример, который вы ищете.
Seadrus

@feersum я вижу;)
Seadrus

Можем ли мы предположить, что строки дополнены пробелами для образования прямоугольника?
feersum

3
@ Zereges, нет: хотя бы один
msh210

Ответы:


4

APL (30)

{∧/∊≤/+⍀¨⍵∘∊¨'!|.":' '()_@$&'}

Это функция, которая принимает в качестве входных данных матрицу символов и выдает логический вывод.

Тестовое задание:

      ex1 ex2 ex3 ex4 ex5
┌─────────┬──────┬─────┬──┬─────┐
│(@@@@@@) │()()()│@_$ &│! │$$$$$│
│ ( $ &  )│......│errrr│()│(   )│
│Q   (  ) │      │h_r-5│  │:::::│
│..  .  ! │      │.:. .│  │.....│
│ : .     │      │ "   │  │     │
│  |"   ! │      │     │  │     │
│    .    │      │     │  │     │
└─────────┴──────┴─────┴──┴─────┘
      {∧/∊≤/+⍀¨⍵∘∊¨'!|.":' '()_@$&'}¨ex1 ex2 ex3 ex4 ex5
1 1 1 0 0

Объяснение:

  • ⍵∘∊¨'!|.":' '()_@$&': для обоих наборов символов (дождь и облака) и для каждого символа в in посмотрите, является ли символ членом набора.
  • +⍀¨: получить промежуточную сумму для каждого столбца и каждого набора
  • ≤/: для каждой позиции в check убедитесь, что количество капель дождя не превышает количество частиц облаков в текущей сумме
  • ∧/∊: вернуть логическое И всех элементов в результате

5

C ++ 11, 186 184 байта

#include<map>
int i,c;int main(){std::map<int,int>p;while(~(c=getchar())){for(int m:{40,41,95,64,36,38})p[i]+=c==m;for(int m:{33,124,46,34,58})if(c==m&&!p[i]--)return 1;i=c-10?i+1:0;}}

Ungolfed

#include <map>
int i, c;
int main()
{
    std::map<int, int> p;
    while (~(c = getchar()))
    {
//        for (int m : { '(', ')', '_', '@', '$', '&'})
        for (int m : { 40, 41, 95, 64, 36, 38})
            p[i] += c == m;
//        for (int m : { '!', '|', '.', '"', ':'})
        for (int m : { 33, 124, 46, 34, 58})
            if (c == m && !p[i]--)
                return 1;
        i = c - '\n' ? i + 1 : 0;
    }
    return 0;
}

Базовый подход: хранение положений облачных частиц в ряду и, если встречается дождевая частица, она проверяет, находится ли облачная частица над ней, и уменьшает счетчик облачных частиц в этом столбце. Программа возвращает 0, если она действительна, и 1 в противном случае.


Вы не можете заменить c-m?0:p[i]++на p[i]+=c==m? Или это больше не работает в C ++ 11?
марин

@marinus Наверное, да.
Зерегес

4

Улитки , 125

{t.{t(\(|\)|\_|\@|\$|\&)=(u.,~)d!(.,~)t.!(.,~},!{t(\!|\||\.|\"|\:)ud!(.,~}t(\(|\)|\_|\@|\$|\&)!(d.,~)u.,~},!{t(\!|\||\.|\"|\:

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

Неуправляемая версия Это содержит поддельные инструкции для облаков или капель дождя вместо того, чтобы выписывать все бред. \whatever(заменяется .на в реальной программе) означает вещь, которая должна быть дождевой каплей, но на самом деле может быть чем угодно, потому что не имеет значения, если мы сопоставим не дождевую каплю с облаком.

{
    t \whatever   ,, Pick a drop in a new column
    {
        t \cloud ,, Find a cloud with 
        =(u.,~)  ,, nothing above in the same column marked
        !(d.,~)  ,, but not in an empty column
        t \whatever
        !(d.,~)
    },
    !(t \drop ud !(.,~) )  ,,no drops remaining in column
    t \cloud
    !(d.,~)
    u.,~
},             ,, repeated 0 or more times
! (t \drop)   ,, no drops left

интересная система комментариев.
Seadrus

2

Python 2, 121 байт

def f(i):
 for l in zip(*i.split('\n')):
  s=0
  for p in l:
   s+=p in'()_@$&';s-=p in'!|.":'
   if s<0:return
 return 1

Предполагается, что ввод будет прямоугольным.


1

JavaScript ES6, 112

Протестируйте приведенный ниже фрагмент в браузере, совместимом с EcmaScript 6, реализующем функции стрелок, оператор распространения и строки шаблонов (я использую Firefox)

f=t=>!t.split`
`.some(r=>[...r].some((c,i)=>(c='!|.":()_@$&'.indexOf(c),n[i]=~c?c<5?~-n[i]:-~n[i]:n[i])<0),n=[])

//TEST
console.log=x=>O.innerHTML+=x+'\n';

test_valid = [
 '(@@@@@@)\n ( $ &  )\nQ   (  )\n..  .  !\n : .\n  |"   !\n    .',
 '()()()\n......',
 '@_$ &\nerrrr\nh_r-5\n.:. .\n "'
] 
console.log('Valid');
test_valid.forEach(t=>console.log(t+'\n'+f(t)+'\n'))

test_invalid = ['!\n()','$$$$$\n(   )\n:::::\n.....']
console.log('Invalid');
test_invalid.forEach(t=>console.log(t+'\n'+f(t)+'\n'))
<pre id=O></pre>


1

Perl 5, 80

79, плюс один -Eвместо-e

@a=();while(<>){@_=split'';(0>($a[$_]+=/[()_@&\$]/-/[!|.":]/)?die:1)for@_}say 1

2
Я не могу читать Perl, но я силен в математике: 79 + 1 = 80
edc65

1

Юлия, 90 знаков

s->all(cumsum(map(i->i∈"!|.\":"?-1:i∈"()_@\$&",mapfoldl(collect,hcat,split(s,"
")))').>-1)

В отличие от исходного решения (ниже), здесь используется математика для определения решения. mapfoldl(collect,hcat,split(s,"\n"))(написано выше с \nзаменой фактической новой строки для сохранения символов) преобразует строку в 2d массив символов. map(i->i∈"!|.\":"?-1:i∈"()_@\$&",...)создает массив чисел, с 1, если символ является облаком, -1, если символ дождь, и 0 в противном случае.

cumsum(...')вычисляет кумулятивные суммы строк (обычно записывается cumsum(...,2), но, поскольку с этого момента мы не заботимся об ориентации, транспонирование стоит только один символ), а затем all(... .>-1)проверяет наличие отрицательного числа - отрицания будут появляться только в том случае, если символ дождя появляется без предшествующего облачного персонажа.

Юлия, 139 136 символов

s->(t=join(mapfoldl(i->split(i,""),.*,split(s,"
")),"
");while t!=(t=replace(t,r"[()_@$&](.*?)[!|.\":]",s"\g<1>"))end;∩("!|.\":",t)==[])

Эта функция сначала транспонирует текст так, что строки становятся столбцами, и наоборот. Обратите внимание, что новые строки присутствуют в коде в виде реальных новых строк, чтобы сохранить один символ на экземпляр.

Затем функция итеративно заменяет пары облако / капля пробелами, и как только все такие пары удаляются, она возвращает true, если есть какие-либо оставшиеся капли, и false в противном случае.

r"[()_@$&](.*?)[!|.\":]"- это регулярное выражение, которое будет лениво сопоставлять пары облако / капелька, а группа 1 содержит все, что находится между облаком и каплей. Затем s"\g<1>"говорит ему удалить совпадающее облако и капли, но держать материал между ними (необходимо, поскольку он может содержать облака) - \g<1>это то, что было найдено в группе 1 регулярного выражения. ∩("!|.\":",t)==[]сгенерирует пересечение символов капли с последней строкой, и если она пуста, то ни один из символов капли не присутствует, и идет дождь.


@nimi - тебе это не нужно. Вы можете заменить hв использовании фактическую анонимную функцию. Примерно так: g((s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n")s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n"))("()()()\n......"))- вызов этого hпросто облегчает вызов .
Глен О

@nimi - что касается «единственной вызываемой функции», это несколько более разумное утверждение, но неясно, что представляет собой сообщество - я собираюсь сделать мета-пост с вопросом об этом.
Глен О

@nimi - это то, что я собираюсь получить разъяснение, прямо сейчас, с мета-постом.
Глен О

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