목록에서 True 값의 범위 찾기


26

도전:

부울 값 목록을 승인하고 True의 모든 범위를 리턴하는 함수 또는 프로그램을 작성하십시오.

테스트 사례 :

f [F]                               = []
f [T]                               = [[0,0]]
f [T,T,F,T]                         = [[0,1],[3,3]]
f [F,T,T,F,F,T,T,T]                 = [[1,2],[5,7]]
f [F,T,T,F,F,F,T,T,T,T]             = [[1,2],[6,9]]
f [T,T,F,F,F,T,T,T,T,T,T,T,T,T,T,F] = [[0,1],[5,14]]
f [F,F,T,T,F,F,F,F,F,F,F,F,T,T,T,T,T,T,T,T,F,F,F,F,F,F,F,F,F,F,F,F,F,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,T,T] = [[2,3],[12,19],[33,54],[93,94]]

규칙 :

  • 목록, 배열, 문자열 등과 같이 입력 인코딩 방식을 선택할 수 있습니다.
  • 출력은 목록과 같은 목록과 같은 문자열 또는 그와 같은 문자열, 따라서 배열, 목록, 튜플, 행렬, 벡터 등으로 인코딩되어야합니다.
  • 부울 값은 상수로 인코딩해야하지만 T / F를 원하는 상수로 간단하게 변환 할 수 있습니다.
  • 편집 : 런타임 IS 동안 eval 또는 이와 유사합니다.
  • 입력이 프로그램 / 기능에 전달되는 방법을 설명하고 테스트 케이스에 대한 입력 / 출력을 제공하는 것을 잊지 마십시오.
  • 계산되지 않은 원하는 입력 형식으로 변환
  • 표준 허점은 허용되지 않습니다
  • 귀하의 언어가이를 수행 할 수있는 기능을 가지고 있다면
  • 나는 내 자신의 제출을 ​​수락하지 않습니다
  • 편집 : 출력 형식이 유연합니다. 목록 또는 이와 유사한 것을 인쇄하지 않는 경우 범위 값은 숫자가 아닌 문자 하나와 별도의 범위로 구분해야합니다.

채점 :

  • 언어에 맞지 않는 한 점수는 바이트 단위입니다 (예 : Piet의 코덱).
  • 최저 점수 승

입력 및 출력에는 약간의 유연성이 있지만 T / F가 모든 작업을 수행하는 기능으로 대체되는 솔루션은 허용되지 않습니다.

디버깅 :

Haskell로 작성하거나 Haskell에서 호출 할 수있는 경우 다음이 기능 / 프로그램을 확인합니다.

import Test.QuickCheck

tf = cycle [True,False]
gen l = foldl (++) [] $ map (\i -> [tf!!i | x<-[1..i]]) l
putIn (a,b) l = zipWith (||) l [(a <= p) && (p <= b) | p <- [0..length l]]
putAllIn rs len = foldr putIn [False|i<-[1..len]] rs
main = print $ quickCheck (check functionNameGoesHere)

1
뭔가 빠졌을 수도 있지만 출력에서 ​​범위가 어떻게 표현되는지에 대한 설명을 볼 수 없습니다.
피터 테일러

1
출력을 1- 인덱싱 할 수 있습니까?
LegionMammal978

범위가 반 독점적 일 수 있습니까?
lirtosiast

