¿Nos hundimos o nadamos?

40

El problema

Un escenario del fin del mundo se describe mediante tres números en una sola línea, n, m, y p. Siguiendo esa línea hay nlíneas con mvalores por línea. Cada valor representa las unidades totales de agua que puede contener cada celda.

Las siguientes plíneas describen el clima para los próximos pdías. 1 unidad de lluvia cae en una sola celda cada día. Si la cantidad de agua en una celda excede la cantidad que puede contener, esa celda se inunda. Si varias celdas adyacentes están a plena capacidad, se tratan como una celda que comparte vecinos comunes (piense en Buscaminas cuando hace clic en un grupo de espacios en blanco).

  • Una sola celda media tiene 4 vecinos.
  • Dos celdas intermedias adyacentes de capacidad total se tratan como una celda que tiene 6 vecinos
  • Una celda de esquina individual tiene 2 vecinos.
  • Una celda de pared simple tiene 3 vecinos.

Cuando una celda se inunda, ocurre un evento de inundación. Todo el exceso de agua se distribuye uniformemente a sus vecinos. Si eso hace que uno o más vecinos se inunden, entonces ocurre otro evento de inundación. Esto continúa hasta que el agua se haya asentado o la ciudad se haya inundado por completo.

Entrada de ejemplo

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 significa que llovió en la fila 1, col 1
  • 1 2 significa que llovió en la fila 2, col 3 (que puede contener cero agua e inmediatamente se inunda)

Después de pdías de lluvia, si la ciudad está completamente inundada, produzca Sink . De lo contrario, salida Swim .

Salida de ejemplo

Nadar

Supuestos

  • La entrada puede proporcionarse a través de stdin, leerse desde "city.txt" o aceptarse como argumento. Los tres están permitidos para no invalidar las respuestas ya publicadas.
  • Las capacidades hídricas serán enteros no negativos.

Más de 40 equipos de estudiantes universitarios de pregrado (de A&M, UT, LSU, Rice, Baylor, etc.) que compiten en un concurso de programación con una variedad de idiomas disponibles no pudieron resolver este problema en 5 horas. Debido a eso, no puedo evitar mencionar que hay una trampa en este rompecabezas que hace que la solución sea trivial. El código más corto sigue ganando, porque estoy seguro de que el código más corto también resolverá el rompecabezas.

Perno de lluvia
fuente
¿Son nlíneas de mvalores o al revés? Su ejemplo no coincide con la especificación escrita.
algormshark
@algorithmshark Corregido
Rainbolt
13
No estoy seguro, pero me parece que te hundes si la cantidad de lluvia es mayor que la suma de lluvia que pueden contener todos los cuadrados; de lo contrario flotas. Es esto?
Hosch250
2
@ hosch250 estropeando la diversión!
Rainbolt
1
"El exceso de agua se distribuye uniformemente a sus vecinos". - es probable que sea 1 unidad de agua. ¿Se distribuye, por ejemplo, como 0.25unidades a cada celda adyacente (suponiendo una sola celda inundada media)?
Neil Slater

Respuestas:

16

Golfscript, 37 30 caracteres

Nuevo y mejorado, gracias a PeterTaylor por sus consejos:

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

Explicacion :

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"

Luego, el programa termina y genera la pila.


Versión anterior + explicación:

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

El mismo enfoque que Fors , solo Golfscripted =). Probablemente se puede hacer más eficiente. La entrada es de stdin.

Explicacion :

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"

Luego, el programa genera la pila, que es solo la respuesta.

