Zähle nachfolgende Wahrheiten

59

Inspiriert von und in Erinnerung an meinen lieben Freund und Kollegen,

Dan Baronet

Dan Baronet , 1956 - 2016. RIP

Er fand die kürzestmögliche APL-Lösung für diese Aufgabe:

Aufgabe

Zählen Sie anhand einer Booleschen Liste die Anzahl der nachgestellten Wahrheitswerte.

Beispielfälle

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

Adam
quelle
Können wir die Liste als eine Folge von Nullen und Einsen nehmen? zB 01100?
Adnan
@Adnan nur, wenn dies für Ihre Sprache die normalste Art ist, Boolesche Listen darzustellen.
Adám
71
Dein Verlust tut mir Leid.
Martin Ender
6
@ MartinEnder Vielen Dank. Es wird schwierig für die Zukunft. Dan brachte mir alles bei, was ich wissen musste, um für Dyalog zu arbeiten.
Adám
5
Abschied von Dan. RIP ...
Erik der Outgolfer

Antworten:

36

Dyalog APL, 6 2 Bytes

⊥⍨

Testen Sie es auf TryAPL .

Wie es funktioniert

(uptack, dyadic : decode) führt eine Basiskonvertierung durch. Wenn der linke Operand ein Vektor ist, führt er eine gemischte Basiskonvertierung durch, die für diese Aufgabe perfekt ist.

Für einen Basisvektor b = b n , ⋯, b 0 und einen Ziffernvektor a = a n , ⋯, a 0 , b ⊥ a wird a in die gemischte Basis b umgewandelt , dh es wird b 0 ⋯ b n-1 a berechnet n + ⋯ + b 0 b 1 a 2 + b 0 a 1 + a 0 .

Mit (Tildedierese, Pendeln) wird der Operator nach links wie folgt geändert. In einem monadischen Kontext wird der Operator mit den gleichen Argumenten für left und right aufgerufen.

Zum Beispiel ist ⊥⍨ a als ⊥ a definiert , das a 0 ⋯ a n + ⋯ + a 0 a 1 a 2 + a 0 a 1 + a 0 berechnet , die Summe aller kumulierten Produkte von rechts nach links .

Für k nachgestellte sind die k am weitesten rechts stehenden Produkte 1 und alle anderen 0 , sodass ihre Summe gleich k ist .

Dennis
quelle
14
Tipp: Dan hat es in nur zwei Bytes geschafft.
Adám
3
Mixed Base Konvertierung! Das ist schlau.
Dennis
1
Oh. Mixed Base Conversion, wie es wieder auffällt.
Conor O'Brien
Bravo! In der Tat, wegen Dan, wir spezielle Gefassten b⊥bund ⊥⍨bgeben bis zu unendlicher Geschwindigkeit-up.
Adám
19

JavaScript (ES6), 21 Byte

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

Testfälle

Arnauld
quelle
Wie funktioniert das? Wie wird f(l)+1ein Wert zurückgegeben > 2?
Oliver
@Oliver Dies ist ein rekursiver Prozess, der als ausgewertet wird l.pop()?(l.pop()?(l.pop()?(...etc...)+1:0)+1:0)+1:0.
Arnauld
Aha. Danke für die Erklärung.
Oliver
11

Gelee , 4 Bytes

ŒrṪP

Probieren Sie es online! oder Überprüfen Sie alle Testfälle.

Für den Fall, dass die Liste leer ist, gibt es einige merkwürdige Beobachtungen. Zunächst gibt die Lauflängencodierung der leeren Liste eine []weitere leere Liste zurück []. Dann wird das letzte Element unter Verwendung von Tail Returns 0anstelle eines Paares zurückerhalten, das [value, count]die regulären Elemente eines lauflängencodierten Arrays sind. Dann Pkehrt das Produkt zurück, 0wenn es aufgerufen 0wird. Dies ist das erwartete Ergebnis.