1
@ LegionMammal978 언어 기본값이 1- 인덱스 인 경우에만 (예 : Mathematica
Michael Klein

@ThomasKwa Nope, "가장자리"의 경우에는 너무 다른 것 같습니다
Michael Klein

답변:


7

Pyth, 17 16 바이트

fT.b*Y,~+ZNtZrQ8

실행 길이 인코딩과 함께 멋진 할당 후 카운터 매직을 사용합니다.

입력을 0s 및 1s 의 배열로 가져옵니다 ( 예 :) [1, 1, 0, 1, 0]. 챌린지와 같은 결과, 예 : [[0, 1], [3, 3]].

테스트 스위트


테스트 스위트를 추가했습니다. 편집이 승인되었고 아무도 스니핑하지 않으면 유효한 답변이 가장 짧습니다.
Michael Klein


7

망막 , 82 34 27 바이트

\b(?<=(.)*_?)
$#1
_+

S_`:

빈 줄은 단일 공백을 포함해야합니다.

입력은 _true 및 :false 의 플랫 문자열입니다 . 출력은 공백으로 구분 된 쌍이며 각각 별도의 줄에 있습니다.

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

설명

82 바이트에서 27 바이트까지의 헤비 골프는 참과 거짓의 표현을 영리하게 선택함으로써 가능했습니다. 나는 _true로 단어 문자 :( 숫자가 아님)와 false로 단어가 아닌 문자 (이스케이프 할 필요가 없음)를 선택했습니다. 이를 통해 범위의 끝을 단어 경계로 감지 할 수 있습니다.

\b(?<=(.)*_?)
$#1

단어 경계와 일치합니다. 우리는 그 경계를 진실 가치의 해당 지수로 대체하고 싶습니다. 원칙적으로 Retina의 최근 $#기능으로는 그룹의 캡처 수를 계산 하는 것이 매우 쉽습니다 . 해당 위치 앞에있는 각 캐릭터를 그룹으로 간단히 캡처합니다. 그 문자들을 세어 우리는 위치를 얻는다. 유일한 발견은 이제 범위의 끝이 하나 떨어져 있다는 것입니다. 우리는 실제로 문자의 인덱스를 원하는 앞에서 경기. 또한 _캡처되지 않은 a 를 선택적으로 일치시켜 쉽게 해결할 수 있으므로 범위의 끝에있을 때 한 문자를 건너 뜁니다.

_+
<space>

이제 모든 밑줄을 공백으로 바꿉니다. 즉, 밑줄을 제거하면서 각 범위의 시작과 끝 사이에 공백을 삽입합니다.

S_`:

콜론이 남습니다 (그리고 여전히 쌍을 분리해야합니다). 우리는 전체 문자열을 각 콜론 주위에 줄로 나눠서 그렇게합니다. S활성 모드를 분할하고, _우리는 콜론의 실행이있을 때 빈 줄의 톤을하지 않는 억압 빈 세그먼트 등.


5

파이썬 2, 69 바이트

p=i=0
for x in input()+[0]:
 if x-p:b=x<p;print`i-b`+';'*b,
 p=x;i+=1

출력 예 :

2 3; 7 16; 18 18;

직접 접근하지 않고 내장되어 있지 않습니다. 현재 값 x과 이전 값을 추적합니다 p. 이것들이 다를 때, 우리는 달리기를 바꿨습니다. 전환에 01, 현재의 인덱스를 출력한다 i. 전환에 10세미콜론 다음에 현재의 인덱스를 뺀 출력한다.

if꽤 냄새입니다. 아마도 재귀가 더 좋을 것입니다.


5

MATL , 17 18 20 바이트

j'T+'1X32X34$2#XX

사용 최신 버전 (9.1.0) 언어 / 컴파일러를.

입력은 문자 T및을 포함하는 문자열 F입니다. 출력은 2 행 테이블이며, 각 열은 언어 기본값 인 1- 인덱싱을 사용하여 범위를 나타냅니다.

2 바이트를 제거해 주신 Stewie Griffin 에게 감사드립니다 .

>> matl
 > j'T+'1X32X34$2#XX
 >
> FTTFFFTTTT
2 7
3 10

설명

간단한 정규식을 기반으로합니다.

j         % input string
'T+'      % regular expression: match one or more `T` in a row
1X3       % predefined string literal: 'start'
2X3       % predefined string literal: 'end'
4$2#XX    % regexp with 4 inputs (all the above) and 2 outputs (start and end indices)
          % implicitly display start and end indices

4

옥타브, 43 바이트

@(x)reshape(find(diff([0,x,0])),2,[])-[1;2]

find(diff([0,x,0]))입력 배열이 true와 false 사이에서 변경되는 모든 위치를 찾습니다. 이것을 2xn 행렬로 재구성함으로써 우리는 두 가지를 달성합니다. 참에서 거짓으로, 그리고 거짓에서 참으로의 변화는 두 개의 행으로 나뉩니다. 이를 통해 각 행에서 1과 2를 뺄 수 있습니다. 옥타브는 0이 아닌 1- 인덱스이므로 1 행에서 1을 빼야합니다. 두 번째 행에서 2를 빼 find(diff())려면 첫 번째 거짓 값의 위치를 ​​찾고 마지막은 참 값을 원 하기 때문에 필요 합니다. 빼기 부분은 MATLAB이 아닌 옥타브에서만 가능합니다.

F=0;T=1;
x=[F,F,T,T,F,F,F,F,F,F,F,F,T,T,T,T,T,T,T,T,F,F,F,F,F,F,F,F,F,F,F,F,F,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,T,T]

reshape(find(diff([0,x,0])),2,[])-[1;2]
ans =    
    2   12   33   93
    3   19   54   94

x=[T,T,F,F,F,T,T,T,T,T,T,T,T,T,T,F]
reshape(find(diff([0,x,0])),2,[])-[1;2]
ans =    
    0    5
    1   14

1
방송의 좋은 사용!
Luis Mendo

4

CJam, 27 25 바이트

0qe`{~~{+}{1$+:X(]pX}?}/;

과 같은 입력이 필요 TTFTFT합니다. 온라인으로 사용해보십시오 .

설명

0                               Push 0, to kick off index
qe`                             Push input and run length encode
                                e.g. FFFFTTTFT -> [[4 'F] [3 'T] [1 'F] [1 'T]]
{                 }/            For each pair in the RLE...
 ~                                Unwrap the pair
  ~                               Evaluate T -> 0 (falsy), F -> 15 (truthy)
   { }{         }?                 Ternary based on T/F
    +                                If 'F: add count to index
       1$+:X(]pX                     If 'T: output inclusive range, updating index
;                               Discard the remaining index at the top of the stack

4

apt, 34 31 25 바이트

이번에는 새로운 접근법을 시도해 보았습니다.

V=[]Ur"T+"@Vp[YY-1+Xl]};V

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

