Compter les vérités de fuite

59

Inspiré par et en mémoire de mon cher ami et collègue,

Dan Baronet

Dan Baronet , 1956 - 2016. RIP

Il a trouvé la solution APL la plus courte possible pour cette tâche:

Tâche

Avec une liste booléenne, comptez le nombre de valeurs de vérité de fin.

Cas d'exemple

{}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
la source
Pouvons-nous prendre la liste comme une chaîne de zéros et de uns? par exemple 01100?
Adnan
@Adnan uniquement si c'est le moyen le plus normal pour votre langue de représenter des listes booléennes.
Adám
71
Désolé pour ta perte.
Martin Ender
6
@MartinEnder Merci. Ce sera difficile d'aller de l'avant. Dan m'a appris tout ce que j'avais besoin de savoir pour travailler chez Dyalog.
Adám
5
Adieu à Dan. RIP ...
Erik the Outgolfer

Réponses:

36

Dyalog APL, 6 2 octets

⊥⍨

Testez-le sur TryAPL .

Comment ça fonctionne

(Uptack, Dyadic: Decode) effectue la conversion de base. Si l'opérande de gauche est un vecteur, il effectue une conversion de base mixte , ce qui est parfait pour cette tâche.

Pour un vecteur de base b = b n , ⋯, b 0 et un vecteur de chiffres a = a n , ⋯, a 0 , b a convertit a en base mixte b , c'est-à-dire qu'il calcule b 0 ⋯ b n-1 a n + ⋯ + b 0 b 1 a 2 + b 0 a 1 + a 0 .

Maintenant, (tilde dieresis, commute) modifie l’opérateur à gauche comme suit. Dans un contexte monadique, il appelle l'opérateur avec les mêmes arguments gauche et droit.

Par exemple, ⊥⍨ a est défini comme un ⊥ a , qui calcule un 0 ⋯ a n + ⋯ + a 0 a 1 a 2 + a 0 a 1 + a 0 , somme de tous les produits cumulatifs de droite à gauche. .

Pour les k suivants , les k produits les plus à droite sont 1 et tous les autres sont 0 , leur somme est donc égale à k .

Dennis
la source
14
Astuce: Dan l'a fait en seulement deux octets.
Adám
3
Conversion de base mixte! C'est malin.
Dennis
1
Oh. Conversion de base mixte, comment elle frappe à nouveau.
Conor O'Brien
Bravo! En fait, à cause de Dan, nous avons privilégié les cas b⊥bet ⊥⍨baccéléré à l'infini.
Adám
19

JavaScript (ES6), 21 octets

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

Cas de test

Arnauld
la source
Comment cela marche-t-il? Comment f(l)+1renvoie une valeur > 2?
Oliver
@Oliver Ceci est un processus récursif, évalué en tant que l.pop()?(l.pop()?(l.pop()?(...etc...)+1:0)+1:0)+1:0.
Arnauld
Je vois. Merci pour l'explication.
Oliver
11

Gelée , 4 octets

ŒrṪP

Essayez-le en ligne! ou Vérifiez tous les cas de test.

Pour le cas où la liste est vide, il y a quelques observations curieuses. Tout d'abord, le codage par durée de la liste vide []renvoie une autre liste vide []. Ensuite, récupérer le dernier élément de celui-ci en utilisant des retours arrière 0au lieu d'une paire [value, count]qui sont les éléments normaux d'un tableau codé par longueur. Ensuite, le produit Previent 0lorsqu'il est appelé, 0ce qui correspond au résultat attendu.

Explication

ŒrṪP  Main link. Input: list M
Œr    Run-length encode
  Ṫ   Tail, get the last value
   P  Product, multiply the values together
milles
la source
Alternativement, ŒgṪSfonctionne aussi!
Lynn
Cela donne le bon résultat pour la liste vide en entrée, mais je suis surpris de la dissection. Cela vous dérangerait-il de traverser ce cas particulier?
Peter Taylor
@ PeterTaylor Je suis surpris aussi que cela a fonctionné. En outre, je viens de remarquer que le premier lien contient le mauvais code.
miles
@PeterTaylor en gelée est mis en œuvre: lambda z: iterable(z).pop() if iterable(z) else 0. iterablelorsqu'il est appelé sur une liste, il retourne simplement la liste, et la liste vide est évidemment falsifiée.
FryAmTheEggman
10

