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


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 .


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


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

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.


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
}

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

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.


"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

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




7

Mathematica, 25 24 Bytes

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

3
Einfach einen Port von Dans cooler Mixed-Base-Lösung aufzeichnen: FromDigits[b=Boole@#,MixedRadix@b]&(35 Bytes).
Greg Martin


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.


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.


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

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.


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.



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


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]

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
)

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


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.



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

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!


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'

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

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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.