후행 진실을 세 어라


59

사랑하는 친구와 동료에게 영감을 받아 기억합니다.

댄 바로 넷

Dan Baronet , 1956 – 2016. RIP

그는 이 작업에서 가능한 가장 짧은 APL 솔루션 을 찾았 습니다 .

태스크

부울 목록이 주어지면 후행 진리 값의 수를 세십시오.

사례

{}0

{0}0

{1}1

{0, 1, 1, 0, 0}0

{1, 1, 1, 0, 1}1

{1, 1, 0, 1, 1}2

{0, 0, 1, 1, 1}3

{1, 1, 1, 1, 1, 1}6


목록을 0과 1의 문자열로 가져올 수 있습니까? 예를 들어 01100?
Adnan

@Adnan은 언어가 부울 목록을 나타내는 가장 일반적인 방법 인 경우에만 해당됩니다.
Adám

71
당신의 손실에 대해 죄송합니다.
Martin Ender

6
@MartinEnder 감사합니다. 앞으로는 힘들 것입니다. Dan은 Dyalog에서 일하기 위해 알아야 할 모든 것을 가르쳐주었습니다.
Adám

5
댄에게 작별. RIP ...
Outgolfer Erik

답변:


36

Dyalog APL, 6 2 바이트

⊥⍨

TryAPL에서 테스트하십시오 .

작동 원리

(uptack, 이항 : 디코드) 기반 변환을 수행한다. 왼쪽 피연산자가 벡터 인 경우 혼합 기준 변환을 수행 하므로이 작업에 적합합니다.

기본 벡터 b = b n , ⋯, b 0 및 숫자 벡터 a = a n , ⋯, a 0 , b ⊥ a의 경우 a 를 혼합 된 기본 b 로 변환 합니다 . 즉, b 0 ⋯ b n-1 a n + ⋯ + b 0 b 1 a 2 + b 0 a 1 + a 0 입니다.

이제 (물결표, 통근)은 다음과 같이 연산자를 왼쪽으로 수정합니다. 모나드 컨텍스트에서는 동일한 왼쪽 및 오른쪽 인수로 연산자를 호출합니다.

예를 들어, ⊥⍨ 로 정의 계산하는 0N + ⋯ + A 0 1 2 + A 0 1 + A 0 , 오른쪽에서 왼쪽으로 모든 제품의 누적 합 .

들어 K 후행 사람의 K 오른쪽 제품은 1 과 다른 모든는 0 자신의 합계가 동일하므로, 케이 .


14
힌트 : Dan은 2 바이트만으로 작업을 수행했습니다.
Adám

3
혼합 기본 변환! 영리 해요
Dennis

1
오. 혼합 된 기본 전환, 다시 발생
코너 O'Brien

브라보! 사실, 단 있기 때문에, 우리는 특수 맡았다 b⊥b⊥⍨b무한 속도 향상에 포기.
Adám

19

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

f=l=>l.pop()?f(l)+1:0

테스트 사례


어떻게 작동합니까? f(l)+1값을 어떻게 반환 > 2합니까?
Oliver

@Oliver 이것은 재귀 프로세스로 평가됩니다 l.pop()?(l.pop()?(l.pop()?(...etc...)+1:0)+1:0)+1:0.
Arnauld

내가 참조. 설명 주셔서 감사합니다.
Oliver

11

젤리 , 4 바이트

ŒrṪP

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오.

목록이 비어있는 경우, 몇 가지 흥미로운 관찰이 있습니다. 먼저 빈 목록을 실행 길이 인코딩하면 []다른 빈 목록이 반환됩니다 []. 그런 다음 run-length 인코딩 배열의 일반 요소 인 tail 대신 tail return 을 사용하여 마지막 요소를 검색합니다 . 그런 다음 제품 이 호출 되면 예상 결과 인 제품이 반환 됩니다 .0[value, count]P00

설명

ŒrṪP  Main link. Input: list M
Œr    Run-length encode
  Ṫ   Tail, get the last value
   P  Product, multiply the values together

또는 ŒgṪS작동합니다!
Lynn

