Ми тонемо чи плаваємо?


40

Проблема

Сценарій кінця світу описується трьома цифрами на одній лінії, n, mі p. За цим рядком знаходяться nрядки зі mзначеннями на рядок. Кожне значення являє собою загальну кількість одиниць води, яку може містити кожна клітина.

Наступні pрядки описують погоду на наступні pдні. 1 одиниця дощу випадає на одну клітинку щодня. Якщо кількість води в клітині перевищує кількість, яку вона може утримувати, ця клітина затоплюється. Якщо декілька сусідніх комірок працюють на повну потужність, вони розглядаються як одна комірка, яка розділяє загальних сусідів (подумайте, що трапився, якщо натиснути на групу заготовок).

  • В одній середній клітині є 4 сусіди
  • Дві сусідні середні клітини на повну ємність розглядаються як одна клітина, яка має 6 сусідів
  • В одній кутовій комірці є 2 сусіди
  • В одній стіновій комірці є 3 сусіди

Коли клітина затоплюється, відбувається повені. Вся зайва вода рівномірно розподіляється на сусідів. Якщо це спричиняє затоплення одного або декількох сусідів, то виникає інша повені. Це триває, поки вода не осідає, або місто повністю не затопить.

Приклад введення

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

  • 0 0 означає, що дощ на рядок 1, стовп 1
  • 1 2 означає, що він дощив на ряду 2, стовпчик 3 (який може утримувати нульову воду і негайно затоплювати!)

Після pднів дощу, якщо місто повністю затоплене, виведіть Раковину . В іншому випадку виведіть Swim .

Приклад Вихід

Плавати

Припущення

  • Введення може бути надано через stdin, прочитане з "city.txt" або прийняте як аргумент. Усім трьом дозволено, щоб не визнати недійсними жодні опубліковані відповіді.
  • Водомісткість буде невід’ємними цілими числами.

40+ колективів студентів нижчих класів (від A&M, UT, LSU, Rice, Baylor та ін.), Які змагались у конкурсі програмування з різними доступними мовами, не могли вирішити цю проблему за 5 годин. Через це я не можу не зазначити, що в цій головоломці є улов, що робить рішення тривіальним. Найкоротший код все-таки виграє, тому що я впевнений, що найкоротший код також вирішить головоломку.


Це nлінії mзначень чи навпаки? Ваш приклад не відповідає письмовій специфікації.
Алгоритм

@algorithmshark Виправлено
Rainbolt

13
Я не впевнений, але мені здається, що ви потопаєте, якщо кількість дощу більше, ніж сума дощу, яку можуть утримати всі квадрати; інакше ти пливеш. Це це?
Hosch250

2
@ hosch250 Псуючи задоволення!
Rainbolt

1
"Надлишок води рівномірно розподіляється на сусідів". - це, ймовірно, буде 1 одиниця води. Чи поширюється воно, наприклад, 0.25одиницями, до кожної сусідньої комірки (якщо припустити одну середню затоплену клітинку)?
Ніл Слейтер

Відповіді:


16

Гольфскрипт, 37 30 символів

Нове та вдосконалене, завдяки PeterTaylor за поради:

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

Пояснення :

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"

Потім програма завершується, виводячи стек.


Стара версія + пояснення:

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

Той самий підхід, як і Форс , просто Гольфскрипт =). Можливо, можна зробити більш ефективним. Введення з stdin.

Пояснення :

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"

Потім програма виводить стек, що є лише відповіддю.


]без відповідності [буде зібрано весь стек у масив, тому початковий [~]може бути спрощений до ~]. Щоб отримати перші grid_sizeелементи масиву, використовуйте <, так що <{+}*майже точно можна заощадити на додаванні загальної ємності. 0>"Sink""Swim"ifможе бути0>"SinkSwim"4/=
Пітер Тейлор

