Czy elektryczna brama garażowa jest otwarta?

24

Moja elektryczna brama garażowa działa w następujący sposób:

  • Jest tylko jeden przycisk do sterowania drzwiami
  • Jeśli drzwi są całkowicie zamknięte i nacisnę przycisk, drzwi zaczynają się otwierać. Pełne otwarcie zajmuje 10 sekund
  • Jeśli drzwi są całkowicie otwarte i wcisnę przycisk, drzwi zaczynają się zamykać. Całkowite zamknięcie zajmuje 10 sekund
  • Jeśli drzwi są częściowo w trakcie otwierania lub zamykania i wcisnę przycisk, drzwi zatrzymują się i zostają częściowo otwarte.
  • Ilekroć drzwi przestają się poruszać, albo po automatycznym zakończeniu akcji otwierania lub zamykania, albo po ręcznej przerwie poprzez naciśnięcie przycisku w trakcie akcji, wówczas mechanizm się odwróci i zapamięta kierunek dla następnej akcji.
  • Jeśli przycisk zostanie naciśnięty, gdy drzwi zostaną zatrzymane, ale częściowo otwarte, czas na zakończenie akcji wyniesie ułamek 10 sekund proporcjonalnie do ilości ruchu, jaką musi wykonać, aby ukończyć akcję.

Załóżmy, że drzwi są całkowicie zamknięte na początku.

Podana zostanie lista wejściowa liczb całkowitych. Te liczby całkowite to liczba sekund, które czekam między kolejnymi naciśnięciami przycisku sterowania.

Wyprowadź dwie rzeczy:

  • wartość procentowa wskazująca stan drzwi po zakończeniu wszystkich naciśnięć przycisków i osiągnięciu przez drzwi stanu ustalonego. Wyjście %symbolu jest opcjonalne.
  • jednoznaczne wskazanie, w którym kierunku będą poruszać się drzwi po kolejnym naciśnięciu przycisku. Może to być up/ down, U/ D, +/ -, 1/ 0lub cokolwiek wybierzesz.

Możesz założyć, że przejście zajmuje nieskończenie mniej niż 10 sekund, aby zakończyć czynność otwierania lub zamykania.

Przykładowe dane wejściowe:

<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

Oczekiwane wyniki odpowiadające powyższym wejściom

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

Działał przykład ostatniego testu

  • Drzwi zaczynają się zamykać. Przycisk jest wciśnięty
  • Poczekaj 11 sekund. Drzwi kończą się w pełni otwarte. Przycisk jest wciśnięty.
  • Poczekaj 10 sekund. Drzwi zamykają się całkowicie. Przycisk jest wciśnięty.
  • Poczekaj 9 sekund. Przycisk jest wciśnięty. Drzwi zatrzymują się przy 90% otwartym.
  • Poczekaj 8 sekund. Przycisk jest wciśnięty. Drzwi zaczynają się zamykać.
  • Poczekaj 7 sekund. Przycisk jest wciśnięty. Drzwi zatrzymują się przy 20% otwartym. Następny kierunek będzie w górę.
Cyfrowa trauma
źródło
Brama garażowa zatrzymuje się w półotwartym, jeśli naciśniesz przycisk podczas zamykania? Mój nie, tylko na otwarcie.
Bálint
@ Bálint w obie strony dla mojego.
Cyfrowa trauma,
@Maltysen pozwala teraz trzymać się procentu.
Cyfrowa trauma
Czy jest w porządku, jeśli wyprowadzana jest liczba zmiennoprzecinkowa, jeśli dane wejściowe również składają się z liczb zmiennoprzecinkowych?
R. Kap
@ R.Kap tak, w porządku.
Cyfrowa trauma

Odpowiedzi:

6

Lua, 258 248 242 bajtów

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

Bez golfa

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

Nie rozumiem, jak mogą wyglądać twoje przypadki testowe ...

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

OP Naprawiono

Paplać
źródło
Właśnie skończyłem pracę i zgadzam się z twoimi wynikami.
Neil
3

Pyth, 50 45 39 bajtów

6 bajtów dzięki Sp3000.

J1,*Tu@S[0T+?|!%GTZ+=Z0*H~_J~Z1G)1+QT0J

Zestaw testowy.

Leaky Nun
źródło
3

JavaScript (ES6), 109 106 bajtów

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")
Neil
źródło
@DigitalTrauma Musiał być błąd optymalizacji. Zoptymalizowałem go i tym razem udało mi się zaoszczędzić 3 kolejne bajty!
Neil
3

Rubin, 152 bajty

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

Przypadki testowe:

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
źródło
Na marginesie, możesz usunąć wymagania dotyczące dodatkowych nawiasów kosztem jednego bajtu, zmieniając ->v{na ->*v{(tak myślę). Ponadto, nie trzeba spacje przed: jak i po? I jesteś pewien, że :a<=0to nie analizuje (:a) <= 0?
Pozew Fund Moniki w
Dobra wskazówka! Potrzebny byłby jednak dostęp do var. Jeśli chodzi o :a<=0, dostanę, ArgumentError: comparison of Symbol with 0 failedjeśli to nie zadziała. Myślę, że ponieważ przeanalizował ?i wie, że jest to operator trójskładnikowy, po prostu działa. Zasady są naprawdę dziwne. Włożyłam spacji ani nawiasów w miejscach, które są potrzebne, aby uniknąć błędów składni, jak SyntaxError: unexpected tLABELi NoMethodError: undefined method u? `.
br3nt
Możesz dokonać edycji, jeśli widzisz jakieś ulepszenia. Miałem nadzieję, że będę mógł się go pozbyć a=u ? a+w : a-wi zmienić tam, a=a+w*dgdzie djest 1lub w -1zależności od kierunku, ale jeszcze tego nie wypracowałem.
br3nt
Z tego co rozumiem, generalnie odradzam edytowanie w celu ulepszenia kodu; zamiast tego powinieneś komentować. Co do twojego pomysłu na ulepszenie, nie wiem; wygląda na to, że może działać, ale na pewno nie wiem.
Pozew Fund Moniki w
2

Python 3.5, 193 187 185 181 175 173 172 bajtów:

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)

Pobiera dane wejściowe w postaci liczb oddzielonych przecinkami, na przykład 1,2,3,4,5lub nawet 1.2,3.4,7.8,9.2. Wyświetla informację, czy drzwi w następnym kroku idą w górę, czy w dół , odpowiednio, za pomocą Ulub D. Z czasem będzie więcej golfa.

Wypróbuj online! (Ideone) (Tutaj dane wejściowe mają postać listy składającej się z liczb oddzielonych przecinkami, np [1,2,3,4,5].)

R. Kap
źródło
1

PHP, 128 120 bajtów

$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];

Kod jest zawinięty tutaj, aby zmieścił się w polu kodu. Umieść wszystko w jednym wierszu, umieść przed nim znacznik otwarty PHP i zapisz go w pliku. Lub uruchom go z wiersza poleceń, używając php -d error_reporting=0 -r '...the code...' [arguments].

Niegolfowany kod źródłowy, zestaw testów i przykłady użycia można znaleźć na github .

aksjomat
źródło