화장실 coreutil을 다시 구현


27

이 과제는 기존 과제와 비슷 하지만 사양의 일부가 명확하지 않고 엄격한 I / O 요구 사항이 적습니다.


인쇄 가능한 ASCII와 줄 바꿈만으로 구성된 문자열을 입력하면 다양한 메트릭 (바이트, 워드, 줄 수)을 출력합니다.

출력해야하는 메트릭은 다음과 같습니다.

  • 바이트 수 입력 문자열은 ASCII 내에 있으므로 문자 수이기도합니다.

  • 단어 수. 이것은 wc"단어"의 정의입니다. 공백이 아닌 모든 시퀀스. 예를 들어 abc,def"ghi"하나의 "단어"입니다.

  • 줄 수 이것은 자명하다. 입력에는 항상 줄 바꿈 문자가 포함됩니다. 즉, 줄 수는 "줄 바꿈 수"와 동의어입니다. 후행 줄 바꿈이 하나 이상있을 수는 없습니다.

출력은 기본 wc출력을 정확하게 복제해야합니다 (파일 이름 제외).

llama@llama:~$ cat /dev/urandom | tr -cd 'A-Za-z \n' | head -90 > example.txt
llama@llama:~$ wc example.txt
  90  165 5501 example.txt

행 수가 먼저오고 그 다음에 단어 수와 마지막으로 바이트 수가옵니다. 또한 각 카운트는 모두 같은 너비가되도록 공백으로 왼쪽 패딩해야합니다. 위의 예 5501에서 "가장 긴"숫자는 4 자리이므로 165한 칸 90과 두 칸으로 채워집니다 . 마지막으로 숫자는 모두 각 문자열 사이에 공백이있는 단일 문자열로 결합되어야합니다.

이것이 이므로 바이트 단위의 가장 짧은 코드가 승리합니다.

(그리고, 그런데 ... 당신은 wc당신의 대답에 명령을 사용할 수 없습니다 . 아직 명확하지 않은 경우에)

테스트 사례 ( \n개행을 나타내며 선택적으로 추가 후행 개행이 필요할 수도 있음) :

"a b c d\n" -> "1 4 8"
"a b c d e f\n" -> " 1  6 12"
"  a b c d e f  \n" -> " 1  6 16"
"a\nb\nc\nd\n" -> "4 4 8"
"a\n\n\nb\nc\nd\n" -> " 6  4 10"
"abc123{}[]()...\n" -> " 1  1 16
"\n" -> "1 0 1"
"   \n" -> "1 0 4"
"\n\n\n\n\n" -> "5 0 5"
"\n\n\na\nb\n" -> "5 2 7"

2
나는 이것이 더 나은 도전이기 때문에 오래된 것을 VTC로 할 것입니다.
Mego

빈 입력을 지원해야합니까?
Ton Hospel

나는 그렇게 생각하지 않는다. 그는 모든 입력이 \ n으로 끝났다고 말했다.
CalculatorFeline

답변:


8

펄, 49 바이트

에 +3 추가 -an0

STDIN 또는 하나 이상의 파일 이름을 인수로 입력하십시오. 다음으로 실행perl -an0 wc.pl

wc.pl:

/\z/g;pos=~//;printf"%@+d %@+d $`
",y/
//,~~@F

설명:

-n0      slurps the whole input into $_ and says we will do our own printing
-a       tells perl to split the input on whitespace into array @F
/\z/g    Matches the absolute end of the input. g modifier so the position 
         is remembered in pos which will now contain the input length