Claudiu
fuente
]sin una coincidencia [, recogerá toda la pila en una matriz, por lo que [~]se puede simplificar una inicial ~]. Para obtener los primeros grid_sizeelementos de una matriz, use <, por <{+}*lo que casi con seguridad puede ahorrarle un poco al agregar la capacidad total. 0>"Sink""Swim"ifpuede ser0>"SinkSwim"4/=
Peter Taylor
@ PeterTaylor: ¡Gracias por los consejos! ¿Estás seguro ~]? Lo intenté y no pareció funcionar. El último truco es bueno, aunque tiene que serlo "SwimSink", lo usaré. y lo de la matriz también parece prometedor, se pondrá a trabajar en eso.
Claudiu
Estoy seguro: ese es un truco estándar que yo y otros hemos estado usando durante años.
Peter Taylor
@ PeterTaylor: Hmm extraño. Pruébelo en el intérprete al que me vinculé, falla. Entonces, bueno, tal vez el intérprete web no sea estándar. Pero también lo intenté ruby golfscript.rby todavía no funcionó ... ¿puedes verificar que funcione en tu extremo? Me sale el mismo error en ambos:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu
1
Cuando inserta un literal de cadena para sustituir la falta de stdin, debe precederlo con un punto y coma para eliminar la cadena vacía que en realidad viene "de stdin". Con eso funciona bien
Peter Taylor
20

C: 100 96 95 caracteres

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

¿Cinco horas? Me llevó cinco minutos. :)

Aragaer, gracias por las simplificaciones! Sin embargo, reorganicé las declaraciones de variables y los argumentos a main, ya que Clang arroja un error si el segundo argumento a main es de otro tipo que no sea char **.

Fors
fuente
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");}. También he jugado con la idea n-=scanf, pero no estoy seguro de si el programa será correcto después de eso. Primero scanfse puede mover al frente forsin cambiar el recuento de caracteres.
aragaer
n-=scanf...no funcionaría, ya que n-=1básicamente es un incremento previo, por lo que se perdería la esquina sureste. El otro cambio es genial.
Fors
7

Python, 4 líneas, 175 caracteres

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, me pregunto si los más de 40 equipos terminaron encontrando la captura ... después de resolverlo de la manera difícil.

tragar
fuente
10
Estaba en uno de los más de 40 equipos. Nos dieron la trampa después de fallar. Todos en el auditorio se enfrentaron simultáneamente. Creo que tal vez no debería haberlo mencionado aquí. ¡Ustedes fueron demasiado rápidos!
Rainbolt
¡Ay! Por cierto, ¿debería obtener la entrada de stdin para este tipo de preguntas? - Soy nuevo en stackexchange. :)
swalladge
Iba a editar mi pregunta para decir especificar STDIN, pero temía que invalidara su respuesta. He estado leyendo acertijos aquí durante aproximadamente un mes, y realmente no he notado si las personas especificaron STDIN o no.
Rainbolt
1
@swalladge ¡Bienvenido a Codegolf! Recomiendo que el título sea un título al anteponer a #.
TimWolla
2
Puede reducirlo a 108 si usa input()y 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 caracteres) y K (40) doble función

Resulta que, como siempre, estos dos tienen exactamente la misma estructura en sus soluciones, por lo que ambos están aquí. Sin embargo, K es mucho más corto, lo cual es una agradable sorpresa.

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

Explicación:

  • ".1!:1]1 - Leer en la primera línea y convertir a enteros.
  • (...)/0 2{- Tome los elementos en el índice 0 y 2 ( ny prespectivamente), y utilícelos como argumentos izquierdo y derecho del verbo (...), respectivamente.
  • +1!:1@#1:- Leer en n+plíneas.
  • [+/@".@$- Tome ( $) las primeras nfilas ( [), descartando el resto, y luego convierta a enteros ( ".) y sume en cada fila ( +/).
  • ]<[:+/- Sume las sumas de filas, y luego comparar este valor con el argumento de la derecha, p. Producimos verdadero si pes menor que la suma.
  • >Sink`Swim{~- Seleccione Swimsi la compra anterior resultó en verdadero o Sinksi es falso.

Uso:

   >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

Y ahora la K:

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

Explicado:

  • . 0:` - Leer en una línea de entrada y convertir a una matriz de enteros.
  • {...}.- Utilice estos tres números n m pcomo argumentos x y zpara esta función.
  • 0::'(x+z)#`- Cree x+zcopias del identificador del archivo de entrada `y luego lea en línea para cada una de ellas ( 0::').
  • .:'x#- Tome los primeros xelementos y conviértalos a un vector de números.
  • z<+//- Suma toda la matriz, y luego prueba para ver si es mayor que z.
  • `Sink`Swim@- Devolver Sinko Swimsegún si la prueba devuelve verdadero.

