Sondaki gerçekleri say


59

Sevgili arkadaşım ve meslektaşımdan ilham alan ve anısına,

Dan Baronet

Dan Baronet , 1956 - 2016. RIP

Bu göreve mümkün olan en kısa APL çözümünü buldu :

Görev

Bir Boole listesi göz önüne alındığında, takip eden doğruluk değerlerinin sayısını sayın.

Örnek vakalar

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


Listeyi bir dizi sıfır ve sıfır olarak alabilir miyiz? mesela 01100?
Adnan

@Adnan, dilinizin boole listelerini temsil etmesi için en normal yol ise.
Adám

71
Kaybın için üzgünüm.
Martin Ender

6
@MartinEnder Teşekkürler. İleri gitmek zor olacak. Dan bana Dyalog için çalışmak için bilmem gereken her şeyi öğretti.
Ad'm 6'16,

5
Dan'e veda. RIP ...
Outgolfer Erik

Yanıtlar:


36

Dyalog APL, 6 2 bayt

⊥⍨

TryAPL'de test edin .

Nasıl çalışır

(üst üste binme, dyadik: kod çözme) temel dönüşüm gerçekleştirir. Sol işlenen bir vektör ise, bu görev için mükemmel olan karışık temel dönüşüm gerçekleştirir .

Bir taban vektörü için B = B n , ⋯ b 0 ve bir rakam vektörü a = bir n , ⋯, bir 0 , b ⊥ bir dönüştüren bir karma baz için b , yani, bu hesaplar b 0 ⋯ b , n-1 , bir n + ⋯ + b 0 b 1 a 2 + b 0 a 1 + a 0 .

Şimdi, (tilde dieresis , commute ) operatörü sola doğru aşağıdaki gibi değiştirir. Monadik bir bağlamda, operatörü eşit sol ve sağ argümanlarla çağırır.

Örneğin, ⊥⍨ bir olarak tanımlanan bir ⊥ bir hesaplar olan bir 0 ⋯ bir N + ⋯ + a 0 , bir 1 , bir 2 + a 0 , bir 1 + a 0 , sağdan sola doğru tüm toplu ürün toplamı .

İçin k arka olanlar, k, en sağdaki ürünler 1 ve diğerleri 0 bunların toplamı eşittir, yani k .


14
İpucu: Dan sadece iki baytta yaptı.
Ad'm 6'16,

3
Karışık temel dönüşüm! Zekice.
Dennis,

1
Ah. Karışık temel dönüşüm, tekrar grev.
Conor O'Brien,

Bravo! Aslında, Dan nedeniyle, özel kasayı kullanıyoruz b⊥bve ⊥⍨bsonsuz hızlanmayı bırakıyoruz .
19

19

JavaScript (ES6), 21 bayt

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

Test durumları


Bu nasıl çalışıyor? f(l)+1Bir değeri nasıl verir > 2?
Oliver

@Oliver Bu, olarak değerlendirilen özyinelemeli bir süreçtir l.pop()?(l.pop()?(l.pop()?(...etc...)+1:0)+1:0)+1:0.
Arnauld,

Anlıyorum. Açıklama için teşekkürler.
Oliver

11

Jöle , 4 bayt

ŒrṪP

Çevrimiçi deneyin! veya Tüm test durumlarını doğrulayın.

Listenin boş olduğu durumda bazı ilginç gözlemler var. İlk olarak, boş listeyi kodlayan çalışma uzunluğu []başka bir boş liste döndürür []. Daha sonra, çalışma uzunluğu kodlanmış bir dizinin normal elemanları olan bir çift yerine kuyruk dönüşlerini kullanan son öğeyi yeniden alma . Daha sonra çağrıldığında beklenen sonuç olan ürün döner .0[value, count]P00

açıklama

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

Alternatif olarak, aynı zamanda ŒgṪSçalışır!
Lynn

Boş liste için girdi olarak doğru çıktıyı verir, ancak diseksiyon verildiğinde şaşırdım. Bu özel davadan geçer misin?
Peter Taylor

@ PeterTaylor Ben de işe yaradı ben de şaşırdım. Ayrıca, ilk bağlantının yanlış kodu olduğunu fark ettim.
mil

