Numeri binari separabili


28

Se esprimi un numero intero positivo in binario senza zeri iniziali e sostituisci ogni 1con a (e ogni 0con a ), allora tutte le parentesi corrisponderanno?

Nella maggior parte dei casi non lo faranno. Ad esempio, 9 è 1001in binario, che diventa ())(, dove corrispondono solo le prime due parentesi.

Ma a volte combaceranno. Ad esempio, 44 ​​è 101100in binario, che diventa ()(()), in cui tutte le parentesi sinistre hanno una parentesi destra corrispondente.

Scrivi un programma o una funzione che accetta un numero intero di base positivo dieci e stampa o restituisce un valore di verità se la versione tra parentesi binarie del numero ha tutte le parentesi corrispondenti. In caso contrario, stampare o restituire un valore errato .

Vince il codice più breve in byte.

Sequenza OEIS correlata.

Esempi veritieri inferiori a 100:

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

Esempi di falsi inferiori a 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


10
C'è una sequenza per tutto ...
Arcturus,

Risposte:


8

TeaScript , 9 byte 16 18 20 22 24

Salvato 2 byte grazie a @ETHproductions

!x÷W(n,¢)

Woah. Questo è breve. Usa l'approccio di @ xnor. Questo utilizzerà la funzione di sostituzione ricorsiva ( W) che sostituirà tutto 10uguale a ()con niente. Se la stringa è vuota è bilanciata.


Utilizzando una versione di TeaScript creata dopo che questa sfida è stata pubblicata, questo potrebbe diventare 7 byte:

!x÷W(n)

Ungolfed

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

Spiegazione

!      // NOT, returns true if empty string, else false
 xT(2)   // To binary
 W(n,``) // n is 10, reclusive replaces 10 or (), with nothing.

1
Eccellente! Due cose che potrebbero aiutare: 1) Se è falso quando si sale, è già stato un errore, quindi non dovresti aver bisogno della prima tilde. 2) Credo che ~--csia falso esattamente nello stesso scenario di c--.
ETHproductions

@ETHproductions fantastico, grazie! Ora sono a 16 byte
Downgoat,

13

Pyth, 10 byte

!uscG`T.BQ

Prova questa suite di test nel compilatore Pyth.

Come funziona

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

Ho trovato l'equivalente !u:G`Tk.BQ. Probabilmente più facile da capire.
orlp

Sì, questa è sicuramente una scelta più naturale.
Dennis,

8

Python2, 87 byte

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

Una terribile implementazione che abusa degli errori di sintassi.


3
Questo è il codice golf. Terribile è un complimento.
corsiKa

8

JavaScript (ES6), 55 54 51 byte

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

Byte salvati grazie a @ Vɪʜᴀɴ e @xsot !

Spiegazione

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

1
È possibile salvare due byte rimuovendo il non necessario f=. È inoltre possibile utilizzare use +canziché c|0case per un numero intero. Puoi anche usare quello (+c?d++:d--)che è ancora più breve
Downgoat,

@ Vɪʜᴀɴ OK. C'è una sorta di guida su quando devo usare f=? Perché molte altre risposte JavaScript sul nome del sito le loro funzioni.
user81655

1
In genere è necessario assegnare un nome alla funzione solo se la sfida richiede di farlo. Altrimenti è lecito ritenere che funzioni senza nome vadano bene.
Alex A.

In Firefox, eseguendo questo per 11, ritorna truequando dovrebbe tornarefalse
Downgoat

2
Non conosco JavaScript, ma ho provato a tagliare qualche byte e funziona in Chrome:n=>![...n.toString(d=2)].some(c=>(d+=c*2-1)<2)*d==2
xsot

7

Python 2, 45 byte

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

Una funzione ricorsiva. Legge le cifre binarie di ndalla fine, mantenendo un conteggio idel livello di annidamento corrente delle parentesi. Se scende al di sotto 0, rifiuta. Quando arriviamo all'inizio, controlla se il conteggio è 0.

In realtà, iniziamo il conteggio i=1per rendere più facile controllare se è caduto 0. L'unico caso di successo terminale è n==0e i==1, verificato con n<i<2. Forziamo questo controllo se si verifica n==0, o se icade 0, nel qual caso fallisce automaticamente.

