Czy toniemy czy pływamy?


40

Problem

Scenariusz końca świata jest opisany przez trzy numery na jednej linii n, mi p. Po tej linii są nwiersze z mwartościami na linię. Każda wartość reprezentuje całkowitą liczbę jednostek wody w każdej komórce.

Poniższe pwiersze opisują pogodę na kolejne pdni. 1 jednostka deszczu spada na jedną komórkę każdego dnia. Jeśli ilość wody w komórce przekroczy ilość, którą może pomieścić, komórka zaleje. Jeśli wiele sąsiednich komórek ma pełną pojemność, są one traktowane jako jedna komórka, która dzieli wspólnych sąsiadów (pomyśl Saper po kliknięciu na grupę pustych miejsc).

  • Pojedyncza środkowa komórka ma 4 sąsiadów
  • Dwa sąsiednie, pełne komórki środkowe o pełnej pojemności są traktowane jako jedna komórka, która ma 6 sąsiadów
  • Pojedyncza komórka narożna ma 2 sąsiadów
  • Pojedyncza komórka ściany ma 3 sąsiadów

Gdy komórka zaleje, nastąpi zdarzenie powodziowe. Nadmiar wody jest równomiernie rozprowadzany wśród sąsiadów. Jeśli spowoduje to zalanie jednego lub więcej sąsiadów, nastąpi kolejne zdarzenie powodziowe. Trwa to, dopóki woda się nie uspokoi lub miasto nie zostanie całkowicie zalane.

Przykładowe dane wejściowe

7 5 3
3 2 3 4 5
2 2 0 3 4
1 1 2 3 3
4 1 2 2 2
4 1 1 2 2
4 4 1 2 2
4 4 2 2 2
0 0
1 2
4 3

  • 0 0 oznacza, że ​​padało w rzędzie 1, kol. 1
  • 1 2 oznacza, że ​​padało w rzędzie 2, kol. 3 (który może utrzymać zerową wodę i natychmiast zalewa!)

Po pdniach deszczu, jeśli miasto zostanie całkowicie zalane, wyjdź zlew . W przeciwnym razie wyślij Swim .

Przykładowy wynik

Pływać

Założenia

  • Dane wejściowe mogą być dostarczane przez stdin, odczytane z „city.txt” lub zaakceptowane jako argument. Wszystkie trzy są dozwolone, aby nie unieważniać żadnych opublikowanych odpowiedzi.
  • Pojemność wody będzie nieujemnymi liczbami całkowitymi.

Ponad 40 zespołów studentów studiów licencjackich (z A&M, UT, LSU, Rice, Baylor itp.) Rywalizujących w konkursie programowym z różnymi dostępnymi językami nie było w stanie rozwiązać tego problemu w ciągu 5 godzin. Z tego powodu nie mogę nie wspomnieć o tym, że istnieje pewien haczyk, który sprawia, że ​​rozwiązanie jest trywialne. Najkrótszy kod wciąż wygrywa, ponieważ jestem przekonany, że najkrótszy kod również rozwiąże zagadkę.


Czy to nlinie mwartości, czy na odwrót? Twój przykład nie pasuje do zapisanej specyfikacji.
algorytm

@algorytmshark Poprawiony
Rainbolt

13
Nie jestem pewien, ale wydaje mi się, że toniesz, jeśli ilość deszczu jest większa niż suma deszczu, którą mogą pomieścić wszystkie kwadraty; w przeciwnym razie unosisz się. Czy to jest to?
Hosch250

2
@ hosch250 Spoiling the fun!
Rainbolt

1
„Nadmiar wody jest równomiernie rozprowadzany wśród sąsiadów”. - prawdopodobnie będzie to 1 jednostka wody. Czy dystrybuuje się jako 0.25jednostki np. Do każdej sąsiedniej komórki (zakładając, że pojedyncza komórka została zalana)?
Neil Slater,

Odpowiedzi:


16

Golfscript, 37 30 znaków

