Оползни
В этой задаче ваша задача состоит в том, чтобы предсказать степень ущерба, нанесенного массивным оползнем. Для этого мы используем следующую упрощенную двумерную модель, параметризованную начальной высотой h >= 0
и критическим коэффициентом c > 0
. Вы начинаете со скалы высоты h
, и предполагается, что местность абсолютно плоская бесконечно слева и справа от нее. Ибо h = 6
ситуация выглядит так:
##########
##########
##########
##########
##########
##########
-----------------------
-
Неподвижен бедрок и #
неустойчивы почвы. Если разница в высоте между двумя соседними столбцами больше, чем c
это происходит, происходит оползень : верхние c
единицы почвы из левого столбца опускаются до следующих c
столбцов справа, по одному на каждый. Крайний правый непустой столбец на рисунке нестабилен c = 2
, поэтому происходит оползень:
#########
#########
##########
##########
##########
############
-----------------------
Столбец все еще нестабилен, что вызывает второй оползень:
#########
#########
#########
#########
############
############
-----------------------
Теперь столбик слева стал нестабильным, поэтому там произошел новый оползень:
########
########
#########
###########
############
############
-----------------------
После этого скала снова стабилизируется. Приятно то, что в этой модели порядок обработки оползней не имеет значения: конечный результат одинаков.
Задание
Ваша программа получает целочисленные параметры h
и в c
качестве входных данных (порядок не имеет значения, но вы должны указать его в своем ответе), и она должна выводить общее количество столбцов , на которые влияет оползень. Это означает количество столбцов в полученном стабильном утесе, высота которого строго между 0
и h
. В приведенном выше примере правильный вывод 4
.
Вы можете написать полную программу или функцию. Побеждает меньшее количество байтов, и стандартные лазейки запрещены.
Тестовые случаи
Они даны в формате h c -> output
.
0 2 -> 0
2 3 -> 0
6 2 -> 4
6 6 -> 0
10 1 -> 10
15 1 -> 14
15 2 -> 11
15 3 -> 6
40 5 -> 16
80 5 -> 28
80 10 -> 17
CJam - 70
Попробуйте это на http://cjam.aditsu.net/
Объяснение:
h
Оператор проверяет последнее значение в стеке , не удаляя его. Если произошел оползень, значением является массив скал, который оценивается как true, потому что он не пустой. Если нет, последнее значение равно 0 (false).Таким образом, в случае оползня цикл продолжается с массивом в стеке, в противном случае он заканчивается 0, помещенным после массива. Этот 0 затем удаляется из массива следующим
-
оператором.источник
Питон,
200190174Расширенная версия:
Изменить: После некоторой оптимизации, я устранил неловкое завершение цикла через разрыв (сохраняет 1 байт). Также изменен слайд со слайса на основе цикла.
источник
sum
на 2 байта. Кроме того, обычно лучше определить полную программу на Python, принимая вводh,c=input()
и печатая результат в конце.sum
может спасти вас один:sum(h>i>0for i in q)
.c=0
Сохраняет байт (я не могу комментировать ваш ответ).Python 2 -
194158 байт(Обратите внимание, что интерпретатор разметки SE преобразует буквенные табуляции в 4 пробела. Строки 7 и 8 этой программы имеют только одну вкладку [т.е. один байт] отступа каждая.)
Принимает ввод на stdin, в
h
первую очередь. Например:Эта программа прошла через множество улучшений. Я редактировал этот ответ, чтобы объяснить некоторые из наиболее важных изменений, но он становился все длиннее. Вы можете проверить историю редактирования, если вам интересно.
объяснение
Сначала
h
иc
читаем из stdin. В Python 2input()
это эквивалентноeval(raw_input())
, поэтому я спрашиваю запятую, разделяющую числа.input()
возвращает кортеж целых чисел, преобразование не требуется.Далее составляется список целых чисел. Это
2*h
долго. Первая половинаh
равна, а вторая половина равна 0. У меня нет никаких оснований доказывать, что этого достаточно, чтобы симулировать бесконечныеh
s слева и 0 справа. Я просто наткнулся на это, и он работает для всех тестовых случаев, поэтому, если кто-то сможет найти вход, он не работает, я с радостью его поменяю. В любом случае, этот список называетсяl
, но называется еще одна его копияb
.b
На самом деле ценность не имеет значения, все, что имеет значение, это то, что это правда. Непустой список является правдивым, и единственный способb
может быть пустым здесь, еслиh
это 0, и в этом случае правильный ответ все еще печатается. В любом другом случаеb
должен быть правдивым, чтобы убедиться, что мы вступаем вwhile b:
цикл. Тем не менее, первое, что происходит в цикле, это установкаb
в 0, значение Фолси. Во время каждого повторения циклb
должен быть специально установлен обратно на истинный, иначе цикл закончится.Остальная часть цикла - это фактическое моделирование. Это очень наивно, по сути, просто перевод кода описания проблемы. Если какой - либо элемент
l
больше , чемc
больше , чем один следующий за ним, оно вычитаютc
и следующиеc
элементы : 1 добавили к ним. (Кстати, побитовая магия, используемая здесь, является просто более коротким способом записиi+1+j
.) При выполнении этих преобразованийb
устанавливается значение 1. В первый раз, когда преобразования не выполняются,b
останется 0, и цикл завершится.Любое истинное выражение оценивается как
True
, а когда вы пытаетесь выполнить математику,True
оно оценивается как 1. То же самое верноFalse
и для 0. Последняя строка программы использует каждый элементl
ase
в выраженииh>e>0
и суммирует результат. Получается число столбцов больше 0, но ниже, чем исходная высота обрыва, что является значением, которое запрашивает вопрос. Она распечатана, и программа завершается.источник
c-=c
эквивалентноc=0
?i+1+j
можно записать какi-~j
Haskell,
163156151 байтИспользование:
h#c
например,6#2
какие выходы4
.Как это работает: вспомогательная функция
s
делает один оползень. Повторно применятьs
до тех пор, пока выход больше не изменится. Подсчитайте затронутые элементы.Нашел функцию «применить до тех пор, пока выход не изменится» (то есть
until=<<((==)=<<)
) в Stackoverflow .источник
f
как infix (h#c=...
) и переместивwhere
предложение в ту же строку. Кроме того, есть еще несколько скобок, которые следует использовать$
, хотя я не уверен, сколько ...()
на это$
- след и ошибка для меня.Mathematica,
1081041009795Использование:
Пример:
источник
C #
303295Оно работает!
Но это ....
Я должен найти новый язык;)
Я проверю эту вещь CJam ...
Улучшен:
источник
int z=i;int y=i-1;
может бытьint z=i,y=i-1;
. Вfor
петле не делать сложные вещи с их индексами, так , например ,for(int i=s.Count-1;i>0;i--)
может бытьfor(int i=s.Count;--i>0;)
.1<0
это более короткий способ написанияfalse
. Я подозреваю, чтоif(s[s.Count-1]>0)s.Add(0);
может потерять условие, не влияя на правильность, просто скорость.