feersum ha salvato due byte ristrutturando i casi non ricorsivi con disparità di corto circuito.


3
Ha bisogno di più abusi condizionali. f=lambda n,i=1:n>0<i*f(n/2,i+(-1)**n) or n<i<2, almeno, salva 1.
feersum

6

CJam, 11 byte

ri2b"}{"f=~

Questo è un po 'sporco: per i numeri tra parentesi, stamperà uno o più blocchi. Per i numeri non separabili, si bloccherà senza stampare nulla su STDOUT. Se lo provi online nell'interprete CJam , tieni presente che non distingue tra STDOUT e STDERR.

Poiché le stringhe non vuote / vuote sono veritiere / errate in CJam e l'output stampato è sempre una stringa, è probabilmente conforme alle regole. Al costo aggiuntivo di altri 3 byte, per un totale di 14 byte , possiamo effettivamente lasciare una stringa di verità o falsa sulla pila che verrà stampata:

Lri2b"}{"f=~]s

Questo si blocca ancora per i numeri non separabili, che è consentito per impostazione predefinita .

Esecuzioni di test

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

Come funziona

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 byte

ri2bs_,{As/s}*!

Prova questo violino nell'interprete CJam o verifica tutti i casi di test contemporaneamente .

Come funziona

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.

1
dannazione, mi hai appena battuto di nuovo ....
GamrCorps il

6

Python, 51 byte

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

Una funzione anonima. Valuta un'espressione che assomiglia

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

Ogni sostituzione rimuove tutto 10, a cui corrisponde (). Dopo aver effettuato tutte le sostituzioni, la funzione restituisce se ciò che resta è solo il prefisso binario 0b. È più che sufficiente effettuare nsostituzioni, dato che un knumero di cifre richiede quasi tutti i k/2passaggi e il suo valore è maggiore 2**k.


4

Ruby, 40 anni

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

Semplice manipolazione delle stringhe. Elimina '10' fino a quando non ne rimane più nessuno.


4

Scherzi a parte , 17 byte

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

Output 0per falso e 1vero. Provalo online .

Spiegazione:

,      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)

4

Japt, 23 byte

Japt è una versione abbreviata di Ja vaScri pt . Interprete

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

Questo mi ricorda quanto Japt deve ancora andare rispetto a TeaScript. Dopo aver rinnovato l'interprete nei prossimi giorni, vorrei aggiungere caratteri "scorciatoia" come quelli di Vɪʜᴀɴ.

Come funziona

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

Poco dopo questa sfida, @ Vɪʜᴀɴ (ora noto come @Downgoat) mi ha aiutato a implementare una funzione di sostituzione ricorsiva, come Wnella risposta TeaScript. Ciò significa che questa sfida ora può essere fatta in soli 5 byte:

!¢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).

Provalo online!


3

Mathematica, 49 byte

(#~IntegerDigits~2//.{x___,1,0,y___}:>{x,y})=={}&

Non riesco a leggere Mathematica. Spiegazione, per favore? :)
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Converti il ​​numero in base 2 (come un elenco), quindi rimuovi ripetutamente 1,0dall'elenco e verifica se il risultato è un elenco vuoto.
alephalpha,

3

Ottava, 48 byte

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

3

C ++, 104 94 byte

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

Esegui con questo compilatore , è necessario specificare l'input standard prima di eseguire.

Spiegazione

  • Le dichiarazioni al di fuori di main vengono inizializzate su 0.
  • La lettura di un decimale si converte implicitamente in binario, perché si tratta di un computer.
  • Controlliamo bit / parentesi da destra a sinistra per via di n>>=1.
  • c+=n&1?-1:1tiene conto della parentesi aperta ).
  • n&c>=0 si interrompe quando rimangono solo 0 iniziali o la parentesi si chiude più di quanto si aprano.

3

Haskell, 49 46 byte

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

Esempio di utilizzo: f 13-> False.

Sto tenendo traccia del livello di annidamento lcome molte altre risposte. Tuttavia, il caso "bilanciato" è rappresentato da 1, quindi lo è il caso " )più di - che (" 0.

PS: trovata la regolazione del livello di annidamento l+(-1)^nnella risposta di xnor .


La signumsembra troppo complicato, che ne dici basta _#0=1<0?
xnor