그것은 빈 목록에 대한 올바른 출력을 입력으로 제공하지만 해부에 대해 놀랐습니다. 그 특별한 경우를 살펴 보시겠습니까?
피터 테일러

@PeterTaylor 나는 그것이 효과가 있다는 것에 놀랐습니다. 또한 첫 번째 링크에 잘못된 코드가 있음을 알았습니다.
마일

Jelly의 @PeterTaylor 는 다음과 같이 구현됩니다 lambda z: iterable(z).pop() if iterable(z) else 0. iterable목록에서 호출되면 목록을 반환하고 빈 목록은 물론 거짓입니다.
FryAmTheEggman



10

하스켈, 26 25 바이트

a%b|b=1+a|0<3=0
foldl(%)0

용법:

Prelude> foldl(%)0 [True,False,True,True]
2

포인트 프리 버전 (26 바이트) :

length.fst.span id.reverse

부울 목록 대신 정수 목록 사용 (Christian Sievers 덕분에 21 바이트) :

a%b=b*(a+1)
foldl(%)0

용법:

Prelude> foldl(%)0 [1,0,1,1]
2

포인트 프리 버전 (25 바이트)

sum.fst.span(==1).reverse

정수 목록의 경우 foldl아이디어가 작동합니다a%b=b*(a+1)
Christian Sievers

9

망막 , 7 5 바이트

