Ce site a eu beaucoup de problèmes lors de l'implémentation de différentes langues dans la balise interprète . Cependant, presque tous étaient des langues ésotériques que personne n'utilisait. Il est temps de faire un interprète pour une langue pratique que la plupart des utilisateurs ici connaissent probablement déjà. Oui, c'est un script shell, au cas où vous auriez des problèmes pour lire le titre (pas que vous ayez). (oui, j'ai intentionnellement fait ce défi, car je m'ennuie de langages comme GolfScript et Befunge qui gagnent tout, donc j'ai mis un défi où un langage de programmation plus pratique a plus de chances de gagner)
Cependant, le script shell est un langage relativement gros, donc je ne vous demanderai pas de l'implémenter. Au lieu de cela, je vais créer un petit sous-ensemble de fonctionnalités de script shell.
Le sous-ensemble sur lequel j'ai décidé est le sous-ensemble suivant:
- Exécution de programmes (les programmes ne contiendront cependant que des lettres, même si les guillemets simples sont autorisés)
- Arguments du programme
- Citations simples (acceptant tout caractère ASCII imprimable, y compris les espaces, à l'exclusion des guillemets simples)
- Chaînes sans guillemets (autorisant les lettres, chiffres et tirets ASCII)
- Pipes
- Déclarations vides
- Plusieurs instructions séparées par une nouvelle ligne
- Trailing / leader / espaces multiples
Dans cette tâche, vous devez lire l'entrée de STDIN et exécuter chaque commande demandée. Vous pouvez supposer en toute sécurité un système d'exploitation compatible POSIX, il n'y a donc pas besoin de portabilité avec Windows, ou quelque chose comme ça. Vous pouvez supposer en toute sécurité que les programmes qui ne sont pas redirigés vers d'autres programmes ne liront pas depuis STDIN. Vous pouvez supposer en toute sécurité que les commandes existeront. Vous pouvez sans risque supposer que rien d'autre ne sera utilisé. Si une hypothèse sûre est brisée, vous pouvez tout faire. Vous pouvez supposer en toute sécurité au plus 15 arguments et des lignes inférieures à 512 caractères (si vous avez besoin d'une allocation de mémoire explicite, ou quelque chose - je vais vraiment donner de petites chances de gagner pour C, même si elles sont encore petites). Vous n'avez pas à nettoyer les descripteurs de fichiers.
Vous êtes autorisé à exécuter des programmes à tout moment - même après avoir reçu la ligne complète ou après la fin de STDIN. Choisissez n'importe quelle approche que vous souhaitez.
Cas de test simple qui vous permet de tester votre shell (notez les espaces blancs après la troisième commande):
echo hello world
printf '%08X\n' 1234567890
'echo' 'Hello, world!'
echo heeeeeeelllo | sed 's/\(.\)\1\+/\1/g'
yes|head -3
echo '\\'
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
Le programme ci-dessus devrait produire le résultat suivant:
hello world
499602D2
Hello, world!
helo
y
y
y
\\
foo BAR zap
Vous n'êtes pas autorisé à exécuter le shell lui-même, à moins que vous n'ayez pas d'arguments pour la commande (cette exception a été faite pour Perl, qui exécute la commande dans le shell lorsque vous placez juste un argument system
, mais n'hésitez pas à abuser de cette exception pour d'autres langues aussi, si vous pouvez le faire d'une manière qui enregistre les caractères), ou la commande que vous exécutez est le shell lui-même. C'est probablement le plus gros problème de ce défi, car de nombreux langages ont des system
fonctions qui exécutent le shell. Utilisez plutôt des API de langage qui appellent directement des programmes, comme le subprocess
module en Python. C'est une bonne idée pour la sécurité de toute façon, et bien, vous ne voudriez pas créer un shell non sécurisé, le voudriez-vous? Cela arrête très probablement PHP, mais il existe quand même d'autres langages.
Si vous allez faire de votre programme dans le script shell, vous n'êtes pas autorisé à utiliser eval
, source
ou .
(comme dans une fonction, pas un caractère). Cela rendrait le défi trop facile à mon avis.
Abus de règle intelligent autorisé. Il y a beaucoup de choses que j'ai explicitement interdites, mais je suis presque sûr que vous êtes toujours autorisé à faire des choses auxquelles je n'ai pas pensé. Parfois, je suis surpris de la façon dont les gens interprètent mes règles. N'oubliez pas non plus que vous pouvez faire n'importe quoi pour tout ce que je n'ai pas mentionné. Par exemple, si j'essaie d'utiliser des variables, vous pouvez effacer le disque dur (mais ne le faites pas).
Le code le plus court gagne, car il s'agit de codegolf.
la source
Réponses:
Bash (92 octets)
Profitant de la même faille que cette réponse , voici une solution beaucoup plus courte:
Python (
247241239 octets)la source
*
), mais à part ça, ça a l'air génial :-). Je suis surpris qu'un nouveau membre ait trouvé une si bonne solution à un problème difficile.C (340 octets)
Je n'ai aucune expérience du golf, mais vous devez commencer quelque part, alors voici:
J'ai ajouté des sauts de ligne pour que vous n'ayez pas à faire défiler, mais je ne les ai pas inclus dans mon compte car ils sont sans signification sémantique. Ceux après les directives du préprocesseur sont requis et ont été comptés.
Version non golfée
traits
'ec'ho He'll''o 'world
travail comme il se doit. Il se pourrait bien que le code aurait été plus simple sans cette fonctionnalité, je serais donc heureux de savoir si cela est nécessaire.Problèmes connus
execvp
d'échec de l' appel, par exemple en raison d'un nom de programme mal saisi. Ensuite, nous avons deux processus jouant simultanément sur le shell.Caractères spéciaux '|' et les sauts de ligne conservent leur signification particulière à l'intérieur des chaînes entre guillemets. Ceci est en violation des exigences, j'examine donc les moyens de résoudre ce problème.Fixe, au coût d'environ 11 octets.Autres notes
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
bloquait. Le problème était apparemment le tube d'écriture non fermé, j'ai donc dû ajouter cette commande close, ce qui a augmenté la taille de mon code de 10 octets. Il y a peut-être des systèmes où cette situation ne se produit pas, donc mon code peut être évalué avec 10 octets de moins. Je ne sais pas.?:
peut avoir emboîté,
sans(…)
.la source
int c, m, f[3];
extérieurmain
pour éviter de déclarer des types. Pour les variables globales, vous n'avez pas à déclarerint
. Mais généralement, solution intéressante.yes|head -3
continuent indéfiniment et le shell se ferme après chaque commande. J'utilise la version 4.6.3 de gcc (Ubuntu / Linaro 4.6.3-1ubuntu5) sans aucun commutateur.#define B break;case
(l'break;
avantdefault
devient)B-1:
) et 2 en remplaçantcase'\n'
etcase'\''
) parcase 10
etcase 39
.bash (+ écran) 160
Sortira quelque chose comme:
la source
Facteur (208 caractères)
Étant donné que les règles ne permettent pas de décharger le travail à un tiers ( http://www.compileonline.com/execute_bash_online.php ), voici une solution:
Vous pouvez également écrire le programme sous forme de ligne unique encore plus courte ( 201 caractères):
la source
Perl, 135 caractères
Cette coquille fait des choses stupides. Démarrez un shell interactif avec
perl shell.pl
et essayez-le:ls
s'imprime dans une colonne, car la sortie standard n'est pas un terminal. Le shell redirige la sortie standard vers un tuyau et lit à partir du tuyau.perl -E 'say "hi"; sleep 1'
attend 1 seconde pour dire bonjour, car le shell retarde la sortie.dd
lit 0 octet, sauf s'il s'agit de la première commande de ce shell. Le shell redirige l'entrée standard d'un tube vide, pour chaque pipeline après le premier.perl -e '$0 = screamer; print "A" x 1000000' | dd of=/dev/null
se termine avec succès.perl -e '$0 = screamer; print "A" x 1000000' | cat | dd of=/dev/null
accroche la coquille!pkill -f screamer
un autre shell), le shell reprend.perl -e 'fork and exit; $0 = sleeper; sleep'
accroche la coquille!'echo $((2+3))'
exécute la commande dans / bin / sh. C'est le comportement de l' exec et du système de Perl avec un seul argument, mais seulement si l'argument contient des caractères spéciaux.Version non golfée
la source