Это проблема в Интернете, заданная Palantir Technologies в своих интервью .
У группы фермеров есть некоторые данные по высоте, и мы собираемся помочь им понять, как ливень течет по их сельхозугодьям. Мы представим землю в виде двумерного массива высот и будем использовать следующую модель, основанную на идее, что вода течет вниз:
Если четыре соседние ячейки имеют большую высоту, мы называем эту ячейку стоком; вода собирается в раковинах. В противном случае вода будет поступать в соседнюю ячейку с наименьшей высотой. Если ячейка не является приемником, вы можете предположить, что у нее есть уникальный младший сосед, и что этот сосед будет ниже ячейки.
Считается, что клетки, которые попадают в одну и ту же раковину - прямо или косвенно - являются частью одного и того же бассейна.
Ваша задача состоит в том, чтобы разделить карту на бассейны. В частности, учитывая карту высот, ваш код должен разбить карту на бассейны и вывести размеры бассейнов в порядке убывания.
Предположим, карты высот являются квадратными. Ввод начнется со строки с одним целым числом, S, высотой (и шириной) карты. Каждая из следующих S строк будет содержать строку карты, каждая с S целыми числами - отметками S ячеек в строке. У некоторых фермеров есть небольшие земельные участки, такие как примеры ниже, а у некоторых есть большие участки. Тем не менее, ни в коем случае фермер не будет иметь участок земли больше, чем S = 5000.
Ваш код должен выводить разделенный пробелами список размеров бассейна в порядке убывания. (Конечные пробелы игнорируются.)
Несколько примеров ниже.
Входные данные:
3
1 5 2
2 4 7
3 6 9
Выход:
7 2
Бассейны, помеченные буквами A и B:
A A B
A A B
A A A
Входные данные:
1
10
Выход:
1
В этом случае есть только один бассейн.
Входные данные:
5
1 0 2 5 8
2 3 4 7 9
3 5 7 8 9
1 2 5 4 2
3 3 5 2 1
Выход:
11 7 7
Бассейны, обозначенные буквами A, B и C:
A A A A A
A A A A A
B B A C C
B B B C C
B B C C C
Входные данные:
4
0 2 1 3
2 1 0 4
3 3 3 3
5 5 2 1
Выход:
7 5 4
Бассейны, обозначенные буквами A, B и C:
A A B B
A B B B
A B B C
A C C C
источник
Ответы:
Mathematica
Список размеров бассейна может быть получен
где
m
заданные входные данные. Чтобы отобразить матрицу, аналогичную приведенной в вопросе, можно заменить// Reverse@Sort@Part[Tally[Flatten@#], All, 2] &
на/. {1 -> "A", 2 -> "B", 3 -> "C"} // MatrixForm
или вместо нее можно отобразить ее в виде изображения//ImageAdjust//Image
.источник
JavaScript - 673
707730751e=[],g=[],h=[],m=[],q=[];function r(){a=s,b=t;function d(d,A){n=a+d,p=b+A;c>e[n][p]&&(u=!1,v>e[n][p]&&(v=e[n][p],w=n,k=p))}c=e[a][b],u=!0,v=c,w=a,k=b;0!=a&&d(-1,0);a!=l&&d(1,0);0!=b&&d(0,-1);b!=l&&d(0,1);g[a][b]=w;h[a][b]=k;return u}function x(a,b,d){function c(a,b,c,k){g[a+b][c+k]==a&&h[a+b][c+k]==c&&(d=x(a+b,c+k,d))}d++;0!=a&&c(a,-1,b,0);a!=l&&c(a,1,b,0);0!=b&&c(a,0,b,-1);b!=l&&c(a,0,b,1);return d}y=$EXEC('cat "'+$ARG[0]+'"').split("\n");l=y[0]-1;for(z=-1;z++<l;)e[z]=y[z+1].split(" "),g[z]=[],h[z]=[];for(s=-1;s++<l;)for(t=-1;t++<l;)r()&&m.push([s,t]);for(z=m.length-1;0<=z;--z)s=m[z][0],t=m[z][1],q.push(x(s,t,0));print(q.sort(function(a,b){return b-a}).join(" "));
Результаты теста (с использованием Nashorn):
Вероятно, будут проблемы со стеком для карт размером 5000 (но это детали реализации :).
Неограниченный источник во всем его бесполезности:
Я добился лучших результатов минимизации, разбив объекты-элементы на отдельные массивы, повсеместно глобализируя и используя побочные эффекты. NSFW.
Эффекты минимизации кода:
Я мог бы достичь почти 700 байтов, не редактируя свернутый код, если бы я хотел изменить исходный код. Но я не сделал, потому что я думаю, что оставление этого как есть дает интересную точку зрения с начальной точки.
источник
var e=[],g=[],h=[],l,m=[],q=[]
доe=g=h=l=m=q=[]
. Вероятно, вы можете избавиться и от других вариантов использованияvar
ключевого слова, если не скрываете глобальные переменные.Python: 276
306 365байтЭто моя первая попытка игры в гольф. Предложения приветствуются!
редактировать: импорт и закрытие файлов занимает слишком много символов! То же самое касается хранения файлов в переменных и понимания вложенного списка.
полностью прокомментировано (2130 байт ...)
источник
open('a').read()
, я думаю.JavaScript (ECMAScript 6) - 226 символов
объяснение
Предыдущая версия - 286 персонажей
Предполагается, что входные данные находятся в переменной
S
;объяснение
Тестовое задание
Выходы:
[7, 2]
Выходы:
[11, 7, 7]
Выходы:
[5, 7, 4]
источник
Юлия, 315
Просто рекурсивная функция, которая либо определяет текущую ячейку, является приемником, либо находит сток, а затем вызывает ее для каждого набора индексов. Не удосужился сделать входную часть, так как я все равно не собирался выигрывать, и эта часть не веселая.
источник
Хаскелл, 271
286Может быть, еще какой-то код для игры в гольф здесь.
объяснение
Основная идея: для каждой ячейки (i, j) найдите самую нижнюю ячейку в «окрестности». Это дает график [ (I, J) → (mi, mj) ]. Если ячейка является самой нижней ячейкой, то (i, j) == (mi, mj) .
Этот график может быть повторен: для каждого a → b в графе замените его на a → c, где b → c находится в графе. Когда эта итерация больше не приводит к изменениям, то каждая ячейка в графе указывает на самую нижнюю ячейку, в которую она будет перемещаться.
Для игры в гольф было сделано несколько изменений: во-первых, координаты представлены в виде списка длиной 2, а не пары. Во-вторых, как только соседи найдены, ячейки представляются своим индексом в виде линейного массива ячеек, а не 2D-координат. В-третьих, поскольку существует n * n ячеек, после n * n итераций граф должен быть устойчивым.
Ungolf'd
источник
Руби, 216
Это немного другой подход, вызывая «поток» только для каждого квадрата один раз (производительность зависит от производительности Array :: index). Он идет от самой высокой отметки к самой низкой, опустошая по одной ячейке за раз в своего нижнего соседа и помечая ячейку как выполненную (добавляя 1 к отметке), когда это будет сделано.
Комментарии и интервалы:
Changelog:
216 - лучший способ отменить выбор внеклассных индексов
221 - получается, «11» предшествует «2» ... вернуться к
to_i
, но сэкономить место на нашемgets
эс.224 - Зачем
s
вообще декларировать ? Иeach
=>map
229 - массивный гольф - сначала рассортируйте возвышения
s
(и, таким образом, отбросьтеwhile
предложение), используйтеmin_by
вместоsort_by{...}[0]
, не беспокойтесьto_i
о возвышениях, используйтеflat_map
и сокращайтеselect{}
блок271 - перенес размер водораздела в новый массив и использовал sort_by
315 - переместил результаты в массив, который дал все виды преимуществ, и сократил список соседних индексов. также получил один символ в индексе лямбда.
355 - первый коммит
источник
Питон -
470 447 445 393 392 378 376 375 374369 байтЯ не могу остановить себя!
Не выигрышное решение, но мне было очень весело создавать его. Эта версия не предполагает, что ввод будет храниться где-либо, а вместо этого читает его из стандартного ввода. Максимальная глубина рекурсии = наибольшее расстояние от точки до ее раковины.
У меня нет времени, чтобы объяснить это сегодня, но вот незакрашенный код:На самом деле это сильно отличается от исходного кода. Я читаю S строк из stdin, split, map to ints и сглаживаю списки, чтобы получить сглаженное поле. Затем я перебираю все плитки (позвольте мне называть их плитками) один раз. Функция потока проверяет соседние листы и выбирает тот, у которого наименьшее значение. Если он меньше, чем значение текущей плитки, перейдите к нему и выполните повторный поиск. Если нет, то текущая плитка является раковиной, и создается новый бассейн. Возвращаемое значение рекурсии - это идентификатор бассейна.
источник
JavaScript (ES6) 190
203редактировать немного больше ES6ish (1 год спустя ...)
Определить функцию с входными строками в виде строки, включая переводы строк, вернуть вывод в виде строки с конечными пробелами
источник
Perl 6,
419404Новые строки добавлены для ясности. Вы можете безопасно удалить их.
Старое решение:
И все же меня побеждают решения Python и JavaScript.
источник