Est-ce que nous coulons ou nage?


40

Le problème

Un scénario de fin du monde est décrit par trois numéros sur une seule ligne, n, met p. Cette ligne est nsuivie de lignes avec des mvaleurs par ligne. Chaque valeur représente le nombre total d'unités d'eau que chaque cellule peut contenir.

Les plignes suivantes décrivent la météo pour les prochains pjours. 1 unité de pluie tombe sur une seule cellule chaque jour. Si la quantité d'eau dans une cellule dépasse la quantité qu'elle peut contenir, cette cellule est inondée. Si plusieurs cellules adjacentes sont à pleine capacité, elles sont traitées comme une cellule partageant des voisins communs (pensez au dragueur de mines lorsque vous cliquez sur un groupe de blancs).

  • Une seule cellule du milieu a 4 voisins
  • Deux cellules intermédiaires adjacentes de pleine capacité sont traitées comme une cellule de 6 voisins
  • Une cellule d'angle unique a 2 voisins
  • Une cellule simple mur a 3 voisins

Lorsqu'une cellule est inondée, un événement d'inondation se produit. Tout excès d’eau est distribué uniformément à ses voisins. Si cela provoque l'inondation d'un ou de plusieurs voisins, un autre événement d'inondation se produit. Cela continue jusqu'à ce que l'eau se soit calmée ou que la ville soit complètement inondée.

Exemple d'entrée

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 signifie qu'il a plu sur la rangée 1, col 1
  • 1 2 signifie qu'il a plu sur la rangée 2, col 3 (qui ne contient aucune eau et est immédiatement inondé!)

Après des pjours de pluie, si la ville est complètement inondée, émettez Sink . Sinon, indiquez Nager .

Exemple de sortie

Nager

Hypothèses

  • Les entrées peuvent être fournies via stdin, lues dans "city.txt" ou acceptées en tant qu'argument. Les trois sont autorisés à ne pas invalider les réponses déjà postées.
  • Les capacités en eau seront des entiers non négatifs.

Plus de 40 équipes d'étudiants de premier cycle (de A & M, UT, LSU, Rice, Baylor, etc.) en compétition dans un concours de programmation avec une variété de langues disponibles ne pourraient pas résoudre ce problème en 5 heures. À cause de cela, je ne peux m'empêcher de mentionner qu'il y a un piège dans ce puzzle qui rend la solution triviale. Le code le plus court gagne toujours, car je suis convaincu que le code le plus court résoudra également le problème.


S'agit-il de nlignes de mvaleurs ou l'inverse? Votre exemple ne correspond pas à la spécification écrite.
algorithmshark

@algorithmshark Corrected
Rainbolt

13
Je ne suis pas sûr, mais il me semble que vous coulez si la quantité de pluie est supérieure à la somme de pluie que toutes les cases peuvent contenir; sinon vous flottez. Est-ce ceci?
Hosch250

2
@ hosch250 Gâcher le plaisir!
Rainbolt

1
"L’excès d’eau est distribué uniformément à ses voisins." - qui est susceptible d'être 1 unité d'eau. Est-ce qu'il distribue par exemple des 0.25unités à chaque cellule adjacente (en supposant une seule cellule inondée moyenne)?
Neil Slater

Réponses:


16

Golfscript, 37 30 caractères

Nouveau et amélioré, grâce à PeterTaylor pour les conseils:

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

Explication :

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"

Le programme se termine alors en sortie de la pile.


Ancienne version + explication:

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

Même approche que Fors , juste Golfscripted =). Peut probablement être rendu plus efficace. L'entrée est de stdin.

Explication :

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"

Le programme affiche ensuite la pile, ce qui n’est que la réponse.


]sans correspondance [, la pile entière sera rassemblée dans un tableau, ce qui [~]permet de simplifier une initiale ~]. Pour obtenir les premiers grid_sizeéléments d’un tableau, utilisez <, vous <{+}*pouvez donc très certainement vous faire économiser un peu en ajoutant la capacité totale. 0>"Sink""Swim"ifpeut être0>"SinkSwim"4/=
Peter Taylor

