Bir listede Gerçek değer aralıklarını bulun


26

Meydan okuma:

Boole değerlerinin listesini kabul eden ve True'in tüm aralıklarını döndüren bir işlev veya program yazın.

Test Durumları:

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

Kurallar:

  • Girişin nasıl kodlanacağını seçebilirsiniz, örneğin bir liste, dizi, dize vb.
  • Çıktı, liste benzerlerine benzer bir liste veya böyle bir diziyi, listeyi, ipucunu, matrisi, vektörü, vb. Gösteren bir dize olarak kodlanmalıdır.
  • Boole değerleri sabit olarak kodlanmalıdır, ancak aksi takdirde T / F'nin istenen sabitlere basit bir şekilde dönüştürülmesine izin verilir
  • EDIT: çalışma zamanı IS izin verilirken eval veya benzeri.
  • Girdilerin programa / işleve nasıl iletildiğini açıklamayı ve test durumlarında girdi / çıktı vermeyi unutmayınız.
  • İstenilen giriş formatına dönüşüm sayılmaz
  • Standart boşluklara izin verilmez
  • Dilinizin bunu yapacak bir işlevi varsa, buna izin verilmez.
  • Kendi gönderimi kabul etmeyeceğim
  • EDIT: Çıkış formatı esnektir. Liste veya benzeri bir şey yazdırılmıyorsa, aralık değerleri sayısal olmayan bir karakterle ve ayrı aralıklarla ayrılmalıdır.