Brachylog , 7 6 5 octets

@]#=+

Essayez-le en ligne!

Explication

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

Du @] - Suffixdébut au plus petit suffixe, il trouvera le plus long terme en premier.

Fataliser
la source
10

CJam (8 octets)

{W%0+0#}

Suite de tests en ligne

Dissection

{    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
la source
10

Haskell, 26 à 25 octets

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

Usage:

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

Version sans point (26 octets):

length.fst.span id.reverse

Utiliser une liste entière au lieu d'une liste bool (21 octets, grâce à Christian Sievers):

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

Usage:

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

Version sans points (25 octets)

sum.fst.span(==1).reverse
Laikoni
la source
Pour les listes entières, l' foldlidée fonctionne aveca%b=b*(a+1)
Christian Sievers
9

Retina , 7 5 bytes

r`1\G

Essayez-le en ligne! (La première ligne active une suite de tests séparée par saut de ligne.)

Définir le format d’entrée pour Retina n’est pas totalement ambigu. Puisque Retina n’a aucun concept, à l’exception des chaînes (et qu’aucune valeur ne puisse être utilisée pour notre définition habituelle de la vérité et de la fausseté), j’utilise habituellement 0et 1(ou quelque chose de positif en général) pour correspondre à la vérité et à la fausseté, car elles représentent zéro ou quelques correspondances, respectivement.

Avec les représentations à un seul caractère, nous n’avons pas non plus besoin d’un séparateur pour la liste (ce qui est en quelque sorte une représentation de liste plus naturelle pour une langue qui n’a que des chaînes). Adám a confirmé qu'il s'agissait d' un format d'entrée acceptable.

Quant à l'expression rationnelle elle-même, elle correspond de rhaut à gauche et \Gancre chaque correspondance sur la précédente. Par conséquent, cela compte combien de 1s nous pouvons apparier à partir de la fin de la chaîne.

Martin Ender
la source
"Oui, pour Retina, étant donné qu'elle ne gère que des chaînes, je pense qu'une chaîne" 01 "ou" FT "est dans l'ordre.
Adm
9

05AB1E , 12 10 6 5 octets

Sauvegardé 1 octet grâce à carusocomputing .

Î0¡¤g

Essayez-le en ligne!

Explication

Î      # push 0 and input
 0¡    # split on 0
   ¤   # take last item in list
    g  # get length
Emigna
la source
0¡¤gest quatre octets.
Urne magique Octopus
@carusocomputing: Nice! Il n'a pas encore été précisé si l'entrée de chaîne était correcte lorsque j'ai écrit cela, mais je vois maintenant qu'elle l'est :)
Emigna
J0¡¤gest également encore plus courte;).
Urne Magique Octopus
@carusocomputing: Malheureusement, nous devons Îgérer les entrées vides, mais cela reste un octet enregistré grâce à :)
Emigna
8

Python, 31 octets

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

Gelée , 4 octets

ṣ0ṪL

TryItOnline! ou tous les tests

Comment?

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

Mathematica, 25 24 octets

Fold[If[#2,#+1,0]&,0,#]&
Alephalpha
la source
3
J'enregistre juste un port de la solution à base mixte de Dan: FromDigits[b=Boole@#,MixedRadix@b]&(35 octets).
Greg Martin
5

Pyth, 6 octets

x_+0Q0

Essayez-le ici!

Ajoute un 0, renverse et trouve l'index du premier 0

Bleu
la source
@Jakube corrigé maintenant - algorithme différent
Bleu
5

C90 (gcc), 46 octets

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

L'entrée s'effectue via des arguments de ligne de commande (un entier par argument), la sortie via le code de sortie .

Essayez-le en ligne!

Comment ça fonctionne

r est une variable globale. Son type par défaut est int et, étant global, sa valeur par défaut est 0 .

L'argument fonction c par défaut int ainsi. Il contiendra l'entier n + 1 pour les tableaux de n booléens; le premier argument de main est toujours le chemin de l'exécutable.

L'argument de la fonction v est déclaré comme int**. Le type réel de v sera char**, mais comme nous n'examinerons que le bit le moins significatif de chaque argument pour distinguer les caractères 0 (point de code 48 ) et 1 (point de code 49 ), cela ne sera pas important pour little-endian Machines.

La boucle while décrémente c et la compare à 0 . Une fois que c atteint 0 , nous sortirons de la boucle. Cela n'est nécessaire que si le tableau ne contient pas de 0 .

Tant que 0<--crenvoie 1 , nous prenons le c ème argument de ligne de commande ( v[c]) et extrayons son premier caractère en déréférencant le pointeur ( *). Nous prenons l'ET au bit ET du booléen 0<--cet le point de code du caractère (ainsi que trois octets parasites qui le suivent), de sorte que la condition retourne 0 une fois qu'un 0 est rencontré, sortant de la boucle.

Dans le cas restant, alors que les arguments de ligne de commande sont à 1 , r++incrémente r de 1 , en comptant ainsi le nombre de 1 en fin de chaîne .

Enfin, c=rstocke la valeur calculée de r dans c . Avec les paramètres par défaut, le compilateur optimise et supprime l’affectation; il génère effectivement l' movl %eax, -4(%rbp)instruction. Étant donné que retrenvoie la valeur du registre EAX, cela génère la sortie souhaitée.

Notez que ce code ne fonctionne pas avec C99, qui renvoie 0 du principal si la fin du principal est atteinte.

Dennis
la source
N'est-ce pas argcau moins 1( argv[0]contenant le nom du fichier)? Vous pouvez enregistrer un octet avec --c&&au lieu de 0<--c&. Le code de sortie de gcc est extrait de argc? Soigné.
Titus
@ Titus Cela ne fonctionnera pas. *v[c]est le point de code de 1 ou 0 , il est donc soit 49 ou 48 et donc toujours la vérité.
Dennis
Avec C89 et C90, gcc renvoie tout ce qui est dans RAX à ce moment-là. C99 renvoie toujours 0 depuis le principal si la fin est atteinte.
Dennis
4

k, 6 octets

+/&\|:

Cette composition de fonction se traduit en sum mins reversein q, le frère de la langue, plus lisible, où min est un minimum glissant.

skeevey
la source
Le: peut-il être supprimé?
streetster
4

J, 9 3 octets

#.~

Ceci est une conversion de base mixte réflexive. Parce que c'est la même chose qu'une conversion de base mixte. Encore.

Cas de test

   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
la source
2
Astuce: Cela ne peut être fait que dans 3 octets, en utilisant la traduction J de la solution de Dan.
Adám
1
@ Adám j'ai essayé de chercher une solution. Je n'ai pas pensé à la conversion de base. C'est vraiment très intelligent de sa part!
Conor O'Brien
1
Oui. C'était Dan. :-(
Adám
4

R, 40 39 25 octets

Solution entièrement retravaillée grâce à @Dason

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

Lire l’entrée de stdin, inverser le vecteur et si le premier élément de est !=0alors la première longueur de l’encodage de longueur ( rle), sinon 0.

Billywob
la source
1
Vous pouvez enregistrer un octet en remplaçant la deuxième ligne par ifelse(r$v,r$l,0)[1]. (Vectorisé si, puis prenez le premier élément.)
rturnbull
1
pas besoin de iflelse - il suffit de multiplier r $ v et r $ l.
Dason
Mais la somme (cumprod (rev (.))) Route devrait économiser beaucoup d'octets de toute façon
Dason
3

Haskell, 24 octets

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

Itère sur la liste, en ajoutant un pour chaque élément et en le réinitialisant 0après avoir atteint un False.

16 octets avec une entrée 0/1:

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

Si la liste était garantie non vide, nous pourrions obtenir 14 octets:

sum.scanr1(*)1

Ceci calcule le produit cumulatif à l’arrière, puis les additionne. Le produit cumulatif reste 1 jusqu'à ce qu'un 0 soit atteint, puis devient 0. Ainsi, les 1 correspondent aux 1 derniers.

Xnor
la source
3

C # 6, 103 72 octets

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

L'utilisation d'une liste non générique bat la liste générique d'un octet lol

-31 octets grâce à Scott

Link Ng
la source
Si vous utilisez un tableau de ints, vous pouvez vous en sortirint a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum();
Scott Le
@ Scott Bien sûr, à quoi étais-je en train de penser? La question spécifie la liste booléenne et ce n'est pas C.
Lien Ng
Compiler en Func<bool[], int>57 octets, c'estusing System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count();
TheLethalCoder
2

Python, 37 octets

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

DASH , 16 octets

@len mstr"1+$"#0

Ce n'est pas la solution DASH la plus courte possible, mais la solution DASH la plus courte possible me dérange. Je poste cette nouvelle approche à sa place.

Usage:

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

Explication

@(                 #. 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
)
Maman Fun Roll
la source
2

Scala, 25 octets

l=>l.reverse:+0 indexOf 0

Ungolfed:

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

Inverse la liste, ajoute un 0 et trouve le premier index de 0, qui est le nombre d'éléments avant le premier 0

corvus_192
la source
2

Lot, 57 octets

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

Prend les entrées en tant que paramètres de ligne de commande. Fonctionne en multipliant l'accumulateur par la valeur actuelle avant de l'ajouter, de sorte que les zéros de la ligne de commande réinitialisent le décompte. Notez que ce %%nn'est pas la même chose que la variable nou %n%.

Neil
la source
2

GolfSharp, 14 octets

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

Java 7, 62 octets

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

Ungolfed & code de test:

Essayez ici.

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

Sortie:

0, 0, 1, 0, 1, 2, 3, 6
Kevin Cruijssen
la source
2

Perl 5.10, 22 octets

21 octets + 1 octet pour le -adrapeau. Depuis que l'expression à base de regex a été faite ...: p

Les valeurs d'entrée du tableau doivent être séparées par un espace.

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

Essayez-le en ligne!

Paul picard
la source
1
Légèrement plus court si vous prenez les arguments via la ligne de commande: perl -E '$_++while pop;say' 0 1 1 0 1 1 1mais cela ne génère rien pour 0(ne savez pas si c'est un problème cependant!)
Dom Hastings
2

Perl, 22 octets

21 octets de code + 1 octet pour le -pdrapeau.

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

Pour l'exécuter:

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

( En fait, le format de l'entrée n'a pas d' importance beaucoup: 0110111, 0 1 1 0 1 1 1, [0,1,1,0,1,1,1]etc. seraient tous les travaux)


Version de 18 octets de @Dom Hastings mais il faut fournir l'entrée sous la forme d'une chaîne de 0 et de 1, ce qui n'est pas autorisé:

perl -pE '/1*$/;$_=length$&' <<< '0110111'
Dada
la source
J'adore ce ;truc :) Si le format est une chaîne continue: perl -pE '/1*$/;$_=length$&' <<< '0110111'pour 18 ans, je ne suis pas sûr que cela plie les règles ou pas ...
Dom Hastings
@DomHastings oui, moi aussi! (Merci Ton de m'avoir montré cela!) Les premier et deuxième commentaires de la question interdisent un peu le format de saisie dont vous avez besoin pour votre solution ... Mais je vais éditer mon post pour suggérer votre version si le format de saisie était plus libre.
Dada
2

PHP, 50 octets

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

Bizarrement, mon premier essai avec une regex s'est avéré plus court que mon essai avec des tableaux ...
Utilisez comme:

php tt.php 1 1 0 1 1
utilisateur59178
la source
2

Ruby 37 32 octets

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

Crée une fonction anonyme qui recherche l'instance la plus à droite d'une valeur false et compte la taille du sous-tableau à partir de cette valeur.

Il utilise !0comme faux, comme 0 sont des valeurs de vérité en Ruby. rindextrouve le dernier index d'une valeur dans un tableau.

Utilisation :

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

Retourne 1


Si on me permettait de passer une chaîne de 0 et de 1 en tant que paramètres de ligne de commande (ce n'est pas comme ça que ruby ​​représente des listes de booléens), je pourrais le réduire à 24:

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

Cela utilise des expressions régulières et affiche la longueur de la chaîne renvoyée par l'expression régulière /(1*)\z/, où \zest la fin de la chaîne. $*[0]est le premier argument passé et est une chaîne de 0 et de 1.

Usage:

trailing_truths.rb 011101

Retourne 1.

IMP1
la source
1
Une fois que vous avez l'index de la dernière fausse valeur, pourquoi devez-vous extraire à nouveau des éléments du tableau?
Lee W
Tu as raison, moi pas. Merci. 5 octets de moins!
IMP1