@PeterTaylor: Merci pour les conseils! Êtes - vous sûr ~]? J'ai essayé et cela n'a pas semblé fonctionner. Le dernier hack est bien qu'il doive l'être "SwimSink"- l'utilisera. et le tableau semble aussi prometteur, il va commencer à travailler là-dessus.
Claudiu

Je suis certain: c’est un tour de force que nous et d’autres utilisons depuis des années.
Peter Taylor

@ PeterTaylor: Hmm étrange. Essayez-le dans l'interprète auquel j'ai lié - cela échoue. Ensuite, d'accord, l'interprète Web n'est peut-être pas standard. Mais j'ai aussi essayé avec ruby golfscript.rbet ça n'a toujours pas marché ... pouvez-vous vérifier que ça marche de votre côté? Je reçois la même erreur sur les deux:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu

1
Lorsque vous insérez un littéral de chaîne pour remplacer l'absence de stdin, vous devez le faire précéder d'un point-virgule pour supprimer la chaîne vide qui provient réellement de "stdin". Cela fonctionne bien
Peter Taylor

20

C: 100 96 95 caractères

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

Cinq heures? Ça m'a pris cinq minutes. :)

Aragaer, merci pour les simplifications! Cependant, j'ai réorganisé les déclarations de variable et les arguments sur main, car Clang génère une erreur si le deuxième argument de main est d'un autre type que 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");}. J'ai également joué avec l'idée de n-=scanf, mais pas sûr si le programme sera correct après cela. Le premier scanfpeut être déplacé au début de forsans changer le nombre de caractères.
aragaer

n-=scanf...ne fonctionnerait pas, car il n-=1s'agit en fait d'un pré-incrément de sorte qu'il raterait le coin sud-est. L'autre changement est génial.
Fors

7

Python, 4 lignes, 175 caractères

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, je me demande si les 40 équipes et plus ont fini par trouver le piège ... après avoir travaillé durement.


10
J'étais sur l'une des 40 équipes et plus. Nous avons eu la capture après avoir échoué. Tout le monde dans l'auditorium se retrouva facepalmed simultanément Je pense que je n'aurais peut-être pas dû le mentionner ici. Vous avez été trop rapide les gars!
Rainbolt

Aie! En passant, devrais-je obtenir les commentaires de stdin pour ce genre de questions? - Je suis nouveau sur stackexchange. :)
swalladge

J'allais modifier ma question pour indiquer préciser STDIN, mais je craignais que cela invalide votre réponse. Je lis des énigmes ici depuis environ un mois et je n’ai pas vraiment remarqué si les personnes spécifiaient STDIN ou non.
Rainbolt

1
@swalladge Bienvenue à Codegolf! Je recommande de faire le titre un titre en ajoutant un #.
TimWolla

2
Vous pouvez le réduire à 108 si vous utilisez input()et map():n,_,p=map(int,input().split());print(['sink','swim'][p>sum(sum(map(int,input().split()))for a in range(n))])
Blender

6

Double fonctionnalité J (50 caractères) et K (40)

Comme d'habitude, ces deux solutions ont exactement la même structure et sont donc toutes les deux ici. K est beaucoup plus court, ce qui est une bonne surprise.

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

