Czy pada deszcz Nie umiem powiedzieć

10

Są to krople deszczu:

! | . " :

Są to cząsteczki chmur:

( ) _ @ $ &

Chcę, żebyś sprawdził, kiedy otrzyma blok tekstu, czy pada deszcz. Pada deszcz, jeśli gdzieś nad każdą kroplą deszczu znajduje się cząstka chmury. Na każdą kroplę deszczu musi przypadać jedna cząsteczka chmury. Wyprowadzać truthy lub wartość falsy oznaczając swoje wnioski.

Prawidłowe przykłady

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

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

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

Nieprawidłowe przykłady

!
()

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

To jest więc wygrywa najkrótszy program z postaci .

Seadrus
źródło
2
„Na każdą kroplę deszczu musi przypadać jedna cząsteczka chmury”
Blue
@feersum Drugi nieprawidłowy przykład to przykład, którego szukasz.
Seadrus,
@feersum Rozumiem;)
Seadrus
Czy możemy założyć, że rzędy są wypełnione spacjami, aby utworzyć prostokąt?
feersum
3
@Zereges, no: co najmniej jeden
msh210

Odpowiedzi:

4

APL (30)

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

Jest to funkcja, która pobiera macierz znaków jako dane wejściowe i daje wynik logiczny.

Test:

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

Wyjaśnienie:

  • ⍵∘∊¨'!|.":' '()_@$&': dla obu zestawów znaków (deszcz i chmury) oraz dla każdego znaku w ⍵ sprawdź, czy postać jest członkiem zestawu.
  • +⍀¨: uzyskaj sumę bieżącą dla każdej kolumny i każdego zestawu
  • ≤/: dla każdej pozycji w ⍵ sprawdź, czy ilość kropel deszczu nie przekracza ilości cząstek chmur w bieżącej sumie
  • ∧/∊: zwraca wartość logiczną ORAZ wszystkich elementów w wyniku
marinus
źródło
5

C ++ 11, 186 184 bajtów

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

Nie golfił

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

Podstawowe podejście, zapamiętywanie pozycji cząstek chmur w rzędzie, a jeśli napotka cząstkę deszczu, sprawdza, czy cząstka chmury znajduje się nad nią i zmniejsza licznik cząstek chmur w tej kolumnie. Program zwraca 0, jeśli jest poprawny, a 1 w przeciwnym razie.

Zereges
źródło
Nie można zastąpić c-m?0:p[i]++z p[i]+=c==m? Czy to już nie działa w C ++ 11?
marinus,
@marinus Prawdopodobnie tak.
Zereges
4

Ślimaki , 125

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

Program wyprowadza obszar siatki (lub 1, jeśli jego powierzchnia wynosi 0), jeśli pada deszcz; inaczej 0. Gdybym tylko zaimplementował klasy znaków w stylu wyrażenia regularnego.

Wersja bez golfa Zawiera fałszywe instrukcje dotyczące chmur lub kropli deszczu zamiast wypisywania wszystkich bełkotów. \whatever(zastąpione przez .w prawdziwym programie) oznacza rzecz, która powinna być kroplą deszczu, ale w rzeczywistości może być czymkolwiek, ponieważ nie ma znaczenia, czy dopasujemy kroplę deszczu do chmury.

{
    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
źródło
ciekawy system komentarzy.
Seadrus,
2

Python 2, 121 bajtów

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

Oczekuje, że wejście będzie wypełnione prostokątem.

TFeld
źródło
1

JavaScript ES6, 112

Przetestuj poniższy fragment kodu w przeglądarce zgodnej z EcmaScript 6, implementując funkcje strzałek, operator rozprzestrzeniania i ciągi szablonów (używam 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
źródło
1

Perl 5, 80

79, plus jeden za -Ezamiast-e

@a=();while(<>){@_=split'';(0>($a[$_]+=/[()_@&\$]/-/[!|.":]/)?die:1)for@_}say 1
msh210
źródło
2
Nie umiem czytać Perla, ale jestem silny z matematyki: 79 + 1 = 80
edc65
1

Julia, 90 znaków

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

W przeciwieństwie do oryginalnego rozwiązania (poniżej), w celu ustalenia rozwiązania wykorzystuje się matematykę. mapfoldl(collect,hcat,split(s,"\n"))(napisane powyżej z \nzastąpionym rzeczywistym znakiem nowej linii w celu zapisania znaków) konwertuje ciąg na tablicę znaków 2d. map(i->i∈"!|.\":"?-1:i∈"()_@\$&",...)tworzy tablicę liczb, gdzie 1 oznacza, że ​​postać jest chmurą, -1, jeśli postać jest deszczem, a 0 w przeciwnym razie.

cumsum(...')oblicza skumulowane sumy wierszy (normalnie byłoby napisane cumsum(...,2), ale ponieważ od tego momentu nie dbamy o orientację, transpozycja kosztuje tylko jeden znak), a następnie all(... .>-1)sprawdza liczbę ujemną - negatywy pojawią się tylko, jeśli znak deszczu pojawia się bez poprzedzania chmurą.

Julia, 139 136 znaków

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

Ta funkcja najpierw transponuje tekst, aby wiersze stały się kolumnami i odwrotnie. Pamiętaj, że znaki nowego wiersza są obecne w kodzie w postaci rzeczywistych znaków nowego wiersza, aby zapisać jeden znak na wystąpienie.

Następnie funkcja iteracyjnie zastępuje pary chmur / kropel spacjami, a po usunięciu wszystkich takich par zwraca wartość true, jeśli pozostały jakieś krople, a fałsz w przeciwnym razie.

r"[()_@$&](.*?)[!|.\":]"- jest to wyrażenie regularne, które w leniwy sposób dopasuje pary chmura / kropla, przy czym grupa 1 zawiera wszystko między chmurą a kroplą. Następnie s"\g<1>"nakazuje mu usunięcie dopasowanej chmury i kropel, ale trzymanie rzeczy pomiędzy (konieczne, ponieważ może zawierać chmury) - \g<1>to wszystko, co zostało dopasowane w grupie 1 wyrażenia regularnego. ∩("!|.\":",t)==[]wygeneruje przecięcie kropelkowych znaków z końcowym łańcuchem, a jeśli jest pusty, to żaden z kropelkowych znaków nie jest obecny i pada deszcz.

Glen O
źródło
@nimi - tak naprawdę tego nie potrzebujesz. Możesz zastąpić hw użyciu rzeczywistą funkcją anonimową. W ten sposób: g((s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n")s->join(foldl(.*,[split(i,"")for i=split(s,"\n")]),"\n"))("()()()\n......"))- wywołanie htego ułatwia wywoływanie.
Glen O
@nimi - co do „pojedynczej funkcji do wywołania”, jest to nieco bardziej rozsądne stwierdzenie, ale nie jest jasne, na czym polega społeczność - zamierzam napisać o tym meta post.
Glen O
@nimi - o to właśnie teraz postaram się uzyskać w meta postu.
Glen O
Pytanie to jest teraz dyskusyjne, ponieważ znalazłem lepszy sposób na zrobienie tego, z tylko jedną funkcją.
Glen O