pos=~//  An empy regex repeats the last succesful match, so /\z/ again.
         After that $` will contain the the number of input characters and
         the array @+ will contain the length of this number
printf   All preparation is complete, we can go print the result
"%@+d"   will become e.g. %6d if the number of characters is a number of
         length 6, so lines and words will get printed right aligned 
         in a field of length 6.
$`       $` we can directly interpolate since it won't contain a %
y/\n//   Count the number of newlines in $_
~~@F     The array of words @F in scalar context gives the number of words

7

파이썬 2, 100 77 바이트

이 솔루션은 여러 줄 문자열을 받아들이고 stdout에 필요한 카운트를 인쇄하는 Python 함수입니다. 형식 문자열을 사용하여 형식 문자열을 작성합니다 ( %%첫 번째 형식 자리 표시자를 이스케이프 해야 함 ).

편집 : Dennis의 인쇄 최적화로 인해 23 바이트가 절약되었습니다.

def d(b):c=len(b);a='%%%us'%len(`c`);print a%b.count('\n'),a%len(b.split()),c

축소 기 전에 다음과 같이 보입니다.

def wc(text) :
    size = len(text);
    numfmt = '%%%us' % len(`size`);
    print numfmt % text.count('\n'), numfmt % len(text.split()), size

7

Pyth, 21 바이트

jdm.[;l`lQ`ld[@bQcQ)Q

테스트 스위트

Pyth에는 여기에 매우 멋진 내장 기능이 있습니다. [문자열 ( @bQ), 개행 ( cQ)) 및 문자열 자체 ( Q)에 줄 바꿈 목록 ( )을 작성하는 것으로 시작합니다 . 그런 다음 .[각 문자열의 길이 ( ld)를 공백 ( ;이 문맥에서)으로 문자 수의 길이 ( )로 채 웁니다 ( l`lQ). 마지막으로 공백 ( jd) 에 참여하십시오 .


6

POSIX awk, 79 75 67 65 바이트

{w+=NF;c+=length+1}END{d=length(c)"d %";printf"%"d d"d\n",NR,w,c}

편집 : POSIX는 length호출 부분을 할인하여 베어 바이트를 저장하고 7 바이트를 절약 할 수 있기 때문에 4 바이트를 절약했으며 Doorknob의 추가 팁 덕분에 2 바이트를 절약 d %했습니다 d.

이것은 원래 GNU awk를위한 것이지만 POSIX awk 기능 만 사용한다고 말할 수 있습니다.

더 나은 형식 :

gawk '{
  w += NF
  c += length($0) + 1  # length($0) misses the newline
}
END {
  d = length(c) # GNU awk's length returns the length of string representation of number
  printf "%"d"d %"d"d %d\n", NR, w, c
}'

@Doorknob 그래, 고마워. 채팅 대화를 본 것 같아? 또한, 졸업해야 그 질문 자주 묻는 질문 - 제안자주 묻는 질문 .
muru

1
오, 나는 당신을 채팅에서 보지 못했습니다. 귀하의 답변이 내받은 편지함에 나타났습니다.
Doorknob

1
설정 d하려면 length(c)"d %"사용자가 변경할 수 있도록해야 printf"%"d d"d\n"2 바이트를 절약 할 수.
Doorknob

1
@Doorknob 정말 감사합니다! 그것은 이국적인 것이 아니라 바이트를 절약하는 평범한 것 같아요.
muru

6

진심으로 , 39 바이트

"
 "╩╜l;$l╝@╜sl'
╜ck`#╛#"{:>%d}"%f`M' j

온라인으로 사용해보십시오!

설명 (줄 바꾸기가으로 바 replaced \n) :