Nowe i ulepszone, dzięki PeterTaylor za wskazówki:

~](\(@*\(@@<{+}*>"SwimSink"4/=

Objaśnienie :

Code                     -                                            - Stack
~]                       - parse input into an array of integers      - []
(                        - pop first number and put on stack          - [] 7
\(                       - \ swaps top two, then pop first num again  - 7 [] 5
@                        - bring 3rd down from stack to front         - [] 5 7
*                        - mult. this is grid size                    - [] 35
\(@                      - bring next # out - the days of rain        - [] 3 35
@                        - bring array out                            - 3 35 []
<                        - take first 35 elements out of array.
                           this extracts just the capacities and 
                           consumes the rest                          - 3 []
{+}*                     - fold the array using plus - this sums the
                           entire thing                               - 3 86
<                        - greater-than comparison: 3 > 86?           - 0
"SwimSink"4/             - push a string and split it to groups of 4  - 0 ["Swim" "Sink"]

=                        - index into the array using the result of
                           the comparison. if rain > capacity, then
                           sink, else swim                            - "Swim"

Program kończy działanie, wysyłając stos.


Stara wersja + objaśnienie:

[~](\(@*\(@{\(@\-}*\;0>"Sink""Swim"if

Takie samo podejście jak Fors , tylko Golfscripted =). Może być prawdopodobnie bardziej wydajny. Dane wejściowe pochodzą ze standardowego wejścia.

Objaśnienie :

Code                     -                                            - Stack
[~]                      - parse input into an array of integers      - []
(                        - pop first number and put on stack          - [] 7
\(                       - \ swaps top two, then pop first num again  - 7 [] 5
@                        - bring 3rd down from stack to front         - [] 5 7
*                        - mult. this is grid size                    - [] 35
\(@                      - bring next # out - the days of rain        - [] 3 35
{                        - define a block which...
 \(@                     - brings next number out
 \-                      - swaps and subtracts 2nd down from top
}                                                                     - [] 3 35 {}
*                        - repeat that block 35 times. this ends up
                           pulling the capacities out one by one
                           and decrementing our number-of-days 
                           number by each one                         - [] -84 
\;                       - swap and kill the array to get rid of
                           unused input                               - -84
0>"Sink""Swim"if         - if the num > 0, evaluate to "Sink", 
                           otherwise to "Swim"                        - "Swim"

Program następnie wypisuje stos, który jest tylko odpowiedzią.


]bez dopasowania [zbierze cały stos do tablicy, więc inicjał [~]można uprościć ~]. Aby uzyskać pierwsze grid_sizeelementy tablicy, użyj <, więc <{+}*prawie na pewno zaoszczędzisz trochę na dodaniu całkowitej pojemności. 0>"Sink""Swim"ifmoże być0>"SinkSwim"4/=
Peter Taylor

@PeterTaylor: Dzięki za wskazówki! Jesteś tego pewien ~]? Próbowałem i nie działało. Ostatni hack jest fajny, ale musi być "SwimSink"- użyje go. i tablica wydaje się również obiecująca, zacznie nad tym pracować.
Claudiu

Jestem pewien: to standardowa sztuczka, której ja i inni używamy od lat.
Peter Taylor,

@PeterTaylor: Hmm dziwne. Spróbuj w tłumaczu , z którym się połączyłem - nie działa. W takim razie - ok, może interpreter internetowy jest niestandardowy. Ale próbowałem też ruby golfscript.rbi nadal nie działa ... czy możesz sprawdzić, czy działa na twoim końcu? Otrzymuję ten sam błąd w obu przypadkach:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu

1
Po wstawieniu literału łańcucha w celu zastąpienia braku stdin należy poprzedzić go średnikiem, aby usunąć pusty ciąg, który faktycznie pochodzi „ze stdin”. Z tym działa dobrze
Peter Taylor

20

C: 100 96 95 znaków

n,m;main(p){scanf("%d%d%d",&n,&m,&p);for(n*=m;n--;scanf("%d",&m))p-=m;puts(p>0?"Sink":"Swim");}

Pięć godzin? Zajęło mi to pięć minut. :)

Aragaer, dziękuję za uproszczenia! Jednak zmieniłem ustawienie deklaracji zmiennych i argumentów na main, widząc, że Clang zgłasza błąd, jeśli drugi argument na main jest innego typu niż char **.


3
96 -p;main(n,m){for(scanf("%d%d%d",&n,&m,&p),n*=m;n--;scanf("%d",&m),p-=m);puts(p>0?"Sink":"Swim");}
aragaer

1
95 - n,m;main(p){for(scanf("%d%d%d",&n,&m,&p),n*=m;n--;scanf("%d",&m))p-=m;puts(p>0?"Sink":"Swim");}. Grałem też z pomysłem n-=scanf, ale nie jestem pewien, czy program będzie potem poprawny. Najpierw scanfmożna przenieść na przód forbez zmiany liczby znaków.
aragaer

n-=scanf...nie zadziałałoby, ponieważ w n-=1zasadzie jest to wstępny przyrost, więc przegapiłoby południowo-wschodni róg. Druga zmiana jest świetna.
Fors

7

Python, 4 linie, 175 znaków

import sys 
F=sys.stdin
n,m,p=[int(a) for a in F.readline().split()]
print("sink") if p > sum([sum(int(x) for x in F.readline().split()) for a in range(n)]) else print("swim")

Lol, zastanawiam się, czy ponad 40 drużyn znalazło haczyk ... po ciężkim wypracowaniu.


10
Byłem w jednej z ponad 40 drużyn. Daliśmy połów po porażce. Wszyscy na widowni rozmawiali jednocześnie. Myślę, że nie powinienem był tutaj o tym wspominać. Byliście zbyt szybcy!
Rainbolt

Ojej! Nawiasem mówiąc, czy powinienem uzyskać dane wejściowe od stdin dla tego rodzaju pytań? - Jestem nowy w stosie wymiany. :)
swalladge

Chciałem zredagować moje pytanie, aby powiedzieć, podaj STDIN, ale obawiałem się, że to unieważni twoją odpowiedź. Czytam tu puzzle od około miesiąca i tak naprawdę nie zauważyłem, czy ludzie wybrali STDIN, czy nie.
Rainbolt

1
@swalladge Witamy w Codegolf! Polecam uczynić nagłówek nagłówkiem, przygotowując #.
TimWolla,

2
Możesz obniżyć go do 108, jeśli używasz input()i map():n,_,p=map(int,input().split());print(['sink','swim'][p>sum(sum(map(int,input().split()))for a in range(n))])
Blender

6

Podwójna funkcja J (50 znaków) i K (40)

Okazuje się, że jak zwykle te dwa mają dokładnie taką samą strukturę w swoich rozwiązaniach, więc oboje są tutaj. K jest jednak o wiele krótszy, co jest miłą niespodzianką.

>Sink`Swim{~(]<[:+/[+/@".@$+1!:1@#1:)/0 2{".1!:1]1

Wyjaśnienie:

  • ".1!:1]1 - Przeczytaj w pierwszym wierszu i przekonwertuj na liczby całkowite.
  • (...)/0 2{- Weź elementy o indeksie 0 i 2 ( ni podpowiednio) i użyj ich jako lewego i prawego argumentu odpowiednio do czasownika (...).
  • +1!:1@#1:- Czytaj w n+pwierszach.
  • [+/@".@$- Take ( $) pierwsze nrzędy ( [), odrzucając resztę, a następnie przekonwertować do liczb całkowitych ( ".) i suma w każdym wierszu ( +/).
  • ]<[:+/- Dodaj razem sum wierszy, a następnie porównać tę wartość do prawego argumentu p. Dajemy prawdę, jeśli pjest mniejsza niż suma.
  • >Sink`Swim{~- Wybierz, Swimczy powyższe kompasowanie dało wynik prawda, Sinkczy fałsz.

Stosowanie:

   >Sink`Swim{~(]<[:+/[+/@".@$+1!:1@#1:)/0 2{".1!:1]1
7 5 3
3 2 3 4 5
2 0 3 3 4
1 1 2 3 3
4 1 2 2 2
4 1 1 2 2
4 4 1 2 2
4 4 2 2 2
0 0
1 2
4 3
Swim

A teraz K:

`Sink`Swim@{z<+//.:'x#0::'(x+z)#`}.. 0:`

Wyjaśniono:

  • . 0:` - Przeczytaj wiersz wejściowy i przekonwertuj na tablicę liczb całkowitych.
  • {...}.- Użyj tych trzech liczb n m pjako argumentów x y ztej funkcji.
  • 0::'(x+z)#`- Utwórz x+zkopie uchwytu pliku wejściowego `, a następnie przeczytaj wiersz dla każdego z nich ( 0::').
  • .:'x#- Weź pierwsze xprzedmioty i przekonwertuj każdy z nich na wektor liczb.
  • z<+//- Zsumuj całą macierz razem, a następnie sprawdź, czy jest większa niż z.
  • `Sink`Swim@- Zwróć Sinklub Swimzgodnie z tym, czy test zwrócił wartość true.

Stosowanie:

  `Sink`Swim@{z<+//.:'x#0::'(x+z)#`}.. 0:`
7 5 3
3 2 3 4 5
2 2 0 3 4
1 1 2 3 3
4 1 2 2 2
4 1 1 2 2
4 4 1 2 2
4 4 2 2 2
0 0
1 2
4 3
`Swim

6

APL, 35

4↑'SwimSink'⌽⍨4×x[3]>+/{+/⎕}¨⍳1⌷x←⎕

Nie jestem pewien, czy jest dozwolone, ale przestaje akceptować dane wejściowe po „mieście”

x←⎕Pobiera dane wejściowe i przechowuje je w zmiennej x(liczby rozdzielane spacjami są interpretowane jako tablica numeryczna)
1⌷Wyodrębnij indeks 1 (tablice APL są oparte na jednym)
Wygeneruj tablicę od 1 do argumentu ( 1⌷x←⎕w tym przypadku)
¨Operacja „Map”
{+/⎕}Weź tablicę z wprowadź i zwróć sumę
+/Sumuj tablicę wygenerowaną przez operację mapowania
4×x[3]>Sprawdź, czy suma < x[3](zwraca 1 lub 0), a następnie pomnóż 4
'SwimSink'⌽⍨Obróć łańcuch 'SwimSink'o tę wartość
4↑Na końcu wyodrębnij pierwsze 4 znaki ciągu


Myślę, że jedyną częścią, która się liczy, jest to, że wypisuje prawidłową odpowiedź dla każdego danego wkładu. Jeśli jest to nietypowe dla CodeGolf, mam nadzieję, że ktoś mnie powiadomi.
Rainbolt,

Zmień ⎕IO←0, a następnie zastąpić 4↑'SwimSink'⌽⍨4×z 'Swim' 'Sink'⊃⍨, x[3]z x[2], oraz 1⌷xz ⊃xuratować dwa bajty.
Adám,

6

AWK, 70

n{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}

To jest ulepszenie przez laindir w moim oświadczeniu (86):

NR==1{h=$1;w=$2;r=$3;next}NR<=h{for(i=1;i<=w;++i)c+=$i}END{print(c>r?"Swim":"Sink")}

NR<=hpowinno być NR<=h+1, w przeciwnym razie dostaniesz fałszywe umywalki, ponieważ ostatnia linia pojemności zostanie pominięta. Można to również skrócić do 70 asn{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir

1
@laindir Cóż, bardzo dziękuję za poprawę! Uważam to za tak zabawne, że Awk jest tuż obok APL, J i K, które zostały wyhodowane, aby pokonać wszystkich podczas gry w golfa! :-)
user40989

@ user40989 Nie rozumiem. Awk wydaje się 40-100% dłuższy niż J / K / APL, mimo że nie są to języki gry w golfa, ale (wywodzą się) z komercyjnych języków programowania.
Adám,

5

CoffeeScript - 128 113

Funkcja, która przyjmuje ciąg jako jedyny argument:

s=(l)->l=l.split /\n/;[n,m,p]=l[x=0].split /\s/;x+=c|0 for c in r.split /\s/ for r in l[1..n];`p>x?"Sink":"Swim"`

Możesz usunąć wcięcie i przenieść wszystko w pierwszym wierszu oddzielone średnikami. Ty też piszesz `p>x?"Sink":"Swim"`zamiast if p>x then"Sink"else"Swim". Pareny do trzeciego zdania również nie są potrzebne.
Konrad Borowski

4

SED, 128

Fajnie było napisać sedwersję tego. Ma następujące niedociągnięcia:

  • Zakłada, że ​​miasto ma więcej niż dwie kolumny, aby łatwo rozpoznać linie deszczu.

  • Zakłada się, że pojemność każdego miasta mieści się w przedziale 0–9.

Oto on:

1d
s/^. .$/R/
G
:a
s/[\n 0]//
/[2-9]/{s/^/C/
y/23456789/12345678/}
s/1/C/
s/0//
s/RC//
h
ta
${s/R//g
s/^Sink//
s/.*C$/Swim/
p}

Zadzwoń z -nflagą.


3

SWI-Prolog 79

Jeśli nie przeszkadza ci fakt, że ta odpowiedź wymaga wprowadzania danych przez zapytanie, a nie przez stdin:

s(A,L):-append(A,B),sumlist(B,C),length(L,D),(D>C->E='Sink';E='Swim'),print(E).

Odpowiedź nie potwierdza formatu wejściowego, ale nie sądzę, że jest to problem, ponieważ konkurs programistyczny również tego nie wymaga.

Przykładowe zapytanie (na przykładzie w pytaniu):

s([[3,2,3,4,5],
   [2,2,0,3,4],
   [1,1,2,3,3],
   [4,1,2,2,2],
   [4,1,1,2,2],
   [4,4,1,2,2],
   [4,4,2,2,2]],
  [(0,0),
   (1,2),
   (4,3)]).

1

Python - 152

import numpy
n, m, p = map(int,raw_input('').split())
print 'swim' if p<numpy.sum(numpy.matrix(';'.join([raw_input('') for i in range(n)]))) else 'sink'

1
Możesz zacząć od usunięcia białych znaków. Po ,, przed i po ', po )...
Ry-

1

Scala - 128

val a=readLine.split(' ')map(_.toInt);println(if((1 to a(0)map(x=>readLine.split(' ')map(_.toInt)sum)sum)>a(2))"swim"else"sink")

Możliwe, że można pominąć nawiasy lub coś w tym stylu, ale Scala jest naprawdę kapryśna w kwestii interpunkcji i stylu bez punktów oraz () vs {} i tak dalej.


0

JavaScript - 73 znaków

for(i=c=0,a=s.split(/\s/);i++<a[0]*a[1];)c+=a[2+i]*1;c>a[2]?"Swim":"Sink"

Zakłada, że ​​dane wejściowe znajdują się w zmiennej si wyjściach Swimlub Sink.

Przykład:

Z pierwotnego pytania - wpisując to w konsoli przeglądarki:

s="7 5 3\n3 2 3 4 5\n2 2 0 3 4\n1 1 2 3 3\n4 1 2 2 2\n4 1 1 2 2\n4 4 1 2 2\n4 4 2 2 2\n0 0\n1 2\n4 3";
for(i=c=0,a=s.split(/\s/);i++<a[0]*a[1];)c+=a[2+i]*1;c>a[2]?"Swim":"Sink"

Wyjścia:

Swim
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.