Affondiamo o nuotiamo?


40

Il problema

Uno scenario apocalittico è descritta da tre numeri su una singola linea, n, m, e p. Seguendo quella linea ci sono nlinee con mvalori per linea. Ogni valore rappresenta le unità totali di acqua che ogni cella può contenere.

Le seguenti prighe descrivono il tempo per i prossimi pgiorni. 1 unità di pioggia cade su una singola cella ogni giorno. Se la quantità di acqua in una cella supera la quantità che può contenere, quella cella si allaga. Se più celle adiacenti sono a piena capacità, vengono trattate come una cella che condivide vicini comuni (pensa a Minesweeper quando fai clic su un gruppo di spazi).

  • Una singola cella centrale ha 4 vicini
  • Due celle medie adiacenti a piena capacità vengono trattate come una cella con 6 vicini
  • Una cella ad angolo singolo ha 2 vicini
  • Una cella a parete singola ha 3 vicini

Quando una cella si allaga, si verifica un evento di inondazione. Tutta l'acqua in eccesso viene distribuita uniformemente ai vicini. Se ciò causa l'allagamento di uno o più vicini, si verifica un altro evento di alluvione. Questo continua fino a quando l'acqua non si è stabilizzata o la città non è completamente allagata.

Esempio di input

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 che ha piovuto sulla riga 1, col 1
  • 1 2 significa che ha piovuto sulla fila 2, col 3 (che può contenere zero acqua e inondazioni immediatamente!)

Dopo pgiorni di pioggia, se la città è completamente allagata, esce Lavello . Altrimenti, crea Swim .

Esempio di output

Nuotare

ipotesi

  • L'input può essere fornito tramite stdin, letto da "city.txt" o accettato come argomento. Sono consentiti tutti e tre per non invalidare le risposte già pubblicate.
  • Le capacità dell'acqua saranno numeri interi non negativi.

Oltre 40 team di studenti universitari (provenienti da A&M, UT, LSU, Rice, Baylor, ecc.) Che hanno partecipato a un concorso di programmazione con una varietà di lingue disponibili non sono stati in grado di risolvere questo problema in 5 ore. Per questo motivo, non posso fare a meno di menzionare che c'è un problema in questo puzzle che rende la soluzione banale. Il codice più corto vince ancora, perché sono così sicuro che anche il codice più breve risolverà il puzzle.


E ' nlinee di mvalori o viceversa? Il tuo esempio non corrisponde alla specifica scritta.
algoritmo

@algorithmshark Corretto
Rainbolt

13
Non ne sono sicuro, ma mi sembra che affondi se la quantità di pioggia è maggiore della somma di pioggia che possono contenere tutti i quadrati; altrimenti galleggi. È così?
Hosch250,

2
@ hosch250 Rovinare il divertimento!
Rainbolt

1
"L'acqua in eccesso viene distribuita uniformemente ai vicini." - è probabile che sia 1 unità di acqua. Distribuisce, ad esempio, 0.25unità per ogni cella adiacente (presupponendo una singola cella allagata centrale)?
Neil Slater

Risposte:


16

Golfscript, 37 30 caratteri

Nuovo e migliorato, grazie a PeterTaylor per suggerimenti:

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

Spiegazione :

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"

Il programma quindi termina, producendo lo stack.


Vecchia versione + spiegazione:

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

Stesso approccio di Fors , solo Golfscripted =). Probabilmente può essere reso più efficiente. L'input proviene da stdin.

Spiegazione :

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"

Il programma quindi emette lo stack, che è solo la risposta.


]senza una corrispondenza [raccoglierà l'intero stack in un array, quindi un'iniziale [~]può essere semplificata ~]. Per ottenere i primi grid_sizeelementi di un array, utilizzare <, quindi <{+}*quasi sicuramente si può risparmiare un po 'sull'aggiunta della capacità totale. 0>"Sink""Swim"ifpuò essere0>"SinkSwim"4/=
Peter Taylor,