"\n "╩╜l;$l╝@╜sl'\n╜ck`#╛#"{:>%d}"%f`M' j
"\n "                                      push a string containing a newline and a space
     ╩                                     push input to register 0 (we'll call it s)
      ╜l;                                  push two copies of len(s) (byte count)
         $l╝                               push len(str(len(s))) to register 1
                                            (this will serve as the field width in the output)
            @╜sl                           push word count by getting the length of the list formed by
                                            splitting s on spaces and newlines
                '\n╜c                      count newlines in input
                     k                     push stack to list
                      `#╛#"{:>%d}"%f`M     map:
                       #                     listify
                        ╛#                   push reg 1 (field width), listify
                          "{:>%d}"           push that string
                                  %          do old-style string formatting for field width
                                   f         do new-style string formatting to pad the field appropriately
                                      ' j  join on spaces

이 언어에 대한 문서를 찾을 수 없습니다. 링크를 제공 할 수 있습니까?
JohnEye


3

AppleScript, 253 바이트

이것은 AppleScript의 텍스트 항목 구분 기호가 공백으로 설정되어 있다고 가정합니다 (이 가정을 강제하기 위해 물건을 계산 해야하는 경우 추가 할 것입니다).

set w to(display dialog""default answer"")'s text returned
set x to b(w)
set y to w's text item's number
set z to w's paragraph's number
a(x,z)&z&a(x,y)&y&" "&x
on a(x,n)
set o to" "
repeat b(x)-b(n)
set o to o&" "
end
o
end
on b(n)
count(n as text)
end

3

CJam, 31 26 바이트

q_)/_S*S%@_]:,:s),f{Se[}S*

온라인으로 사용해보십시오!

작동 원리

q_                         e# Read all input from STDIN and push two copies.
  )                        e# Pop the last character (linefeed) of the second copy.
   /                       e# Split the remaining string at linefeeds.
    _                      e# Push a copy.
     S*                    e# Join the copy, separating by spaces.
       S%                  e# Split at runs of spaces.
         @_                e# Rotate the original input on top and push a copy.
           ]               e# Wrap all four items in an array.
            :,             e# Get the length of each item.
              :s           e# Cast the lengths (integers) to strings.
                )          e# Pop the last length (byte count).
                 ,         e# Get the number of digits.
                  f{Se[}   e# Left-pad all three length with spaces to that length.
                        S* e# Join, separating by spaces.

3

줄리아, 112 81 바이트

f(s,n=endof,l="$(n(s))",g=r->lpad(n(split(s,r))-1,n(l)))=g(r"\n")" "g(r"\S+")" "l

문자열을 받아들이고 문자열을 반환하는 함수입니다.

다음을 함수 인수로 저장합니다.

  • n = endof 인덱싱 가능한 컬렉션의 마지막 인덱스를 가져 오는 함수 (이 경우 문자열 길이)
  • l = "$(n(s))보간법을 사용하여 입력 길이를 문자열로 변환
  • g정규 표현식을 받아들이고 해당 정규 표현식에서 입력 분할의 길이-1을 반환하고 길이와 일치하는 공백으로 채워진 람다 함수 입니다 l.

를 사용하여 줄 수와를 사용하여 g(r"\n")단어 수를 g(r"\S+")얻은 다음 l공백 으로 구분하여 줄을 결합 합니다.

Dennis 덕분에 31 바이트를 절약했습니다!


2

MATL, 38 바이트

'\n'32cZtttnGnw-wPZvPYbnqbnvvV!3Z"vX:!

당신은 할 수 있습니다 온라인으로보십시오! 그래도 오래 걸리지 않아야합니다 ...

계산을 위해

'\n'32cZt  %// Takes implicit input and replaces any \n with a space
tt         %// Duplicate that string twice
nGnw-w     %// Length of the string with \n's minus length with spaces to give number of \n's
PZvPYbnq   %// Take string with spaces, flip it, remove leading spaces, flip it again,
           %// split on spaces, find length and decrement for number of words
bn         %// get length of string with spaces, the number of characters

마지막 부분은 출력 형식을 수행합니다

vvV!       %// concatenate the 3 numbers to a column vector, convert to string and transpose
3Z"v       %// make string '   ' and concatenate on the bottom of previous string
X:!        %// linearise and transpose to get correct output (impicitly printed)

잘 했어요! 온라인 사용해보기 링크 에서 "debug"플래그를 제거 하시겠습니까?
Luis Mendo

으악! 고마워요!
David

나는 당신이 바꿀 수 있다고 생각 !3Z"vX:!하여 Z{Zc( cellstr다음 strjoin)
루이스 Mendo

1

자바 스크립트 (ES6), 115 바이트

s=>[/\n\/g,/\S+/g,/[^]/g].map(r=>l=(s.match(r)||[]).length).map(n=>(' '.repeat(99)+n).slice(-`${l}`.length)).join` `

입력이 필요하지 않습니다. 서식은 고통 스러웠다. 패딩의 양에 상한이 있다면 (' '.repeat(99)+n)더 짧은 것으로 줄일 수 있습니다 ` ${n}`.


나는 당신이 바꿀 수 있다고 생각 /[^]/g/./g할인율 두 바이트
패트릭 로버츠

@PatrickRoberts 아니요, 줄 바꿈을 건너 뛰므로 카운트가 해제됩니다.
Neil

아, 전에는 눈치 채지 못했습니다.
Patrick Roberts

1

PowerShell, 140 바이트

param($a)$c="$((($l=($a-split"`n").Count-1),($w=($a-split"\S+").Count-1),($b=$a.length)|sort)[-1])".Length;
"{0,$c} {1,$c} {2,$c}"-f$l,$w,$b

(명확성을 위해 줄 바꿈 : D)

첫 번째 줄은 input을 취하고 $a다음 부분은 모두 한 문장입니다. 우리는 some-string 's와$c 동일하게 설정 하고 있습니다 .length . 이것은 필수 패딩을 형성합니다. 문자열 내부에는 즉각적인 코드 블록 $(...)이 있으므로 문자열로 평가되기 전에 코드가 실행됩니다.

코드 블록에서 |sort명령을 통해 3 개의 항목을 전송 한 다음 가장 큰 항목을 가져옵니다 (...)[-1]. 여기에서 열을 올바른 너비로 가져옵니다. 세 항목은 $l-split바꿈, 줄 바꿈, $w단어 개수, -split공백 위치 및 $b길이입니다.

두 번째 줄은 -f연산자를 사용하는 출력 입니다 (의 의사 속기 String.Format()). 확장 변수를 문자열에 삽입하는 또 다른 방법입니다. 여기서 우리는 모든 출력이 왼쪽으로 채워져 각 열이 $c넓어 지기를 원합니다 . 패딩은 공백을 통해 수행됩니다. 0, 12받는 대응 $l, $w$b라인 수, 단어 수 및 바이트 수를 적절히 패딩 및 출력하도록 포맷 연산자의 인수, 즉이다.

이를 위해서는 문자열에 이미 확장 된 줄 바꿈이 있어야합니다 (예 : Get-Content텍스트 파일 또는 무언가에 대해 수행 한 다음 파이프에 연결하거나 변수에 저장 한 다음 해당 입력에서이 코드 호출). 백틱이있는 스타일 이스케이프 문자 ( `n대신에 의미 \n).

