Policz końcowe prawdy

59

Zainspirowany i na pamiątkę mojego drogiego przyjaciela i kolegi,

Dan Baronet

Dan Baronet , 1956-2016. ODP

Znalazł najkrótsze możliwe rozwiązanie APL do tego zadania:

Zadanie

Biorąc pod uwagę listę boolowską, policz liczbę końcowych wartości prawdy.

Przykładowe przypadki

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

Adám
źródło
Czy możemy wziąć listę jako ciąg zer i jedynek? na przykład 01100?
Adnan,
@Adnan tylko wtedy, gdy jest to najbardziej normalny sposób reprezentowania list boolowskich w Twoim języku.
Adám
71
Przykro z powodu twojej straty.
Martin Ender,
6
@MartinEnder Dziękujemy. Naprzód będzie ciężko. Dan nauczył mnie wszystkiego, co musiałem wiedzieć, aby pracować dla Dyalog.
Adám,
5
Pożegnanie z Danem. RIP ...
Erik the Outgolfer

Odpowiedzi:

36

Dyalog APL, 6 2 bajty

⊥⍨

Przetestuj na TryAPL .

Jak to działa

(uptack, dyadic: decode) wykonuje konwersję bazy. Jeśli lewy operand jest wektorem, dokonuje konwersji mieszanej bazy, co jest idealne do tego zadania.

Dla wektora bazowego b = b n , ⋯, b 0 i wektora cyfry a = a n , ⋯, a 0 , b ⊥ a konwertuje a na mieszaną zasadę b , tzn. Oblicza b 0 ⋯ b n-1 a n + ⋯ + b 0 b 1 a 2 + b 0 a 1 + a 0 .

Teraz (tyldy dieresis, dojazdy) modyfikuje operatora w lewo w następujący sposób. W kontekście monadycznym wywołuje operatora z jednakowymi argumentami po lewej i prawej stronie.

Na przykład, ⊥⍨ jest zdefiniowana jako , który oblicza 0n + ⋯ + A 0 1 2 + A 0 1 + A 0 , przy czym suma wszystkich skumulowanych produktów od prawej do lewej .

W przypadku k końcowych, k produktów po prawej stronie ma wartość 1, a wszystkie pozostałe mają wartość 0 , więc ich suma jest równa k .

Dennis
źródło
14
Wskazówka: Dan zrobił to tylko w dwóch bajtach.
Adám,
3
Mieszana konwersja bazy! To sprytne.
Dennis,
1
O. Mieszana konwersja bazy, jak uderza ponownie.
Conor O'Brien
Brawo! W rzeczywistości, dzięki Danowi, zajmowaliśmy się specjalnymi sprawami b⊥bi poddawaliśmy ⊥⍨bsię nieskończonemu przyspieszaniu.
Adám
19

JavaScript (ES6), 21 bajtów

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

Przypadki testowe

Arnauld
źródło
Jak to działa? Jak f(l)+1zwraca wartość > 2?
Oliver
@Oliver Jest to proces rekurencyjny, oceniany jako l.pop()?(l.pop()?(l.pop()?(...etc...)+1:0)+1:0)+1:0.
Arnauld
Widzę. Dziękuję za wyjaśnienie.
Oliver
11

Galaretka , 4 bajty

ŒrṪP

Wypróbuj online! lub Zweryfikuj wszystkie przypadki testowe.

W przypadku, gdy lista jest pusta, istnieje kilka ciekawych spostrzeżeń. Po pierwsze, kodowanie długości pustej listy []zwraca kolejną pustą listę []. Następnie wycofuję ostatni element z tego, używając powrotów ogona 0zamiast pary, [value, count]które są zwykłymi elementami tablicy zakodowanej na całej długości. Następnie produkt Pzwraca, 0gdy zostanie wywołany, 0co jest oczekiwanym rezultatem.

Wyjaśnienie

ŒrṪP  Main link. Input: list M
Œr    Run-length encode
  Ṫ   Tail, get the last value
   P  Product, multiply the values together
mile
źródło
Alternatywnie, też ŒgṪSdziała!
Lynn,
Daje właściwe dane wyjściowe dla pustej listy jako danych wejściowych, ale jestem zaskoczony biorąc pod uwagę rozbiór. Czy mógłbyś przejrzeć tę specjalną skrzynkę?
Peter Taylor,
@PeterTaylor Jestem też zaskoczony, że to zadziałało. Zauważyłem też, że pierwszy link ma zły kod.
mile
@PeterTaylor w galarecie jest zaimplementowany jako: lambda z: iterable(z).pop() if iterable(z) else 0. iterablewywołany na liście po prostu zwraca listę, a pusta lista jest oczywiście fałszem.
FryAmTheEggman
10

Brachylog , 7 6 5 bajtów

@]#=+

Wypróbuj online!

