Está chovendo? Não sei dizer

10

Estes são pingos de chuva:

! | . " :

Estas são partículas de nuvens:

( ) _ @ $ &

Quero que você verifique, quando recebe um bloco de texto, se está ou não chovendo. Está chovendo se, para cada gota de chuva, há uma partícula de nuvem em algum lugar acima dela. Deve haver uma partícula de nuvem para cada gota de chuva. Mostra uma truthy ou valor Falsas denotando suas conclusões.

Exemplos válidos

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

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

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

Exemplos inválidos

!
()

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

Este é um portanto, o programa mais curto em caracteres vence.

Seadrus
fonte
2
"Deve haver uma partícula nuvem para cada gota de chuva"
Azul
@feersum O segundo exemplo inválido é o exemplo que você está procurando.
Seadrus 7/11
@feersum I see;)
Seadrus
Podemos assumir que as linhas são preenchidas com espaços para formar um retângulo?
precisa saber é
3
@Zereges, não: pelo menos um
msh210

Respostas:

4

APL (30)

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

Esta é uma função que recebe uma matriz de caracteres como entrada e fornece uma saída booleana.

Teste:

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

Explicação:

  • ⍵∘∊¨'!|.":' '()_@$&': para ambos os conjuntos de caracteres (chuva e nuvens) e cada caractere em ⍵, veja se o personagem é um membro do conjunto.
  • +⍀¨: obtenha uma soma contínua para cada coluna e cada conjunto
  • ≤/: para cada posição em ⍵, verifique se a quantidade de gotas de chuva não excede a quantidade de partículas de nuvens na soma em execução
  • ∧/∊: retorna o AND booleano de todos os elementos no resultado
marinus
fonte
5

C ++ 11, 186 184 bytes

#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;
}

Abordagem básica, armazenando posições de partículas de nuvem em uma fileira e, se houver partícula de chuva, verifica se a partícula de nuvem está acima dela e diminui o contador de partículas de nuvem nessa coluna. O programa retornará 0 se for válido e 1 caso contrário.

Zereges
fonte
Você não pode substituir c-m?0:p[i]++com p[i]+=c==m? Ou isso não funciona mais no C ++ 11?
Marinus
@ marinus Provavelmente sim.
Zereges
4

Caracóis , 125

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

O programa gera a área da grade (ou 1 se sua área for 0) se estiver chovendo; caso contrário, 0. Se eu tivesse implementado classes de caracteres no estilo regex.

Versão ungolfed Contém instruções falsas para nuvens ou pingos de chuva, em vez de escrever toda a tagarelice. \whatever(substituído por .no programa real) significa algo que deve ser uma gota de chuva, mas pode realmente ser qualquer coisa, porque não importa se combinamos uma não-chuva com uma nuvem.

{
    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
feersum
fonte
sistema de comentários interessante.
Seadrus
2

Python 2, 121 bytes

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

Espera que a entrada seja preenchida para ser retangular.

TFeld
fonte
1

JavaScript ES6, 112

Teste a execução do snippet abaixo em um navegador compatível com EcmaScript 6, implementando funções de seta, operador de propagação e seqüências de caracteres de modelo (eu uso o 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>

edc65
fonte
1

Perl 5, 80

79, mais um para em -Evez de-e

@a=();while(<>){@_=split'';(0>($a[$_]+=/[()_@&\$]/-/[!|.":]/)?die:1)for@_}say 1
msh210
fonte
2
Eu não posso ler Perl, mas eu sou forte em matemática: 79 + 1 = 80
edc65
1

Julia, 90 caracteres

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

Ao contrário da solução original (abaixo), isso usa a matemática para determinar a solução. mapfoldl(collect,hcat,split(s,"\n"))(escrito acima com \nsubstituído por uma nova linha real para salvar caracteres) converte a sequência em uma matriz 2D de caracteres. map(i->i∈"!|.\":"?-1:i∈"()_@\$&",...)cria uma matriz de números, com 1 se o caractere for uma nuvem, -1 se o caractere for chuva e 0 caso contrário.

cumsum(...')calcula as somas cumulativas das linhas (normalmente seria gravado cumsum(...,2), mas como não nos importamos com a orientação a partir deste ponto, a transposição custa apenas um caractere) e depois all(... .>-1)verifica um número negativo - negativos só ocorrerão se um caractere de chuva aparece sem ser precedido por um caractere de nuvem.

Julia, 139 136 caracteres

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

Essa função primeiro transpõe o texto para que as linhas se tornem colunas e vice-versa. Observe que as novas linhas estão presentes no código na forma de novas linhas reais, para salvar um caractere por instância.

A função substitui iterativamente pares de nuvens / gotas por espaços e, uma vez removidos todos esses pares, retorna true se houver alguma gota restante e falsa caso contrário.

r"[()_@$&](.*?)[!|.\":]"- este é um regex que corresponderá pares de nuvem / gota de maneira lenta, com o grupo 1 contendo tudo entre nuvem e gota. Em seguida, s"\g<1>"solicita que ele remova a nuvem e as gotículas correspondentes, mas mantenha o material no meio (necessário, pois pode conter nuvens) - \g<1>é o que correspondeu ao grupo 1 do regex. ∩("!|.\":",t)==[]irá gerar a interseção dos caracteres da gota com a sequência final e, se estiver vazia, nenhum dos caracteres da gota estará presente e está chovendo.

Glen O
fonte
@nimi - você realmente não precisa. Você pode substituir o hem uso pela função anônima real. Assim: g((s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n")s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n"))("()()()\n......"))- chamar hapenas facilita a chamada .
Glen O
@nimi - quanto à "função única a ser chamada", essa é uma afirmação um pouco mais razoável, mas não está claro o que a comunidade está de pé - eu vou fazer um meta post perguntando sobre isso.
Glen O
@ nimi - é sobre isso que eu vou obter esclarecimentos, agora, com uma meta post.
Glen O
É discutível para esta pergunta agora, pois achei uma maneira melhor de fazê-lo, com apenas uma função.
Glen O