Comment puis-je quitter Vim?

42

Vim est un excellent éditeur de texte pour les systèmes Unix, mais il est notoire d’être difficile à quitter.

Ecrivez un programme complet qui sortira :qpour sortir de Vim. Il doit alors lire une seule ligne d’entrée, puisqu’il recevra une invite bash, auquel cas la sortie a réussi, ou une erreur, auquel cas il ya des modifications non enregistrées.

L'invite de bash sera la suivante:

E37@vimmachine: /var/override)

Alors que l'erreur sera la suivante:

E37: No write since last change (add ! to override)

Après avoir reçu l'invite bash, le travail du programme est terminé et il ne devrait plus donner de sortie (sauf pour les espaces).

Dès que l'erreur est signalée, votre programme doit générer de manière aléatoire (c'est-à-dire que chaque possibilité a une probabilité non nulle d'être choisie) la :q!sortie sans enregistrer ou la :xsauvegarde et la sortie.

C'est du donc le moins d'octets dans chaque langue gagne!

Skidsdev
la source
26
Je ne savais pas que :xc'était une chose! J'ai toujours utilisé :wq:)
musicman523
3
Et si mon invite bash est E37: No write since last change? Comment un algorithme peut-il distinguer une invite d’un message d’erreur?
Anatolyg
5
@anatolyg ça ne peut pas, mais ça ne doit pas non plus. L'invite donnée sera toujours celle ci-dessus, c'est-à-direE37@vimmachine: /var/override)
Skidsdev le
2
L'invite donnée sera toujours celle ci - dessus. Cela devrait être indiqué dans la spécification de défi. Tel quel, cela ressemble à ceci , ce qui peut vouloir dire beaucoup de choses.
Dennis
5
(a rejoint le golf pour ce commentaire, sheesh) @ musicman523 ne jamais utiliser :xpour quitter vim. Un jour, vous frapperez accidentellement :Xpuis des touches aléatoires lorsque vous serez confus. Une fois que :wqvous aurez enfin vu votre dossier,
Aaron McMillin

Réponses:

16

Python 2 , 66 octets

Sauvegardé 3 octets grâce à @ Mr.Xcoder et 4 grâce à @Mayube!

from random import*
if'('in input(':q'):print choice([':x',':q!'])

Essayez-le en ligne!

musicman523
la source
2
Si vous passez à Python 2, vous pouvez économiser 1 octet en utilisant à la print place de print(). Et vous pouvez prendre l'entrée avec des guillemets
M. Xcoder
@ Mr.Xcoder Merci, il m'a en fait sauvé 3 octets!
musicman523
Oui, je n'ai pas vu que vous aviez deux déclarations imprimées
M. Xcoder le
3
J'ai donné ce conseil à totalementhumain, donc ce n'est que justice, je vous le donne également. Vous pouvez supprimer print':q'complètement et changer input()àinput(':q')
Skidsdev
@ Mayube oh c'est génial, merci!
musicman523
7

Ruby , 35 octets