puanlama:

  • Dilinize uygun olmadığı sürece puan bayt cinsindendir (Piet'deki kodlayıcılar gibi)
  • En düşük puan kazanır

Girdi ve çıktıda bir miktar esneklik var, ancak T / F'nin yerine tüm işleri yapan işlevlerle değiştirilen çözümlere izin verilmiyor.

Hata ayıklama:

Sizinkini Haskell'e yazarsanız veya Haskell'den arayabilirseniz, işlevinizi / programınızı kontrol eder:

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
Bir şey eksik olabilir, ancak bir aralığın çıktıda nasıl temsil edildiğinin bir tanımını göremiyorum.
Peter Taylor

1
Çıktı 1 dizinli olabilir mi?
LegionMammal978

Aralıklar yarı münhasır olabilir mi?
lirtosiast

1
@ LegionMammal978 Yalnızca dil varsayılanınız 1 dizinli ise, örneğin Mathematica
Michael Klein

@ThomasKwa Hayır, "kenar" durumlar için çok farklı görünüyor
Michael Klein

Yanıtlar:


7

Pyth, 17 16 bayt

fT.b*Y,~+ZNtZrQ8

Çalışma uzunluğu kodlamasıyla birlikte bazı atama sonrası sayaç büyülerini kullanır.

Girdiyi 0s ve 1s dizisi olarak alır , örn [1, 1, 0, 1, 0]. Mücadelede olduğu gibi çıktılar, örn [[0, 1], [3, 3]].

Test odası


Bir test paketi ekledim. Düzenleme onaylanırsa ve kimse kaçırmazsa, en kısa geçerli cevaba sahipsiniz.
Michael Klein,


7

Retina , 82 34 27 bayt

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

S_`:

Boş satır, tek bir boşluk içermelidir.

Giriş, _doğru ve :yanlış için düz bir dizedir . Çıktı, her biri ayrı bir satırda boşlukla ayrılmış çiftlerdir.

Çevrimiçi deneyin.

açıklama

82'den 27 bayta kadar olan ağır golf, doğru ve yanlışın temsilini akıllıca seçerek mümkündü. Bir kelime karakteri, _(bu bir rakam değil) doğru ve kelime dışı bir karakter :, (kaçmak gerekmeyen) false için seçtim. Bu, aralıkların sonlarını sözcük sınırları olarak algılamama izin veriyor.

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

Bir kelime sınırını eşleştiriyoruz. Bu sınırı, truthy değerinin karşılık gelen indeksi ile değiştirmek istiyoruz. Prensip olarak, Retina'nın $#bir grup yakalama sayısını sayan son özelliği ile oldukça kolaydır . Bu pozisyonun önündeki her karakteri bir gruba çekiyoruz. Bu karakterleri sayarak pozisyon alıyoruz. Tek yakalamak, menzilin uçlarının şimdi birer birer kesilmesidir. Aslında karakterin indeksini maçın önünde istiyoruz . Bu, isteğe bağlı olarak _, yakalanmayan birini eşleştirerek kolayca sabitlenir , böylece bir aralığın sonunda olduğumuzda bir karakteri atlar.

_+
<space>

Şimdi tüm alt çizgi dizilerini bir boşlukla değiştiriyoruz. Yani, alt çizgilerden kurtulurken, her aralığın başlangıcı ile bitişi arasına bir boşluk koyarız.

S_`:

Bu, kolonları bırakır (ve hala çiftleri ayırmamız gerekir). Bunu, tüm dizgiyi her iki kolonun etrafındaki çizgilere bölerek yapıyoruz. SEtkinler bölünmüş moda ve _biz kolonların ishal olduğunda boş satırları ton alamadım bastırır boş kesimi gibi.


5

Python 2,69 bayt

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

Örnek çıktı:

2 3; 7 16; 18 18;

Direkt bir yaklaşım, yerleşik değil. Geçerli değeri xve önceki değeri izler p. Bunlar farklı olduğunda, koşuları değiştirdik. Anahtarlama günü 0için 1geçerli dizini yazdırır i. Anahtarlama günü 1için 0, bir noktalı virgül ardından akım endeksi eksi birini yazdırır.

ifOldukça kötü kokulu olduğunu. Belki özyineleme daha iyi olurdu,


5

MATL , 17 18 20 bayt

j'T+'1X32X34$2#XX

Dilin / derleyicinin geçerli sürümünü (9.1.0) kullanır .

Giriş, karakterleri içeren bir dizedir Tve F. Çıktı, iki satırlı bir tablodur; burada her sütun, varsayılan dil olan 1 indekslemeyi kullanan bir aralığı belirtir.

Stewie Griffin'e 2 byte'ı ayırdığı için teşekkürler .

Örnek

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

açıklama

Basit bir düzenli ifadeye dayanır:

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

Oktav, 43 Bayt

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

find(diff([0,x,0]))giriş dizisinin true ve false arasında değiştiği tüm konumları bulur. Bunu 2'ye 2'lik bir matris haline getirerek iki şeyi başarırız: Doğrudan yanlışa ve yanlışdan doğruya değişiklikler iki satıra bölünür. Bu, bu sıraların her birinden 1 ve 2'yi çıkarmayı mümkün kılar. Sıfırdan indeksli değil, Octave 1-indeksli olduğundan, 1. sırada birinci çıkarma gereklidir. Satır 2'den 2'yi çıkarmak find(diff()), en son gerçek değeri isterken ilk yanlış değerin konumunu bulduğundan gereklidir . Çıkarma kısmı MATLAB'da değil, sadece Octave'de mümkündür.

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
Yayının güzel kullanımı!
Luis Mendo

4

CJam, 27 25 bayt

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

Gibi girişi bekliyor TTFTFT. Çevrimiçi deneyin .

açıklama

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

Japt, 34 31 25 bayt

Yeni bir yaklaşım denemek bu sefer gerçekten işe yaradı.

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

Çevrimiçi deneyin!

Girdi ile bir dizedir Fiçin falseve Tiçin true. Çıktı bir dizi dizisidir; string temsili, tek bir dizi gibi görünmesini sağlar.

Nasıl çalışır

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

Not: Şimdi birkaç kişinin bu algoritmayı şimdiden bulduğunu görüyorum, ancak bağımsız olarak keşfettim.

Rekabet etmeyen sürüm, 22 bayt

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

En son GitHub işleminde yeni bir özellik ekledim: lider ;, değişkenleri A-J,Lfarklı değerlere ayarlar . Aboş bir diziye ayarlanır, böylece onu elle oluşturma gereksinimini ortadan kaldırır.


3

Haskell, 74 bayt

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

Kullanım örneği: map(\l->(fst$l!!0,fst$last l)).wordsBy(not.snd).zip[0..] $ [True,False,True,True,False]-> [(0,0),(2,3)].

Nasıl çalışır:

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

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

Bu, 2B dizi veya tamsayılar döndüren adsız bir monadik fiildir (unary işlevi). Aşağıdaki gibi kullanılır.

  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

açıklama

[: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

Ruby, 39

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

Örnek çağırma:

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

..Yakut dahil aralıkları temsil nasıl.

Buradaki ilginç olan şey, aralığın sonunun endeksini nasıl elde edeceğim. Bu garip. Dinamik olarak, aralığın son karakteriyle eşleşen düzenli bir ifadeyi ve ardından doğru eşleşmeyi zorlamak için izleyen tüm karakterleri ve dizgenin sonunu yaratırım. Daha sonra =~orjinal dizgede o regex'in dizinini almak için kullanıyorum .

Şüpheli, bunu -naF bayraklarını kullanarak Ruby'de yapmanın daha kısa bir yolu olabilir.


2

JavaScript (ES6), 59

Dizge olarak giriş yapan Tve Fdiziler halinde çıktı döndüren adsız bir işlev

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

ÖLÇEK

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>


Vay, Japt'ta da aynı çözümü buldum ve onu JS'ye çevirmek üzereydim. Güzel bir :)
ETHproductions

2

𝔼𝕊𝕄𝕚𝕟, 18 karakter / 28 bayt

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

Try it here (Firefox only).

açıklama

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

2

Haskell, 62 bayt

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

Girdi olarak 0 ve 1 'in bir listesini alır.

Liste göz önüne alındığında, lher iki tarafta da 0 ile işaretleyin ve ardışık çiftlerin dizine alınmış listesini hesaplar. Örneğin

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

Ardından, ardışık öğelere karşılık gelen (0,1)ve (1,0)0 ve 1 bloklarının başlangıcı olan, 1'in sonlarını almak için 0'ın başlangıcından çıkardığı endeksleri çıkarın ve sonuçları sıkıştırın.


Vay, bu sözdizimi Haskell'in alacağını düşündüğümden daha fazla büküyor. Fermuardaki "fl = let s = zip3 [0 ..] (0: l) (l ++ [0]) 'e eşdeğer midir? [İ | (i, 0,1) <- s] [i-1 | (i , 1,0) <- s] "?
Michael Klein

1
@MichaelKlein Evet, burada nimi'den korumalardaki bağlama hilesini öğrendim . Aynı zamanda daha uzun lambda bağlamaya eşdeğerdir 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 bayt

m-VdU2cx1aV+ZQ+QZ2

Açıklama:

             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

Burada dene .


2

Perl, 47 bayt

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

Aşağıdaki perlrun seçenekleriyle -lpe:

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

Çıktının hattın ayrıldığı alternatif (34 bayt):

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

1

Python 2, 108 bayt

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

Test durumları:

$ 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]]