Wyjaśnienie

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

Ponieważ @] - Suffixzaczyna się od największego sufiksu aż do najmniejszego, najpierw znajdzie najdłuższy bieg.

Fatalizować
źródło
10

CJam (8 bajtów)

{W%0+0#}

Zestaw testów online

Sekcja

{    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
}
Peter Taylor
źródło
10

Haskell, 26 25 bajtów

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

Stosowanie:

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

Wersja Pointfree (26 bajtów):

length.fst.span id.reverse

Użycie listy liczb całkowitych zamiast listy bool (21 bajtów, dzięki Christian Sievers):

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

Stosowanie:

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

Wersja Pointfree (25 bajtów)

sum.fst.span(==1).reverse
Laikoni
źródło
W przypadku list liczb całkowitych foldlpomysł działa za%b=b*(a+1)
Christian Sievers
9

Siatkówka , 7 5 bajtów

r`1\G

Wypróbuj online! (Pierwszy wiersz włącza pakiet testowy oddzielony od linii).

Zdefiniowanie formatu wejściowego dla Retina nie jest całkowicie jednoznaczne. Ponieważ Retina nie ma żadnego rodzaju pojęcia oprócz ciągów (a także żadnej wartości, której można by użyć do naszej zwykłej definicji prawdy i fałszu), zwykle używam 0i 1(lub ogólnie czegoś pozytywnego), aby odpowiadać prawdzie i fałszowi, ponieważ reprezentują one odpowiednio zero lub niektóre dopasowania.

W przypadku reprezentacji jednoznakowych nie potrzebujemy również separatora dla listy (co w pewnym sensie jest bardziej naturalną reprezentacją listy dla języka, który ma tylko ciągi znaków). Adám potwierdził, że jest to akceptowalny format wejściowy.

Jeśli chodzi o sam regex, dopasowuje od right do lewej i \Gzakotwicza każde dopasowanie do poprzedniego. Dlatego liczy się to, ile 1s możemy dopasować od końca łańcucha.

Martin Ender
źródło
„Tak, dla Retiny, ponieważ obsługuje ona tylko łańcuchy, myślę, że łańcuch„ 01 ”lub„ FT ”jest w porządku.
Adám
9

05AB1E , 12 10 6 5 bajtów

Zaoszczędzono 1 bajt dzięki carusocomputing .

Î0¡¤g

Wypróbuj online!

Wyjaśnienie

Î      # push 0 and input
 0¡    # split on 0
   ¤   # take last item in list
    g  # get length
Emigna
źródło
0¡¤gma cztery bajty.
Magic Octopus Urn
@carusocomputing: Nicea! Nie było jeszcze wyjaśnione, czy ciąg znaków był w porządku, kiedy to napisałem, ale teraz widzę, że tak jest :)
Emigna
J0¡¤gjest też jeszcze krótszy;).
Magic Octopus Urn
@carusocomputing: Niestety musimy Îobsłużyć puste dane wejściowe, ale nadal jest to bajt zapisany dzięki :)
Emigna
8

Python, 31 bajtów

lambda a:(a[::-1]+[0]).index(0)
Mitch Schwartz
źródło
7

Galaretka , 4 bajty

ṣ0ṪL

TryItOnline! lub wszystkie testy

W jaki sposób?

ṣ0ṪL - Main link: booleanList
ṣ0   - split on occurrences of 0 ([] -> [[]]; [0] -> [[],[]]; [1] -> [[1]]; ...)
  Ṫ  - tail (rightmost entry)
   L - length
Jonathan Allan
źródło
7

Mathematica, 25 24 bajtów

Fold[If[#2,#+1,0]&,0,#]&
alephalpha
źródło
3
Właśnie nagrywam port fajnego rozwiązania Dana o mieszanej bazie: FromDigits[b=Boole@#,MixedRadix@b]&(35 bajtów).
Greg Martin
5

Pyth, 6 bajtów

x_+0Q0

Wypróbuj tutaj!

Dołącza 0, odwraca i znajduje indeks pierwszego 0

niebieski
źródło
@Jakube naprawiono teraz - inny algorytm
Blue
5

C90 (gcc), 46 bajtów

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

Dane wejściowe są za pomocą argumentów wiersza poleceń (jedna liczba całkowita na argument), dane wyjściowe za pomocą kodu wyjścia .

Wypróbuj online!

Jak to działa

r jest zmienną globalną. Domyślny typ to int, a ponieważ jest globalny, domyślnie przyjmuje wartość 0 .

Argument funkcji c również domyślnie ma wartość int . Będzie zawierał liczbę całkowitą n + 1 dla tablic n booleanów; pierwszy argument main jest zawsze ścieżką do pliku wykonywalnego.

Argument funkcji v jest zadeklarowany jako int**. Rzeczywistym typem v będzie char**, ale ponieważ zbadamy tylko najmniej znaczący bit każdego argumentu, aby odróżnić znaki 0 (punkt kodowy 48 ) i 1 (punkt kodowy 49 ) od siebie, nie będzie to miało znaczenia dla little-endian maszyny

Pętla while zmniejsza wartość c i porównuje ją z wartością 0 . Gdy c osiągnie wartość 0 , wyrwiemy się z pętli. Jest to konieczne tylko wtedy, gdy tablica nie zawiera 0 „s.

Dopóki 0<--czwraca 1 , bierzemy c- ty argument wiersza poleceń ( v[c]) i wyodrębniamy jego pierwszy znak, usuwając odwołanie ze wskaźnika ( *). Bierzemy bitowe AND logicznej 0<--ci punkt kodowy znaku (i trzy bajty śmieci po nim), więc warunek zwróci 0, gdy napotka się 0 , zrywając z pętli.

W pozostałym przypadku, gdy argumentami wiersza poleceń są 1 , r++zwiększa r o 1 , licząc w ten sposób liczbę końcowych 1 .

Na koniec c=rprzechowuje obliczoną wartość r in c . Przy ustawieniach domyślnych kompilator optymalizuje i usuwa przypisanie; faktycznie generuje movl %eax, -4(%rbp)instrukcję. Ponieważ retzwraca wartość rejestru EAX, generuje to pożądane wyjście.

Zauważ, że ten kod nie działa z C99, który zwraca 0 z main, jeśli osiągnięty jest koniec main .

Dennis
źródło
Czy to nie jest ( argcprzynajmniej 1z argv[0]nazwą pliku)? Możesz zapisać jeden bajt --c&&zamiast 0<--c&. Kod wyjścia gcc jest pobierany z argc? Schludny.
Tytus
@Titus To nie zadziała. *v[c]jest punktem kodowym 1 lub 0 , więc jest to 49 lub 48, a zatem zawsze prawdziwe.
Dennis
W przypadku C89 i C90 gcc zwraca wszystko, co w tej chwili jest w RAX. C99 zawsze zwraca 0 z głównego, jeśli osiągnięty jest koniec.
Dennis
4

k, 6 bajtów

+/&\|:

Ta kompozycja funkcji przekłada się na sum mins reversein q, bardziej czytelne rodzeństwo języka, w którym min jest ruchomym minimum.

skeevey
źródło
Czy można: upuścić?
streetster,
4

J, 9 3 bajty

#.~

Jest to zwrotna konwersja mieszanej zasady. Ponieważ jest to to samo, co konwersja mieszanej zasady. Jeszcze raz.

Przypadki testowe

   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|
+-----------+-+
Conor O'Brien
źródło
2
Wskazówka: Można to zrobić tylko w 3 bajtach, używając tłumaczenia J rozwiązania Dana.
Adám,
1
@ Adám Próbowałem znaleźć rozwiązanie. Nie myślałem o konwersji podstawowej. To naprawdę sprytne z jego strony!
Conor O'Brien
1
Tak. To był Dan. :-(
Adám
4

R, 40 39 25 bajtów

Całkowicie przerobione rozwiązanie dzięki @Dason

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

Odczytaj dane wejściowe ze standardowego wejścia, odwróć wektor i jeśli pierwszy element jest !=0następnie wypisywany na pierwszą długość kodowania długości przebiegu ( rle), w przeciwnym razie 0.

Billywob
źródło
1
Możesz zapisać bajt, zmieniając drugi wiersz na ifelse(r$v,r$l,0)[1]. (Vectorized if, a następnie weź pierwszy element.)
rturnbull
1
nie potrzebujesz iflelse - wystarczy pomnożyć r $ v i r $ l.
Dason
Ale i tak trasa sumy (cumprod (rev (.))) Powinna i tak zaoszczędzić wiele bajtów
Dason
3

Haskell, 24 bajty

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

Iteruje po liście, dodając po jednym dla każdego elementu, resetując się 0po trafieniu w a False.

16 bajtów z wejściem 0/1:

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

Gdyby lista nie była pusta, moglibyśmy uzyskać 14 bajtów:

sum.scanr1(*)1

To oblicza skumulowany produkt z tyłu, a następnie sumuje je. Skumulowany iloczyn pozostaje 1, aż do trafienia 0, a następnie staje się 0. Więc 1 odpowiada końcowym 1.

xnor
źródło
3

C # 6, 103 72 bajty

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

Korzystanie z listy nieogólnej bije listę ogólną o 1 bajt lol

-31 bajtów dzięki Scott

Link nr
źródło
Jeśli użyjesz tablicy ints, możesz uciecint a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum();
Scott
@ Scott Oczywiście, o czym myślałem ... Będę jednak trzymać bool. Pytanie określa listę boolowską, a nie jest to C.
Link
Skompiluj do a Func<bool[], int>dla 57 bajtów, tj.using System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count();
TheLethalCoder
2

Python, 37 bajtów

f=lambda l:len(l)and-~f(l[:-1])*l[-1]
orlp
źródło
2

DASH , 16 bajtów

@len mstr"1+$"#0

To nie jest najkrótsze możliwe rozwiązanie DASH, ale na mnie działa błąd. Zamieszczam to nowatorskie podejście na swoim miejscu.

Stosowanie:

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

Wyjaśnienie

@(                 #. 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
)
Mama Fun Roll
źródło
2

Scala, 25 bajtów

l=>l.reverse:+0 indexOf 0

Nie golfowany:

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

Odwraca listę, dodaje 0 i znajduje pierwszy indeks 0, czyli liczbę elementów przed pierwszym 0

corvus_192
źródło
2

Partia, 57 bajtów

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

Pobiera dane wejściowe jako parametry wiersza polecenia. Działa poprzez pomnożenie akumulatora przez bieżącą wartość przed dodaniem go, tak aby wszelkie zera w wierszu poleceń zresetowały licznik. Zauważ, że %%nto nie to samo co zmienna nlub %n%.

Neil
źródło
2

GolfSharp, 14 bajtów

n=>n.V().O(F);
downrep_nation
źródło
2

Java 7, 62 bajty

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

Kod niepoznany i testowy:

Wypróbuj tutaj.

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

Wynik:

0, 0, 1, 0, 1, 2, 3, 6
Kevin Cruijssen
źródło
2

Perl 5.10, 22 bajty

21 bajtów + 1 bajt na -aflagę. Ponieważ wyrażenie oparte na wyrażeniach regularnych zostało wykonane ...: s

Wartości wejściowe dla tablicy muszą być oddzielone spacją.

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

Wypróbuj online!

Paul Picard
źródło
1
Nieco krótszy, jeśli argumenty są pobierane z wiersza poleceń: perl -E '$_++while pop;say' 0 1 1 0 1 1 1ale to nic nie daje 0(nie jestem pewien, czy to jest problem!)
Dom Hastings,
2

Perl, 22 bajty

21 bajtów kodu + 1 bajt na -pflagę.

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

Aby uruchomić:

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

(Faktycznie, format danych wejściowych nie ma znaczenia dużo: 0110111, 0 1 1 0 1 1 1, [0,1,1,0,1,1,1]itd. By wszystkie prace)


Wersja 18- bajtowa z @Dom Hastings, ale wymaga podania danych wejściowych jako ciągu 0 i 1, co jest niedozwolone:

perl -pE '/1*$/;$_=length$&' <<< '0110111'
Dada
źródło
Uwielbiam tę ;sztuczkę :) Jeśli format jest ciągłym ciągiem: perl -pE '/1*$/;$_=length$&' <<< '0110111'przez 18 nie jestem pewien, czy to zgina reguły, czy nie ...
Dom Hastings
@DomHastings tak, ja też! (Dzięki, Ton, że mi to pokazałeś!) Pierwsze i drugie komentarze tego rodzaju pytania zabraniają formatu danych wejściowych potrzebnych dla twojego rozwiązania ... Ale zmodyfikuję mój post, aby zasugerować twoją wersję, jeśli format danych wejściowych był bardziej wolny.
Dada,
2

PHP, 50 bajtów

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

Dziwnie, moja pierwsza próba z wyrażeniem regularnym okazała się krótsza niż moja próba z tablicami ...
Użyj takich jak:

php tt.php 1 1 0 1 1
użytkownik59178
źródło
2

Ruby 37 32 bajty

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

Tworzy anonimową funkcję, która znajduje najbardziej prawą instancję fałszywej wartości i liczy wielkość podtablicy zaczynając od tej wartości.

Używa wartości !0false, ponieważ 0 to prawdziwe wartości Rubiego. rindexznajduje ostatni indeks wartości w tablicy.

Zastosowanie :

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

Zwraca 1


Jeśli pozwolono mi na przekazanie ciągu 0 i 1 jako parametrów wiersza poleceń (co nie jest tym, w jaki sposób ruby ​​reprezentuje listy wartości logicznych), mógłbym sprowadzić go do 24:

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

Używa wyrażeń regularnych i wypisuje długość łańcucha zwróconego przez wyrażenie regularne /(1*)\z/, gdzie \zjest koniec łańcucha. $*[0]jest pierwszym przekazywanym argumentem i jest łańcuchem zer i jedynek.

Stosowanie:

trailing_truths.rb 011101

Zwraca 1.

IMP1
źródło
1
Kiedy masz indeks ostatniej fałszywej wartości, dlaczego musisz ponownie pobierać elementy z tablicy?
Lee W
Masz rację, ja nie. Dzięki. 5 bajtów mniej!
IMP1