Explication:

  • ".1!:1]1 - Lire dans la première ligne et convertir en nombres entiers.
  • (...)/0 2{- Prenez les éléments aux index 0 et 2 ( net prespectivement) et utilisez-les comme arguments de gauche et de droite du verbe (...), respectivement.
  • +1!:1@#1:- Lire dans les n+plignes.
  • [+/@".@$- Prenez ( $) les premières nlignes ( [), en éliminant le reste, puis convertissez-les en nombres entiers ( ".) et faites la somme de chaque ligne ( +/).
  • ]<[:+/- Additionner les sommes des lignes, puis comparer cette valeur à l'argument droit, p. Nous produisons true si pest inférieur à la somme.
  • >Sink`Swim{~- Sélectionnez Swimsi la compression ci-dessus a pour résultat true ou Sinksi false.

Usage:

   >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

Et maintenant le K:

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

A expliqué:

  • . 0:` - Lire une ligne d'entrée et convertir en un tableau d'entiers.
  • {...}.- Utilisez ces trois nombres n m pcomme arguments x y zde cette fonction.
  • 0::'(x+z)#`- Créez des x+zcopies du descripteur de fichier d'entrée `, puis indiquez une ligne pour chacune d'elles ( 0::').
  • .:'x#- Prenez les premiers xéléments et convertissez-les en un vecteur de nombres.
  • z<+//- Faites la somme de la matrice entière, puis testez pour voir si elle est supérieure à z.
  • `Sink`Swim@- Retour Sinkou Swimselon que le test est retourné vrai.

Usage:

  `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←⎕

Pas sûr si cela est autorisé, mais il cesse d'accepter les entrées après la "ville"

x←⎕Prend une entrée et la stocke dans une variable x(les nombres délimités par des espaces sont interprétés comme un tableau numérique)
1⌷Extrait d'index 1 (les tableaux APL sont à base unique)
Génère un tableau de 1 à l'argument ( 1⌷x←⎕dans ce cas)
¨opération "Map"
{+/⎕}Tirer un tableau de entrer et renvoyer la somme
+/Somme du tableau généré par l'opération de mappage
4×x[3]>Tester si la somme < x[3](renvoie 1 ou 0), puis multiplier 4
'SwimSink'⌽⍨Rotation de la chaîne 'SwimSink'par cette quantité
4↑Enfin, extrayez les 4 premiers caractères de la chaîne


Je pense que la seule partie qui compte est que cela donne la réponse correcte pour chaque entrée donnée. Si cela est inhabituel pour CodeGolf, j'espère que quelqu'un me le fera savoir.
Rainbolt

Modifiez ⎕IO←0, puis remplacez 4↑'SwimSink'⌽⍨4×par 'Swim' 'Sink'⊃⍨, x[3]avec x[2]et 1⌷xavec ⊃xpour sauvegarder deux octets.
Adám

6

AWK, 70

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

Ceci est une amélioration par laindir sur ma soumission (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<=hdevrait être NR<=h+1, sinon vous obtiendrez de faux puits lorsque la dernière ligne de capacités sera ignorée. Cela peut aussi être réduit à 70 asn{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir

1
@laindir Eh bien, merci beaucoup pour cette amélioration! Je trouve ça tellement amusant qu’Awk soit juste à côté d’APL, J et K, qui ont été créés pour battre tout le monde en code-golf! :-)
user40989

@ user40989 Je ne comprends pas. Awk semble 40 à 100% plus long que J / K / APL, même s’ils ne sont pas des langues de golf, mais plutôt (proviennent de) langages de programmation commerciaux.
Adám

5

CoffeeScript - 128 113

Une fonction qui prend la chaîne comme seul 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"`

Vous pouvez supprimer l'indentation et tout déplacer sur la première ligne, séparés par des points-virgules. Vous écrivez aussi `p>x?"Sink":"Swim"`au lieu de if p>x then"Sink"else"Swim". Les parens pour la troisième déclaration ne sont pas nécessaires non plus.
Konrad Borowski

4

SED, 128

C'était amusant d'écrire une sedversion de ceci. Il présente les inconvénients suivants:

  • Il suppose que la ville a plus de deux colonnes, pour reconnaître facilement les lignes de pluie.

  • Cela suppose que la capacité de chaque ville est comprise entre 0 et 9.

C'est ici:

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}

Appel avec le -ndrapeau.


3

SWI-Prolog 79

Si cela ne vous dérange pas que cette réponse prenne entrée par requête plutôt que via stdin:

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

La réponse ne valide pas le format de saisie, mais je ne pense pas que ce soit un problème, car le concours de programmation ne vous oblige pas non plus à le faire.

Exemple de requête (en utilisant exemple dans la question):

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
Vous pouvez commencer par éliminer certains espaces. Après ,, avant et après ', après )
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")

Il serait peut-être possible d'omettre certaines parenthèses ou quelque chose, mais Scala est vraiment instable sur la ponctuation et le style sans points et () vs {} et tout le reste.


0

Javascript - 73 Caractères

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

Suppose que l’entrée est dans la variable set les sorties Swimou Sink.

Exemple:

De la question initiale - en entrant ceci dans la console du navigateur:

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"

Les sorties:

Swim
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.