PS C:\Tools\Scripts\golfing> .\reimplement-wc.ps1 "This line`nis broken`ninto three lines.`n"
 3  7 38


0

루비, 108 바이트

f=->s{a=[s.count($/),s.split(/\S+/).size-1,s.size].map(&:to_s)
a.map{|b|" "*(a.map(&:size).max-b.size)+b}*" "}

0

펄, 71 62 61 바이트

+1 포함 -n

$;=length($b+=y///c);$w+=split$"}{printf"%$;d %$;d $b",$.,$w

댓글 :

while (<>) {                         # implicit because of -n
    $; = length(                     # printf formatting: width
       $b += y///c                   # count characters
    );
    $w += split $"                   # count words
}{                                   # explicit: end while, begin END block
    printf "%$;d %$;d $b", $., $w    #  $. = $INPUT_LINE_NUMBER
}                                    # implicit because of -n
  • @TonHospel 덕분에 다른 바이트를 다시 저장하십시오.
  • @TonHospel 덕분에 9 바이트를 절약하여 거래의 몇 가지 트릭을 보여주세요!

거래의 몇 가지 트릭 : y///c보다 짧은 길이로 사용하십시오 $_. split$"스칼라 컨텍스트에서의 단어 수를 제공합니다 $_. $;대신 문장 부호 변수를 사용 하면 보간 바로 뒤에 서식 문자열을 $W넣을 수 있습니다 d. 그럼 당신은 놓을 수 d있는을 $W하고 괄호를 놓습니다. 그리고 -p아무것도 얻지 못하고 -n, 그냥 printf인쇄를 하게하세요 (미각에 줄 바꿈 추가)
Ton Hospel

정말 고마워요!
Kenney

와 같은 계산 체인 $a=foo;$b=bar$a은 일반적으로 $b=bar($a=foo)1 바이트를 절약하여 로 쓸 수 있습니다 . $;및에 적용 할 수 있습니다 $b. $;매번 재 계산 되면 상관 없습니다
Ton Hospel

감사! 나는 두 개의 블록이 있기 때문에 그것을 간과했다 ...
Kenney

0

루아, 74 66 바이트

골프 :

t=arg[1]_,l=t:gsub('\n','')_,w=t:gsub('%S+','')print(l,w,t:len())

언 골프 드 :

text = arg[1]
_,lines = text:gsub('\n','')
_,words = text:gsub('%S+','')
print(lines, words, text:len())

명령 행 인수를 통해 입력을받습니다.

arg[1]바이트를 저장하기 위해 첫 번째 인수 ( )의 이름을 바꿉니다 . string.gsub수정 된 문자열뿐만 아니라 대체 횟수도 반환하므로이를 사용하여 먼저 '\n'(줄 바꿈) 계산 한 다음 '%S+'(한 개 이상의 공백이 아닌 문자 (예 : 단어))을 계산합니다. 대체 문자열에 원하는 것을 사용할 수 있으므로 빈 문자열 ( '')을 사용하여 바이트를 저장합니다. 그런 다음 string.len문자열의 길이, 즉 바이트 수를 찾는 데 사용 합니다. 그런 다음 마지막으로 모두 인쇄합니다.


그래도 줄과 단어 값의 왼쪽 패딩이 보이지 않습니다
Ton Hospel

0

망막, 65

^((\S+)|(¶)|.)*
$#3 $#2 $.0
+`(\b(.)+ )(?!.*\b(?<-2>.)+$)
a$1
a
<space>

온라인으로 사용해보십시오!

첫 번째 단계는 실제 화장실 프로그램이고 나머지는 패딩을위한 것입니다. a자리 것은 아마 필요하고, 그룹의 일부는 아마 조금 단순화 할 수있다.


0

하스켈, 140 바이트

import Text.Printf
w h=let{l=length;s=show.l;c=s h;m=s.words$h;n=s.lines$h;f=maximum$map l[c, m, n];p=printf"%*s"f}in p n++' ':p m++' ':p c

ungolfed 버전은 확장 변수 및 함수 이름과 함께 아래에 있습니다.

import Text.Printf

wc str =
  let charcount = show.length $ str
      wordcount = show.length.words $ str
      linecount = show.length.lines $ str
      fieldwidth = maximum $ map length [charcount, wordcount, linecount]
      printer = printf "%*s" fieldwidth
  in printer linecount ++ (' ' : printer wordcount ++ (' ' : printer charcount))

문자열을 받아들이고 문자열을 반환하는 함수입니다. 그것은 단지 사용 Prelude기능 words(RESP를. lines) 주어진 단어 (RESP. 선)의 수를 얻기 위해 그들과 같은 정의를 사용하는 것처럼 보인다 wc, 다음 (문자열로) 가장 긴 값을 가져옵니다 카운트 사이와의 printf 형식 복용을 사용 형식화를위한 인수 사이의 너비


0

C, 180 178 바이트

#include <stdio.h>
#include <ctype.h>
main(b,w,l,c,d){d=' ';b=w=l=0;while((c=fgetc(stdin))!=EOF){if(!isspace(c)&&isspace(d))w++;b++;d=c;if(c==10)l++;}printf("%d %d %d\n",l,w,b);}


0

05AB1E , 24 23 바이트

¨¶¡¹… 
    S¡õK¹)€g§Zg>jJ¦

j현재 버그가 있었으므로 §J. 없이 21 바이트 일 수 있습니다 .

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

¨          # Remove the trailing newline of the (implicit) input
 ¶¡        # And split it on newlines
¹… 
    S¡     # Take the first input again, and split it on [" \n\t"]
      õK   # Then remove all empty string items
¹          # And take the first input again as is
)          # Wrap all three value of the stack to a single list
 g        # Take the length of each of the items
   §       # Cast the integers to strings (should have been implicit, but `j` is bugged)
    Z      # Take the max (always the last / amount of bytes) (without popping the list)
     g>    # Take the length + 1 of this max
       j   # Append leading spaces so all items or of this length
        J  # Join them together (should have been done by the `j` already, but it's bugged)
         ¦ # Remove the leading space (and output implicitly to STDOUT)

0

-s , 25 바이트

sX##a-#_._M[nNa`\S+`Na#a]

여러 줄 문자열을 명령 줄 인수로 사용합니다. 온라인으로 사용해보십시오!

가장 긴 숫자가 항상 문자 수라는 것을 깨닫게 해준 Dennis의 CJam 답변 덕분 입니다.

설명

                           s is space; n is newline; a is 1st cmdline arg (implicit)
           [            ]  Construct a list of three elements:
            nNa             Number of newlines in a
               `\S+`Na      Regex search: number of runs of non-whitespace characters in a
                      #a    Length of a (i.e. number of characters in a)
          M                To each element of that list, map this function:
   #a                       Number of characters in a
  #                         Length of that number
     -#_                    Subtract length of each element
sX                          Construct a string of that many spaces
        ._                  Prepend it to the element
                           The resulting list is autoprinted, space-separated (-s flag)

다음 -rs은 stdin에서 입력을받는 플래그 가 있는 29 바이트 솔루션입니다 .

[#g`\S+`NST:gY#g+1]MsX#y-#_._

온라인으로 사용해보십시오!


0

파워 쉘, 123 115 바이트

switch -r($args|% t*y){'\s'{$a=0}'\S'{$w+=!$a;$a=1}'(?s).'{$b++}'
'{$l++}}$c="$b".Length
"{0,$c} {1,$c} $b"-f$l,+$w

테스트 스크립트 :

$f = {

switch -r($args|% t*y){    # evaluate all matched cases
    '\s'   {$a=0}          # any whitespace (newline not included)
    '\S'   {$w+=!$a;$a=1}  # any not-whitespace (newline not included)
    '(?s).'{$b++}          # any char (newline included!)
    '`n'   {$l++}          # new line char
}
$c="$b".Length
"{0,$c} {1,$c} $b"-f$l,+$w


}

