La porte de garage électrique est-elle ouverte?

24

Ma porte de garage électrique fonctionne comme ceci:

  • Il n'y a qu'un seul bouton poussoir pour contrôler la porte
  • Si la porte est complètement fermée et que j'appuie sur le bouton, la porte commence à s'ouvrir. L'ouverture complète prend 10 secondes
  • Si la porte est complètement ouverte et que j'appuie sur le bouton, la porte commence à se fermer. La fermeture complète prend 10 secondes
  • Si la porte est en cours d'ouverture ou de fermeture et que j'appuie sur le bouton, la porte s'arrête et reste partiellement ouverte.
  • Chaque fois que la porte s'arrête de bouger, soit à la fin automatique d'une action d'ouverture ou de fermeture, soit à partir d'une interruption manuelle en poussant le bouton à mi-chemin d'une action, le mécanisme s'inversera et se souviendra de sa direction pour l'action suivante.
  • Si le bouton est enfoncé lorsque la porte est arrêtée mais partiellement ouverte, le temps nécessaire pour terminer son action sera d'une fraction de 10 secondes proportionnellement à la quantité de mouvement nécessaire pour terminer l'action.

Supposons que la porte est complètement fermée au début.

Une liste d'entrée d'entiers sera donnée. Ces nombres entiers sont le nombre de secondes que j'attends entre les pressions successives du bouton de commande.

Sortie deux choses:

  • un pourcentage indiquant l'état de la porte une fois que toutes les pressions sur les boutons sont terminées et que la porte a atteint un état stable. La sortie du %symbole est facultative.
  • une indication non ambiguë de la direction dans laquelle la porte se déplacera lors de la prochaine pression sur le bouton. Cela peut être up/ down, U/ D, +/ -, 1/ 0ou ce que vous choisissez.

Vous pouvez supposer que la porte prend infiniment moins de 10 secondes pour terminer une action d'ouverture ou de fermeture.

Exemples d'entrées:

<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

Sorties attendues correspondant aux entrées ci-dessus

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

Exemple travaillé du dernier test

  • La porte démarre fermée. Le bouton est enfoncé
  • Attendez 11 secondes. La porte finit par s'ouvrir complètement. Le bouton est enfoncé.
  • Attendez 10 secondes. La porte se ferme complètement. Le bouton est enfoncé.
  • Attendez 9 secondes. Le bouton est enfoncé. La porte s'arrête à 90% ouverte.
  • Attendez 8 secondes. Le bouton est enfoncé. La porte se ferme.
  • Attendez 7 secondes. Le bouton est enfoncé. La porte s'arrête à 20% d'ouverture. La prochaine direction sera vers le haut.
Traumatisme numérique
la source
Votre porte de garage s'arrête à demi-ouverte, si vous appuyez sur le bouton, pendant la fermeture? La mienne non, seulement pour l'ouverture.
Bálint
@ Bálint dans les deux sens pour le mien.
Digital Trauma
@Maltysen permet de s'en tenir au pourcentage maintenant.
Digital Trauma
Est-ce correct si un nombre à virgule flottante est sorti si l'entrée se compose également de nombre (s) à virgule flottante?
R. Kap
@ R.Kap oui, ça va.
Digital Trauma

Réponses:

6

Lua, 258 248 242 octets

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

Non golfé

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

Je ne vois pas comment vos cas de test peuvent être corrects ...

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 Fixed

Jaser
la source
Je viens de terminer mon entrée et je suis également d'accord avec vos résultats.
Neil
3

Pyth, 50 45 39 octets

6 octets grâce au Sp3000.

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

Suite de tests.

Leaky Nun
la source
3

JavaScript (ES6), 109 106 octets

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
la source
@DigitalTrauma Doit être une erreur d'optimisation. Je l'ai réoptimisé et j'ai réussi à économiser 3 octets supplémentaires cette fois!
Neil
3

Rubis, 152 octets

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

Cas de test:

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
la source
En guise de note amusante, vous pouvez supprimer l'exigence de parenthèses supplémentaires au prix d'un octet, en changeant ->v{en ->*v{(je pense). En outre, vous avez besoin des espaces avant le :et après? Et êtes-vous sûr que l' :a<=0analyse ne fonctionne pas (:a) <= 0?
Fund Monica's Lawsuit
Bon conseil! Il faudrait cependant peser l'accès à la var. Quant à :a<=0moi, j'en aurais un ArgumentError: comparison of Symbol with 0 failedsi ça ne fonctionnait pas. Je pense que parce qu'il a analysé le ?et sait qu'il est dans un opérateur ternaire, cela fonctionne juste. Les règles sont en effet étranges. J'ai mis des espaces ou des crochets aux endroits nécessaires pour éviter les erreurs de syntaxe comme SyntaxError: unexpected tLABELet NoMethodError: undefined method u? ''.
br3nt
N'hésitez pas à faire une modification si vous pouvez voir des améliorations. J'espérais pouvoir m'en débarrasser a=u ? a+w : a-wet le changer a=a+w*doù il dest 1ou -1selon la direction, mais je ne l'ai pas encore réglé.
br3nt
D'après ce que je comprends, l'édition pour améliorer le code est généralement déconseillée; à la place, vous devriez commenter. Quant à votre idée d'amélioration, je ne sais pas; il semble que cela pourrait fonctionner, mais je ne sais pas pour sûr.
Fund Monica's Lawsuit
2

Python 3.5, 193 187 185 181 175 173 172 octets:

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)

Prend la saisie sous la forme de nombres séparés par des virgules, par exemple 1,2,3,4,5ou même 1.2,3.4,7.8,9.2. Indique si la porte de l'étape suivante monte ou descend avec Uou D, respectivement. Va jouer au golf avec le temps.

Essayez-le en ligne! (Ideone) (Ici, l'entrée est prise sous la forme d'une liste composée de nombres séparés par des virgules, par exemple [1,2,3,4,5].)

R. Kap
la source
1

PHP, 128 120 octets

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

Le code est enveloppé ici pour tenir dans la zone de code. Mettez tout sur une seule ligne, placez le marqueur PHP ouvert devant et enregistrez-le dans un fichier. Ou exécutez-le à partir de la ligne de commande à l'aide de php -d error_reporting=0 -r '...the code...' [arguments].

Le code source non golfé, la suite de tests et des exemples d'utilisation peuvent être trouvés sur github .

axiaque
la source