Открыта ли дверь электрического гаража?

24

Моя электрическая дверь гаража работает так:

  • Есть только одна кнопка для управления дверью
  • Если дверь полностью закрыта, и я нажимаю кнопку, дверь начинает открываться. Требуется 10 секунд, чтобы полностью открыть
  • Если дверь полностью открыта, и я нажимаю кнопку, дверь начинает закрываться. Для полного закрытия требуется 10 секунд
  • Если дверь частично открывается или закрывается, и я нажимаю кнопку, то дверь останавливается и остается частично открытой.
  • Всякий раз, когда дверь перестает двигаться, либо из-за автоматического завершения открытого или закрытого действия, либо из-за ручного прерывания путем нажатия кнопки на полпути во время действия, механизм перевернется и запомнит свое направление для следующего действия.
  • Если кнопка нажата, когда дверь остановлена, но частично открыта, то время, необходимое ей для завершения своего действия, составит долю в 10 секунд пропорционально количеству, которое необходимо переместить для выполнения действия.

Предположим, что дверь полностью закрыта в начале.

Будет введен список целых чисел. Эти целые числа - это количество секунд, которые я жду между последовательными нажатиями кнопки управления.

Выведите две вещи:

  • процент, указывающий состояние двери после того, как все нажатия кнопок завершены, и дверь достигла устойчивого состояния. Вывод %символа не является обязательным.
  • однозначное указание направления движения двери при следующем нажатии кнопки. Это может быть up/ down, U/ D, +/ -, 1/ 0или все, что вы выберете.

Вы можете предположить, что дверь занимает бесконечно меньше 10 секунд, чтобы завершить действие открытия или закрытия.

Пример входных данных:

<empty list>  # button was pushed just once
20            # button was pushed twice with 20 seconds between
10
5
20 20
10 10
5 5
1 2 3
8 9 10 11
11 10 9 8 7

Ожидаемые результаты, соответствующие вышеуказанным данным

100% D
0% U
0% U
50% D
100% D
100% D
0% U
100% D
0% U
20% U

Сработал пример последнего теста

  • Дверь начинается с закрытой. Кнопка нажата
  • Подождите 11 секунд. Дверь заканчивается полностью открытой. Кнопка нажата.
  • Подождите 10 секунд. Дверь заканчивается полностью закрытой. Кнопка нажата.
  • Подождите 9 секунд. Кнопка нажата. Дверь останавливается при открытии на 90%.
  • Подождите 8 секунд. Кнопка нажата. Дверь начинает закрываться.
  • Подождите 7 секунд. Кнопка нажата. Дверь останавливается при открытии на 20%. Следующее направление будет вверх.
Цифровая травма
источник
У вас гаражная дверь останавливается при полуоткрытии, если вы нажимаете кнопку при закрытии? Мой не только для открытия.
Балинт
@ Балинт в мою сторону.
Цифровая травма
@Maltysen позволяет придерживаться процентов сейчас.
Цифровая травма
Можно ли выводить число с плавающей запятой, если вход также состоит из чисел с плавающей запятой?
Р. Кап
@ Р.Кап, да, все в порядке.
Цифровая травма

Ответы:

6

Lua, 258 248 242 байта

u,s,p=1>0,0>1,0;io.read():gsub("%d+",function(a)if(not s)then p=u and p+a or p-a;if(p>=10 or p<=0)then s,p=1>0,p>0 and 10 or 0;end;u,s=not u,not s else s=0>1;end end)if(not s)then p=u and 10 or 0;u=not u;end;print(10*p.."% "..(u and"U"or"D"))

Ungolfed

u,s,p=true,false,0;                          -- Up direction, Stopped, Position
io.read():gsub("%d+",function(t)             -- For each number in input
    if(not s)then                            -- If door wasn't stopped
        p=u and p+t or p-t;                  -- Position = Moving up ? +t : -t
        if(p>=10 or p<=0)then                -- If door fully opened or closed
            s,p=true,p>0 and 10 or 0;        -- Then door stopped at 0 or 10
        end 
        u,s=not u,not s;                     -- Toggle direction and toggle stopped
    else 
        s=false;                             -- If stopped, nothing happened, un-stop.
    end 
end)
-------------------- Done pressing the button --------------------
if(not s)then                                -- If left off moving
    p=u and 10 or 0;                         -- Finish movement
    u=not u;                                 -- Toggle direction
end 
print(10*p.."% "..(u and"U"or"D"))           -- Output answer

Я не понимаю, как ваши тесты могут быть правильными ...

20 20 -- Initial push, after 20, garage is at 100, push to start it down, after 20, garage is at 0, push to start it up, garage finishes up.
10 10 -- Same as above
1 2 3 -- 0 U Moving, wait 1, 1 D Stopped, wait 2, 0 U stopped, wait 3, 100 D stopped