r`1\G

온라인으로 사용해보십시오! 첫 번째 줄은 줄 바꿈으로 구분 된 테스트 스위트를 활성화합니다.

Retina의 입력 형식을 정의하는 것이 완전히 모호한 것은 아닙니다. Retina는 문자열을 제외한 모든 유형의 개념이 없으며 (일반적으로 진실과 거짓에 대한 일반적인 정의에 사용할 수있는 값도 없음), 나는 일반적 으로 진실과 허위에 대응하기 위해 01(또는 일반적으로 긍정적 인 것을) 사용합니다. 각각 0 또는 일부 일치합니다.

단일 문자 표현을 사용하면 목록에 대한 구분 기호도 필요하지 않습니다 (어떻게하면 문자열 만있는 언어에 대해 더 자연스러운 목록 표현 임). Adám 은 입력 가능한 형식 임을 확인했습니다 .

정규 표현식 자체 r는 오른쪽에서 왼쪽으로 \G일치하고 각 일치를 이전과 일치시킵니다. 따라서 이것은 1문자열의 끝에서 몇 개의 s를 일치시킬 수 있는지 계산합니다 .


"예, Retina의 경우 문자열 만 처리한다는 점에서"01 "또는"FT "문자열이
올바른

9

05AB1E , 12 10 6 5 바이트

carusocomputing 덕분에 1 바이트가 절약되었습니다 .

Î0¡¤g

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

설명

Î      # push 0 and input
 0¡    # split on 0
   ¤   # take last item in list
    g  # get length

0¡¤g4 바이트입니다.
매직 문어 Urn

@ carusocomputing : 좋은! 이 글을 쓸 때 문자열 입력에 문제가 없는지 아직 명확하지 않았지만 이제는 다음과 같습니다.
Emigna

J0¡¤g여전히 짧습니다;).
매직 문어 Urn

@carusocomputing : 불행히도 Î빈 입력을 처리 해야 하지만, 여전히 바이트 절약 덕분에 :)
Emigna




7

Mathematica, 25 24 바이트

Fold[If[#2,#+1,0]&,0,#]&

3
Dan의 멋진 혼합 기반 솔루션 포트 FromDigits[b=Boole@#,MixedRadix@b]&(35 바이트) 만 기록하면 됩니다.
Greg Martin


5

C90 (gcc), 46 바이트

r;main(c,v)int**v;{while(0<--c&*v[c])r++;c=r;}

입력은 명령 행 인수 (인수 당 하나의 정수)를 통해 종료 코드 를 통해 출력됩니다 .

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

작동 원리

r 은 전역 변수입니다. 유형은 기본적으로 int 이며 전역 인 경우 기본값은 0 입니다.

함수 인수 c의 기본값은 int 입니다. n 개의 부울 배열에 대해 정수 n + 1 을 유지합니다 . main 의 첫 번째 인수 는 항상 실행 파일의 경로입니다.

함수 인수 v 는로 선언됩니다 int**. 의 실제의 형태 V가 될 것입니다 char**,하지만 우리는 문자 만 말해 각 인수의 최하위 비트 검사 것이기 때문에 0 (코드 포인트 48 )과 1 (코드 포인트 49 ) 떨어져,이 작은 엔디안에 문제가되지 않습니다 기계.

while 루프 는 c를 감소 시키고 0 과 비교합니다 . 일단 C가 도달 0을 , 우리는 루프의 탈옥 수 있습니다. 배열에 0 이없는 경우에만 필요합니다 .

10<--c반환 하는 한 c 번째 명령 줄 인수 ( )를 가져 와서 포인터 ( )를 역 참조하여 첫 문자를 추출합니다 . 우리는 비트 AND 부울의 수행 조건이 돌아 있도록하고, 문자 (과 그 뒤에 이어지는 세 개의 쓰레기 바이트)의 코드 포인트를 00가 발생 루프에서 파괴.v[c]*0<--c

명령 라인 인자 인 반면, 나머지 경우에, 1 , r++증분 연구를 하여 1 이렇게 후행의 수를 세고, 1 '을들.

마지막 c=r의 계산 된 값을 저장 RC를 . 기본 설정으로 컴파일러는 할당을 최적화하고 제거합니다. 실제로 movl %eax, -4(%rbp)명령을 생성합니다 . retEAX 레지스터의 값을 반환 하므로 원하는 출력을 생성합니다.

이 코드는 않습니다 하지 반환 C99, 작업을 0 에서 주요 의 끝 경우 주가 에 도달한다.


밤은 argc적어도 1(와 argv[0]파일 이름을 포함)? --c&&대신에 1 바이트를 저장할 수 0<--c&있습니다. gcc´s 종료 코드는 argc? 산뜻한.
Titus

@Titus 작동하지 않습니다. *v[c]코드 포인트는 1 또는 0 이므로 49 또는 48 이므로 항상 진실합니다.
Dennis

C89와 C90에서 gcc는 그 순간 RAX에있는 모든 것을 반환합니다. 끝에 도달하면 C99는 항상 main에서 0 을 반환합니다 .
Dennis

4

k, 6 바이트

+/&\|:

이 함수 구성 은 언어의 가독성이 높은 형제 인 sum mins reversein로 번역되며 q, 여기서 min은 최소 롤링입니다.


를 떨어 뜨릴 수 있습니까?
streetster

4

J, 9 3 바이트

#.~

이것은 반사 혼합 기본 변환입니다. 이것은 혼합 기본 변환과 동일하기 때문입니다. 다시.

테스트 사례

   v =: #.~
   ]t =: '';0;1;0 1 1 0 0;1 1 1 0 1;1 1 0 1 1;0 0 1 1 1;1 1 1 1 1 1
++-+-+---------+---------+---------+---------+-----------+
||0|1|0 1 1 0 0|1 1 1 0 1|1 1 0 1 1|0 0 1 1 1|1 1 1 1 1 1|
++-+-+---------+---------+---------+---------+-----------+
   v&.> t
+-+-+-+-+-+-+-+-+
|0|0|1|0|1|2|3|6|
+-+-+-+-+-+-+-+-+
   (,. v&.>) t
+-----------+-+
|           |0|
+-----------+-+
|0          |0|
+-----------+-+
|1          |1|
+-----------+-+
|0 1 1 0 0  |0|
+-----------+-+
|1 1 1 0 1  |1|
+-----------+-+
|1 1 0 1 1  |2|
+-----------+-+
|0 0 1 1 1  |3|
+-----------+-+
|1 1 1 1 1 1|6|
+-----------+-+

2
힌트 : Dan 솔루션의 J 변환을 사용하여 3 바이트 만 수행 할 수 있습니다.
Adám

1
@ Adám 나는 해결책을 찾으려고 노력했다. 기본 전환을 생각하지 않았습니다. 정말 영리합니다!
코너 O'Brien

1
예. 댄이었다. :-(
Adám

4

R, 40 39 25 바이트

@Dason 덕분에 완전히 재 작업 된 솔루션

sum(cumprod(rev(scan())))

stdin에서 입력을 읽고 벡터를 뒤집은 !=0다음 의 첫 번째 요소가 실행 길이 인코딩의 첫 번째 길이 ( rle)이면 출력합니다 0.


1
두 번째 줄을로 변경하여 바이트를 저장할 수 있습니다 ifelse(r$v,r$l,0)[1]. (if 경우 벡터화 한 다음 첫 번째 요소를 가져옵니다.)
rturnbull

1
iflelse가 필요하지 않습니다-r $ v와 r $ l을 곱하십시오.
Dason

그러나 sum (cumprod (rev (.))) 경로는 어쨌든 많은 바이트를 절약해야합니다
Dason

3

하스켈, 24 바이트

foldl(\a b->sum[a+1|b])0

목록을 반복하여 각 요소에 하나씩 추가하고 a에 도달 한 0후 재설정 합니다 False.

0/1 입력의 16 바이트 :

foldl((*).(+1))0

목록이 비어 있지 않다면 14 바이트를 얻을 수 있습니다.

sum.scanr1(*)1

이것은 뒤에서 누적 곱을 계산 한 다음 합산합니다. 누적 곱은 0에 도달 할 때까지 1을 유지 한 다음 0이됩니다. 따라서 1은 후행 1에 해당합니다.



3

C # 6, 103 72 바이트

using System.Linq;
int a(bool[] l)=>l.Reverse().TakeWhile(x=>x).Count();

제네릭이 아닌 목록을 사용하면 일반 목록이 1 바이트 LOL이기는

Scott 덕분에 -31 바이트


ints 배열을 사용하면 다음 과 같이 벗어날 수 있습니다.int a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum();
Scott

@Scott 물론 내가 무슨 생각을했는지 ... 나는 바보를 고수 할 것이다. 질문은 부울 목록을 지정하지만 C가 아닙니다.
Link Ng

Func<bool[], int>57 바이트를위한 컴파일using System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count();
TheLethalCoder

2

파이썬, 37 바이트

f=lambda l:len(l)and-~f(l[:-1])*l[-1]

2

대시 , 16 바이트

@len mstr"1+$"#0

가능한 가장 짧은 DASH 솔루션은 아니지만 가능한 가장 짧은 DASH 솔루션이 나에게 버그가 있습니다. 나는이 새로운 접근법을 그 자리에 게시하고있다.

용법:

(@len mstr"1+$"#0)"100111"

설명

@(                 #. Lambda
  len (            #. Get the length of the array after...
    mstr "1+$" #0  #. ... matching the argument with regex /1+$/
  )                #. * mstr returns an empty array for no matches
)

2

스칼라, 25 바이트

l=>l.reverse:+0 indexOf 0

언 골프 드 :

l=>(l.reverse :+ 0).indexOf(0)

목록을 뒤집고 0을 추가하고 첫 번째 인덱스 0을 찾습니다. 첫 번째 인덱스 0 앞에있는 요소 수입니다


2

배치, 57 바이트

@set n=0
@for %%n in (%*)do @set/an=n*%%n+%%n
@echo %n%

입력을 명령 행 매개 변수로 사용합니다. 추가하기 전에 누산기에 현재 값을 곱하여 작동하므로 명령 줄의 0이 카운트를 재설정합니다. 그 주 %%n과 동일하지 않습니다 n또는 %n%변수입니다.



2

자바 7, 62 바이트

int c(boolean[]a){int r=0;for(boolean b:a)r=b?r+1:0;return r;}

언 골프 및 테스트 코드 :

여기에서 시도하십시오.

class M{
  static int c(boolean[] a){
    int r = 0;
    for (boolean b : a){
      r = b ? r+1 : 0;
    }
    return r;
  }

  public static void main(String[] a){
    System.out.print(c(new boolean[]{}) + ", ");
    System.out.print(c(new boolean[]{ false }) + ", ");
    System.out.print(c(new boolean[]{ true }) + ", ");
    System.out.print(c(new boolean[]{ false, true, true, false, false }) + ", ");
    System.out.print(c(new boolean[]{ true, true, true, false, true }) + ", ");
    System.out.print(c(new boolean[]{ true, true, false, true, true }) + ", ");
    System.out.print(c(new boolean[]{ false, false, true, true, true }) + ", ");
    System.out.print(c(new boolean[]{ true, true, true, true, true, true }));
  }
}

산출:

0, 0, 1, 0, 1, 2, 3, 6

2

펄 5.10, 22 바이트

-a플래그의 경우 21 바이트 + 1 바이트 정규 표현식 기반 표현식이 완료된 후 ... : p

배열의 입력 값은 공백으로 구분해야합니다.

$n++while pop@F;say$n

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


1
약간 당신은 커맨드 라인을 통해 인수를 짧은 경우 : perl -E '$_++while pop;say' 0 1 1 0 1 1 1하지만이에 아무것도 출력하지 않습니다 0(즉, 문제가 있지만 있는지 확실하지를!)
돔 헤이스팅스

2

펄, 22 바이트

21 바이트의 코드 + 1 바이트의 -p플래그

s/.(?=.*0)//g;$_=y;1;

그것을 실행하려면 :

perl -pE 's/.(?=.*0)//g;$_=y;1;' <<< "0 1 1 0 1 1 1"

(사실, 입력의 형식이 많이 중요하지 않습니다 : 0110111, 0 1 1 0 1 1 1, [0,1,1,0,1,1,1]등을하는 모든 작업)


18 바이트 버전 에서 @Dom 스팅 하지만 허용되지 않은 0과 1의 문자열로 입력을 제공 할 필요

perl -pE '/1*$/;$_=length$&' <<< '0110111'

;트릭을 사랑 :) 형식이 하나의 연속 문자열 인 경우 : perl -pE '/1*$/;$_=length$&' <<< '0110111'18, 그것이 규칙을 구부릴 지 여부는 확실하지 않습니다 ...
Dom Hastings

@DomHastings 그래, 나도! 질문에 대한 첫 번째 의견과 두 번째 의견은 솔루션에 필요한 입력 형식을 허용하지 않습니다 ...하지만 입력 형식이 더 많은 경우 내 게시물을 편집하여 버전을 제안합니다. 비어 있는.
Dada

2

PHP, 50 바이트

<?=strlen(preg_filter('/.*[^1]/','',join($argv)));

이상하게도 정규 표현식을 사용한 첫 번째 시도는 배열을 사용한 시도보다 짧았습니다
.

php tt.php 1 1 0 1 1

2

루비 37 32 바이트

->n{n.size-1-(n.rindex(!0)||-1)}

가장 오른쪽에있는 false 값 인스턴스를 찾고 해당 값에서 시작하는 하위 배열의 크기를 계산하는 익명 함수를 만듭니다.

!0루비에서는 0이 참 값이므로 거짓으로 사용합니다 . rindex배열에서 값의 마지막 인덱스를 찾습니다.

사용법 :

boolean_list = [true, false, false, true]
->n{n.size-1-(n.rindex(!0)||-1)}[boolean_list]

1을 반환


루비가 부울 목록을 나타내는 방식이 아닌 명령 줄 매개 변수로 0과 1의 문자열을 전달할 수 있다면 24로 줄일 수 있습니다.

$*[0]=~/(1*)\z/;p$1.size

정규 표현식을 사용하고 정규 표현식에서 리턴 한 문자열의 길이를 인쇄합니다 /(1*)\z/. 여기서 \z문자열의 끝입니다. $*[0]전달 된 첫 번째 인수이며 0과 1의 문자열입니다.

용법:

trailing_truths.rb 011101

1을 반환합니다.


1
마지막 false 값의 인덱스가 있으면 왜 배열에서 요소를 다시 검색해야합니까?
Lee W

당신 말이 맞아요 감사. 5 바이트 할인!
IMP1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.