Sinken oder schwimmen wir?

40

Das Problem

Ein Schreckensszenario wird von drei Zahlen auf einer einzelnen Zeile beschrieben n, mund p. Auf diese Zeile folgen nZeilen mit mWerten pro Zeile. Jeder Wert gibt die Gesamtmenge an Wasser an, die jede Zelle aufnehmen kann.

Die folgenden pZeilen beschreiben das Wetter für die nächsten pTage. Pro Tag fällt 1 Einheit Regen auf eine einzelne Zelle. Wenn die Wassermenge in einer Zelle die Menge überschreitet, die sie aufnehmen kann, wird diese Zelle überflutet. Wenn mehrere benachbarte Zellen die volle Kapazität haben, werden sie als eine Zelle behandelt, die gemeinsame Nachbarn haben (denken Sie an Minesweeper, wenn Sie auf eine Gruppe von Leerzeichen klicken).

  • Eine einzelne mittlere Zelle hat 4 Nachbarn
  • Zwei benachbarte mittlere Zellen mit voller Kapazität werden als eine Zelle mit 6 Nachbarn behandelt
  • Eine einzelne Eckzelle hat 2 Nachbarn
  • Eine Einzelwandzelle hat 3 Nachbarn

Wenn eine Zelle überflutet, tritt ein Überflutungsereignis auf. Das überschüssige Wasser wird gleichmäßig an die Nachbarn verteilt. Wenn dies zu einer Überschwemmung eines oder mehrerer Nachbarn führt, tritt ein weiteres Überschwemmungsereignis auf. Dies setzt sich fort, bis sich das Wasser gesetzt hat oder die Stadt vollständig überflutet ist.

Beispiel Eingabe

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 2 2 2
0 0
1 2
4 3

  • 0 0 bedeutet, dass es in Zeile 1, Spalte 1 geregnet hat
  • 1 2 bedeutet, dass es in Reihe 2, Spalte 3 geregnet hat (die kein Wasser fassen kann und sofort überschwemmt!)

pWenn die Stadt nach Regentagen vollständig überflutet ist, geben Sie Sink aus . Andernfalls geben Sie Swim aus .

Beispielausgabe

Schwimmen

Annahmen

  • Die Eingabe kann über stdin erfolgen, aus "city.txt" gelesen oder als Argument akzeptiert werden. Alle drei sind erlaubt, um bereits gepostete Antworten nicht ungültig zu machen.
  • Die Wasserkapazitäten sind nicht negative ganze Zahlen.

Über 40 Teams von Studenten (von A & M, UT, LSU, Rice, Baylor usw.), die an einem Programmierwettbewerb mit verschiedenen verfügbaren Sprachen teilgenommen haben, konnten dieses Problem nicht in 5 Stunden lösen. Aus diesem Grund kann ich nur erwähnen, dass dieses Rätsel einen Haken hat, der die Lösung trivial macht. Der kürzeste Code gewinnt immer noch, weil ich so zuversichtlich bin, dass der kürzeste Code auch das Rätsel lösen wird.

Regenblitz
quelle
Handelt es sich num mWertelinien oder umgekehrt? Ihr Beispiel entspricht nicht der schriftlichen Spezifikation.
Algorithmushai
@algorithmshark Korrigierte
Rainbolt
13
Ich bin nicht sicher, aber es scheint mir, dass Sie sinken, wenn die Menge des Regens größer ist als die Summe des Regens, die alle Quadrate halten können; sonst schwimmst du. Ist es das?
Hosch250
2
@ hosch250 Den Spaß verderben!
Rainbolt
1
"Das überschüssige Wasser wird gleichmäßig an die Nachbarn verteilt." - Das ist wahrscheinlich 1 Einheit Wasser. Verteilt es sich als z. B. 0.25Einheiten auf jede benachbarte Zelle (unter der Annahme einer einzelnen mittelüberfluteten Zelle)?
Neil Slater

Antworten:

16

Golfscript, 37 30 Zeichen

Neu und verbessert, danke an PeterTaylor für die Tipps:

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

Erklärung :

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"

Das Programm wird dann beendet und der Stapel ausgegeben.


Alte Version + Erklärung:

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

Gleicher Ansatz wie Fors , nur Golfscripted =). Kann wahrscheinlich effizienter gemacht werden. Die Eingabe erfolgt von stdin.

Erklärung :

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"

Das Programm gibt dann den Stapel aus, der nur die Antwort ist.

