Satır numaralandırma - uygulamak nl


13

Göreviniz nl, GNU çekirdek yardımcı programlarından komut satırı aracına benzer bir program uygulamaktır.

Standart boşluklar yasaklanmıştır.

nlKendisi veya =GNU sed'deki komut gibi bir dosya veya dizenin satırlarını numaralandırmak için yerleşik veya harici bir işlev, program veya yardımcı program kullanamazsınız .

Şartname

Giriş

Program, dosya adlarını bağımsız değişken olarak kabul eder. Kodunuzun çapraz platform olması gerekmez; kodu çalıştıran işletim sisteminin dosya adı biçimi kullanılmalıdır, yani Windows'ta bulunuyorsanız, dizin ayırıcı \veya olabilir /.

-Belirtilmişse de dahil olmak üzere 64 giriş dosyasını alabilmeniz gerekir . 64'ten fazla verilirse, yalnızca ilk 64'ü kullanın.

Dosya adları listesinde -standart girişi temsil eder.

Dosya adları verilirse, dosyalardan verildikleri sırayla okuyun ve içeriklerini birleştirin, her biri ve sonuna yeni bir satır ekleyin. Bir veya daha fazla dosya adından okuyamıyorsanız (dosya mevcut olmadığından veya dosya için okuma izniniz olmadığından) yok sayın. Belirtilen tüm dosya adları geçersizse, hiçbir şey çıktılamaz.

Dosya adı verilmemişse standart girişten okuyun. Standart girişten yalnızca dosya adı verilmemişse veya -verilmişse okuyun.

Çıktı

Program çıktısı, standart çıkışa, çizgilerle giriş böylece sayılı (Sen girdi olduğunu varsayalım olabilir \n, \r\nya da \r:; sizin için uygun olanı seçmek, ama hangi birini belirtmek satır sonları)

<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>
...
...

Satır numarası için 6 karakter boşluk ayrılır ve bu karakterlerin sonuna eklenir; geri kalanı boşluk haline gelir (örneğin 1, 5 önde gelen alana 22sahip olacak, 4 önde gelen alana sahip olacak ...). Giriş yeterince uzunsa, satır satırında satır sonunda yer kalmaz 999999. 999999 satırından sonra hiçbir şey çıkarmamalısınız.

Giriş boşsa, hiçbir şey çıktılamaz.

Çıkış durumu

Küçük sayılar önceliklidir: 1 ve 2 numaralı hatalarla karşılaşıldıysa, durum 1 ile çıkın.

Giriş başarıyla alındıysa ve satırlar başarıyla numaralandırılıp çıktıysa durum 0 ile çıkın.

Komut satırında belirtilen bir veya daha fazla dosya bulunamadıysa veya okunamıyorsa durum 1 ile çıkın.