@PeterTaylor Jelly olduğu gibi uygulanır: lambda z: iterable(z).pop() if iterable(z) else 0. iterableBir listede çağrıldığında sadece listeyi döndürür ve boş liste elbette sahtedir.
FryAmTheEggman

10

Brachylog , 7 6 5 bayt

@]#=+

Çevrimiçi deneyin!

açıklama

@]        A suffix of the Input...
  #=      ...whose elements are all equal
    +     Sum its elements

Yana @] - Suffixbüyük soneki gelen tüm yol en küçük birine kadar başladıktan, ilk uzun vadede bulacaksınız.


10

CJam (8 bayt)

{W%0+0#}

Çevrimiçi test paketi

teşrih

{    e# begin a block
  W%  e# reverse the array
  0+  e# append 0 so there's something to find
  0#  e# find index of first 0, which is number of nonzeros before it
}

10

Haskell, 26 25 bayt

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

Kullanımı:

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

Noktasız versiyon (26 bayt):

length.fst.span id.reverse

Bool listesi yerine bir tamsayı listesi kullanmak (Christian Sievers sayesinde 21 bayt):

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

Kullanımı:

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

Noktasız versiyon (25 bayt)

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

Tamsayı listeleri için foldlfikir ile çalışıra%b=b*(a+1)
Christian Sievers

9

Retina , 7 5 bayt

r`1\G

Çevrimiçi deneyin! (İlk satır satır besleme ile ayrılmış bir test takımı sağlar.)

Retina için giriş formatını tanımlamak tamamen açık değildir. Retina dizeleri hariç her türlü kavramı yok olduğundan (ve ayrıca truthy ve falsy bizim her zamanki tanımı için kullanılabilecek hiçbir değer), genellikle kullanmak 0ve 1temsil ettikleri şekilde (ya da genel olarak olumlu bir şey), truthy ve falsy karşılık gelecek Sıfır veya bazı eşleşmeler sırasıyla.

Tek karakterli gösterimlerle, ayrıca liste için bir ayırıcıya ihtiyacımız yoktur (bir şekilde, yalnızca dizeleri olan bir dilin daha doğal liste gösterimidir). Adám , bunun kabul edilebilir bir giriş formatı olduğunu onayladı .

Regex'in kendisine gelince, rsoldan sağa doğru eşleşir ve \Gher eşleşmeyi öncekine tutturur. Bu nedenle, bu 1dizgenin sonundan ne kadar eşleşebileceğimizi sayar .


"Evet, Retina için, yalnızca dizeleri işlediği için," 01 "veya" FT "dizisinin sıralı olduğunu düşünüyorum.
Adám

9

05AB1E , 12 10 6 5 bayt

Carusocomputing sayesinde 1 bayt kaydedildi .

Î0¡¤g

Çevrimiçi deneyin!

açıklama

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

0¡¤gdört bayttır.
Magic Octopus Urn,

@carusocomputing: Güzel! Bunu yazdığımda string girişi tamam olup olmadığı henüz netleşmedi, ama şimdi görüyorum ki :)
Emigna

J0¡¤gAyrıca hala daha kısadır;).
Magic Octopus Urn,

@ carusocomputing: Maalesef Îboş girişi ele almamız gerekiyor , ancak yine de kaydedilmiş bir bayt oldu :)
Emigna




7

Mathematica, 25 24 bayt

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

3
Sadece Dan'in serin karışık tabanlı çözümünün bir portunu kaydediyor: FromDigits[b=Boole@#,MixedRadix@b]&(35 byte).
Greg Martin

5

Pyth, 6 bayt

x_+0Q0

Burada dene!

0 ekler, ilk 0'ın dizinini tersine çevirir ve bulur


@Jakube şimdi düzeltildi - farklı algoritma
Blue

5

C90 (gcc), 46 bayt

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

Giriş, komut satırı argümanları (her argüman başına bir tamsayı), çıkış kodu ile çıkar .

Çevrimiçi deneyin!

Nasıl çalışır

r global bir değişkendir. Türü varsayılan olarak int ve genel olarak, varsayılan olarak 0'dır .

C işlev argümanı , int olarak da öntanımlıdır . N Boolean dizileri için n + 1 tamsayısını tutacaktır ; ana ilk argümanı her zaman çalıştırılabilir yoludur.

İşlev argümanı v , olarak bildirildi int**. Gerçek v tipi olacaktır char**, ancak 0 (kod noktası 48 ) ve 1 (kod noktası 49 ) karakterlerini birbirinden ayırmak için her argümanın en az anlamlı bitini inceleyeceğimiz için , bu küçük-endian dillerinde önemli olmaz makineleri.

While döngüsü c'yi azaltır ve 0 ile karşılaştırır . Bir kez c ulaşır 0 , biz döngünün dışında kırarım. Bu sadece dizi 0 içermiyorsa gereklidir .

Sürece 0<--cdöner 1 , biz alır c inci komut satırı bağımsız ( v[c]) ve işaretçiyi kaldırma tarafından ile ilk karakteri özü ( *). Biz ikilik VE Boolean almak 0<--ckoşulu dönecektir böylece, ve karakter (ve onu takip üç çöp baytlık) kod noktası 0 bir kez 0 karşılaşıldığında döngünün dışında kırarak,.

Komut satırı bağımsız buna karşın kalan durumda, 1 , r++artırır r ile 1 böylece arka sayısının sayılması, 1 's.

Son olarak, c=rhesaplanan değeri depolayan r içinde c . Varsayılan ayarlarla, derleyici atamayı optimize eder ve kaldırır; aslında movl %eax, -4(%rbp)talimatı oluşturur . Yana retEAX kaydının döner değeri, bu arzu edilen bir çıktı üretir.

Bu kod unutmayın değil döndüren C99, çalışmak 0 dan ana sonuna eğer ana ulaşılır.


Isn't argcen az 1(ile argv[0]dosya adını içerir)? Bunun --c&&yerine bir byte tasarruf edebilirsiniz 0<--c&. GMC çıkış kodu alınır argcmı? Temiz.
Titus,

@Titus Bu işe yaramaz. 1 veya 0*v[c] kod noktasıdır , yani 49 veya 48'dir ve bu nedenle her zaman truthy'dir.
Dennis,

C89 ve C90 ile, gcc o anda RAX'ta olanı döndürür. Sona ulaşıldığında C99 her zaman 0'dan ana değerini döndürür .
Dennis,

4

k, 6 bayt

+/&\|:

Bu işlev kompozisyon çevirir sum mins reverseiçinde qdakika bir yuvarlanma minimum dilin daha okunabilir kardeş,.


: Bırakılabilir mi?
streetster

4

J, 9 3 bayt

#.~

Bu dönüşlü karışık baz dönüşümdür. Çünkü bu karışık baz dönüşümüyle aynıdır. Tekrar.

Test durumları

   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
İpucu: Bu Dan'ın çözümünün J çevirisi kullanılarak yalnızca 3 baytta yapılabilir.
Ad'm 6'16,

1
@ Adám Bir çözüm aramaya çalıştım. Temel dönüşüm düşünmedim. Bu gerçekten çok zekice!
Conor O'Brien,

1
Evet. Dan’di. :-(
Adám 6'16

4

R, 40 39 25 bayt

@Dason sayesinde tamamen elden geçirilmiş çözüm

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

Girdiyi stdin'den okuyun, vektörü ters çevirin ve eğer ilk elemanı !=0ilk çıktıysa, çalışma uzunluğu kodlamasının ilk uzunluğunu ( rle) çıktı 0.


1
İkinci satırı değiştirerek bir bayt kaydedebilirsiniz ifelse(r$v,r$l,0)[1]. (Varsa
vectorized

1
iflelse'ye gerek yok - sadece r $ v ve r $ l ile çarpın.
Dason

Ancak toplam (cumprod (rev (.))) Güzergahı yine de çok fazla bayt kurtarmalıdır
Dason

3

Haskell, 24 bayt

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

Her öğe için bir tane ekleyerek, listeye 0girdikten sonra sıfırlayarak listeyi tekrar sıralar False.

0/1 girişli 16 bayt :

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

Listenin boş olmadığı garanti edilirse 14 bayt alabiliriz:

sum.scanr1(*)1

Bu, biriken ürünü arkadan hesaplar, sonra bunları toplar. Birikim çarpana kadar toplam ürün 1 olarak kalır ve sonra 0 olur. Yani, 1'ler takip eden 1'lere karşılık gelir.



3

C # 6, 103 72 bayt

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

Genel olmayan listeyi kullanmak genel listeyi 1 byte lol atıyor.

Scott sayesinde -31 bayt


Bir dizi ints kullanırsanız, int a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum();
Scott

@Scott Elbette ne düşünüyordum ... Gerçi bool ile bağlı kalacağım. Soru boolean listesini belirtir ve C değildir.
Link Ng

Func<bool[], int>57 bayt için bir derleme, yaniusing System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count();
TheLethalCoder 8:16

2

Python, 37 bayt

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

2

DASH , 16 bayt

@len mstr"1+$"#0

Mümkün olan en kısa DASH çözümü değil, ancak mümkün olan en kısa DASH çözümü üzerimden geliyor. Bu yeni yaklaşımı onun yerine gönderiyorum.

Kullanımı:

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

açıklama

@(                 #. 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

Scala, 25 bayt

l=>l.reverse:+0 indexOf 0

Ungolfed:

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

Listeyi tersine çevirir, 0 ekler ve ilk 0'dan önceki öğelerin sayısı olan ilk dizini bul.


2

Toplu iş, 57 bayt

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

Komut satırı parametreleri olarak girdi alır. Eklemeden önce akümülatörü mevcut değerle çarparak çalışır, böylece komut satırındaki sıfırlar sayımı sıfırlar. Not %%naynı değildir nveya %n%değişken.



2

Java 7, 62 bayt

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

Ungolfed ve test kodu:

Burada dene.

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

Çıktı:

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

2

Perl 5.10, 22 bayt

-aBayrak için 21 bayt + 1 bayt . Regex tabanlı ifade yapıldıktan sonra ...: p

Dizinin giriş değerleri boşlukla ayrılmalıdır.

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

Çevrimiçi deneyin!


1
Eğer komut satırı üzerinden argüman alırsanız biraz daha kısa: perl -E '$_++while pop;say' 0 1 1 0 1 1 1ama bu bir şey çıkarmaz 0(eğer bir sorun olsa bile emin değilim!)
Dom Hastings

2

Perl, 22 bayt

-pBayrak için 21 bayt kod + 1 bayt .

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

Çalıştırmak için:

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

(Aslında, giriş biçimi çok önemli değildir: 0110111, 0 1 1 0 1 1 1, [0,1,1,0,1,1,1]vb olurdu bütün iş)


18 bayt versiyonu ile ilgili @Dom Hastings ancak izin verilmez, 0 ile 1 arasında bir dizi olarak girdi kaynağı gerektirir:

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

Bu ;hileyi sevmek :) Eğer biçim bir sürekli dize ise: perl -pE '/1*$/;$_=length$&' <<< '0110111'18 için, kurallara
Dom Hastings

@DomHastings evet, ben de! (Bana bunu gösterdiğin için teşekkürler Ton!) Sorunun ilk ve ikinci yorumları çözümün için ihtiyacın olan giriş biçimini reddetti ... Ancak girişin biçimi daha fazlaysa, versiyonunu önermek için yazımı düzenleyeceğim. Beleş.
Dada

2

PHP, 50 bayt

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

Esrarlı bir regex ile ilk denemeydi ... diziler ile benim denemede daha kısa olduğu ortaya çıktı
gibi kullanın:

php tt.php 1 1 0 1 1

2

Yakut 37 32 bayt

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

Yanlış değerin en doğru örneğini bulan anonim bir işlev oluşturur ve bu değerden başlayan alt dizinin boyutunu sayar.

!0Ruby'de truthy değerleri olduğu için false olarak kullanır . rindexBir dizideki değerin son dizinini bulur.

Kullanım :

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

1 döndürür


Komut satırı parametreleri olarak 0s ve 1s dizisinden geçirilmeme izin verilirse (bu da ruby'nin boolean listelerini gösterme şekli değildir), 24'e indirebilirim:

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

Bu düzenli ifadeleri kullanır ve düzenli ifade tarafından döndürülen dize uzunluğunu basar /(1*)\z/, \zdizenin sonudur. $*[0]ilk argüman geçen ve 0s ve 1s dizesidir.

Kullanımı:

trailing_truths.rb 011101

1 döndürür.


1
Son yanlış değerin dizinine sahip olduğunuzda, neden diziden elemanları geri almak zorundasınız?
Lee W

Haklısın, bilmiyorum. Teşekkürler. 5 bayt kapalı!
IMP1
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.