Su tarea es implementar un programa similar a la nl
herramienta de línea de comandos de las utilidades principales de GNU.
Las lagunas estándar están prohibidas.
No puede utilizar ninguna función, programa o utilidad incorporada o externa para numerar las líneas de un archivo o cadena, como nl
sí mismo o el =
comando en GNU sed.
Especificación
Entrada
El programa acepta nombres de archivo como argumentos. Su código no tiene que ser multiplataforma; se debe usar el formato de nombre de archivo del sistema operativo que ejecuta el código, es decir, si está en Windows, el separador de directorio puede ser \
o /
.
Debe poder tomar 64 archivos de entrada, incluso -
si se especifica. Si se dan más de 64, solo maneje los primeros 64.
En la lista de nombres de archivo, -
representa la entrada estándar.
Si se dan nombres de archivo, lea los archivos en el orden en que se dan y concatene sus contenidos, insertando una nueva línea entre cada uno y al final. Si no puede leer uno o más de los nombres de archivo (porque el archivo no existe o no tiene permisos de lectura), ignórelos. Si todos los nombres de archivo especificados no son válidos, no envíe nada.
Si no se dan nombres de archivo, lea desde la entrada estándar. Solo lea desde la entrada estándar si no se dan nombres de archivo o si -
se da.
Salida
La salida se programa, a la salida estándar, la entrada con las líneas numeradas de este modo (Usted puede asumir que la entrada tiene \n
, \r\n
o \r
los finales de línea, recoger lo que sea conveniente para usted, pero especificar cuál):
<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>
...
...
Se asignan 6 caracteres de espacio para el número de línea, y se inserta al final de estos caracteres; el resto se convierte en espacios (por ejemplo 1
, tendrá 5 espacios iniciales, 22
tendrá 4 espacios iniciales, ...). Si la entrada es suficientemente larga, eventualmente se quedará sin espacio para el número de línea, en la línea 999999
. No debe generar nada después de la línea 999999.
Si la entrada está vacía, no genera nada.
Estado de salida
Los números más bajos tienen prioridad: si se encontraron los errores 1 y 2, salga con el estado 1.
Salga con el estado 0 si la entrada se recibió con éxito y las líneas se numeraron y salieron correctamente.
Salga con el estado 1 si uno o más de los archivos especificados en la línea de comando no se encontraron o no se pudieron leer.
Salga con el estado 2 si se proporcionaron demasiados archivos (más de 64).
Salga con el estado 3 si la entrada fue demasiado larga (más de 999999 líneas). \
Puntuación
Este es el código de golf: ¡el programa más corto gana!
Puedo agregar bonos más tarde para implementar ciertas opciones que nl
tiene. No hay bonos por el momento.
prompt()
emular args y stdin de programa?Respuestas:
Bash, 121
fuente
if
expresiones sean un poco más cortas si usa expresiones aritméticas, por ejemplo(($#>64))&&s=2
s=0;(($#>64))&&s=2
cons=$[2*($#>64)]
,(($s==0))||
con((s))&&
y laif
declaración con[ -f "$f" ]||s=1
.awk
también se concatenará si se pasan varios archivos, por lo que esto cuenta oficialmente como un uso inútil de cat ;-). En cambio, creo que esto funcionará:awk '...' $@
Ruby, 195
fuente
STDIN
tiene un alias$<
.ARGF
, que también se leerá del resto de los archivos dados como argumentos. Creo que esto se puede reducir aún más usando deARGF
alguna manera (incluso parece reconocer"-"
que es estándar).block in <main>': undefined method
[] 'para # <Enumerator: 0x000006002980c8> (NoMethodError) de britishteanl: 2: eneach' from britishteanl:2:in
<main>' - ¿qué pasa? Lo ejecuté comoruby britishteanl folder/filename
Perl, 84 + 2 (
-pl
) = 86 bytesDespachado:
Importante saber:
-p
ajusta el programa dado-e
en el buclewhile
/continue
BEGIN
el código se ejecutará antes de la parte principal (implícita)-r
también falla si el archivo no existe!-e
y el valor predeterminado es prueba$_
, dado implícitamente enmap { ... } @ARGV
$.
contiene el número de línea actualfuente
pitón 173
fuente
-
forsys.stdin
. ¡Una posible solución podría ser algo asífh=sys.stdin if f=='-' else open(f)
y luego ir conx=fh.readline()
?! Lamentablemente, no lo hace más corto. :)J (162)
Explicación:
]`(]&<&'-')@.(0=#)2}.ARGV
: Obtenga los argumentos de la línea de comandos y elimine los dos primeros (porque esos son el intérprete y el nombre del archivo de script). Si la lista resultante está vacía, regrese['-']
(es decir, como si el usuario hubiera pasado solamente-
), de lo contrario, devuelva la lista sin cambios.(
...::1:)
: si la función interna falla, devuelve1
, de lo contrario devuelve lo que devuelve la función interna.((2*64<#)[
...)
: evalúa la función interna y tira el resultado. Luego, si la longitud de la lista aprobada no fue mayor que64
, devuelva0
, de lo contrario devuelva2
.&.>@;@{.@(_64&(<\))
: obtenga la mayoría de los64
elementos de la lista y para cada uno de ellos ejecute la siguiente función:(1!:1)@(<`3:@.('-'-:]))
: si el elemento era-
, lea el contenido del descriptor de archivo3
(stdin), de lo contrario lea el contenido del archivo nombrado por ese elemento. Si esto falla (es decir, el archivo no existe), el código anterior lo detectará y devolverá1
.exit@3:`(
...)@.(1e6>#)@(<;.2)
: divide la cadena en sus terminaciones de línea. Si hay 1.000.000 o más líneas, salga con el estado3
. De otra manera:,&TAB@(6&":)&.>@>:@i.@#
: genera los números para cada línea, los formatea en una columna de 6 dígitos y agrega unTAB
al final de cada cadena,,&.>]
: agrega cada número al frente de cada línea.stdout@(,&LF)@;
: luego muestra todo, seguido de un extraLF
.exit
: salir con el valor de retorno de esa funciónfuente
Ruby, 76 bytes
Un byte para la
p
bandera. Corre conruby -p nl.rb
.Los argumentos estándar o de archivo son manejados automáticamente por Ruby. Ya sale con el código 1 si no existe un argumento de archivo.
$.
es el número de líneas que se han leído.$*
son los argumentos de la línea de comandos, y los archivos se eliminan a medida que se leen. Lap
bandera ejecuta elBEGIN
bloque y envuelve el resto del programa dentro de un ciclo while-gets-print, utilizándolo$_
como entrada / salida.fuente
Perl,
125122 bytesfuente
C,
362359Solo por el gusto de hacerlo. ;-) Funciona con avances de línea LF o CR / LF.
fuente