@PeterTaylor: Дякую за поради! Ви впевнені ~]? Я спробував це, але, здавалося, не вийшло. Останній хак приємний, хоча має бути "SwimSink"- використовуватиме його. і річ із масиву також здається перспективною, буде працювати над цим.
Клавдіу

Я впевнений: це стандартний трюк, який я та інші використовую роками.
Пітер Тейлор

@PeterTaylor: Хм дивно. Спробуйте це у перекладача, до якого я пов’язаний, - це не вдається. Тоді - добре, можливо, веб-перекладач є нестандартним. Але я спробував також, ruby golfscript.rbі все одно не вийшло ... чи можете ви переконатися, що він працює на ваш кінець? Я отримую однакову помилку в обох:undefined method '+' for nil:NilClass (NoMethodError)
Клавдіу,

1
Коли ви вставляєте рядковий літерал, щоб замінити відсутність stdin, вам слід передувати його крапкою з комою, щоб видалити порожній рядок, який насправді надходить "з stdin". З цим це працює чудово
Пітер Тейлор

20

C: 100 96 95 символів

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

П’ять годин? Взяв мене п’ять хвилин. :)

Араґаєр, дякую за спрощення! Проте я переставляв декларації та аргументи змінної на main, бачачи, як Clang видає помилку, якщо другий аргумент до main є будь-якого іншого типу 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");}
араґер

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");}. Я також грав з ідеєю n-=scanf, але не впевнений, чи буде програма після цього правильною. Спочатку scanfможна перемістити на передню частину, forне змінюючи кількість символів.
араґер

n-=scanf...не буде працювати, так як в n-=1основному це попередній приріст, тому він буде пропускати південно-східний кут. Інша зміна - чудова.
Форс

7

Пітон, 4 рядки, 175 символів

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

Лол, мені цікаво, чи 40+ команд знайшли улов ... після того, як відпрацювали його важким шляхом.


10
Я був в одній із команд 40+. Ми отримали вилов після відмови. Усі в аудиторії одночасно стикалися з обличчям. Я думаю, можливо, я не мав би цього згадувати тут. Ви, хлопці, були надто швидкими!
Rainbolt

Ой! До речі, я повинен отримати інформацію від stdin для таких питань? - Я новачок у stackexchange. :)
swalladge

Я збирався редагувати своє запитання, щоб сказати, вказати STDIN, але я побоювався, що це визнає недійсною вашу відповідь. Я читав тут загадки близько місяця, і не дуже помітив, чи вказали люди STDIN чи ні.
Rainbolt

1
@swalladge Ласкаво просимо до Codegolf! Я рекомендую зробити заголовок заголовком, попередньо додавши a #.
TimWolla

2
Ви можете знизити його до 108, якщо використовуєте input()та 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 знаків) та K (40) подвійні функції

Виявляється, як зазвичай, ці двоє мають однакову структуру у своїх рішеннях, тож вони обидва тут. K, проте, це набагато коротше, що приємно здивує.

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

Пояснення:

  • ".1!:1]1 - Прочитайте в першому рядку і перетворіть на цілі числа.
  • (...)/0 2{- Візьміть елементи в індексах 0 і 2 ( nі pвідповідно) і використовуйте їх як лівий і правий аргументи до дієслова (...)відповідно.
  • +1!:1@#1:- Прочитайте в n+pрядках.
  • [+/@".@$- Візьміть ( $) перші nрядки ( [), відкинувши решту, а потім перетворіть на цілі числа ( ".) та підсумовуйте кожен рядок ( +/).
  • ]<[:+/- Складіть рядки суми, а потім порівняти це значення правого аргументу p. Ми виробляємо істину, якщо pменша сума.
  • >Sink`Swim{~- Виберіть, Swimчи вказане вище співчуття істинне, чи Sinkпомилкове.

Використання:

   >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

А тепер K:

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

Пояснили:

  • . 0:` - Прочитайте у рядку введення та перетворите на масив цілих чисел.
  • {...}.- Використовуйте ці три числа n m pв якості аргументів x y zцієї функції.
  • 0::'(x+z)#`- Створіть x+zкопії ручки вхідного файлу `, а потім прочитайте у рядку для кожного з них ( 0::').
  • .:'x#- Візьміть перші xпредмети і перетворіть кожен у вектор чисел.
  • z<+//- Підсумовуйте всю матрицю разом, а потім перевіряйте, чи не перевищує вона z.
  • `Sink`Swim@- Повернення Sinkабо Swimвідповідно до того, чи повернувся тест справжнім.

