줄 번호 매기기-nl 구현


13

귀하의 작업은 nlGNU 핵심 유틸리티 의 명령 줄 도구 와 유사한 프로그램을 구현하는 것 입니다.

표준 허점 은 금지되어 있습니다.

nl자체 또는 =GNU sed 의 명령 과 같이 파일 또는 문자열의 줄 번호를 지정하기 위해 내장 또는 외부 함수, 프로그램 또는 유틸리티를 사용할 수 없습니다 .

사양

입력

프로그램은 파일 이름을 인수로 허용합니다. 코드가 크로스 플랫폼 일 필요는 없습니다. 코드를 실행하는 OS의 파일 이름 형식을 사용해야합니다. 예를 들어 Windows에있는 경우 디렉토리 구분 기호는 \또는 /입니다.

-지정된 경우를 포함하여 64 개의 입력 파일을 가져올 수 있어야 합니다. 64 개가 넘는 경우 첫 64 개만 처리하십시오.

파일 이름 목록에서 -표준 입력을 나타냅니다.

파일 이름이 제공되면 파일에서 주어진 순서대로 파일을 읽고 내용을 연결하여 각 파일 사이와 끝에 새 줄을 삽입하십시오. 하나 이상의 파일 이름을 읽을 수없는 경우 (파일이 없거나 파일에 대한 읽기 권한이 없기 때문에) 무시하십시오. 지정된 모든 파일 이름이 유효하지 않으면 아무것도 출력하지 않습니다.

파일 이름이 없으면 표준 입력에서 읽습니다. 파일 이름이 없거나 주어진 경우 표준 입력에서만 읽습니다 -.

산출