Çok fazla dosya (64'ten fazla) verildiğinde durum 2'den çıkın.

Giriş çok uzunsa (999999 satırdan fazla) durum 3 ile çıkın. \

puanlama

Bu kod golf - en kısa program kazanır!

Bazı seçenekleri uygulamak için daha sonra bonuslar ekleyebilirim nl. Şu anda bonus yok.


Satır numaralandırma sürekli midir, yoksa her dosya için kendisini "sıfırlar" mı?
britishtea

@britishtea Sürekli

1
Eğer js'de bir şey göndermek istiyorsak düğümü kullanmak gerekli midir? Yoksa fonksiyon argümanlarını kullanabilir veya prompt()program argümanlarını ve stdin'i taklit edebilir miyiz ?
DankMemes

1
İkili dosyalar? Kodlama? Unicode işaretleri?
edc65

Yanıtlar:


6

Baş, 121

s=$[2*($#>64)]
for f in "$@";{ [ -f $f ]||s=1;}
((s))&&exit $s
awk '{if(NR>=10**6){exit 3}printf("%6d\t%s\n",NR,$0)}' $@

1
Eğer yapabilirsiniz ifsen mesela aritmetik ifadelerini kullanır eğer ifadeler biraz daha kısa(($#>64))&&s=2
Dijital Travma

2
@DigitalTrauma Bir şey öğrendim!
Sammitch

1
Sen yerini alabilir s=0;(($#>64))&&s=2ile s=$[2*($#>64)], (($s==0))||birlikte ((s))&&ve ifbirlikte ifadesi [ -f "$f" ]||s=1.
Dennis


2
awkayrıca birden fazla dosya aktarılırsa birleştirilir, bu yüzden bu resmen cat ;-) ' nin gereksiz bir kullanımı olarak sayılır . Bunun yerine bunun işe yarayacağını düşünüyorum:awk '...' $@
Digital Trauma

2

Yakut, 195

o,l=$*[64]?[2]:[],999999
($*==[]?[?-]:$*).each{|n|f=n==?-?STDIN: open(n)rescue o<<1&&next
s=f.read.lines
s[l]?o<<3:1
puts s[0..l].map.with_index(1){|l,i|i.to_s.rjust(6)+?\t+l}}
exit !o[0]?0:o.min

Bence STDINtakma ad $<.
Martin Ender

ARGFBağımsız değişken olarak verilen dosyaların geri kalanından da okunacak bir takma addır. Bu bir ARGFşekilde (hatta "-"stdin olarak kabul gibi görünüyor) kullanarak daha da aşağı golf olabilir düşünüyorum .
britishtea

britishteanl: 4: block in <main>': undefined method # <Numaralandırıcı için [] içinde : 0x000006002980c8> (NoMethodError) için britishteanl: 2: içinde each' from britishteanl:2:in <main> '- sorun nedir? Ben koştumruby britishteanl folder/filename

Ruby sürümünde bir fark olduğundan şüpheliyim. Hem Ruby 2.0.0 hem de Ruby 2.1.2'de sorunsuz bir şekilde örnek çalıştırdım. Hangi sürümü kullanıyorsunuz?
britishtea

2

Perl, 84 + 2 ( -pl) = 86 bayt

perl -ple'BEGIN{map{-r||exit 1}@ARGV;@ARGV>63&&exit 2}$.>=1e6&&exit 3;$_=printf"%5d\t%s",$.,$_'

Deparsed:

perl -MO=Deparse -ple'BEGIN{map{-r||exit 1}@ARGV;@ARGV>63&&exit 2}$.>=1e6&&exit 3;$_=printf"%5d\t%s",$.,$_' output.txt; echo $?

BEGIN { $/ = "\n"; $\ = "\n"; }
sub BEGIN {
    map {exit 1 unless -r $_;} @ARGV;
    exit 2 if @ARGV > 63;
}
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    exit 3 if $. >= 1000000;
    $_ = printf("%5d\t%s", $., $_);
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

Bilmek önemlidir:

  • -psargıları programı ile verilen -ede while/ continuedöngü
  • BEGIN kodu (örtük) ana bölümden önce yürütülür
  • dosya -rvarsa !-eve $_örtük olarak verilen varsayılan olarak teste varsayılan olarak dosya testi başarısız olurmap { ... } @ARGV
  • $. geçerli satır numarasını tutar
  • dinlenme kendini açıklayıcı olmalıdır;)

Büyük cevap ve Programlama Bulmacalar ve Kod Golf hoş geldiniz! Belki de kodunuzun nasıl çalıştığına dair bir açıklama eklemek için düzenleyebilirsiniz.
wizzwizz4

1

python 173

import os,sys
c=0
l=1
for f in sys.argv[1:]:
    if c>64:exit(2)
    if not os.path.isfile(f):exit(1)
    c+=1
    for x in open(f):
        if l>=10**6:exit(3)
        print '%6d\t%s'%(l,x),;l+=1

Ben senin Kod şu anda eksik olduğunu düşünüyorum -FOR sys.stdin. Olası bir çözüm böyle bir şey olabilir fh=sys.stdin if f=='-' else open(f)ve sonra x=fh.readline()? Ne yazık ki daha kısa yapmaz. :)
Dave J

1

J (162)

exit(((2*64<#)[exit@3:`(stdout@(,&LF)@;@(,&TAB@(6&":)&.>@>:@i.@#,&.>]))@.(1e6>#)@(<;.2)@(1!:1)@(<`3:@.('-'-:]))&.>@;@{.@(_64&(<\))) ::1:)]`(]&<&'-')@.(0=#)2}.ARGV

Açıklama:

  • ]`(]&<&'-')@.(0=#)2}.ARGV: Komut satırı bağımsız değişkenlerini alın ve ilk ikisini kaldırın (çünkü bunlar yorumlayıcı ve kod dosyası adıdır). Ortaya çıkan liste boşsa, geri dönün ['-'](örneğin, yalnızca kullanıcı geçmiş gibi -), aksi takdirde listeyi değiştirmeden geri gönderin.
  • (... ::1:): iç işlev başarısız olursa, geri dönün 1, aksi takdirde iç işlev döndürüldüğünde geri dönün.
  • ((2*64<#)[... ): iç işlevi değerlendirin ve sonucu atın. Ardından, iletilen listenin uzunluğu daha yüksek değilse 64, geri dönün 0, aksi takdirde geri dönün 2.
  • &.>@;@{.@(_64&(<\)): 64listeden en fazla eleman alın ve her biri için aşağıdaki fonksiyonu çalıştırın:
    • (1!:1)@(<`3:@.('-'-:])): öğe öyleyse, -dosya tanımlayıcısının 3(stdin) içeriğini okuyun, aksi takdirde o öğe tarafından adlandırılan dosyanın içeriğini okuyun. Bu başarısız olursa (yani dosya yoksa), yukarıdaki kod onu yakalar ve geri döner 1.
    • exit@3:`(... )@.(1e6>#)@(<;.2): dizeyi satır sonlarına böler. 1.000.000 veya daha fazla satır varsa, durumla çıkın 3. Aksi takdirde:
      • ,&TAB@(6&":)&.>@>:@i.@#: her satır için sayıları oluşturun, 6 basamaklı bir sütunda biçimlendirin ve TABher dizenin sonuna a ekleyin ,
      • ,&.>]: her sayıyı her satırın önüne eklemenizi sağlar.
      • stdout@(,&LF)@;: sonra her şeyi, ardından bir ekstra çıktı LF.
  • exit: bu işlevin dönüş değeriyle çık

1

Yakut, 76 bayt

pBayrak için bir bayt . İle çalıştırın ruby -p nl.rb.

BEGIN{x=$*.size-65}
exit 2if$*.size==x
exit 3if$.>999999
$_="%6d"%$.+?\t+$_

stdin veya dosya argümanları Ruby tarafından otomatik olarak işlenir. Bir dosya argümanı yoksa zaten kod 1 ile çıkar. $.okunan satır sayısıdır. $*komut satırı bağımsız değişkenleridir ve dosyalar okundukça dosyalar çıkarılır. pBayrak yürütür BEGINbloğu kullanılarak, a-alırken baskı döngüsü içindeki programın geri kalanı sarar $_giriş / çıkış olarak.


Spesifikasyon, başlangıçta vazgeçmek yerine 64'ten fazla verilirse ilk 64 girişi işlemeniz gerektiğini söylüyor.
Anders Kaseorg

@AndersKaseorg düzeltildi.
daniero

1

Perl, 125 122 bayt

@a=@ARGV;for(@a){$i++>63&&exit 2;($_ eq '-'or-e$_)or next;@ARGV=$_;while(<>){$c>1E6-2&&exit 3;printf"%5d\t%s",++$c,$_}say}

Bu, maksimum 64 bağımsız değişkeni ve çıkış durumu ile ilgili özellikleri karşılamaz.
Anders Kaseorg

@AndersKaseorg Düzeltildi!
Gowtham

0

Cı, 362 359

Sadece eğlenmek için. ;-) LF veya CR / LF hat beslemeleri ile çalışır.

#include<stdio.h>
#define R return
#define P printf(
e,t,l;void*f;r(){P"% 6d\t",++l);for(;(t=fgetc(f))^-1&&l<1000000;){if(ferror(f))R 1;P"%c",t);if(t==10)P"% 6d\t",++l);}P"\n");R l<1000000?0:3;}main(int c,char**v){e=c>65?2:0;for(++v;*v||c<2;++v){t=c<2||!strcmp(*v,"-")?f=stdin,0:!(f=fopen(*v,"rb"));if(t||(t=r()))e=!e|(e>t)?t:e;if(f&&f!=stdin)fclose(f);}R e;}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.