Використання:

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

Не впевнений, чи дозволено, але він припиняє приймати вхід після "міста"

x←⎕Бере введення та зберігає його у змінній x(проміжки з обмеженими пробілами числами інтерпретуються як числовий масив)
1⌷Витяг індексу 1 (масиви APL є одноосновними)
Створення масиву з 1 до аргументу ( 1⌷x←⎕у цьому випадку
¨операція "Карта"
{+/⎕}Візьміть масив з введіть і поверніть суму
+/Сума масиву, створеного операцією з картою.
4×x[3]>Перевірте, якщо сума < x[3](повертає 1 або 0), а потім помножте 4
'SwimSink'⌽⍨Поверніть рядок 'SwimSink'на цю суму
4↑Нарешті, витягніть перші 4 символи рядка


Я думаю, що важлива лише частина - це те, що вона дає правильну відповідь на будь-який даний вхід. Якщо це незвично для CodeGolf, сподіваюся, хтось дасть мені знати.
Rainbolt

Змініть ⎕IO←0, а потім замініть 4↑'SwimSink'⌽⍨4×на 'Swim' 'Sink'⊃⍨, x[3]з x[2]і 1⌷xна, ⊃xщоб зберегти два байти.
Adám

6

AWK, 70

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

Це посилення Лайндіра за моїм поданням (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<=hповинно бути NR<=h+1, інакше ви отримаєте помилкові раковини, оскільки пропущений останній рядок ємностей. Це також можна скоротити до 70, якn{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir

1
@laindir Ну, дуже дякую за покращення! Мені це так весело, що Awk просто приходить поруч із APL, J та K, які були розведені, щоб перемогти всіх у коді-гольфінгу! :-)
user40989

@ user40989 Я не розумію. Awk здається на 40-100% довше J / K / APL, навіть якщо вони не є гольф-мовами, а скоріше (випливають із) комерційних мов програмування.
Адам

5

CoffeeScript - 128 113

Функція, яка приймає рядок як єдиний аргумент:

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

Можна видалити відступ і перемістити все на першому рядку, розділеному крапками з комою. Ви також пишете `p>x?"Sink":"Swim"`замість if p>x then"Sink"else"Swim". Паролі для третього твердження також не потрібні.
Конрад Боровський

4

СЕД, 128

Було весело писати sedверсію цього. У нього є такі недоліки:

  • Передбачається, що місто має більше двох стовпців, щоб легко розпізнати лінії дощу.

  • Він передбачає, що місткість кожного міста знаходиться в межах 0-9.

Ось:

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}

Дзвінок із -nпрапором.


3

SWI-Prolog 79

Якщо ви не заперечуєте проти того, що ця відповідь приймає запит, а не через stdin:

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

Відповідь не підтверджує формат введення, але я не думаю, що це проблема, оскільки конкурс програмування також не вимагає від вас цього робити.

Зразок запиту (використовуючи приклад у запитанні):

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

Пітон - 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
Ви можете почати, взявши пробіл. Після ,, до і після ', після )
Ри-

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

Можливо, можливо пропустити деякі круглі дужки чи щось подібне, але Скала насправді непоганий щодо пунктуації та безточного стилю та () проти {} та чого іншого.


0

Javascript - 73 символи

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

Припускає, що вхід знаходиться у змінній sі виводить Swimабо Sink.

Приклад:

З початкового питання - введення цього в консоль браузера:

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"

Виходи:

Swim
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.