입력은 Ffor falseTfor 문자열 입니다 true. 출력은 배열의 배열입니다. 문자열 표현은 단일 배열처럼 보입니다.

작동 원리

          // Implicit: U = input string
V=[]      // Set V to an empty array. (Why don't I have a variable pre-defined to this? :P)
Ur"T+"    // Take each group of one or more "T"s in the input,
@         // and map each matched string X and its index Y to:
Vp[       //  Push the following to an array in V:
Y         //   Y,
Y-1+Xl    //   Y - 1 + X.length.
]};       //  This pushes the inclusive start and end of the string to V.
V         // Implicit: output last expression

참고 : 이제 여러 사람들이 이미이 알고리즘을 생각해 냈지만 독립적으로 발견했습니다.

비경쟁 버전, 22 바이트

;Ur"T+"@Ap[YY-1+Xl]};A

에서 GitHub에 커밋 최신 선도적 : 나는 새로운 기능을 추가 한 ;세트 변수에 A-J,L다른 값을. A빈 배열로 설정되어 있으므로 수동으로 만들 필요가 없습니다.


3

하스켈, 74 바이트

import Data.Lists
map(\l->(fst$l!!0,fst$last l)).wordsBy(not.snd).zip[0..]

사용 예 : map(\l->(fst$l!!0,fst$last l)).wordsBy(not.snd).zip[0..] $ [True,False,True,True,False]-> [(0,0),(2,3)].

작동 방식 :

                               -- example input: [True,False,True,True,False]

zip[0..]                       -- pair each element of the input with it's index
                               -- -> [(0,True),(1,False),(2,True),(3,True),(4,False)]
wordsBy(not.snd)               -- split at "False" values into a list of lists
                               -- -> [[(0,True)],[(2,True),(3,True)]]
map                            -- for every element of this list
   (\l->(fst$l!!0,fst$last l)) -- take the first element of the first pair and the
                               -- first element of the last pair
                               -- -> [(0,0),(2,3)]

3

J, 26 바이트