@PeterTaylor: grazie per i suggerimenti! Ne sei sicuro ~]? L'ho provato e non sembrava funzionare. L'ultimo hack è bello, anche se deve essere "SwimSink": lo userà. e anche l'array sembra promettente, ci lavoreremo sopra.
Claudiu,

Ne sono certo: è un trucco standard che io e altri usiamo da anni.
Peter Taylor

@PeterTaylor: Hmm strano. Provalo nell'interprete a cui mi sono collegato - fallisce. Quindi - ok forse l'interprete web non è standard. Ma ci ho provato anche con ruby golfscript.rbe ancora non ha funzionato ... puoi verificare che funzioni dalla tua parte? Ottengo lo stesso errore su entrambi:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu

1
Quando si inserisce una stringa letterale per sostituire la mancanza di stdin, è necessario precederla con un punto e virgola per rimuovere la stringa vuota che in realtà proviene "dallo stdin". Con ciò funziona benissimo
Peter Taylor

20

C: 100 96 95 caratteri

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

Cinque ore? Mi ci sono voluti cinque minuti. :)

Aragaer, grazie per le semplificazioni! Tuttavia, ho riordinato le dichiarazioni delle variabili e gli argomenti in main, visto che Clang genera un errore se il secondo argomento in main è di qualsiasi altro tipo 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");}. Ho anche giocato con l'idea di n-=scanf, ma non sono sicuro se il programma sarà corretto dopo. Innanzitutto scanfpuò essere spostato in primo piano forsenza modificare il conteggio dei personaggi.
Aragaer,

n-=scanf...non funzionerebbe, poiché in n-=1pratica è un pre-incremento, quindi mancherebbe l'angolo sud-orientale. L'altro cambiamento è grandioso.
Fors

7

Python, 4 righe, 175 caratteri

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, mi chiedo se le oltre 40 squadre abbiano finito per trovare il pescato ... dopo averlo lavorato nel modo più duro.


10
Ero in una delle oltre 40 squadre. Ci hanno dato il pescato dopo aver fallito. Tutti nell'auditorium sono stati affrontati contemporaneamente. Penso che forse non avrei dovuto menzionarlo qui. Siete stati troppo veloci!
Rainbolt

Ahia! A proposito, dovrei ottenere l'input da stdin per questo tipo di domande? - Sono nuovo di StackExchange. :)
swalladge,

Stavo per modificare la mia domanda per dire specificare STDIN, ma temevo che avrebbe invalidato la tua risposta. Ho letto i puzzle qui per circa un mese e non ho notato se le persone hanno specificato STDIN o meno.
Rainbolt

1
@swalladge Benvenuti in Codegolf! Consiglio di fare del titolo un titolo anteponendo a #.
TimWolla

2
Puoi portarlo a 108 se lo usi input()e map():n,_,p=map(int,input().split());print(['sink','swim'][p>sum(sum(map(int,input().split()))for a in range(n))])
Blender

6

Funzione doppia J (50 caratteri) e K (40)

Risulta, come al solito, questi due hanno la stessa struttura esatta nelle loro soluzioni, quindi sono entrambi qui. K è molto più breve, tuttavia, il che è una piacevole sorpresa.

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