Фиксированный ОП

болтун
источник
Я только что закончил свою работу, и я согласен с вашими результатами тоже.
Нейл
3

JavaScript (ES6), 109 106 байт

a=>a.map(e=>(s^=1)?(r-=e*(d=-d))>9?(s=0,r=10):r<1?(r=s=0):r:r,r=s=0,d=1)&&(s?r:5*++d)*10+(d-s?"% D":"% U")
Нил
источник
@DigitalTrauma Должна быть ошибка оптимизации. Я повторно оптимизировал его и каким-то образом сумел сохранить еще 3 байта на этот раз!
Нейл
3

Рубин, 152 байта

->v{u,s,a=!!1,!0,0;v.map{|w|!s ?(a=u ? a+w : a-w;a>=10 ?(s,a=!!1,10):a<=0 ?(s,a=!!1,0):0;u,s=!u,!s):s=!0};!s ?(a=(u=!u)?0:10):0;p"#{10*a}% #{u ??U:?D}"}

Тестовые случаи:

f=->v{u,s,a=!!1,!0,0;v.map{|w|!s ?(a=u ? a+w : a-w;a>=10 ?(s,a=!!1,10):a<=0 ?(s,a=!!1,0):0;u,s=!u,!s):s=!0};!s ?(a=(u=!u)?0:10):0;p"#{10*a}% #{u ??U:?D}"}

f[[]]            # => "100% D"
f[[20]]          # => "0% U"
f[[10]]          # => "0% U"
f[[5]]           # => "50% D"
f[[20,20]]       # => "100% D"
f[[10,10]]       # => "100% D"
f[[5,5]]         # => "0% U"
f[[1,2,3]]       # => "100% D"
f[[8,9,10,11]]   # => "0% U"
f[[11,10,9,8,7]] # => "20% U"
br3nt
источник
Как весело стороне записки, вы можете удалить требование дополнительных кронштейнов на стоимость одного байта, путем изменения ->v{в ->*v{(я думаю). Кроме того , вам нужно пространство перед: тем , а также после того, как ? И ты уверен, что :a<=0не разбирает (:a) <= 0?
Фонд Моники Иск
Хороший совет! Должен быть взвешен с доступом к var, хотя. Что касается :a<=0, я бы получил, ArgumentError: comparison of Symbol with 0 failedесли бы это не сработало. Я думаю, потому что он проанализировал ?и знает, что это троичный оператор, он просто работает. Правила действительно странные. Я поставил пробелы или скобки в местах, которые необходимы, чтобы избежать синтаксических ошибок, таких как SyntaxError: unexpected tLABELи NoMethodError: undefined method u? '`.
br3nt
Не стесняйтесь вносить изменения, если вы видите какие-либо улучшения. Я надеялся, что смогу избавиться от него a=u ? a+w : a-wи изменить его на то, a=a+w*dгде dнаходится 1или в -1зависимости от направления, но я еще не решил это.
br3nt
Насколько я понимаю, редактирование для улучшения кода обычно не рекомендуется; вместо этого вы должны прокомментировать. Что касается вашей идеи по улучшению, я не знаю; кажется, что это может сработать, но я точно не знаю.
Фонд Моника иск
2

Python 3.5, 193 187 185 181 175 173 172 байта:

def G(*p):
 O=100;y=0;l=10;z,v='UG'
 for g in[*p,O]:
  if v=='G':Q=O*g//10;y=min(max(0,[Q,y-Q][z=='D']),O);l=min(10,g);z='UD'[z=='U']
  v='GS'[(O>y>0)*(v!='S')]
 print(y,z)

Принимает ввод в виде разделенных запятыми чисел, например 1,2,3,4,5или даже 1.2,3.4,7.8,9.2. Выводит, идет ли дверь на следующем шаге вверх или вниз с помощью Uили D, соответственно. Будет ли гольф больше со временем.

Попробуйте онлайн! (Идеально) (Здесь ввод берется в виде списка, состоящего из разделенных запятыми чисел, например [1,2,3,4,5].)

Р. Кап
источник
1

PHP, 128 120 байт

$d=$argv[]=10;
foreach($argv as$a)
  if($r){$p=min(max($p+$a*$d,0),100);$r=$p<1||99<$p;$d=-$d;}else$r=1;
echo"$p% ".DU[$d>0];

Код обернут здесь, чтобы поместиться в поле кода. Поместите все в одну строку, поместите перед ним маркер открытия PHP и сохраните его в файл. Или запустите его из командной строки, используя php -d error_reporting=0 -r '...the code...' [arguments].

Исходный код ungolfed, набор тестов и примеры использования можно найти на github .

axiac
источник