[:I.&.|:3(<`[/,]`>/)\0,,&0

이것은 2D 배열 또는 정수를 반환하는 명명되지 않은 monadic 동사 (단항 함수)입니다. 다음과 같이 사용됩니다.

  f =: [:I.&.|:3(<`[/,]`>/)\0,,&0
  f 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 0
0  1
5 14

설명

[:I.&.|:3(<`[/,]`>/)\0,,&0
                       ,&0  Append 0 to input
                     0,     then prepend 0.
        3(         )\       For each 3-element sublist (a b c):
               ]`>/           Compute b>c
          <`[/                Compute a<b
              ,               Concatenate them
                            Now we have a 2D array with 1's on left (right) column
                            indicating starts (ends) or 1-runs.
[:I.&.|:                    Transpose, get indices of 1's on each row, transpose back.

3

루비, 39

->s{s.scan(/T+/){p$`.size..s=~/.#$'$/}}

샘플 호출 :

2.2.3 :266 > f=->s{s.scan(/T+/){p$`.size..s=~/.#$'$/}}
 => #<Proc:0x007fe8c5b4a2e8@(irb):266 (lambda)> 
2.2.3 :267 > f["TTFTTFTTTFT"]
0..1
3..4
6..8
10..10

..루비가 포함 된 범위를 나타내는 방법이다.

여기서 흥미로운 점은 범위 끝의 인덱스를 얻는 방법입니다. 이상하다. 올바른 일치를 강제하기 위해 범위의 마지막 문자와 일치하는 정규 표현식을 동적으로 만들고 모든 후속 문자와 문자열 끝을 동적으로 만듭니다. 그런 다음 사용합니다=~ 정규 표현식의 색인을 원래 문자열로 가져옵니다.

Ruby에서 -naF 플래그를 사용하여이를 수행하는 더 짧은 방법이있을 수 있습니다.


2

자바 스크립트 (ES6), 59

익명 함수, 문자열로 입력 TF 하여 배열의 배열로 출력을 반환

x=>x.replace(/T+/g,(a,i)=>o.push([i,a.length+i-1]),o=[])&&o

테스트

f=x=>x.replace(/T+/g,(a,i)=>o.push([i,a.length+i-1]),o=[])&&o

// TEST

arrayOut=a=>`[${a.map(e=>e.map?arrayOut(e):e).join`,`}]`

console.log=x=>O.textContent+=x+'\n'

;[
  'F','T','TTFT','FTTFFTTT','FTTFFFTTTT','TTFFFTTTTTTTTTTF',
  'FFTTFFFFFFFFTTTTTTTTFFFFFFFFFFFFFTTTTTTTTTTTTTTTTTTTTTTFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFTT'
].forEach(t=>console.log(t+'\n'+arrayOut(f(t))+'\n'))
<pre id=O></pre>


와우, 방금 Japt에서 동일한 솔루션을 생각해 내고 JS로 번역하려고했습니다. 좋은 것 :)
ETHproductions

2

𝔼𝕊𝕄𝕚𝕟, 18 자 / 28 바이트

ïħ`T+`,↪ᵖ[_,$Ꝉ+‡_]

Try it here (Firefox only).

설명

ïħ`T+`,↪ᵖ[_,$Ꝉ+‡_] // implicit: ï=input
ïħ`T+`,            // for each T-sequence...
       ↪ᵖ[_,$Ꝉ+‡_] // push [start index of sequence, end index of sequence] to the stack
                   // implicit stack output

2

하스켈, 62 바이트

f l|s<-zip3[0..](0:l)$l++[0]=zip[i|(i,0,1)<-s][i-1|(i,1,0)<-s]

0과 1의 목록을 입력으로받습니다.

list가 주어지면 l양쪽에 0을 채우고 색인화 된 연속 쌍 목록을 계산합니다. 예를 들어

l = [1,1,0]
s = [(0,0,1),(1,1,1),(2,1,0),(3,0,0)]

이어서, 연속적인 요소에 대응하는 인덱스를 추출 (0,1)하고 (1,0)(1)의 단부를 얻을 0의 시작에서 1을 감산하는 0과 1의 블록의 시작이다, 그 결과를 참아.


와, 그것은 하스켈이 생각했던 것보다 구문을 더 많이 구부립니다. zip [i | (i, 0,1) <-s] [i-1 | (i의 "fl = let s = zip3 [0 ..] (0 : l) (l ++ [0])과 동일합니까? , 1,0) <-s] "?
Michael Klein

1
예 @MichaelKlein, 나는 경비에 바인딩의 트릭을 알게 여기 nimi에서 . 또한 더 긴 binding-via-lambda와 동일합니다 f l=(\s->zip[i|(i,0,1)<-s][i-1|(i,1,0)<-s])$zip3[0..](0:l)$l++[0].
xnor

2

Pyth, 19 18 바이트

m-VdU2cx1aV+ZQ+QZ2

설명:

             implicit: Q=input
m            map lambda d:
  -V         Vectorized subtraction by [0,1]
     d
     U2     
c            split every 2 elements
  x            find all indexes of
    1          1s
    aV         in vectorized xor:
       +ZQ     Q with a 0 on the front
       +QZ     Q with a 0 on the end
  2

여기에서 시도 하십시오 .


2

펄, 47 바이트

s/F*(T*)(T)F*/[$-[0],$+[1]],/g;chop$_;$_="[$_]"

다음과 같은 perlrun 옵션을 사용하십시오 -lpe.

$ perl -lpe's/F*(T*)(T)F*/[$-[0],$+[1]],/g;chop$_;$_="[$_]"' <<< 'TTFFFTTTTTTTTTTF'
[[0,1],[5,14]]

출력이 라인으로 구분되는 대안 (34 바이트) :

$ perl -pE's/F*(T*)(T)F*/$-[0] $+[1]\n/g;chomp' <<< TTFFFTTTTTTTTTTF
0 1
5 15

1

파이썬 2, 108 바이트

l=input();l+=[0];o=[];s=k=0
for i,j in enumerate(l):s=j*~k*i or s;~j*l[i-1]and o.append([s,i-1]);k=j
print o

테스트 사례 :

$ python2 rangesinlists2.py
[0]
[]
$ python2 rangesinlists2.py
[-1]
[[0, 0]]
$ python2 rangesinlists2.py
[-1,-1,0,-1]
[[0, 1], [3, 3]]
$ python2 rangesinlists2.py
[0,-1,-1,0,0,-1,-1,-1]
[[1, 2], [5, 7]]
$ python2 rangesinlists2.py
[0,-1,-1,0,0,0,-1,-1,-1,-1]
[[1, 2], [6, 9]]
$ python2 rangesinlists2.py
[-1,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0]
[[0, 1], [5, 14]]
$ python2 rangesinlists2.py
[0,0,-1,-1,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1]
[[2, 3], [12, 19], [33, 54], [93, 94]]

분명히 이것보다 짧은 해결책이 있지만 작동합니다.


1

Haskell : 123 바이트 (예 : 이길 수 없음)

f l=[(s,e)|let m=length l-1,let r=[0..m],s<-r,e<-r,and[l!!x|x<-[s..e]],s<=e,let(#)p=not$l!!p,s==0||(#)(s-1),e==m||(#)(e+1)]

덜 골프 :

f l = [(start,end) | start <- [0..max], end <- [0..max], allTrue start end, start <= end, notBelow start, notAbove end]
  where
    max = (length l) - 1
    allTrue s e = and (subList s e)
    subList s e = [l !! i | i <- [s,e]]
    notBelow  s = (s == 0) || (not (l !! (s-1)))
    notAbove  e = (s == m) || (not (l !! (e+1)))

골프를 치지 않을 때도 : allTrue s e = and (subList s e)또는 allTrue = (and.) . sublist.
nimi

좋아, 내가 기억하지 못하는 이유 때문에, 나는 골프를 풀 때 더 분명하다고 생각했다 ... (편집)
Michael Klein

1
분명한 의견에 대해서는 의견이 다릅니다. 나는 또한 all (==True) (subList s e)매우 분명 하다고 생각 합니다.
nimi


1

apt, 27 바이트

A=[];Ur"T+"@Ap[YXl +´Y]};A·

골프를 치는 방법이 있어야합니다 ...

어쨌든, 그것은 나의 𝔼𝕊𝕄𝕚𝕟 답변과 동일합니다.


와우, 방금이 솔루션을 생각해 냈습니다 .... 멋진 알고리즘!
ETHproductions

1

APL, 17 자

{(↑,↑∘⊖)¨⍵⊂⍵×⍳⍴⍵}

에서 ⎕IO←0⎕ML←3. 영어로:

  • ⍵×⍳⍴⍵: 인수가 false 인 인수 인 경우 인덱스 벡터의 요소를 0으로 만듭니다.
  • ⍵⊂: 각 진리의 시작 부분을 자르고 거짓을 버립니다.
  • (↑,↑∘⊖)¨: 각 하위 배열의 첫 번째 요소와 마지막 요소를 가져옵니다.

0

PowerShell, 82 바이트

("$args"|sls 't+'-A).Matches|%{if($_){'{0},{1}'-f$_.Index,($_.Index+$_.Length-1)}}

다음을 사용하는 정규식 솔루션 MatchInfo를 객체의 속성을 .

PS > .\BoolRange.ps1 'F'


PS > .\BoolRange.ps1 'T'
0,0

PS > .\BoolRange.ps1 'TTFFFTTTTTTTTTTF'
0,1
5,14

0

Mathematica, 45 바이트

SequencePosition[#,{True..},Overlaps->False]&

특별히 흥미롭지 않은; 내장을 사용합니다.


0

클로저, 109 자

#(first(reduce(fn[[r i]p](let[e(+(count p)i)][(if(first p)(conj r[i(dec e)])r)e]))[[]0](partition-by not %)))

내 생각에 가장 먼저 온 것은 reduce 하고 partition-by.

간단한 테스트 케이스 (매핑 TtrueFfalse) :

(def f #(first(reduce(fn[[r i]p](let[e(+(count p)i)][(if(first p)(conj r[i(dec e)])r)e]))[[]0](partition-by not %))))
(f (map #(= 'T %) '[F,T,T,F,F,T,T,T]))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.