Spiegazione:

  • ".1!:1]1 - Leggi nella prima riga e converti in numeri interi.
  • (...)/0 2{- Prendi gli elementi all'indice 0 e 2 ( ne prispettivamente) e usali come argomenti sinistro e destro del verbo (...), rispettivamente.
  • +1!:1@#1:- Leggi in n+prighe.
  • [+/@".@$- Prendi ( $) le prime nrighe ( [), scartando il resto, quindi converti in numeri interi ( ".) e somma su ogni riga ( +/).
  • ]<[:+/- Aggiungi insieme le somme delle righe, e quindi confrontare questo valore per l'argomento giusto, p. Produciamo vero se pè inferiore alla somma.
  • >Sink`Swim{~- Selezionare Swimse la sopra menzionata è risultata vera o Sinkfalsa.

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

E ora la K:

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

Ha spiegato:

  • . 0:` - Leggi in una riga di input e converti in un array di numeri interi.
  • {...}.- Utilizzare questi tre numeri n m pcome argomenti x y zper questa funzione.
  • 0::'(x+z)#`- Creare x+zcopie dell'handle del file di input `, quindi leggerlo in una riga per ciascuno di essi ( 0::').
  • .:'x#- Prendi i primi xoggetti e convertili in un vettore di numeri.
  • z<+//- Somma l'intera matrice insieme, quindi prova per vedere se è maggiore di z.
  • `Sink`Swim@- Restituisci Sinko Swimsecondo se il test è tornato vero.

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

6

APL, 35

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

Non sono sicuro se consentito ma smette di accettare input dopo la "città"

x←⎕Prende l'input e lo memorizza in una variabile x(i numeri delimitati da spazi vengono interpretati come un array numerico)
1⌷Estrai indice 1 (gli array APL sono basati su uno)
Genera un array da 1 all'argomento ( 1⌷x←⎕in questo caso)
¨Operazione "Mappa"
{+/⎕}Prendi array da inserire e restituire la somma
+/Somma l'array generato dall'operazione della mappa
4×x[3]>Test se la somma < x[3](restituisce 1 o 0), quindi moltiplicare 4
'SwimSink'⌽⍨Ruotare la stringa 'SwimSink'per quell'importo
4↑Infine, estrarre i primi 4 caratteri della stringa


Penso che l'unica parte che conta sia che produca la risposta corretta per ogni dato input. Se questo è insolito per CodeGolf, si spera che qualcuno me lo faccia sapere.
Rainbolt

Modificare ⎕IO←0, quindi sostituire 4↑'SwimSink'⌽⍨4×con 'Swim' 'Sink'⊃⍨, x[3]con x[2]e 1⌷xcon ⊃xper salvare due byte.
Adám,

6

AWK, 70

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

Questo è un miglioramento di laindir sulla mia proposta (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<=hdovrebbe essere NR<=h+1, altrimenti si otterranno falsi sink mentre viene saltata l'ultima linea di capacità. Questo può anche essere ridotto a 70 comen{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir il

1
@laindir Bene, grazie mille per il miglioramento! Lo trovo così divertente, che Awk arriva appena accanto a APL, J e K, che sono stati allevati per battere tutti sul golf del codice! :-)
user40989

@ user40989 Non capisco. Awk sembra più lungo del 40-100% rispetto a J / K / APL, anche se non sono linguaggi da golf, ma piuttosto (derivano da) linguaggi di programmazione commerciale.
Adám,

5

CoffeeScript - 128 113

Una funzione che accetta la stringa come unico argomento:

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"`

È possibile rimuovere il rientro e spostare tutto sulla prima riga separati da punti e virgola. Al `p>x?"Sink":"Swim"`posto di scrivi anche tu if p>x then"Sink"else"Swim". Anche le parentesi per la terza dichiarazione non sono necessarie.
Konrad Borowski il

4

SED, 128

È stato divertente scrivere una sedversione di questo. Ha le seguenti carenze:

  • Presuppone che la città abbia più di due colonne, per riconoscere facilmente le linee della pioggia.

  • Presuppone che la capacità di ciascuna città sia compresa tra 0 e 9.

Ecco qui:

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}

Chiama con la -nbandiera.


3

SWI-Prolog 79

Se non ti dispiace il fatto che questa risposta richieda input per query, anziché tramite stdin:

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

La risposta non convalida il formato di input, ma non penso che sia un problema, dal momento che anche il contest di programmazione non richiede di farlo.

Query di esempio (usando l'esempio nella domanda):

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
Potresti iniziare eliminando degli spazi bianchi. Dopo ,, prima e dopo ', dopo )...
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")

Potrebbe essere possibile omettere alcune parentesi o qualcosa del genere, ma Scala è davvero incostante sulla punteggiatura e sullo stile senza punti e () vs {} e quant'altro.


0

Javascript - 73 caratteri

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

Presuppone che l'ingresso sia nella variabile se gli output SwimoSink .

Esempio:

Dalla domanda originale: inserendo questo nella console del browser:

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"

Uscite:

Swim
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.