Erläuterung

ŒrṪP  Main link. Input: list M
Œr    Run-length encode
  Ṫ   Tail, get the last value
   P  Product, multiply the values together
Meilen
quelle
Alternativ ŒgṪSfunktioniert auch!
Lynn
Es gibt die richtige Ausgabe für die leere Liste als Eingabe, aber ich bin angesichts der Zerlegung überrascht. Würde es Ihnen etwas ausmachen, diesen speziellen Fall durchzugehen?
Peter Taylor
@PeterTaylor Ich bin auch überrascht, dass es funktioniert hat. Außerdem habe ich gerade bemerkt, dass der erste Link den falschen Code hat.
Meilen
@PeterTaylor in Jelly implementiert als: lambda z: iterable(z).pop() if iterable(z) else 0. iterableWenn eine Liste aufgerufen wird, wird nur die Liste zurückgegeben, und die leere Liste ist natürlich falsch.
FryAmTheEggman
10

Brachylog , 7 6 5 Bytes

@]#=+

Probieren Sie es online!

Erläuterung

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

Da @] - Suffixvom größten bis zum kleinsten Suffix begonnen wird, wird der längste Lauf zuerst ermittelt.

Tödlich
quelle
10

CJam (8 Bytes)

{W%0+0#}

Online-Testsuite

Präparation

{    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
quelle
10

Haskell, 26 25 Bytes

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

Verwendungszweck:

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

Punktfreie Version (26 Bytes):

length.fst.span id.reverse

Verwenden einer Integer-Liste anstelle einer Bool-Liste (21 Bytes, danke an Christian Sievers):

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

Verwendungszweck:

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

Punktfreie Version (25 Bytes)

sum.fst.span(==1).reverse
Laikoni
quelle
Für Integer-Listen foldlfunktioniert die Idee mita%b=b*(a+1)
Christian Sievers
9

Retina , 7 5 Bytes

r`1\G

Probieren Sie es online! (Die erste Zeile aktiviert eine durch Zeilenvorschub getrennte Testsuite.)

Die Definition des Eingabeformats für Retina ist nicht eindeutig. Da Retina kein Konzept außer Zeichenketten hat (und auch keinen Wert, der für unsere übliche Definition von Wahrhaftigkeit und Falschheit verwendet werden kann), benutze ich normalerweise 0und 1(oder etwas Positives im Allgemeinen), um Wahrhaftigkeit und Falschheit zu entsprechen, wie sie darstellen Null bzw. einige Übereinstimmungen.

Bei Einzelzeichendarstellungen benötigen wir auch kein Trennzeichen für die Liste (dies ist in gewisser Weise die natürlichere Listendarstellung für eine Sprache, die nur Zeichenfolgen enthält). Adám hat bestätigt, dass dies ein akzeptables Eingabeformat ist.

Der rreguläre Ausdruck selbst passt von rechts nach links und die \GAnker passen jeweils zum vorherigen. Daher zählt dies, wie viele 1s ab dem Ende der Zeichenfolge übereinstimmen können.

Martin Ender
quelle
"Ja, für Retina, da es nur Zeichenfolgen verarbeitet, denke ich, dass eine" 01 "- oder" FT "- Zeichenfolge in Ordnung ist.
Adám
9

05AB1E , 12 10 6 5 Bytes

1 Byte dank Carusocomputing eingespart .

Î0¡¤g

Probieren Sie es online!

Erläuterung

Î      # push 0 and input
 0¡    # split on 0
   ¤   # take last item in list
    g  # get length
Emigna
quelle
0¡¤gist vier Bytes.
Magic Octopus Urn
@carusocomputing: Schön! Es wurde noch nicht geklärt, ob die Eingabe von Zeichenfolgen in Ordnung war, als ich dies schrieb, aber ich sehe jetzt, dass es ist :)
Emigna
J0¡¤gist auch noch kürzer;).
Magic Octopus Urn
@carusocomputing: Leider müssen wir Îdie leere Eingabe behandeln, aber es ist immer noch ein Byte gespeichert, danke :)
Emigna
8

Python, 31 Bytes

lambda a:(a[::-1]+[0]).index(0)
Mitch Schwartz
quelle
7

Gelee , 4 Bytes

ṣ0ṪL

TryItOnline! oder alle Tests

Wie?

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

Mathematica, 25 24 Bytes

Fold[If[#2,#+1,0]&,0,#]&
Alephalpha
quelle
3
Einfach einen Port von Dans cooler Mixed-Base-Lösung aufzeichnen: FromDigits[b=Boole@#,MixedRadix@b]&(35 Bytes).
Greg Martin
5

Pyth, 6 Bytes

x_+0Q0

Probieren Sie es hier aus!

Hängt eine 0 an, kehrt um und findet den Index der ersten 0

Blau
quelle
@ Jakube jetzt behoben - anderer Algorithmus
Blau
5

C90 (gcc), 46 Bytes

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

Die Eingabe erfolgt über Befehlszeilenargumente (eine Ganzzahl pro Argument) und die Ausgabe über Exit-Code .

Probieren Sie es online!

Wie es funktioniert

r ist eine globale Variable. Sein Typ ist standardmäßig int und als globaler Wert standardmäßig 0 .

Das Funktionsargument c ist ebenfalls standardmäßig int . Es wird die ganze Zahl n + 1 für Arrays von n Booleschen Werten enthalten. Das erste Argument von main ist immer der Pfad der ausführbaren Datei.

Das Funktionsargument v wird als deklariert int**. Der tatsächliche Typ von v ist char**, aber da wir nur das niedrigstwertige Bit jedes Arguments untersuchen, um die Zeichen 0 (Codepunkt 48 ) und 1 (Codepunkt 49 ) voneinander zu unterscheiden, ist dies für Little-Endian nicht von Bedeutung maschinen.

Die while-Schleife dekrementiert c und vergleicht es mit 0 . Sobald c 0 erreicht , brechen wir aus der Schleife aus. Dies wird nur benötigt, wenn das Array keine 0 enthält .

Solange 0<--ckehrt 1 , wir die Takes c th Befehlszeilenargument ( v[c]) und dessen erstes Zeichen durch Extrahieren mit dereferenzieren den Zeiger ( *). Wir nehmen die bitweise UND -Verknüpfung der Booleschen 0<--cund den Codepunkt des Zeichens (und drei Müll Bytes , die ihm folgen), so dass der Zustand zurückkehren 0 einmal 0 angetroffen wird, aus der Schleife zu brechen.

In dem verbleibenden Fall, während die Befehlszeilenargumente sind 1 , r++inkrementiert r von 1 , wodurch die Anzahl der Zählung nachlauf 1 ‚s.

Schließlich c=rspeichert den berechneten Wert von R in c . Mit den Standardeinstellungen optimiert und entfernt der Compiler die Zuordnung. es erzeugt tatsächlich die movl %eax, -4(%rbp)Anweisung. Da retder Wert des EAX-Registers zurückgegeben wird, wird die gewünschte Ausgabe generiert.

Beachten Sie, dass dieser Code nicht mit C99 funktioniert, das 0 von main zurückgibt, wenn das Ende von main erreicht ist.

Dennis
quelle
Ist es nicht argczumindest 1(mit argv[0]dem Dateinamen)? Sie könnten ein Byte mit --c&&anstelle von speichern 0<--c&. gcc´s Exit Code stammt von argc? Ordentlich.
Titus
@Titus Das geht nicht. *v[c]ist der Codepunkt 1 oder 0 , also entweder 49 oder 48 und somit immer wahr.
Dennis
Mit C89 und C90 gibt gcc alles zurück, was sich gerade in RAX befindet. C99 gibt immer 0 von main zurück, wenn das Ende erreicht ist.
Dennis
4

k, 6 Bytes

+/&\|:

Diese Funktionskomposition übersetzt sum mins reversein q, das besser lesbare Geschwisterpaar der Sprache, bei dem die Minuten ein rollendes Minimum darstellen.

Skeevey
quelle
Kann der fallengelassen werden?
Streetster
4

J, 9 3 Bytes

#.~

Dies ist eine reflexive gemischte Basenumwandlung. Weil dies dasselbe ist wie eine gemischte Basenumwandlung. Nochmal.

Testfälle

   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
quelle
2
Hinweis: Dies kann mit der J-Übersetzung von Dans Lösung in nur 3 Bytes erfolgen.
Adám
1
@Adám Ich habe versucht nach einer Lösung zu suchen. Habe nicht an Base Conversion gedacht. Das ist wirklich ziemlich schlau von ihm!
Conor O'Brien
1
Ja. Das war Dan. :-(
Adám
4

R, 40 39 25 Bytes

Komplett überarbeitete Lösung dank @Dason

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

Lesen Sie die Eingabe von stdin, kehren Sie den Vektor um, und wenn das erste Element von !=0dann die erste Länge der Lauflängencodierung ( rle) ausgibt , sonst 0.

Billywob
quelle
1
Sie können ein Byte speichern, indem Sie die zweite Zeile in ändern ifelse(r$v,r$l,0)[1]. (Vectorized if, und nehmen Sie dann das erste Element.)
rturnbull
1
Die iflelse ist nicht erforderlich. Multiplizieren Sie einfach r $ v und r $ l.
Dason
Aber die sum (cumprod (rev (.))) Route sollte sowieso eine Menge Bytes sparen
Dason
3

Haskell, 24 Bytes

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

Durchläuft die Liste, fügt eine für jedes Element hinzu und setzt auf zurück, 0nachdem es a getroffen hat False.

16 Bytes mit 0/1 Eingang:

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

Wenn die Liste garantiert nicht leer wäre, könnten wir 14 Bytes bekommen:

sum.scanr1(*)1

Dadurch wird das kumulative Produkt von hinten berechnet und dann summiert. Das kumulative Produkt bleibt 1, bis eine 0 erreicht wird, und wird dann zu 0. Die Einsen entsprechen also den nachfolgenden Einsen.

xnor
quelle
3

C # 6, 103 72 Bytes

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

Die Verwendung einer nicht generischen Liste schlägt die generische Liste um 1 Byte (lol)

-31 Bytes dank Scott

Link Ng
quelle
Wenn Sie eine Reihe von ints verwenden, können Sie mitint a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum();
Scott
@Scott Natürlich, was habe ich mir gedacht ... ich bleibe aber bei bool. Die Frage gibt die Boolesche Liste an und ist nicht C.
Link Ng
Kompilieren Sie zu a Func<bool[], int>für 57 Bytes, dhusing System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count();
TheLethalCoder
2

Python, 37 Bytes

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

DASH , 16 Bytes

@len mstr"1+$"#0

Es ist nicht die kürzestmögliche DASH-Lösung, aber die kürzestmögliche DASH-Lösung nervt mich. Ich poste diesen neuartigen Ansatz an seiner Stelle.

Verwendungszweck:

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

Erläuterung

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

Scala, 25 Bytes

l=>l.reverse:+0 indexOf 0

Ungolfed:

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

Kehrt die Liste um, fügt eine 0 hinzu und ermittelt den ersten Index von 0, dh die Anzahl der Elemente vor der ersten 0

corvus_192
quelle
2

Batch, 57 Bytes

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

Übernimmt Eingaben als Befehlszeilenparameter. Multipliziert den Akku mit dem aktuellen Wert, bevor er hinzugefügt wird, sodass alle Nullen in der Befehlszeile den Zähler zurücksetzen. Beachten Sie, dass dies %%nnicht mit der Variablen noder identisch %n%ist.

Neil
quelle
2

GolfSharp, 14 Bytes

n=>n.V().O(F);
downrep_nation
quelle
2

Java 7, 62 Bytes

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

Ungolfed & Testcode:

Probieren Sie es hier aus.

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

Ausgabe:

0, 0, 1, 0, 1, 2, 3, 6
Kevin Cruijssen
quelle
2

Perl 5.10, 22 Bytes

21 Bytes + 1 Byte für -aFlag. Da der Ausdruck auf Regex-Basis erstellt wurde ...: p

Die Eingabewerte für das Array müssen durch ein Leerzeichen getrennt werden.

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

Probieren Sie es online!

Paul Picard
quelle
1
Etwas kürzer, wenn Sie Argumente über die Befehlszeile übernehmen: perl -E '$_++while pop;say' 0 1 1 0 1 1 1Dies gibt jedoch nichts aus für 0(nicht sicher, ob das ein Problem ist!)
Dom Hastings
2

Perl, 22 Bytes

21 Byte Code + 1 Byte für -pFlag.

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

Um es auszuführen:

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

(Eigentlich ist das Format der Eingabe keine Rolle spielt viel: 0110111, 0 1 1 0 1 1 1, [0,1,1,0,1,1,1]usw. würden alle Arbeit)


18-Byte-Version von @Dom Hastings , die Eingabe muss jedoch als Zeichenfolge von 0 und 1 angegeben werden, was nicht zulässig ist:

perl -pE '/1*$/;$_=length$&' <<< '0110111'
Dada
quelle
Lieben diesen ;Trick :) Wenn Format eine fortlaufende Zeichenfolge ist: perl -pE '/1*$/;$_=length$&' <<< '0110111'für 18, nicht sicher, ob das die Regeln verbiegt oder nicht ...
Dom Hastings
@ DomHastings ja, ich auch! (Danke, Ton, dass du mir das gezeigt hast!) Der erste und der zweite Kommentar der Frage verbieten irgendwie das Format der Eingabe, das du für deine Lösung benötigst ... Aber ich werde meinen Beitrag bearbeiten, um deine Version vorzuschlagen, wenn das Format der Eingabe mehr war kostenlos.
Dada
2

PHP, 50 Bytes

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

Seltsamerweise fiel mein erster Versuch mit einem Regex kürzer aus als mein Versuch mit Arrays ...
Verwendung wie:

php tt.php 1 1 0 1 1
user59178
quelle
2

Ruby 37 32 Bytes

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

Erstellt eine anonyme Funktion, die die am weitesten rechts stehende Instanz eines falschen Werts findet und die Größe des Subarrays ab diesem Wert zählt.

Es wird !0als false verwendet, da 0 in Ruby die Wahrheitswerte sind. rindexFindet den letzten Index eines Wertes in einem Array.

Verwendung :

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

Gibt 1 zurück


Wenn mir erlaubt wäre, eine Zeichenfolge von 0 und 1 als Befehlszeilenparameter zu übergeben (was nicht der Fall ist, wenn Ruby Listen von Booleschen Werten darstellt), könnte ich es auf 24 bringen:

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

Dabei werden reguläre Ausdrücke verwendet und die Länge der Zeichenfolge ausgegeben, die vom regulären Ausdruck zurückgegeben /(1*)\z/wird. Dabei \zhandelt es sich um das Ende der Zeichenfolge. $*[0]wird das erste Argument übergeben und ist eine Zeichenfolge aus 0s und 1s.

Verwendungszweck:

trailing_truths.rb 011101

Gibt 1 zurück.

IMP1
quelle
1
Wenn Sie den Index des letzten falschen Werts haben, warum müssen Sie Elemente erneut aus dem Array abrufen?
Lee W
Du hast recht, ich nicht. Vielen Dank. 5 Bytes aus!
IMP1