Elbette bundan daha kısa bir çözüm var, ama işe yarıyor.


1

Haskell: 123 bayt (Örnek, kazanamaz)

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)]

Daha az golf oynadı:

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

Golf bile olmasa bile: allTrue s e = and (subList s e)ya da belki allTrue = (and.) . sublist.
nimi

Tamam, hatırlamıyorum bir nedenden dolayı, ungolfing yaparken daha "açık" olduğunu düşündüm ... (Düzenlendi)
Michael Klein

1
Oh, elbette, düşünceler "net" olana göre değişir. Ayrıca all (==True) (subList s e)çok açık olduğunu düşünüyorum .
nimi


1

Japt, 27 bayt

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

Bu golf oynamak için bir yol olmalı ...

Her neyse, benim cevabım ile aynı.


Vay, ben sadece bu çözümü buldum .... Güzel algoritma!
ETHProductions

1

APL, 17 karakter

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

Gelen ⎕IO←0ve ⎕ML←3. İngilizcede:

  • ⍵×⍳⍴⍵: Argümanın yanlış olduğu argüman sürece index vektörünün elemanlarını sıfırlar.
  • ⍵⊂: Her bir hakikatin başlangıcında kesin ve yanlış olanları atın
  • (↑,↑∘⊖)¨: her alt dizinin ilk ve son elemanını al

0

PowerShell, 82 bayt

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

MatchInfo nesnesinin özelliklerini kullanarak Regex çözümü .

Örnek

PS > .\BoolRange.ps1 'F'


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

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

0

Mathematica, 45 bayt

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

Özellikle ilginç değil; bir yerleşik kullanır.


0

Clojure, 109 karakter

#(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 %)))

Aklıma gelen ilk şey, reduceve partition-by.

Basit test durumu (haritalar Tiçin trueve Fiçin false):

(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]))
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.