Nombres binaires parenthifiables

28

Si vous exprimez un entier positif en binaire sans zéros de tête et remplacez chaque 1par a (et chaque 0par a ), alors toutes les parenthèses correspondront-elles?

Dans la plupart des cas, ils ne le feront pas. Par exemple, 9 est 1001en binaire, qui devient ())(, où seules les deux premières parenthèses correspondent.

Mais parfois, ils correspondent. Par exemple, 44 est 101100en binaire, qui devient ()(()), où toutes les parenthèses gauches ont une parenthèse droite correspondante.

Écrivez un programme ou une fonction qui prend un entier de base positif dix et affiche ou retourne une valeur vraie si la version binaire entre parenthèses du nombre a toutes les parenthèses correspondantes. Si ce n'est pas le cas, imprimez ou renvoyez une valeur falsifiée .

Le code le plus court en octets gagne.

Séquence OEIS associée.

Exemples véridiques inférieurs à 100:

2, 10, 12, 42, 44, 50, 52, 56

Exemples de fausseté inférieurs à 100:

1, 3, 4, 5, 6, 7, 8, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 45, 46, 47, 48, 49, 51, 53, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
Loisirs de Calvin
la source
5
Plus OEIS
Mego
10
Il y a une séquence pour tout ...
Arcturus

Réponses:

8

TeaScript , 9 octets 16 18 20 22 24

Enregistré 2 octets grâce à @ETHproductions

!x÷W(n,¢)

Woah. C'est court. Utilise l'approche de @ xnor. Cela utilisera la fonction de remplacement récursif ( W) qui remplacera tout 10égal à ()rien. Si la chaîne est vide, elle est équilibrée.


L'utilisation d'une version de TeaScript créée après la publication de ce défi pourrait devenir 7 octets:

!x÷W(n)

Non golfé

!xT(2)W(n,``)

Explication

!      // NOT, returns true if empty string, else false
 xT(2)   // To binary
 W(n,``) // n is 10, reclusive replaces 10 or (), with nothing.
Downgoat
la source
1
Excellent! Deux choses qui pourraient aider: 1) Si c'est de la fausse montée, c'est déjà de la fausse descente, donc vous ne devriez pas avoir besoin du premier tilde. 2) Je crois que ~--cc'est faux dans exactement le même scénario que c--.
ETHproductions
@ETHproductions génial, merci! Maintenant, je suis à 16 octets
Downgoat
13

Pyth, 10 octets

!uscG`T.BQ

Essayez cette suite de tests dans le compilateur Pyth.

Comment ça marche

              (implicit) Store the evaluated input in Q.
       .BQ    Return the binary string representation of Q.
 u            Reduce w/base case; set G to .BQ and begin a loop:
     `T         Return str(10) = "10".
   cG           Split G (looping variable) at occurrences of "10".
  s             Join the pieces without separators.
              Set G to the returned string.
              If the value of G changed, repeat the loop.
              This will eventually result in either an empty string or a
              non-empty string without occurrences of "10".
