Votre tâche consiste à implémenter un programme similaire à l' nl
outil de ligne de commande des utilitaires principaux GNU.
Les failles standard sont interdites.
Vous ne pouvez utiliser aucune fonction, programme ou utilitaire intégré ou externe pour numéroter les lignes d'un fichier ou d'une chaîne, comme nl
lui-même ou la =
commande dans GNU sed.
spécification
Contribution
Le programme accepte les noms de fichiers comme arguments. Votre code n'a pas besoin d'être multiplateforme; le format de nom de fichier du système d'exploitation exécutant le code doit être utilisé, c'est-à-dire que si vous êtes sous Windows, le séparateur de répertoire peut être \
ou /
.
Vous devez pouvoir prendre 64 fichiers d'entrée, y compris -
s'il est spécifié. Si plus de 64 sont donnés, ne gérez que les 64 premiers.
Dans la liste des noms de fichiers, -
représente l'entrée standard.
Si des noms de fichiers sont donnés, lisez les fichiers dans l'ordre où ils sont donnés et concaténez leur contenu, en insérant une nouvelle ligne entre chacun et à la fin. Si vous ne pouvez pas lire un ou plusieurs des noms de fichiers (parce que le fichier n'existe pas ou que vous ne disposez pas des autorisations de lecture pour celui-ci), ignorez-les. Si tous les noms de fichiers spécifiés ne sont pas valides, ne rien produire.
Si aucun nom de fichier n'est donné, lisez à partir de l'entrée standard. Lire uniquement à partir de l'entrée standard si aucun nom de fichier n'est donné ou si -
est donné.
Production
Le programme sortira, en sortie standard, l'entrée avec des lignes numérotées ainsi (vous pouvez supposer que l'entrée a \n
, \r\n
ou des \r
fins de ligne; choisissez celle qui vous convient, mais spécifiez laquelle):
<5 spaces>1<tab><content of line 1 of input>
<5 spaces>2<tab><content of line 2 of input>
...
<4 spaces>10<tab><content of line 10 of input>
...
<3 spaces>100<tab><content of line 100 of input>
...
...
6 caractères d'espace sont alloués pour le numéro de ligne, et il est inséré à la fin de ces caractères; les autres deviennent des espaces (par exemple, 1
auront 5 espaces de tête, 22
auront 4 espaces de tête, ...). Si l'entrée est suffisamment longue, vous finirez par manquer d'espace pour le numéro de ligne, à la ligne 999999
. Vous ne devez rien sortir après la ligne 999999.
Si l'entrée est vide, rien ne sort.
Statut de sortie
Les nombres inférieurs sont prioritaires: si des erreurs 1 et 2 se sont produites, quittez avec le statut 1.
Quittez avec l'état 0 si l'entrée a été reçue avec succès et si les lignes ont été numérotées et sorties avec succès.
Quittez avec le statut 1 si un ou plusieurs des fichiers spécifiés sur la ligne de commande sont introuvables ou ne peuvent pas être lus.
Quittez avec le statut 2 si trop de fichiers (plus de 64) ont été donnés.
Quittez avec l'état 3 si l'entrée était trop longue (plus de 999999 lignes). \
Notation
C'est le code-golf - le programme le plus court gagne!
Je peux ajouter des bonus plus tard pour la mise en œuvre de certaines options nl
. Il n'y a pas de bonus pour le moment.
prompt()
pour émuler le programme args et stdin?Réponses:
Bash, 121
la source
if
raccourcir un peu vos expressions si vous utilisez des expressions arithmétiques, par exemple(($#>64))&&s=2
s=0;(($#>64))&&s=2
pars=$[2*($#>64)]
,(($s==0))||
par((s))&&
et l'if
instruction par[ -f "$f" ]||s=1
.awk
concatènera également si plusieurs fichiers sont passés, donc cela compte officiellement comme une utilisation inutile de cat ;-). Au lieu de cela, je pense que cela fonctionnera:awk '...' $@
Rubis, 195
la source
STDIN
est aliasé$<
.ARGF
, qui lira également le reste des fichiers fournis comme arguments. Je pense que cela peut être approfondi en utilisant enARGF
quelque sorte (il semble même reconnaître"-"
comme étant stdin).block in <main>': undefined method
[] 'for # <Enumerator: 0x000006002980c8> (NoMethodError) from britishteanl: 2: ineach' from britishteanl:2:in
<main>' - qu'est-ce qui ne va pas? Je l'ai couru en tant queruby britishteanl folder/filename
Perl, 84 + 2 (
-pl
) = 86 octetsDébarqué:
Important à savoir:
-p
enveloppe le programme donné avec-e
lewhile
continue
boucle /BEGIN
le code sera exécuté avant la partie principale (implicite)-r
échoue également si le fichier n'existe pas!-e
et passe par défaut au test$_
, donné implicitement dansmap { ... } @ARGV
$.
contient le numéro de ligne actuella source
python 173
la source
-
forsys.stdin
. Une solution possible pourrait être quelque chose comme çafh=sys.stdin if f=='-' else open(f)
et ensuite aller avecx=fh.readline()
?! Malheureusement, cela ne le raccourcit pas. :)J (162)
Explication:
]`(]&<&'-')@.(0=#)2}.ARGV
: Récupérez les arguments de la ligne de commande et supprimez les deux premiers (car ce sont l'interpréteur et le nom du fichier de script). Si la liste résultante est vide, retournez['-']
(c'est-à-dire, comme si l'utilisateur avait passé seulement-
), sinon retournez la liste inchangée.(
...::1:)
: si la fonction interne échoue, retournez1
, sinon retournez tout ce que la fonction interne a renvoyé.((2*64<#)[
...)
: évalue la fonction interne et jette le résultat. Ensuite, si la longueur de la liste transmise n'était pas supérieure à64
, retournez0
, sinon retournez2
.&.>@;@{.@(_64&(<\))
: obtenir la plupart des64
éléments de la liste et pour chacun d'eux exécuter la fonction suivante:(1!:1)@(<`3:@.('-'-:]))
: si l'élément était-
, lisez le contenu du descripteur de fichier3
(stdin), sinon lisez le contenu du fichier nommé par cet élément. Si cela échoue (c'est-à-dire que le fichier n'existe pas), le code ci-dessus le rattrapera et le retournera1
.exit@3:`(
...)@.(1e6>#)@(<;.2)
: divise la chaîne sur ses fins de ligne. S'il y a 1 000 000 lignes ou plus, quittez avec le statut3
. Autrement:,&TAB@(6&":)&.>@>:@i.@#
: générer les nombres pour chaque ligne, les formater dans une colonne à 6 chiffres et ajouter unTAB
à la fin de chaque chaîne,,&.>]
: ajoutez chaque numéro au début de chaque ligne.stdout@(,&LF)@;
: puis sortez le tout, suivi d'un extraLF
.exit
: exit avec la valeur de retour de cette fonctionla source
Rubis, 76 octets
Un octet pour le
p
drapeau. Courez avecruby -p nl.rb
.Les arguments stdin ou file sont gérés automatiquement par Ruby. Il se ferme déjà avec le code 1 si un argument de fichier n'existe pas.
$.
est le nombre de lignes lues.$*
correspond aux arguments de la ligne de commande et les fichiers sont extraits lors de la lecture des fichiers. L'p
indicateur exécute leBEGIN
bloc et enveloppe le reste du programme dans une boucle while-gets-print, en utilisant$_
comme entrée / sortie.la source
Perl,
125122 octetsla source
C,
362359Juste pour le plaisir. ;-) Fonctionne avec les sauts de ligne LF ou CR / LF.
la source