Uso:

  `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
Algoritmo de tiburón
fuente
6

APL, 35

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

No estoy seguro si está permitido, pero deja de aceptar entradas después de la "ciudad"

x←⎕Toma datos y los almacena en variables x(los números delimitados por espacios se interpretan como una matriz numérica)
1⌷Extrae el índice 1 (las matrices APL están basadas en uno)
Genera una matriz de 1 al argumento ( 1⌷x←⎕en este caso)
¨Operación "Map"
{+/⎕}Toma matriz de ingrese y devuelva la suma
+/Suma la matriz generada por la operación de mapeo
4×x[3]>Pruebe si la suma < x[3](devuelve 1 o 0), luego multiplique 4
'SwimSink'⌽⍨Gire la cadena 'SwimSink'por esa cantidad
4↑Finalmente, extraiga los primeros 4 caracteres de la cadena

TwiNight
fuente
Creo que la única parte que importa es que genera la respuesta correcta para cualquier entrada dada. Si esto es inusual para CodeGolf, espero que alguien me lo haga saber.
Rainbolt
Cambie ⎕IO←0, luego reemplace 4↑'SwimSink'⌽⍨4×con 'Swim' 'Sink'⊃⍨, x[3]con x[2]y 1⌷xcon ⊃xpara guardar dos bytes.
Adám
6

AWK, 70

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

Esta es una mejora de laindir en mi presentación (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")}
usuario40989
fuente
NR<=hdebería ser NR<=h+1, de lo contrario, obtendrá sumideros falsos ya que se omite la última línea de capacidades. Esto también se puede acortar a 70 comon{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir
1
@laindir Bueno, muchas gracias por la mejora! Me parece tan divertido, que Awk simplemente viene junto a APL, J y K, ¡que fueron criados para vencer a todos en el golf de códigos! :-)
user40989
@ user40989 No entiendo. Awk parece 40-100% más largo que J / K / APL, a pesar de que no son lenguajes de golf, sino (derivan de) lenguajes de programación comercial.
Adám
5

CoffeeScript - 128 113

Una función que toma la cadena como único argumento:

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
fuente
Puede eliminar la sangría y mover todo en la primera línea separados por punto y coma. También escribes en `p>x?"Sink":"Swim"`lugar de if p>x then"Sink"else"Swim". Parens para la tercera declaración tampoco son necesarios.
Konrad Borowski
4

SED, 128

Fue divertido escribir una sedversión de esto. Tiene las siguientes deficiencias:

  • Se supone que la ciudad tiene más de dos columnas, para reconocer fácilmente las líneas de lluvia.

  • Se supone que la capacidad de cada ciudad está en el rango de 0-9.

Aquí está:

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}

Llama con la -nbandera.

usuario40989
fuente
3

SWI-Prolog 79

Si no le importa el hecho de que esta respuesta toma entrada por consulta, en lugar de a través de stdin:

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

La respuesta no valida el formato de entrada, pero no creo que sea un problema, ya que el concurso de programación tampoco requiere que lo hagas.

Consulta de muestra (usando el ejemplo en la pregunta):

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̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fuente
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'
usuario1159256
fuente
1
Podrías comenzar sacando un poco de espacio en blanco. Después ,, antes y después ', despué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")

Puede ser posible omitir algunos paréntesis o algo así, pero Scala es realmente voluble sobre la puntuación y el estilo sin puntos y () vs {} y otras cosas.

Joe K
fuente
0

Javascript - 73 caracteres

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

Asume que la entrada está en la variable sy las salidas Swimo Sink.

Ejemplo:

De la pregunta original, ingresando esto en la consola del navegador:

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"

Salidas:

Swim
MT0
fuente