p:q
p %i(q! x)[rand 2]if/\(/=~gets

Essayez-le en ligne!

André Diego Piske
la source
1
Vous pouvez raser un octet en supprimant l'espace entre pet :q;)
ymbirtt
1
génial et bizarre! Merci @ymbirtt
André Diego Piske le
6

05AB1E , 19 octets

„:q,'Nåi„:x…:q!‚.R,

Essayez-le en ligne!

„:q,                # Print the string ":q"
    'Nåi            # If N is in the input
        „:x         #   Push the string ":x"
           …:q!     #   Push the string ":q!"
               ‚    #   Wrap them into an array
                .R, #   Randomly print one of them
Riley
la source
5

Python 2 , 76 75 72 69 octets

Cette réponse a été dépassée .

-1 octet grâce à Rod. -3 octets grâce à Mayube. -3 octets grâce à Artyer.

from random import*
print'::qx!'[random()>.5:('N'in input(':q'))*5:2]

Essayez-le en ligne!

totalement humain
la source
Ceci imprime une nouvelle ligne où le défi indiqueit should not give any more output
musicman523
@Mayube May we output a newline upon terminating? @Adám sure, that's fine
Stephen
1
random()>.5sauver un octet
Rod
2
Le caractère aléatoire doit-il être distribué uniformément? Sinon, vous pourriez le faire random()>0, car il y a très peu de chances que random()cela revienne 0.
mbomb007
1
@Artyer Vous savez ce que [0, 1)signifie, non? Cela signifie que zéro est inclus car la plage est zéro-inclus. stackoverflow.com/a/4396303/2415524 ... Le moyen le plus simple de s'en souvenir est que, sur une droite numérique, les points fermés sont inclus et les points ouverts ne le sont pas. Les crochets semblent fermés et les parens semblent ouverts.
mbomb007
5

Vimscript, 45 41 octets

ec"q"|exe"/("|ec["q!","x"][getpid()%2]

Rasé 4 octets en utilisant getpid()pour obtenir un numéro. (Quelqu'un peut-il penser à un moyen plus rapide d'obtenir un nombre qui ne sera pas identique partout, tout le temps?)

En supposant +3 octets pour appeler Vim avec -cpour exécuter le script ci-dessus et -pour lire les entrées de stdin:

vim -c 'ec"q"|exe"/("|ec["q!","x"][reltime()[1]%2]' -
muru
la source
3

JavaScript, 52 46 octets

Enregistrement de 6 octets grâce à @ETHProductions

prompt(':q')[30]&&alert(new Date%2?':q!':':x')
Downgoat
la source
N'a-t-il pas besoin d'un !après :qsi l'entrée est une erreur?
Shaggy
@ Shaggy aww, je n'ai pas remarqué cela, il y a 9 octets
Rédaction de messages
Je pense que vous pouvez économiser quelques octets avec prompt(':q')[30]&&.... Aussi,new Date%2?':x':':q!'
ETHproductions
@ETHproductions oh oui, merci! ne sais pas comment j'ai oublié un ternaire
Downgoat
3

C # (.NET Core) , 140 139 138 octets

using static System.Console;class P{static void Main(){Write(":q");if(ReadLine()[3]==':')Write(new System.Random().Next()>9?":x":":q!");}}

Essayez-le en ligne!

  • 1 octet économisé grâce à LiefdeWen!
  • 1 octet économisé grâce à Mord Zuber!
Charlie
la source
Placer votre programme dans l' Systemespace vous fait en mesure de raccourcir System.Randomà Random, sauver 1 octet
LiefdeWen
@CarlosAlejo travaille pour moi dans TIO, mais il q!ne sort pas:q!
Skidsdev
1
@CarlosAlejo Ahh, je n'avais même pas réalisé que vous n'aviez pas utilisé d'espace de nom, la question ne dit pas non plus uniformément aléatoire, toutes les possibilités devraient avoir une chance non nulle, donc vous passez .Next(2)>0à .Next()>9, cela laisse un peu un mauvais goût dans la bouche mais c'est toujours légal.
LiefdeWen
4
using static System.Consolevous laisse tomber tous les C.appels, et vous enregistre un octet
Mord Zuber
1
@MordZuber qu'est-ce que ...? Je ne savais même pas que c'était possible! Merci!
Charlie
3

> <> , 32 30 29 octets

  • Eu un licenciement !o.
  • -1 octet grâce à Aaron.

iii0["@!qx:q:"ooi{=?;o!ox~oo;

Essayez-le en ligne!

Explication (ancien)

"@!qx:q:"ooi~i~i~i{=?;o!ox~oo;
"@!qx:q:"                        Push @!qx:q: on the stack (in reverse)
         oo                      Print :q [stack: @!qx:]
           i~i~i~                Remove first 3 input characters
                 i               Load @ or : from the input (= i)
                  {              Shift stack to the left [stack: !qx:i@]
                   =?            If 4th character was @
                     ;              Exit
                                 Else
                      o             Print :
                       !o           Jump to
                         x          Random direction (left or right because
                                    up and down retrigger x)
                                       Left:
                     ;o!o                 Print x and exit.
                                       Right:
                          ~oo;            Remove x, print q! and exit.

(sera mis à jour bientôt)

PidgeyUsedGust
la source
Je ne suis pas sûr que cela soit autorisé, mais vous pouvez gagner un octet en lisant d’abord les 3 caractères à supprimer, puis commencer à travailler sur une nouvelle pile avec [: iii0[vous laisser avec une pile vide; sympa quand même, j'aime la façon dont vous renseignez toutes vos sorties possibles au début pour éviter des citations supplémentaires
Aaron
@ Aaron Merci, c'est un truc très soigné! Pourquoi ne serait-il pas permis?
PidgeyUsedGust Le
Parce que vous liriez l'entrée avant d'avoir imprimé la sortie menant à sa production, ce qui, je suppose, va à l'encontre de l'esprit du défi. Cependant, ce n'est pas comme si le défi pouvait être mis en oeuvre de manière réaliste avec l'interprète officiel> <>, car python attendra l'entrée EOF de l'entrée avant d'exécuter le code> <> (ou quelque chose du genre)
Aaron
2

En fait , 27 octets

":q"ü[":x",":q!"]`⌂`J'!,cIƒ

Essayez-le en ligne! (Remarque: TIO ne jouant pas bien avec stdin, j'ai remplacé le ,(lu à partir de stdin) par la chaîne littérale, que vous pouvez modifier pour le tester. En outre, vous devez désactiver le cache de sortie pour obtenir une réponse différente avec la sortie aléatoire.)

Explication:

":q"ü[":x",":q!"]`⌂`J'!,cIƒ
":q"ü                       - Push the literal :q and print
     [":x",":q!"]           - Push the list of literals :x and :q!
                 `⌂`J       - Push function literals ⌂ (terminate) and J (choose random element from list)
                     '!     - Push the literal !
                       ,    - Read from stdin
                        c   - Pop top two values a,b and return "a".count(b)
                         I  - Pop top three values a,b,c and return b if a is truthy and c if a is falsy
                          ƒ - Pop a function from the stack and call it
dispersion
la source
1

APL (Dyalog) , 27 octets

':q'⋄('!'∊⍞)/':q!' ':x'⊃⍨?2

Essayez-le en ligne!

':q' imprimer ceci

 puis

?2 entier aléatoire parmi les deux premiers

⊃⍨ utilisez-le pour sélectionner

':q!' ':x' cette liste de deux chaînes

()/ Reproduire cela avec, c.-à-d. Faire n copies de chaque élément dans celui-ci, où n est

'!'∊⍞ le point d'exclamation est-il un membre de la saisie de texte? (Booléen, c'est-à-dire 0 ou 1)

Adam
la source
1

Lot, 98 octets

@echo :q
@set/ps=
@if %s:~3,1%==@ exit/b
@set/an=%random%%%2
@if %n%==0 (echo :x)else echo :q!
Neil
la source
1

Ruby , 33 octets (32 codes, +1 pour l'indicateur -n)

p:q;$_[?!]? p([:q!,:x][$$%2]): p

Je ne suis pas trop sûr de l' $$%2extrait. Je l'utilise pour générer un bit aléatoire afin d'indexer mon tableau en prenant le pid modulo 2 du processus Ruby actuel, et ce sera assez imprévisible. .sampleajoute un octet supplémentaire.

Essayez-le en ligne!

Ymbirtt
la source
1

JavaScript, 76 71 50 octets

prompt(":q")[3]<"@"?alert(new Date%2?":q!":":x"):0

Sauvegardé un tas d'octets grâce à Artyer et Neil, ainsi que la condensation de mes ternaires et le déplacement de la première alerte sur prompt (duh).

Stephen
la source
2
Pourquoi ne pas simplement appeler prompt()directement? (De plus, êtes-vous autorisé prompt(":q")?)
Neil
Vous pouvez utiliser l'heure comme un nombre aléatoire ( new Date%2au lieu de Math.random()>.5), et vous pouvez utiliser l'invite directement comme @Neil a dit:prompt()[3]<
Artyer
Pourquoi Neil? J'en avais fait un .indexOfavant de remarquer l'autre façon de le faire. Oublié de revenir, merci!
Stephen
@Artyer merci, j'avais pensé à cela et puis oublié à ce sujet
Stephen
1

Python 2 , 64 octets

import time
if'w'in input(':q'):print'::qx!'[time.time()%2>1::2]

Essayez-le en ligne!

Étant donné que cela est juste une agglomération de deux de ces réponses Python, j'ai marqué ce que la communauté wiki.

Artyer
la source
1

Python 2 , 47 octets

print'::qx!'[id(0)%3<2:('N'in input(':q'))*5:2]

Essayez-le en ligne

Explication:

La source du hasard est id(0)%3<2. La fonction idrenvoie l'emplacement de la mémoire du paramètre. Passer n'importe quoi donnera une adresse mémoire non déterministe. Le résultat sera toujours pair, mais il ne sera parfois divisible que par 3. Les résultats modulo 3 varient. Donc, cela peut être une source de hasard. Utiliser <2signifie qu'environ 2/3 du temps, le booléen résultant est True.

Le reste de la réponse est inspiré par celui-ci .

mbomb007
la source
1

Keg ,14 12 octets

\:~2%[q\!|x]

Ceci pousse un nombre aléatoire et sort en correspondance avec le nombre aléatoire.

UNE _
la source
0

TCL, 95 octets

puts :q;puts [if [string match *!* [gets stdin]] {puts [lindex ":q! :x" [expr round(rand())]]}]

Une solution simple et assez longue en tcl ...

hdrz
la source
0

Appels système Linux de 86Bytes Assembly

global _start
_start:
mov edx,4
mov ecx,g 
mov ebx,1
mov eax,4
int 0x80
g db ':q!',10
ulascan
la source
0

LOGO, 37 36 octets

pr[:q]if 4<count rl[pr pick[:q! :x]]

Essayez-le en ligne à Anarchy Golf Performance Checker .

Explication:

pr[:q]if 4<count rl[pr pick[:q! :x]]   Main program.
pr                                     Print
  [:q]                                 the list `[:q]` without delimiter `[]`
      if           [              ]    If...
         4<                            4 is less than...
           count                       the number of word in the...
                 rl                    ReadLine (from stdin),
                    pr                 print
                       pick            a random word picked from the list...
                           [:q! :x]    [:q! :x]

(parce qu'il E37@vimmachine: /var/override)a 2 mots, alors qu'il E37: No write since last change (add ! to override)a 10 mots)

utilisateur202729
la source
Une explication serait géniale.
pajonk
0

Perl 5 (avec l'indicateur -E), 35 octets

say":q";<>=~l&&say qw(:q! :x)[$$%2]

Exécutez ceci avec perl -E 'say":q";<>=~l&&say qw(:q! :x)[$$%2]'.

Essayez-le en ligne!

Ungolfed:

say(":q");
if(<> =~ /l/){ #read a line and check if it contains 'l'
    @a=(":q!",":x");
    say($a[$$ % 2]); #print one element from array based on PID
}
utilisateur4098326
la source