@xnor: si grazie.
nimi,

Perché non l>0invece di l==1?
Michael Klein,

@MichaelKlein: perché solo l==1è bilanciato. Se l>1, le parentesi sono sbilanciate.
nimi,

@nimi vedo, ho frainteso il modo in cui funziona
Michael Klein

3

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

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

Grazie a xnor per aver salvato due byte e feersum per aver portato il numero di byte finali a 49!

Spiegazione

Il numero di input n, viene elaborato dal suo bit meno significativo. iè un contatore che tiene traccia del numero di 0 e 1. Si noti che è stato inizializzato 1per salvare un byte. Il loop si interromperà prima di nraggiungere 0 se il numero di 1 supera il numero di 0 ( i<=0).

Perché le parentesi siano bilanciate, sono necessarie due condizioni:

  • Il numero di 0 e 1 è uguale (cioè i==1)
  • Il numero di 1 non supera mai il numero di 0 durante questo processo (ovvero il loop non si interrompe prematuramente n==0). Modifica: mi sono reso conto che questa condizione non è necessaria in quanto ideve essere non positiva se n!=0la condizione precedente è sufficiente.

Se ie nnon sono negativi allora lo i==n==0è i+n==0.
orlp,

ipuò essere negativo se il loop si interrompe prematuramente.
xsot,

In realtà, i|n==0dovrebbe sempre funzionare.
orlp

Ottimo suggerimento, quella linea ora sembra migliore.
xsot,

while i*ndovrebbe funzionare
xnor

3

JavaScript ES5, 118 87 85 82 77 byte

Tecnica interessante secondo me. Meno un sacco di molto, grazie a @ETHproductions e @NotthatCharles

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

JavaScript ES6, 77 57 56 54 byte

-21 byte alle produzioni ETH.

x=>[...x=x.toString(2)].map(_=>x=x.replace(10,""))&&!x

Mi piace la traduzione tra parentesi. Tuttavia, se lo lasci tra 1 e 0, è un po 'più breve:function p(x){x=x.toString(2);r=/10/;while(x.search(r)>=0){x=x.replace(r,"")}return!x}
ETHproductions

@ETHproductions Ottimo punto! Penso che lascerò l'altro codice in fondo, mi piace molto l'algoritmo ^ _ ^ Grazie amico!
Conor O'Brien,

La versione ES6 può ancora essere giocata a golf un sacco: x=>([...x=x.toString(2)].map(_=>x=x.replace(/10/,"")),!x)il trucco è spostare il ciclo while in a .map, poiché non ci sono mai più '10 in un input rispetto alla sua lunghezza.
ETHproductions

@ETHproductions Grazie ancora ^ _ ^ Bel trucco con map.
Conor O'Brien,

Nessun problema :) A proposito, un altro byte può essere salvato con un trucco edc65 usa sempre: x=>[...x=x.toString(2)].map(_=>x=x.replace(/10/,""))&&!xIDK se può essere più breve però.
ETHproductions

2

D, 209 170 byte

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

Questo fa esattamente quello che dovrebbe fare senza aggiunte o benefici.


2

C, 67 byte

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

Praticamente una porta della mia presentazione di Python.


2

Prolog, 147 byte

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

Come funziona

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

Converte il numero decimale N nella sua rappresentazione binaria come elenco (invertito). Significato:

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

Poi:

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

Recluta sulla lista [H | T] aumentando N se l'elemento head è 0 altrimenti diminuendolo.
Se N in qualsiasi momento diventa negativo o se N alla fine non è 0, restituisce false, altrimenti true.

Il taglio

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

Esiste per impedire il backtracking e la ricerca di soluzioni non binarie per b (N, [N])

Test
Provalo online qui
Eseguilo con una query come:

p(42).

2

PowerShell, 106 byte

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

Non vinceremo alcuna competizione di breve durata, questo è certo. Ma ehi, almeno sta battendo Java?

