Sua tarefa é implementar um programa semelhante à nl
ferramenta de linha de comando dos utilitários principais do GNU.
As brechas padrão são proibidas.
Você não pode usar nenhuma função, programa ou utilitário interno ou externo para numerar as linhas de um arquivo ou string, como nl
ele próprio ou o =
comando no GNU sed.
Especificação
Entrada
O programa aceita nomes de arquivos como argumentos. Seu código não precisa ser multiplataforma; o formato de nome de arquivo do sistema operacional executando o código deve ser usado, ou seja, se você estiver no Windows, o separador de diretório pode ser \
ou /
.
Você deve conseguir 64 arquivos de entrada, inclusive -
se ele estiver especificado. Se mais de 64 forem fornecidos, lide apenas com os primeiros 64.
Na lista de nomes de arquivos, -
representa a entrada padrão.
Se os nomes de arquivos forem fornecidos, leia os arquivos na ordem em que são fornecidos e concatene seu conteúdo, inserindo uma nova linha entre cada um e no final. Se você não conseguir ler um ou mais nomes de arquivos (porque o arquivo não existe ou você não possui permissões de leitura), ignore-os. Se todos os nomes de arquivos especificados forem inválidos, não produza nada.
Se nenhum nome de arquivo for fornecido, leia a partir da entrada padrão. Leia apenas da entrada padrão se nenhum nome de arquivo for fornecido ou se -
for fornecido.
Resultado
A saída do programa vontade, para a saída padrão, a entrada com linhas numeradas assim (Você pode supor que a entrada tem \n
, \r\n
ou \r
final de linha, escolher o que for conveniente para você, mas especificar qual):
<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 caracteres de espaço são alocados para o número da linha e são inseridos no final desses caracteres; o restante se torna um espaço (por exemplo 1
, terá 5 espaços à esquerda, 22
terá 4 espaços à esquerda, ...). Se a entrada for suficientemente longa, você acabará ficando sem espaço para o número da linha, na linha 999999
. Você não deve produzir nada após a linha 999999.
Se a entrada estiver vazia, não produza nada.
Status de saída
Os números mais baixos têm prioridade: se os erros 1 e 2 forem encontrados, saia com o status 1.
Saia com o status 0 se a entrada foi recebida com sucesso e as linhas numeradas e produzidas com sucesso.
Saia com o status 1 se um ou mais dos arquivos especificados na linha de comandos não foram encontrados ou não puderam ser lidos.
Saia com o status 2 se forem fornecidos muitos arquivos (mais de 64).
Saia com o status 3 se a entrada for muito longa (mais de 999999 linhas). \
Pontuação
Este é o código-golfe - o programa mais curto vence!
Posso adicionar bônus mais tarde por implementar certas opções que nl
possuem. Não há bônus no momento.
prompt()
para emular o programa args e stdin?Respostas:
Bash, 121
fonte
if
expressões um pouco mais curtas se usar expressões aritméticas, por exemplo:(($#>64))&&s=2
s=0;(($#>64))&&s=2
pors=$[2*($#>64)]
,(($s==0))||
com((s))&&
e aif
instrução por[ -f "$f" ]||s=1
.awk
também concatenará se forem passados vários arquivos, portanto isso conta oficialmente como um uso inútil de cat ;-). Em vez disso, acho que isso funcionará:awk '...' $@
Ruby, 195
fonte
STDIN
é um alias para$<
.ARGF
, que também lerá o resto dos arquivos dados como argumentos. Eu acho que isso pode ser melhorado usando deARGF
alguma forma (parece até reconhecer"-"
como sendo stdin).block in <main>': undefined method
[] 'para # <Enumerator: 0x000006002980c8> (NoMethodError) de britishteanl: 2: emeach' from britishteanl:2:in
<main>' - o que há de errado? Eu executei-o comoruby britishteanl folder/filename
Perl, 84 + 2 (
-pl
) = 86 bytesDeparsed:
Importante saber:
-p
quebra o programa fornecido-e
no loopwhile
/continue
BEGIN
código será executado antes da parte principal (implícita)-r
também falha se o arquivo não existir!-e
e o padrão é o teste$_
, fornecido implicitamente emmap { ... } @ARGV
$.
mantém o número da linha atualfonte
python 173
fonte
-
parasys.stdin
. Uma solução possível pode ser algo comofh=sys.stdin if f=='-' else open(f)
e, em seguida, vá comx=fh.readline()
?! Infelizmente, não o torna mais curto. :)J (162)
Explicação:
]`(]&<&'-')@.(0=#)2}.ARGV
: Obtenha os argumentos da linha de comando e remova os dois primeiros (porque esses são o intérprete e o nome do arquivo de script). Se a lista resultante estiver vazia, retorne['-']
(ou seja, como se o usuário tivesse passado apenas-
), caso contrário, retorne a lista inalterada.(
...::1:)
: se a função interna falhar, retorne1
; caso contrário, retorne o que a função interna retornou.((2*64<#)[
...)
: avalie a função interna e jogue o resultado fora. Então, se o comprimento da lista passada não for maior que64
, retorne0
, caso contrário retorne2
.&.>@;@{.@(_64&(<\))
: obtenha o máximo de64
elementos da lista e, para cada um deles, execute a seguinte função:(1!:1)@(<`3:@.('-'-:]))
: se o elemento foi-
, leia o conteúdo do descritor de arquivo3
(stdin), caso contrário, leia o conteúdo do arquivo nomeado por esse elemento. Se isso falhar (ou seja, o arquivo não existe), o código acima o capturará e retornará1
.exit@3:`(
...)@.(1e6>#)@(<;.2)
: divide a string em suas terminações de linha. Se houver 1.000.000 ou mais linhas, saia com status3
. De outra forma:,&TAB@(6&":)&.>@>:@i.@#
: gere os números para cada linha, formate-os em uma coluna de 6 dígitos e adicioneTAB
a no final de cada sequência,,&.>]
: adicione cada número à frente de cada linha.stdout@(,&LF)@;
: em seguida, imprima a coisa toda, seguida de um extraLF
.exit
: sai com o valor de retorno dessa funçãofonte
Ruby, 76 bytes
Um byte para a
p
bandeira. Corra comruby -p nl.rb
.Os argumentos stdin ou file são tratados automaticamente pelo Ruby. Ele já sai com o código 1 se um argumento de arquivo não existir.
$.
é o número de linhas que foram lidas.$*
são os argumentos da linha de comando e os arquivos são removidos à medida que os arquivos são lidos. Op
sinalizador executa oBEGIN
bloco e envolve o restante do programa em um loop while-gets-print, usando$_
como entrada / saída.fonte
Perl,
125122 bytesfonte
C,
362359Apenas pela diversão. ;-) Trabalha com alimentações de linha LF ou CR / LF.
fonte