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


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

  • 0 0 означает, что дождь в ряду 1, цв 1
  • 1 2 означает, что в ряду 2, седло 3 (дождь может дождаться нуля и сразу затопить!)

После pдней дождя, если город полностью затоплен, выведите Sink . В противном случае выведите 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

Golfscript, 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

Такой же подход, как у Форса , только Golfscripted =). Скорее всего, можно сделать более эффективным. Ввод от стандартного ввода.

Пояснение :

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

1
Когда вы вставляете строковый литерал, чтобы заменить отсутствие стандартного ввода, вам следует поставить перед ним точку с запятой, чтобы удалить пустую строку, которая на самом деле идет «из стандартного ввода». При том, что он работает нормально
Питер Тейлор

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

Пять часов? У меня ушло пять минут. :)

Aragaer, спасибо за упрощения! Однако я переставил объявления переменных и аргументы в 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");}
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");}. Я также играл с идеей n-=scanf, но не уверен, что программа будет правильной после этого. Первый scanfможет быть перемещен вперед forбез изменения количества символов.
aragaer

n-=scanf...не сработает, так как в n-=1основном это предварительный прирост, поэтому он пропустит юго-восточный угол. Другое изменение - это здорово.
Форс

7

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

Lol, я думаю, что более 40 команд в конечном итоге нашли подвох ... после того, как решили его нелегко.


10
Я был в одной из 40+ команд. Нам дали улов после неудачи. Все в зрительном зале лицевые лица одновременно. Я думаю, возможно, я не должен был упомянуть это здесь. Вы, ребята, были слишком быстры!
Rainbolt

Ой! Кстати, я должен получить вход от stdin для такого рода вопросов? - Я новичок в стек-обмене. :)
ласточка

Я собирался отредактировать свой вопрос, чтобы сказать, укажите 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

А теперь К:

`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зависимости от того, вернул ли тест значение true.

Использование:

  `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чтобы сэкономить два байта.
Адам

6

AWK, 70

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

Это улучшение от laindir в моем представлении (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-Пролог 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
Вы можете начать с удаления пробелов. После ,, до и после ', после )...
Ry-

1

Скала - 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")

Можно было бы опустить некоторые скобки или что-то в этом роде, но Scala действительно непостоянна в отношении пунктуации и стиля без точек, а также () vs {} и еще много чего.


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.