Claudiu
quelle
]Ohne eine Übereinstimmung [wird der gesamte Stapel in einem Array gesammelt, so dass eine Initiale [~]vereinfacht werden kann ~]. grid_sizeVerwenden Sie <, um die ersten Elemente eines Arrays abzurufen, und <{+}*sparen Sie so mit ziemlicher Sicherheit etwas an der Addition der Gesamtkapazität. 0>"Sink""Swim"ifkann sein0>"SinkSwim"4/=
Peter Taylor
@ PeterTaylor: Danke für die Tipps! Bist du dir sicher ~]? Ich habe es versucht und es schien nicht zu funktionieren. Der letzte Hack ist schön, obwohl es sein muss "SwimSink"- wird es verwenden. und die Array-Sache scheint auch vielversprechend, wird daran arbeiten.
Claudiu
Ich bin mir sicher: Das ist ein Standardtrick, den ich und andere schon seit Jahren anwenden.
Peter Taylor
@ PeterTaylor: Hmm seltsam. Probieren Sie es in dem Interpreter aus, mit dem ich verlinkt habe - es schlägt fehl. Dann - ok, vielleicht ist der Webinterpreter nicht Standard. Aber ich habe es auch mit versucht ruby golfscript.rbund es hat immer noch nicht funktioniert ... kannst du überprüfen, ob es auf deiner Seite funktioniert? Ich bekomme den gleichen Fehler auf beiden:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu
1
Wenn Sie ein Zeichenfolgenliteral einfügen, um das Fehlen von stdin zu ersetzen, müssen Sie ein Semikolon voranstellen, um die leere Zeichenfolge zu entfernen, die tatsächlich "aus stdin" stammt. Damit funktioniert es gut
Peter Taylor
20

C: 100 96 95 Zeichen

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");}

5 Stunden? Hat fünf Minuten gedauert. :)

Aragaer, danke für die Vereinfachungen! Ich habe jedoch die Variablendeklarationen und -argumente in main neu angeordnet, da Clang einen Fehler auslöst, wenn das zweite Argument in main von einem anderen Typ ist als char **.

Fors
quelle
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");}. Ich habe auch mit Ahnung von gespielt n-=scanf, bin mir aber nicht sicher, ob das Programm danach korrekt sein wird. Erstens scanfkann nach vorne verschoben werden, forohne die Zeichenanzahl zu ändern.
Aragaer
n-=scanf...würde nicht funktionieren, da es sich im n-=1Grunde genommen um ein Pre-Inkrement handelt, sodass es die südöstliche Ecke verfehlen würde. Die andere Veränderung ist großartig.
Fors
7

Python, 4 Zeilen, 175 Zeichen

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, ich frage mich, ob die 40+ Teams den Haken gefunden haben ... nachdem sie es auf die harte Tour gebracht haben.

schlucken
quelle
10
Ich war in einem der über 40 Teams. Wir bekamen den Haken nach dem Scheitern. Jeder im Auditorium sah gleichzeitig zu. Ich denke, vielleicht hätte ich es hier nicht erwähnen sollen. Ihr wart zu schnell!
Rainbolt
Autsch! Übrigens, sollte ich den Input von stdin für diese Art von Fragen bekommen? - Ich bin neu bei StackExchange. :)
Swalladge
Ich wollte meine Frage bearbeiten, um STDIN anzugeben, aber ich befürchtete, dass dies Ihre Antwort ungültig machen würde. Ich lese hier seit ungefähr einem Monat Rätsel und habe nicht wirklich bemerkt, ob Leute STDIN angegeben haben oder nicht.
Rainbolt
1
@swalladge Willkommen bei Codegolf! Ich empfehle, die Überschrift durch Voranstellen von a zu einer Überschrift zu machen #.
TimWolla
2
Sie können es auf 108 bringen , wenn Sie verwenden input()und map():n,_,p=map(int,input().split());print(['sink','swim'][p>sum(sum(map(int,input().split()))for a in range(n))])
Blender
6

J (50 Zeichen) und K (40) doppeltes Merkmal

Wie üblich haben diese beiden die exakt gleiche Struktur in ihren Lösungen, also sind sie beide hier. K ist jedoch viel kürzer, was eine angenehme Überraschung ist.

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

Erläuterung:

  • ".1!:1]1 - Lesen Sie die erste Zeile ein und konvertieren Sie sie in ganze Zahlen.
  • (...)/0 2{Nehmen Sie die Elemente bei Index 0 und 2 (- nund pjeweils), und verwenden Sie sie als die linke und rechte Argumente auf das Verb (...), respectively.
  • +1!:1@#1:- n+pZeilen einlesen.
  • [+/@".@$- Nehmen Sie ( $) die ersten nZeilen ( [), verwerfen Sie den Rest und konvertieren Sie dann in ganze Zahlen ( ".) und addieren Sie in jeder Zeile ( +/).
  • ]<[:+/- Addieren Sie die Zeilensummen und vergleichen Sie diesen Wert mit dem richtigen Argument p. Wir produzieren wahr, wenn pweniger als die Summe ist.
  • >Sink`Swim{~- Wählen Sie aus, Swimob die obige Kompression zu true oder Sinkfalse führte.

Verwendungszweck:

   >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

Und jetzt das K:

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

Erklärt:

  • . 0:` - Lesen Sie eine Eingabezeile ein und konvertieren Sie sie in ein Array von Ganzzahlen.
  • {...}.- Verwenden Sie diese drei Zahlen n m pals Argumente x y zfür diese Funktion.
  • 0::'(x+z)#`- Erstellen Sie x+zKopien des Eingabedateizugriffs `und lesen Sie dann jeweils eine Zeile ein ( 0::').
  • .:'x#- Nimm die ersten xGegenstände und wandle sie in einen Zahlenvektor um.
  • z<+//- Summieren Sie die gesamte Matrix und testen Sie, ob sie größer als ist z.
  • `Sink`Swim@- Geben Sie zurück Sinkoder geben Sie Swiman, ob der Test wahr ist.

