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 \n
substituí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.