@(
    , ("a b c d`n", "1 4 8")
    , ("a b c d e f`n", " 1  6 12")
    , ("  a b c d e f  `n", " 1  6 16")
    , ("a`nb`nc`nd`n", "4 4 8")
    , ("a`n`n`nb`nc`nd`n", " 6  4 10")
    , ("abc123{}[]()...`n", " 1  1 16")
    , ("`n", "1 0 1")
    , ("   `n", "1 0 4")
    , ("`n`n`n`n`n", "5 0 5")
    , ("`n`n`na`nb`n", "5 2 7")
) | % {
    $s,$e = $_
    $r = &$f $s
    "$($e-eq$r): $r"
}

산출:

True: 1 4 8
True:  1  6 12
True:  1  6 16
True: 4 4 8
True:  6  4 10
True:  1  1 16
True: 1 0 1
True: 1 0 4
True: 5 0 5
True: 5 2 7

설명:

  • $args|% t*y arument 문자열을 문자로 분할
  • switch -r($args|% t*y)일치하는 모든 사례를 평가
    • '\s' 공백의 경우
    • '\S' 공백이 아닌 경우
    • '(?s).' 모든 문자의 경우 (줄 바꿈 포함)
    • '\n' 개행 문자의 경우 (개행 문자는 자체를 나타냄)
  • $c="$b".Length바이트 수를 계산하십시오. 설계 상 $ b는 항상 max ($ l, $ w, $ b)입니다.
  • "{0,$c} {1,$c} $b"-f$l,+$w길이가 같은 형식 번호. 변수 $ w는 int로 변환됩니다. 단어가없는 문자열이 필요합니다. '입력은 항상 후행 줄 바꾸기를 포함하고 $ l 및 $ b는 0 일 수 없으므로 다른 변수 형식은'있는 그대로 '입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.