¿Esta lloviendo? No puedo decir

10

Estas son gotas de lluvia:

! | . " :

Estas son partículas de nubes:

( ) _ @ $ &

Quiero que verifiquen, cuando se les da un bloque de texto, si está lloviendo o no. Está lloviendo si, por cada gota de lluvia, hay una partícula de nube en algún lugar por encima de ella. Debe haber una partícula de nube por cada gota de lluvia. Produzca un valor verdadero o falso que denote sus conclusiones.

Ejemplos válidos

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

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

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

Ejemplos inválidos

!
()

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

Este es un por lo que gana el programa más corto en caracteres .

Seadrus
fuente
2
"Debe haber una partícula de nube por cada gota de lluvia"
Azul
@feersum El segundo ejemplo no válido es el ejemplo que está buscando.
Seadrus
@feersum Ya veo;)
Seadrus
¿Podemos suponer que las filas están rellenadas con espacios para formar un rectángulo?
feersum el
3
@Zereges, no: al menos uno
msh210

Respuestas:

4

APL (30)

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

Esta es una función que toma una matriz de caracteres como entrada y proporciona una salida booleana.

Prueba:

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

Explicación:

  • ⍵∘∊¨'!|.":' '()_@$&': para ambos conjuntos de caracteres (lluvia y nubes) y para cada carácter en ⍵, vea si el personaje es miembro del conjunto.
  • +⍀¨: obtenga una suma acumulada para cada columna y cada conjunto
  • ≤/: para cada posición en ⍵, verifique que la cantidad de gotas de lluvia no exceda la cantidad de partículas de nubes en la suma acumulada
  • ∧/∊: devuelve el AND booleano de todos los elementos en el resultado
marinus
fuente
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;}}

Sin golf

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

Enfoque básico, almacenando las posiciones de las partículas de la nube en una fila y si se encuentra una partícula de lluvia, verifica si la partícula de la nube está por encima y disminuye el contador de partículas de la nube en esa columna. El programa devuelve 0 si es válido y 1 de lo contrario.

Zereges
fuente
¿No puedes reemplazar c-m?0:p[i]++con p[i]+=c==m? ¿O eso ya no funciona en C ++ 11?
Marinus
@marinus Probablemente sí.
Zereges
4

Caracoles , 125

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

El programa genera el área de la cuadrícula (o 1 si su área es 0) si está lloviendo; de lo contrario 0. Si solo hubiera implementado clases de caracteres de estilo regex.

Versión no golfista Contiene instrucciones falsas para nubes o gotas de lluvia en lugar de escribir todas las galimatías. \whatever(reemplazado con .en el programa real) significa algo que debería ser una gota de lluvia, pero en realidad puede ser cualquier cosa porque no importa si hacemos coincidir una gota de lluvia con una nube.

{
    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
fuente
interesante sistema de comentarios.
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 la entrada que se rellena sea rectangular.

TFeld
fuente
1

JavaScript ES6, 112

Pruebe a ejecutar el fragmento a continuación en un navegador compatible con EcmaScript 6 que implementa funciones de flecha, operador extendido y cadenas de plantilla (uso 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
fuente
1

Perl 5, 80

79, más uno para en -Elugar de-e

@a=();while(<>){@_=split'';(0>($a[$_]+=/[()_@&\$]/-/[!|.":]/)?die:1)for@_}say 1
msh210
fuente
2
No puedo leer Perl, pero soy fuerte en matemáticas: 79 + 1 = 80
edc65
1

Julia, 90 personajes

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

A diferencia de la solución original (a continuación), esto usa las matemáticas para determinar la solución. mapfoldl(collect,hcat,split(s,"\n"))(escrito arriba con \nreemplazado por una nueva línea real para guardar caracteres) convierte la cadena en una matriz 2D de caracteres. map(i->i∈"!|.\":"?-1:i∈"()_@\$&",...)crea una matriz de números, con 1 si el personaje es una nube, -1 si el personaje es lluvia y 0 en caso contrario.

cumsum(...')calcula las sumas acumuladas de las filas (normalmente se escribirían cumsum(...,2), pero dado que no nos importa la orientación a partir de este momento, la transposición solo cuesta un carácter), y luego all(... .>-1)verifica un número negativo; los negativos solo ocurrirán si un carácter de lluvia aparece sin ser precedido por un personaje de nube.

Julia, 139 136 caracteres

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

Esta función primero transpone el texto para que las filas se conviertan en columnas y viceversa. Tenga en cuenta que las nuevas líneas están presentes en el código en forma de nuevas líneas reales, para guardar un carácter por instancia.

Luego, la función reemplaza iterativamente los pares de nubes / gotas con espacios, y una vez que se eliminan todos estos pares, devuelve verdadero si quedan gotas y falso en caso contrario.

r"[()_@$&](.*?)[!|.\":]"- esta es una expresión regular que emparejará pares de nubes / gotas de una manera perezosa, con el grupo 1 que contiene todo entre nube y gota. Luego s"\g<1>"le dice que elimine las nubes y las gotas coincidentes, pero que mantenga las cosas en el medio (lo que es necesario ya que puede contener nubes); esto \g<1>es lo que coincida en el grupo 1 de la expresión regular. ∩("!|.\":",t)==[]generará la intersección de los caracteres de gota con la cadena final, y si está vacía, entonces ninguno de los caracteres de gota está presente y está lloviendo.

Glen O
fuente
@nimi: en realidad no lo necesitas. Puede reemplazar el huso con la función anónima real. De esta manera: g((s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n")s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n"))("()()()\n......"))- llamarlo hhace que sea más fácil invocarlo.
Glen O
@nimi: en cuanto a la "función única para llamar", esa es una afirmación un poco más razonable, pero no está claro en qué se basa la comunidad: voy a hacer una meta publicación preguntando al respecto.
Glen O
@nimi: de eso voy a obtener aclaraciones, ahora mismo, con una meta publicación.
Glen O
Es discutible para esta pregunta ahora, ya que encontré una mejor manera de hacerlo, con solo una función.
Glen O