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


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 .


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


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

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.


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
}

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

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.


„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

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




7

Mathematica, 25 24 bajtów

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

3
Właśnie nagrywam port fajnego rozwiązania Dana o mieszanej bazie: FromDigits[b=Boole@#,MixedRadix@b]&(35 bajtów).
Greg Martin


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 .


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.


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

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.


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.



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


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]

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
)

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


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%.



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

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!


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'

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

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.