Verwendungszweck:

  `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
algorithmshark
quelle
6

APL, 35

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

Ich bin mir nicht sicher, ob es erlaubt ist, aber es akzeptiert keine Eingaben nach der "Stadt".

x←⎕Übernimmt die Eingabe und speichert sie in einer Variablen x(durch Leerzeichen getrennte Zahlen werden als numerisches Array interpretiert).
1⌷Extrahiert den Index 1 (APL-Arrays basieren auf Eins).
Generiert ein Array von 1 bis zum Argument ( 1⌷x←⎕in diesem Fall).
¨"Map"
{+/⎕}-Operation Geben Sie die Summe ein und geben Sie sie zurück.
+/Summieren Sie das durch die Kartenoperation erzeugte Array.
4×x[3]>Testen Sie, ob die Summe < x[3](1 oder 0) ist, und multiplizieren Sie dann 4.
'SwimSink'⌽⍨Drehen Sie die Zeichenfolge 'SwimSink'um diesen Betrag
4↑. Extrahieren Sie schließlich die ersten 4 Zeichen der Zeichenfolge

TwiNight
quelle
Ich denke, der einzige entscheidende Punkt ist, dass für jede Eingabe die richtige Antwort ausgegeben wird. Wenn dies für CodeGolf ungewöhnlich ist, wird es mich hoffentlich jemand wissen lassen.
Rainbolt
Ändern Sie ⎕IO←0, und ersetzen Sie dann 4↑'SwimSink'⌽⍨4×mit 'Swim' 'Sink'⊃⍨, x[3]mit x[2]und 1⌷xmit ⊃x, um zwei Bytes zu speichern.
Adám,
6

AWK, 70

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

Dies ist eine Verbesserung von laindir zu meiner Behauptung (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")}
user40989
quelle
NR<=hsollte sein NR<=h+1, sonst erhalten Sie falsche Senken, da die letzte Zeile der Kapazitäten übersprungen wird. Dies kann auch auf 70 als verkürzt werdenn{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir
1
@laindir Nun, vielen Dank für die Verbesserung! Ich finde es so lustig, dass Awk neben APL, J und K steht, die gezüchtet wurden, um alle beim Code-Golfen zu schlagen! :-)
user40989
@ user40989 Ich verstehe nicht. Awk scheinen 40-100% länger zu sein als J / K / APL, obwohl es sich nicht um Golfsprachen handelt, sondern um (aus) kommerzielle Programmiersprachen.
Adám,
5

CoffeeScript - 128 113

Eine Funktion, die die Zeichenfolge als einziges Argument verwendet:

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"`
TimWolla
quelle
Sie können den Einzug entfernen und alles in der ersten Zeile durch Semikolons getrennt verschieben. Du schreibst auch `p>x?"Sink":"Swim"`statt if p>x then"Sink"else"Swim". Parens für die dritte Anweisung werden ebenfalls nicht benötigt.
Konrad Borowski
4

SED, 128

Es hat Spaß gemacht, eine sedVersion davon zu schreiben . Es hat folgende Mängel:

  • Es wird davon ausgegangen, dass die Stadt mehr als zwei Säulen hat, um Regenlinien leicht zu erkennen.

  • Es wird davon ausgegangen, dass die Kapazität jeder Stadt im Bereich von 0 bis 9 liegt.

Hier ist es:

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}

Rufen Sie mit der -nFlagge.

user40989
quelle
3

SWI-Prolog 79

Wenn es Ihnen nichts ausmacht, dass diese Antwort nicht über stdin, sondern per Abfrage eingegeben wird:

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

Die Antwort validiert das Eingabeformat nicht, aber ich glaube nicht, dass es ein Problem ist, da Sie dies auch beim Programmierwettbewerb nicht tun müssen.

Beispielabfrage (mit Beispiel in der Frage):

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)]).
n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
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'
user1159256
quelle
1
Sie könnten beginnen, indem Sie etwas Leerzeichen entfernen. Nach ,, vor und nach ', nach )...
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")

Es könnte möglich sein, einige Klammern oder ähnliches wegzulassen, aber Scala ist sehr wankelmütig in Bezug auf Interpunktion und punktfreien Stil und () vs {} und so weiter.

Joe K
quelle
0

Javascript - 73 Zeichen

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

Angenommen, die Eingabe befindet sich in der Variablen sund gibt Swimoder aus Sink.

Beispiel:

Von der ursprünglichen Frage - Eingabe in die Browserkonsole:

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"

Ausgänge:

Swim
MT0
quelle