프로그램은 번호가 매겨진 라인이있는 입력을 표준 출력으로 출력합니다 (입력에 \n, \r\n또는 \r줄 끝 이 있다고 가정 할 수 있습니다 .

<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 자의 공백이 할당되며이 문자의 끝에 삽입됩니다. 나머지는 공백이됩니다 (예 : 15 개의 선행 공백이 있고 224 개의 선행 공백이 있습니다. ...). 입력이 충분히 길면 line에 줄 번호를위한 공간이 부족하게됩니다 999999. 999999 행 이후에는 아무것도 출력하지 않아야합니다.

입력이 비어 있으면 아무것도 출력하지 않습니다.

종료 상태

낮은 숫자가 우선합니다 : 오류 1과 2가 발생하면 상태 1로 종료하십시오.

입력이 성공적으로 수신되고 행의 번호가 매겨져 출력되면 상태 0으로 종료하십시오.

명령 행에 지정된 하나 이상의 파일을 찾을 수 없거나 읽을 수없는 경우 상태 1로 종료하십시오.

너무 많은 파일 (64 개 이상)이 제공된 경우 상태 2로 종료하십시오.

입력이 너무 길면 (999999 줄 이상) 상태 3으로 종료하십시오. \

채점

이것은 코드 골프입니다-가장 짧은 프로그램이 이깁니다!

nl가지고있는 특정 옵션을 구현하기 위해 나중에 보너스를 추가 할 수 있습니다 . 현재 보너스가 없습니다.


줄 번호 매기기가 연속적이거나 짧습니까? 각 개별 파일에 대해 "재설정"됩니까?
britishtea

@britishtea 그것은 연속적이다

1
js로 무언가를 제출하려면 노드를 사용해야합니까? 아니면 함수 args를 사용하거나 prompt()프로그램 args와 stdin을 에뮬레이트 할 수 있습니까?
DankMemes

1
이진 파일? 부호화? 유니 코드 마커?
edc65

답변:


6

배쉬, 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
if산술 연산 식을 사용하면 식을 상당히 짧게 만들 수 있습니다.(($#>64))&&s=2
Digital Trauma

2
@DigitalTrauma 나는 것을 배웠다!
Sammitch

1
당신은 대체 할 수 s=0;(($#>64))&&s=2s=$[2*($#>64)], (($s==0))||((s))&&if와 문 [ -f "$f" ]||s=1.
Dennis


2
awk여러 파일을 전달하면 연결되기 때문에 공식적 으로 cat ;-)를 쓸모없는 것으로 간주 합니다. 대신 나는 이것이 효과가 있다고 생각한다.awk '...' $@
Digital Trauma

2

루비, 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

STDIN에 별칭이 있다고 생각 합니다 $<.
Martin Ender

의 별칭으로 ARGF, 인수로 제공된 나머지 파일에서 읽습니다. 나는 이것이 ARGF어떻게 든 사용하여 골프를 밟을 수 있다고 생각합니다 (심지어 "-"stdin 으로 인식 되는 것 같습니다 ).
britishtea

britishteanl : block in <main>': undefined method 2 : in each' from britishteanl:2:in <main> ' 에서 # <Enumerator : 0x000006002980c8> (NoMethodError)에 대한 britishteanl : 4 : in [] '-무엇이 잘못 되었나요? 나는로 실행ruby britishteanl folder/filename

루비 버전과 다른 점이 의심됩니다. Ruby 2.0.0과 Ruby 2.1.2 모두에서 문제없이 샘플을 실행했습니다. 어떤 버전을 사용하고 있습니까?
britishtea

2

Perl, 84 + 2 ( -pl) = 86 바이트

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

출발 :

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

알아야 할 중요한 사항 :

  • -p랩 프로그램과 소정 -ewhile/ continue루프
  • BEGIN 코드는 (암시 적) 주요 부분보다 먼저 실행됩니다
  • 파일 -r이 존재하지 않고 !-e기본적으로 testing으로 설정 되면 파일 테스트 가 실패합니다 $_.map { ... } @ARGV
  • $. 현재 줄 번호를 유지
  • 나머지는 설명이 필요합니다.)

정답, 프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다! 코드 작동 방식에 대한 설명을 추가하기 위해 편집 할 수 있습니다.
wizzwizz4

1

파이썬 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

귀하의 코드에 현재에 -대한 정보 가 누락 된 것 같습니다 sys.stdin. 가능한 해결책은 같은 수 있습니다 fh=sys.stdin if f=='-' else open(f)다음으로 이동 x=fh.readline()?! 불행히도 그것은 더 짧아지지 않습니다. :)
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

설명:

  • ]`(]&<&'-')@.(0=#)2}.ARGV: 명령 행 인수를 가져오고 첫 번째 두 인수를 제거하십시오 (이는 인터프리터 및 스크립트 파일 이름이므로). 결과 목록이 비어있는 경우 반환합니다 ['-'](예 : 사용자가 통과 한 것처럼)- ) 반환하고, 그렇지 않으면 목록을 변경하지 않고 반환합니다.
  • (... ::1:): 내부 함수가 실패하면 return1 , 그렇지 않으면 반환 한 것을 반환합니다.
  • ((2*64<#)[... ): 내부 함수를 평가하고 결과를 버립니다. 전달 된 목록의 길이보다 높았다 경우, 64반환, 0그렇지 않으면 반환2 .
  • &.>@;@{.@(_64&(<\)): 최대한 활용 64 목록 요소를 오고 각 요소에 대해 다음 기능을 실행하십시오.
    • (1!:1)@(<`3:@.('-'-:])): 요소가 -이면 파일 디스크립터 3(stdin)의 내용을 읽고, 그렇지 않으면 해당 요소가 지정한 파일의 내용을 읽으십시오. 이것이 실패하면 (즉, 파일이 존재하지 않는 경우) 위의 코드는 그것을 잡아서 반환합니다1 합니다.
    • exit@3:`(... )@.(1e6>#)@(<;.2): 줄 끝에서 문자열을 나눕니다. 1.000.000 개 이상의 줄이 있으면 status로 종료하십시오 3. 그렇지 않으면:
      • ,&TAB@(6&":)&.>@>:@i.@#: 각 행의 숫자를 생성하고 6 자리 열로 형식화 한 후 TAB각 문자열의 끝에 a 를 추가하십시오.
      • ,&.>]: 각 줄 앞에 각 숫자를 추가합니다.
      • stdout@(,&LF)@;: 그런 다음 전체를 출력 한 다음 추가를 출력합니다 LF.
  • exit: 해당 함수의 반환 값으로 종료

1

루비, 76 바이트

p플래그의 1 바이트 로 실행하십시오 ruby -p nl.rb.

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

stdin 또는 파일 인수는 Ruby에 의해 자동으로 처리됩니다. 파일 인수가 존재하지 않으면 이미 코드 1로 종료됩니다. $.읽은 줄 수입니다. $*명령 줄 인수이며 파일을 읽을 때 파일이 튀어 나옵니다. p플래그는 실행 BEGIN블록을 사용하고, A-느끼는 동안 인쇄 루프 내부 프로그램의 나머지 부분을 감싸는 $_입력 / 출력한다.


스펙은 처음에 포기하지 않고 64 개 이상이 주어진 경우 처음 64 개의 입력을 처리해야한다고 말합니다.
Anders Kaseorg

@AndersKaseorg가 수정되었습니다.
daniero

1

펄, 125122 바이트

@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}

이는 64 개의 인수 최대 값 및 종료 상태와 관련된 스펙을 만족하지 않습니다.
Anders Kaseorg

@AndersKaseorg 수정되었습니다!
Gowtham

0

C, 362 359

그것의 재미를 위해. ;-) LF 또는 CR / LF 줄 바꿈과 함께 작동합니다.

#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;}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.