Utilizza la lunghissima chiamata .NET [convert]::ToString($a,2)per convertire il nostro numero di input in una stringa che rappresenta le cifre binarie. Quindi eseguiamo il loop attraverso quella stringa con 1..$b.length|%{..}. Ogni ciclo, se la nostra cifra è un 1(valutato con %2piuttosto che -eq1per salvare un paio di byte), incrementiamo il nostro contatore; altrimenti, lo diminuiamo. Se mai raggiungere negativo, significa che ci sono stati più )di quanto (finora incontrati, così abbiamo uscita 0e exit. Una volta che siamo nel ciclo, $cè uno 0o qualche numero >0, quindi prendiamo il logico-non !di esso, che ottiene l'output.

Questo ha la stranezza dell'output 0se le parentesi non sono corrispondenti perché ne abbiamo di più ), ma l'output Falsese le parentesi sono non corrispondenti perché ne abbiamo di più (. Dichiarazioni di falsità sostanzialmente equivalenti dal punto di vista funzionale, semplicemente interessanti. Se tutte le parentesi corrispondono, le uscite True.


Certo, sicuramente. (Bene, se posso risolvere il fastidioso dubbio che sto risolvendo il problema sbagliato, lo farò).
TessellatingHeckler,

1

GNU Sed (con estensione eval), 27

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

Sed non ha davvero un'idea definita di verità e falsità, quindi qui sto sostenendo che la stringa vuota significa verità e tutte le altre stringhe significano falsità.

Se ciò non è accettabile, possiamo procedere come segue:

GNU Sed (con estensione eval), 44

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

Questo genera 1 per verità e 0 altrimenti.


1

𝔼𝕊𝕄𝕚𝕟 (ESMin), 21 caratteri / 43 byte

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

Try it here (Firefox only).

Si noti che questo utilizza variabili predefinite per i numeri (in particolare 2 e 0). Esistono variabili numeriche predefinite da 0 a 256.

19 caratteri / 40 byte, non competitivo

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

Try it here (Firefox only).

Deciso di implementare l'output implicito ... Tuttavia, i moduli di output precedenti sono ancora supportati, in modo da ottenere diverse opzioni di output!


perché tutti misurano in base al conteggio dei caratteri
fase

1

Java, 129 131 byte

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

Probabilmente può essere abbreviato. Spiegazione a venire. Grazie a Geobits per 4 byte di sconto!


È possibile combinare int k=0;con int j=0;?
ETHproductions

No, j è una variabile interna nel ciclo for e non può essere referenziata al di fuori di essa.
GamrCorps,

Dovresti essere in grado di combinare in altro modo, però: int k=0,j=0;for(...Quindi puoi inserire la char[]dichiarazione nell'inizializzatore del ciclo per salvare anche un punto e virgola.
Geobits,

Il problema più grande è che questo dà falsi positivi. Restituisce vero per 9, 35, 37, 38, per esempio .
Geobits,

@Geobits oops, non me ne ero nemmeno reso conto, risolverò quando ne avrò la possibilità.
GamrCorps il

1

C ++, 61 byte

Penso che l'attuale risposta in C ++ sia errata: restituisce un valore di verità per tutti i numeri pari, ad es. 4. Disclaimer: non sono stato in grado di usare il compilatore menzionato, quindi ho usato g ++ 4.8.4. Il problema risiede nell'uso dell'operatore binario AND anziché dell'AND logico che viene utilizzato per interrompere in anticipo quando il numero di parentesi chiuse supera il numero di parentesi aperte. Questo approccio potrebbe funzionare se trueè rappresentato come una parola con un modello di bit completamente vero. Sul mio sistema, e probabilmente sulla maggior parte degli altri sistemi, trueè equivalente a 1; solo un bit è vero. Inoltre, n/=2è più corto di n>>=1. Ecco una versione migliorata come funzione:

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

0

𝔼𝕊𝕄𝕚𝕟 (molto non competitivo), 6 caratteri / 8 byte

!ïⓑĦⅩ

Try it here (Firefox only).

Ho deciso di rivisitare questa sfida dopo molto, molto tempo. 𝔼𝕊𝕄𝕚𝕟 è migliorato molto.

Il motivo per cui questa è una risposta separata è perché le 2 versioni sono quasi completamente diverse.

Spiegazione

Converte l'input in binario, sostituisce ricorsivamente istanze di 10, quindi controlla se il risultato è una stringa vuota.


0

C # 98 byte

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

aperto per eventuali suggerimenti. mi piace questa sfida anche se è vecchio stile

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.