!             Return (and print) the logical NOT of the resulting string.
Dennis
la source
J'ai trouvé l'équivalent !u:G`Tk.BQ. Sans doute plus facile à comprendre.
orlp
Oui, c'est certainement un choix plus naturel.
Dennis
8

Python2, 87 octets

try:exec"print 1,"+"".join(["],","["][int(c)]for c in bin(input())[2:])
except:print 0

Une implémentation terrible qui abuse des erreurs de syntaxe.

orlp
la source
3
C'est le golf de code. Terrible est un compliment.
corsiKa
8

JavaScript (ES6), 55 54 51 octets

n=>![...n.toString(d=2)].some(c=>(d+=c*2-1)<2)*d==2

Octets enregistrés grâce à @ Vɪʜᴀɴ et @xsot !

Explication

n=>
  ![...n.toString(    // convert the input to an array of binary digits
    d=2)]             // d = current depth (+2)
      .some(c=>       // iterate through the digits
        (d+=c*2-1)    // increment or decrement the parenthesis depth
          <2          // if the depth goes negative, return false
      )*
        d==2          // if we finished at a depth of 0, return true
user81655
la source
1
Vous pouvez enregistrer deux octets en supprimant ceux qui ne sont pas nécessaires f=. Vous pouvez également utiliser use +cau lieu de c|0to case à un entier. Vous pouvez également utiliser (+c?d++:d--)ce qui est encore plus court
Downgoat
@ Vɪʜᴀɴ OK. Existe-t-il une sorte de guide pour savoir quand je dois l'utiliser f=? Parce que beaucoup d'autres réponses JavaScript sur le site nomment leurs fonctions.
user81655
1
En règle générale, vous ne devez donner un nom à la fonction que si le défi vous y oblige. Sinon, il est prudent de supposer que les fonctions sans nom sont correctes.
Alex A.
Dans Firefox, l'exécution de ceci pour 11, retourne truequand il devrait revenirfalse
Downgoat
2
Je ne connais pas javascript, mais j'ai essayé de couper quelques octets et cela fonctionne en chrome:n=>![...n.toString(d=2)].some(c=>(d+=c*2-1)<2)*d==2
xsot
7

Python 2, 45 octets

f=lambda n,i=1:i*n>0<f(n/2,i+(-1)**n)or n<i<2

Une fonction récursive. Lit les chiffres binaires nde la fin, en comptant ile niveau d'imbrication actuel des parens. S'il tombe en dessous 0, rejetez. Lorsque nous atteignons le début, vérifie si le nombre est 0.

En fait, nous commençons le décompte à i=1pour qu'il soit facile de vérifier s'il est tombé 0. Le seul cas de réussite du terminal est n==0et i==1, vérifié avec n<i<2. Nous forçons cette vérification à se produire si n==0, ou si elle itombe 0, auquel cas elle échoue automatiquement.

feersum a économisé deux octets en restructurant les cas non récursifs avec des inégalités de court-circuit.

xnor
la source
3
A besoin de plus d'abus conditionnel. f=lambda n,i=1:n>0<i*f(n/2,i+(-1)**n) or n<i<2, au moins, sauve 1.
feersum
6

CJam, 11 octets

ri2b"}{"f=~

C'est un peu impur: pour les nombres entre parenthèses, il imprimera un ou plusieurs blocs. Pour les numéros sans parenthèse, il se bloquera sans rien imprimer sur STDOUT. Si vous essayez ceci en ligne dans l' interpréteur CJam , gardez à l'esprit qu'il ne fait pas de distinction entre STDOUT et STDERR.

Étant donné que les chaînes non vides / vides sont véridiques / fausses dans CJam et que la sortie imprimée est toujours une chaîne, elle respecte sans doute les règles. Au coût supplémentaire de 3 octets supplémentaires , pour un total de 14 octets , on peut en fait une laisse truthy ou falsy chaîne sur la pile qui sera imprimé:

Lri2b"}{"f=~]s

Cela se bloque toujours pour les numéros sans parenthèse, ce qui est autorisé par défaut .

Essais

$ cjam <(echo 'ri2b"}{"f=~') <<< 52 2>&-; echo
{{}{}}
$ cjam <(echo 'ri2b"}{"f=~') <<< 53 2>&-; echo

$ cjam <(echo 'ri2b"}{"f=~') <<< 54 2>&-; echo

$ cjam <(echo 'ri2b"}{"f=~') <<< 55 2>&-; echo

$ cjam <(echo 'ri2b"}{"f=~') <<< 56 2>&-; echo
{{{}}}

Comment ça marche

ri          e# Read an integer from STDIN.
  2b        e# Push the array of its binary digits.
    "}{"f=  e# Replace 0's with }'s and 1's with {'s.
          ~ e# Evaluate the resulting string.
            e# If the brackets match, this pushes one or more blocks.
            e# If the brackets do not match, the interpreter crashes.

CJam, 15 octets

ri2bs_,{As/s}*!

Essayez ce violon dans l'interpréteur CJam ou vérifiez tous les cas de test à la fois .

Comment ça marche

ri               Read an integer from STDIN.
  2b             Push the array of its binary digits.
    s            Cast to string.
     _,          Push the string's length.
       {    }*   Do that many times:
        As/        Split at occurrences of "10".
           s       Cast to string to flatten the array of strings.
              !  Push the logical NOT of the result.
Dennis
la source
1
zut, tu me bat à peine à nouveau ....
GamrCorps
6

Python, 51 octets

lambda n:eval("'0b'==bin(n)"+".replace('10','')"*n)

Une fonction anonyme. Évalue une expression qui ressemble à

'0b'==bin(n).replace('10','').replace('10','').replace('10','')...

Chaque remplacement supprime tout 10ce qui correspond (). Une fois tous les remplacements effectués, la fonction retourne si ce qui reste n'est que le préfixe binaire 0b. Il suffit plus que de faire des nremplacements, car un knombre à -digit prend au plus des k/2étapes et sa valeur est la plus élevée 2**k.

xnor
la source
4

Rubis, 40

->i{n='%0b'%i;1while n.slice!'10';n<?0}

Manipulation de chaîne simple. Laisse '10' jusqu'à ce qu'il n'en reste plus.

Pas que Charles
la source
4

Sérieusement , 17 octets

,;2@¡@`""9u$(Æ`nY

Sorties 0pour faux et 1pour vrai. Essayez-le en ligne .

Explication:

,      get value from stdin
;      dupe top of stack
2@¡    pop a: push a string containing the binary representation of a (swapping to get order of operands correct)
@      swap top two elements to get original input back on top
`""9u$(Æ` define a function:
  ""     push empty string
  9u$    push "10" (push 9, add 1, stringify)
  (      rotate stack right by 1
  Æ      pop a,b,c: push a.replace(b,c) (replace all occurrences of "10" in the binary string with "")
n      pop f,a: call f a times
Y      pop a: push boolean negation of a (1 if a is falsey else 0)
Mego
la source
4

Japt, 23 octets

Japt est une version abrégée de Ja vaScri pt . Interprète

Us2 a e@+X?++P:P-- &&!P

Cela me rappelle jusqu'où Japt doit encore aller par rapport à TeaScript. Après avoir réorganisé l'interprète dans les prochains jours, j'aimerais ajouter des caractères de "raccourci" comme Vɪʜᴀɴ.

Comment ça marche

       // Implicit: U = input number, P = empty string
Us2 a  // Convert U to base 2, then split the digits into an array.
e@     // Assert that every item X in this array returns truthily to:
 +X?   //  If X = 1,
 ++P   //   ++P. ++(empty string) returns 1.
 :P--  //  Otherwise, P--. Returns false if P is now -1.
&&!P   // Return the final result && !P (true if P is 0; false otherwise).
       // Implicit: output final expression

Peu de temps après ce défi, @ Vɪʜᴀɴ (maintenant connu sous le nom de @Downgoat) m'a aidé à implémenter une fonction de remplacement récursif, comme Wdans la réponse TeaScript. Cela signifie que ce défi peut désormais être effectué en seulement 5 octets:

!¢eAs  // Implicit: U = input integer, A = 10
 ¢     // Convert U to binary.
  eAs  // Recursively remove instances of A.toString().
!      // Return the logical NOT of the result (true only for the empty string).

Testez-le en ligne!

ETHproductions
la source
3

Mathematica, 49 octets

(#~IntegerDigits~2//.{x___,1,0,y___}:>{x,y})=={}&
alephalpha
la source
Je ne peux pas lire Mathematica. Explication, s'il vous plaît? :)
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Convertissez le nombre en base 2 (sous forme de liste), puis supprimez-le à plusieurs reprises 1,0de la liste et testez si le résultat est une liste vide.
alephalpha
3

Octave, 48 octets

@(a)~((b=cumsum(2*dec2bin(a)-97))(end)|any(b<0))
alephalpha
la source
3

C ++, 104 94 octets

#include<iostream>
int n,c;int main(){for(std::cin>>n;n&c>=0;n>>=1)c+=n&1?-1:1;std::cout<<!c;}

Exécuter avec ce compilateur , doit spécifier une entrée standard avant de s'exécuter.

Explication

  • Les déclarations en dehors de main initialisent à 0.
  • La lecture d'une décimale se transforme implicitement en binaire, car il s'agit d'un ordinateur.
  • Nous vérifions les bits / parenthèses de droite à gauche à cause de n>>=1.
  • c+=n&1?-1:1conserve le nombre de parenthèses ouvertes ).
  • n&c>=0 s'arrête lorsqu'il ne reste que des 0 en tête ou que les parenthèses se ferment plus qu'elles n'ouvrent.
Linus
la source
3

Haskell, 49 46 octets

0#l=l==1
_#0=2<1
n#l=div n 2#(l+(-1)^n)
f=(#1)

Exemple d'utilisation: f 13-> False.

Je garde une trace du niveau d'imbrication lcomme beaucoup d'autres réponses. Cependant, le cas «équilibré» est représenté par 1, donc le cas «plus- )que- (» l'est 0.

PS: a trouvé l'ajustement du niveau d'imbrication l+(-1)^ndans la réponse de xnor .

nimi
la source
Cela signumsemble trop compliqué, pourquoi pas juste _#0=1<0?
xnor
@xnor: oui, merci.
nimi
Pourquoi pas à la l>0place de l==1?
Michael Klein
@MichaelKlein: parce que seul l==1est équilibré. Si l>1, les parenthèses ne sont pas équilibrées.
nimi
@nimi Je vois, j'ai mal interprété comment cela fonctionne
Michael Klein
3

Python 2, 60 57 56 55 53 52 50 49 octets

n=input()
i=1
while i*n:i+=1|n%-2;n/=2
print i==1

Merci à xnor pour avoir économisé deux octets et feersum pour avoir porté le nombre final d'octets à 49!

Explication

Le numéro d'entrée,, nest traité à partir de son bit le moins significatif. iest un compteur qui garde la trace du nombre de 0 et de 1. Notez qu'il est initialisé 1pour enregistrer un octet. La boucle s'interrompra avant d' natteindre 0 si le nombre de 1 dépasse le nombre de 0 ( i<=0).

Pour que les parenthèses soient équilibrées, deux conditions sont requises:

  • Le nombre de 0 et de 1 est égal (c.-à-d. i==1)
  • Le nombre de 1 ne dépasse jamais le nombre de 0 pendant ce processus (c'est-à-dire que la boucle ne s'interrompt pas prématurément n==0). Edit: J'ai réalisé que cette condition n'est pas nécessaire car elle idoit être non positive si n!=0la condition précédente est suffisante.
xsot
la source
Si iet ne nsont pas négatifs, alors i==n==0c'est i+n==0.
orlp
ipeut être négatif si la boucle s'interrompt prématurément.
xsot
En fait, i|n==0devrait toujours fonctionner.
orlp
Grande suggestion, cette ligne semble meilleure maintenant.
xsot
while i*ndevrait fonctionner
xnor
3

JavaScript ES5, 118 87 85 82 77 octets

Technique intéressante à mon avis. Beaucoup moins, grâce à @ETHproductions et @NotthatCharles

function p(x){x=x.toString(2);while(/10/.test(x))x=x.replace(10,"");return!x}

JavaScript ES6, 77 57 56 54 octets

-21 octets aux productions ETH.

x=>[...x=x.toString(2)].map(_=>x=x.replace(10,""))&&!x
Conor O'Brien
la source
J'aime la traduction entre parenthèses. Cependant, si vous le laissez en 1 et en 0, c'est un peu plus court:function p(x){x=x.toString(2);r=/10/;while(x.search(r)>=0){x=x.replace(r,"")}return!x}
ETHproductions
@ETHproductions Bon point! Je pense que je vais laisser l'autre code en bas, j'aime vraiment l'algorithme ^ _ ^ Merci mon pote!
Conor O'Brien
La version ES6 peut toujours être jouée un tas: x=>([...x=x.toString(2)].map(_=>x=x.replace(/10/,"")),!x)L'astuce est de déplacer la boucle while dans un .map, car il n'y a jamais plus de 10 dans une entrée que sa longueur.
ETHproductions
@ETHproductions Merci encore ^ _ ^ Belle astuce avec map.
Conor O'Brien
Pas de problème :) BTW, un autre octet peut être sauvegardé avec une astuce qu'edc65 utilise tout le temps: x=>[...x=x.toString(2)].map(_=>x=x.replace(/10/,""))&&!xIDK s'il peut devenir plus court cependant.
ETHproductions du
2

D, 209 170 octets

import std.stdio;import std.format;import std.conv;void main(char[][]a){string b=format("%b",to!int(a[1]));int i;foreach(c;b){i+=c=='1'?1:-1;if(i<0)break;}writeln(i==0);}

Cela fait exactement ce qu'il est censé faire sans ajouts ni avantages.

phase
la source
2

C, 67 octets

n;main(i){for(scanf("%d",&n);n*i;n/=2)i+=1-n%2*2;putchar(48+!~-i);}

À peu près un portage de ma soumission python.

xsot
la source
2

Prolog, 147 octets

b(N,[X|L]):-N>1,X is N mod 2,Y is N//2,b(Y,L).
b(N,[N]).
q([H|T],N):-N>=0,(H=0->X is N+1;X is N-1),q(T,X).
q([],N):-N=0.
p(X):-b(X,L),!,q(L,0).

Comment ça marche

b(N,[X|L]):-N>1,X is N mod 2,Y is N//2,b(Y,L).
b(N,[N]).

Convertit le nombre décimal N en sa représentation binaire sous forme de liste (inversée). Sens:

b(42,[0,1,0,1,0,1]) is true

Ensuite:

q([H|T],N):-N>=0,(H=0->X is N+1;X is N-1),q(T,X).
q([],N):-N=0.

Récursive sur la liste [H | T] en augmentant N si l'élément head vaut 0 sinon en le diminuant.
Si N à tout moment devient négatif ou si N à la fin n'est pas 0, retourne faux, sinon vrai.

La coupure

p(X):-b(X,L),!,q(L,0).

Existe-t-il pour empêcher le retour en arrière et trouver des solutions non binaires aux

tests b (N, [N])
Essayez-le en ligne ici
Exécutez-le avec une requête comme:

p(42).
Emigna
la source
2

PowerShell, 106 octets

param($a)$b=[convert]::ToString($a,2);1..$b.Length|%{if($b[$_-1]%2){$c++}else{$c--}if($c-lt0){0;exit}};!$c

Je ne gagnerai aucune compétition de la plus courte durée, c'est certain. Mais bon, au moins ça bat Java?

Utilise l'appel très long .NET [convert]::ToString($a,2)pour convertir notre numéro d'entrée en une chaîne représentant les chiffres binaires. Nous passons ensuite en boucle à travers cette chaîne avec 1..$b.length|%{..}. Chaque boucle, si notre chiffre est un 1(évalué avec %2plutôt que -eq1pour économiser quelques octets), nous incrémentons notre compteur; sinon, on le décrémente. Si nous atteignons un résultat négatif, cela signifie qu'il y a eu plus )que ce qui a été (rencontré jusqu'à présent, alors nous produisons 0et exit. Une fois que nous avons parcouru la boucle, $cest soit 0un certain nombre >0, alors nous prenons le non logique de celui- !ci, qui obtient la sortie.

Cela a la particularité de sortir 0si les parens ne correspondent pas parce que nous en avons plus ), mais de sortir Falsesi les parens ne correspondent pas parce que nous en avons plus (. Déclarations de fausseté essentiellement fonctionnellement équivalentes, juste intéressantes. Si les parens correspondent tous, les sorties True.

AdmBorkBork
la source
D'accord, bien sûr. (Eh bien, si je peux résoudre le doute persistant que je résous le mauvais problème, je le ferai).
TessellatingHeckler
1

GNU Sed (avec extension eval), 27

s/.*/dc -e2o&p/e
:
s/10//
t

Sed n'a pas vraiment une idée définie de véridique et de falsey, alors ici je prétends que la chaîne vide signifie véridique et toutes les autres chaînes signifient falsey.

Si cela n'est pas acceptable, nous pouvons alors procéder comme suit:

GNU Sed (avec extension eval), 44

s/.*/dc -e2o&p/e
:
s/10//
t
s/.\+/0/
s/^$/1/

Cela renvoie 1 pour véridique et 0 sinon.

Traumatisme numérique
la source
1

𝔼𝕊𝕄𝕚𝕟 (ESMin), 21 caractères / 43 octets

ô⟦ïßḂ]Ĉ⇀+$?⧺Ḁ:Ḁ‡)⅋!Ḁ)

Try it here (Firefox only).

Notez que cela utilise des variables prédéfinies à des nombres (spécifiquement 2 et 0). Il existe des variables numériques prédéfinies de 0 à 256.

19 caractères / 40 octets, non concurrentiel

⟦ïßḂ]Ĉ⇀+$?⧺Ḁ:Ḁ‡)⅋!Ḁ

Try it here (Firefox only).

Décidé d'implémenter la sortie implicite ... Cependant, les formulaires de sortie précédents sont toujours pris en charge, vous avez donc plusieurs options de sortie!

Mama Fun Roll
la source
parce que tout le monde mesure par nombre de caractères
phase
1

Java, 129 131 octets

boolean T(int i){int j=0,k=0;for(char[]a=Integer.toString(i,2).toCharArray();j<a.length&&k>=0;j++){k+=a[j]=='1'?1:-1;}return k==0;}

Peut probablement être raccourci. Explication à venir. Merci à Geobits pour 4 octets de moins!

GamrCorps
la source
Est-il possible de combiner int k=0;avec int j=0;?
ETHproductions
Non, j est une variable interne dans la boucle for et ne peut pas être référencée en dehors de celle-ci.
GamrCorps
Vous devriez cependant pouvoir combiner dans l'autre sens: int k=0,j=0;for(...vous pouvez ensuite placer la char[]déclaration dans l'initialiseur de boucle pour enregistrer un point-virgule également.
Geobits
Le plus gros problème est que cela donne des faux positifs. Il renvoie vrai pour 9, 35, 37, 38, par exemple .
Geobits
@Geobits oups, je ne m'en suis même pas rendu compte, je le réparerai quand j'en aurai l'occasion.
GamrCorps
1

C ++, 61 octets

Je pense que la réponse C ++ actuelle est fausse: elle retourne une valeur véridique pour tous les nombres pairs, par exemple 4. Avertissement: Je n'ai pas pu utiliser le compilateur mentionné, j'ai donc utilisé g ++ 4.8.4. Le problème réside dans l'utilisation de l'opérateur binaire ET au lieu de l'opérateur logique ET qui est utilisé pour rompre tôt lorsque le nombre de parenthèses fermantes dépasse le nombre de parenthèses ouvrantes. Cette approche pourrait fonctionner si trueest représentée comme un mot avec un motif de bits vrai. Sur mon système, et probablement la plupart des autres systèmes, trueest équivalent à 1; un seul bit est vrai. En outre, n/=2est plus court que n>>=1. Voici une version améliorée en fonction:

int f(int n,int c=0){for(;c>=0&&n;n/=2)c+=n&1?-1:1;return c;}
vysar
la source
0

𝔼𝕊𝕄𝕚𝕟 (très non compétent), 6 caractères / 8 octets

!ïⓑĦⅩ

Try it here (Firefox only).

J'ai décidé de revisiter ce défi après très, très longtemps. 𝔼𝕊𝕄𝕚𝕟 s'est tellement amélioré.

La raison pour laquelle il s'agit d'une réponse distincte est que les 2 versions sont presque complètement différentes.

Explication

Convertit l'entrée en binaire, remplace récursivement les instances de 10, puis vérifie si le résultat est une chaîne vide.

Mama Fun Roll
la source
0

C # 98 octets

bool f(int m){int i=0;foreach(char s in Convert.ToString((m),2)){if(s=='1')i+=2;i--;}return i==0;}

ouvert à toutes suggestions. j'aime ce défi même si c'est vieux

downrep_nation
la source