Двоєчні числа, що визначаються за допомогою вибору


28

Якщо ви виражаєте деяке додатне ціле число у двійковій формі , не маючи провідних нулів, і замінюйте кожну 1з a (і кожну 0на a ), то чи всі дужки будуть збігатися?

У більшості випадків вони не стануть. Наприклад, 9 знаходиться 1001у двійковій формі, яка стає ())(там, де збігаються лише перші дві дужки.

Але іноді вони будуть відповідати. Наприклад, 44 знаходиться 101100у двійковій ()(())формі , яка стає такою, де всі ліві дужки мають правильні дужки.

Напишіть програму або функцію, яка має позитивну основу десяти цілих чисел і друкує або повертає триєдине значення, якщо версія двійково-дужки числа має всі відповідні дужки. Якщо цього немає, надрукуйте або поверніть фальшиве значення.

Виграє найкоротший код у байтах.

Пов'язана OEIS послідовність.

Прості приклади нижче 100:

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

Приклади хибної помилки нижче 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
Існує послідовність для всього ...
— Арктур

Відповіді:


8

TeaScript , 9 байт 16 18 20 22 24

Збережено 2 байти завдяки @ETHproductions

!x÷W(n,¢)

Вуа. Це коротко. Використовує підхід @ xnor. Для цього буде використана функція рекурсивної заміни ( W), яка замінить всі 10рівні ()нічим. Якщо рядок порожній, він врівноважується.


Використовуючи версію TeaScript, зроблену після опублікування цього виклику, вона може стати 7 байтами:

!x÷W(n)

Безумовно

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

Пояснення

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

1
Відмінно! Дві речі, які можуть допомогти: 1) Якщо під час піднімання вгору хибний, він вже хибний, і тому перший тилд вам не знадобиться. 2) Я вважаю ~--c, що хибність точно за тим же сценарієм, що і c--.
— ETHproductions

@ETHproductions приголомшливий, дякую! Зараз я
— знижуюсь

13

Pyth, 10 байт

!uscG`T.BQ

Спробуйте цей набір тестів у компіляторі Pyth.

Як це працює

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

Я придумав еквівалент !u:G`Tk.BQ. Можливо, простіше зрозуміти.
— orlp

Так, це, безумовно, більш природний вибір.
— Денніс

8

Python2, 87 байт

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

Страшна реалізація, яка зловживає синтаксичними помилками.


3
Це код гольфу. Страшний - це комплімент.
— corsiKa

8

JavaScript (ES6), 55 54 51 байт

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

Збережені байти завдяки @ Vɪʜᴀɴ та @xsot !

Пояснення

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
Ви можете зберегти два байти, видаливши непотрібні f=. Ви також можете використовувати використання +cзамість c|0регістру до цілого числа. Ви також можете скористатися (+c?d++:d--)ще коротшим
— Downgoat

@ Vɪʜᴀɴ Гаразд. Чи є якийсь посібник щодо того, коли мені потрібно користуватися f=? Тому що багато інших відповідей JavaScript на сайті називають їх функції.
— користувач81655

1
Зазвичай вам потрібно вказати ім'я функції лише в тому випадку, якщо виклик вимагає від вас цього. Інакше можна з упевненістю припустити, що неназвані функції прекрасні.
— Олексій А.

У Firefox, запускаючи це для 11, повертається, trueколи він повинен повернутисяfalse
— Downgoat

2
Я не знаю JavaScript, але я спробував вирізати кілька байт, і це працює в хромі:n=>![...n.toString(d=2)].some(c=>(d+=c*2-1)<2)*d==2
— xsot

7

Python 2, 45 байт

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

Рекурсивна функція. Читає двійкові цифри nз кінця, зберігаючи підрахунок iпоточного рівня гніздування парен. Якщо вона опуститься нижче 0, відхиліть. Коли ми досягнемо старту, перевіряємо, чи є рахунок 0.

Насправді ми починаємо підрахунок, i=1щоб легко перевірити, чи не впав він 0. Єдиний випадок успішного терміналу - це, n==0і i==1перевіряється n<i<2. Ми змушуємо цю перевірку статися, якщо n==0або якщо вона iпотрапляє 0, в такому випадку вона автоматично виходить з ладу.

feersum врятував два байти шляхом реструктуризації нерекурсивних випадків з нерівностями до короткого замикання.


3
Потрібні більш умовні зловживання. f=lambda n,i=1:n>0<i*f(n/2,i+(-1)**n) or n<i<2, принаймні, економить 1.
— feersum

6

CJam, 11 байт

ri2b"}{"f=~

Це нечистота: для номерів, які підлягають встановленню батьків, він надрукує один або кілька блоків. Що стосується номерів, які не підлягають відправці на батьків, він вийде з ладу, не надрукувавши нічого для STDOUT. Якщо ви спробуєте це в Інтернеті в інтерпретаторі CJam , пам’ятайте, що він не відрізняє STDOUT від STDERR.

Оскільки непусті / порожні рядки є truthy / фальшивими у CJam, а друкований вихід завжди є рядком, він, безперечно, відповідає правилам. При додатковій вартості ще 3-х байт, в цілому 14 байт , ми фактично можемо залишити трикутну або хибну рядок на стеку, який буде надруковано:

Lri2b"}{"f=~]s

Це все ще виходить з ладу для номерів, які не можуть змінюватися батьками, що дозволено за замовчуванням .

Тестові запускання

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

Як це працює

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 байт

ri2bs_,{As/s}*!

Спробуйте цю загадку в інтерпретаторі CJam або перевірити всі тестові випадки одразу .

Як це працює

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
чорт, ти ледве бив мене знову ....
— GamrCorps

6

Пітон, 51 байт

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

Анонімна функція. Оцінюється за виразом, який виглядає так

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

Кожна заміна видаляє всі 10, які відповідають (). Після внесення всіх замін функція повертає те, що залишилося лише бінарний префікс 0b. Це більше ніж достатньо для nзаміни, оскільки kчисло -знака займає більшість k/2кроків, а його значення - найбільше 2**k.


4

Рубі, 40

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

Прості струнні маніпуляції. Скидає «10», поки не залишиться нічого.


4

Серйозно , 17 байт

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

Виходи 0для хибних і 1правдивих. Спробуйте в Інтернеті .

Пояснення:

,      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 байти

Japt - скорочена версія Ja vaScri pt . Перекладач

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

Це нагадує мені, наскільки япт ще повинен пройти порівняно з TeaScript. Після оновлення перекладача протягом наступних кількох днів я хотів би додати «ярликові» символи, як Vɪʜᴀɴ.

Як це працює

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

Незабаром після цього виклику @ Vɪʜᴀɴ (тепер відомий як @Downgoat) допоміг мені реалізувати функцію рекурсивної заміни, як Wу відповіді TeaScript. Це означає, що зараз цей виклик можна виконати всього в 5 байтах:

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

Перевірте це в Інтернеті!


3

Математика, 49 байт

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

Я не можу читати Mathematica. Пояснення, будь ласка? :)
— Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Перетворіть число в базу 2 (як список), потім кілька разів вийміть 1,0зі списку і перевірте, чи є результат порожнім списком.
— алефальфа


3

C ++, 104 94 байт

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

Запустіть цей компілятор , перед тим як запустити, потрібно вказати стандартний ввід.

Пояснення

  • Декларації поза основним ініціалізуються на 0.
  • Читання десятків неявно перетворюється на двійкове, оскільки це комп'ютер.
  • Ми перевіряємо біти / дужки справа вліво через n>>=1.
  • c+=n&1?-1:1зберігає кількість відкритих дужок ).
  • n&c>=0 зупиняється, коли залишаються лише провідні 0, або круглі дужки закриваються більше, ніж вони відкриваються.

3

Haskell, 49 46 байт

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

Приклад використання: f 13-> False.

Я стежу за рівнем гніздування, lяк і багато інших відповідей. Однак "збалансований" випадок представлений знаком ", тому " випадок 1"більше- )ніж (" 0.

PS: знайшов коригування рівня гніздування l+(-1)^nу відповіді xnor .


signumЗдається занадто складним, як щодо просто _#0=1<0?
— xnor

@xnor: так, дякую.
— німі

Чому б не l>0замість цього l==1?
— Майкл Клейн

@MichaelKlein: тому що лише l==1збалансований. Якщо l>1дужки є неврівноваженими.
— німі

@nimi Я бачу, я неправильно трактував, як це працює
— Майкл Кляйн

3

Python 2, 60 57 56 55 53 52 50 49 байт

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

Завдяки xnor за збереження двох байтів і feersum за приведення остаточного числа байтів до 49!

Пояснення

Вхідне число, nобробляється з його найменш значущого біта. i- лічильник, який відслідковує кількість 0 і 1. Зауважте, що вона ініціалізована 1для збереження байта. Цикл припиняється до nдосягнення 0, якщо число 1's перевищує число 0's ( i<=0).

Щоб дужки були збалансовані, необхідні дві умови:

  • Кількість 0 і 1 дорівнює (тобто i==1)
  • Під час цього процесу число 1 ніколи не перевищує число 0 (тобто цикл не припиняється передчасно n==0). Редагувати: Я зрозумів, що ця умова не є необхідною, оскільки вона iповинна бути позитивною, якщо n!=0так попередня умова є достатньою.

Якщо iі nє негативними, то i==n==0є i+n==0.
— orlp

iможе бути негативним, якщо петля припиняється передчасно.
— xsot

Власне, i|n==0завжди має працювати.
— orlp

Чудова пропозиція, ця лінія виглядає зараз краще.
— xsot

while i*nповинен працювати
— xnor

3

JavaScript ES5, 118 87 85 82 77 байт

Цікава техніка на мою думку. Мінус цілого біса багато, завдяки @ETHproductions та @NotthatCharles

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

JavaScript ES6, 77 57 56 54 байт

-21 байт до ETHproductions.

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

Мені подобається переклад в дужки. Однак якщо залишити це як 1 та 0, це трохи коротше:function p(x){x=x.toString(2);r=/10/;while(x.search(r)>=0){x=x.replace(r,"")}return!x}
— ETHproductions

@ETHproductions Добрий момент! Я думаю, що я залишу інший код внизу, мені дуже подобається алгоритм ^ _ ^ Спасибі товариш!
— Conor O'Brien

Версія ES6 все ще може бути купою для гольфу: x=>([...x=x.toString(2)].map(_=>x=x.replace(/10/,"")),!x)фокус полягає в тому, щоб перемістити цикл while в a .map, оскільки ніколи не існує більше 10-х вхідних даних, ніж його довжина.
— ETHproductions

@ETHproductions Ще раз дякую ^ _ ^ Приємний трюк с map.
— Conor O'Brien

Немає проблем :) BTW, інший байт можна зберегти за допомогою трюку, який edc65 використовує весь час: x=>[...x=x.toString(2)].map(_=>x=x.replace(/10/,""))&&!xIDK, якщо він може скоротитись.
— ETHproductions

2

D, 209 170 байт

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

Це робить саме те, що потрібно робити без будь-яких доповнень чи переваг.


2

C, 67 байт

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

Досить порт мого пітона.


2

Пролог, 147 байт

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

Як це працює

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

Перетворює десяткове число N у його двійкове подання у вигляді списку (зворотній). Значення:

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

Потім:

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

Повторюється за списком [H | T] збільшуючи N, якщо головний елемент дорівнює 0, інакше зменшуючи його.
Якщо N в будь-якій точці стає негативним або якщо N врешті-решт не 0, повернути помилковим, інакше істинно.

Розріз

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

Чи є для того, щоб не допустити зворотного відстеження та пошуку небінарних рішень для

тестування b (N, [N]).
Спробуйте це онлайн тут.
Запустіть його із запитом, як:

p(42).

2

PowerShell, 106 байт

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

Не вигравати жодних найкоротших змагань, це точно. Але ей, принаймні це побиття Java?

Використовує дуже довгий виклик .NET [convert]::ToString($a,2)для перетворення нашого вхідного номера у рядок, що представляє двійкові цифри. Потім ми перебираємо цикл через цю рядок із 1..$b.length|%{..}. Кожен цикл, якщо наша цифра є 1(оцінюється, %2а не -eq1для того, щоб зберегти пару байтів), ми збільшуємо свій лічильник; інакше ми його декрементуємо. Якщо ми коли-небудь досягнемо негативного, це означає, що було більше, )ніж (зустрічалося до цього часу, тому ми виводимо 0і exit. Після того, як ми пройдемо цикл, $cце 0чи то чи якесь число >0, тож ми приймаємо логічне не !його, яке отримує вихід.

Це має вигадку виводу, 0якщо паролі не збігаються, тому що у нас більше ), але виведення, Falseякщо паролі невідповідні, тому що у нас більше (. По суті функціонально еквівалентні хибні висловлювання, просто цікаві. Якщо всі парени збігаються, виводиться True.


Гаразд, звичайно. (Ну, якщо я зможу виправити невдалий сумнів у тому, що я вирішую неправильну проблему, я зроблю).
— TessellatingHeckler

1

GNU Sed (з подовженням eval), 27

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

У Sed справді немає певного уявлення про truthy та falsey, тому тут я стверджую, що порожня струна означає truthy, а всі інші струни означають falsey.

Якщо це не прийнятно, ми можемо зробити наступне:

GNU Sed (з подовженням eval), 44

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

Це виводить 1 для truthy та 0 в іншому випадку.


1

𝔼𝕊𝕄𝕚𝕟 (ESMin), 21 символів / 43 байти

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

Try it here (Firefox only).

Зауважте, що для цього використовуються змінні, визначені заздалегідь для чисел (конкретно 2 і 0). Існують заздалегідь задані змінні числа від 0 до 256.

19 символів / 40 байт, неконкурентні

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

Try it here (Firefox only).

Вирішили застосувати неявний вихід ... Однак попередні форми виводу все ще підтримуються, тому ви отримуєте кілька варіантів виведення!


тому що всі міряються за підрахунком знаків
— фаза

1

Java, 129 131 байт

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

Напевно, можна скоротити. Пояснення про майбутнє. Дякуємо Geobits за 4 байти!


Чи можна поєднувати int k=0;з int j=0;?
— ETHproductions

Ні, j є внутрішньою змінною у циклі for і не може бути посиланням поза нею.
— GamrCorps

Ви повинні мати можливість комбінувати інший спосіб: int k=0,j=0;for(...тоді ви можете помістити char[]декларацію всередину ініціалізатора циклу, щоб зберегти крапку з комою.
— Геобіт

Більша проблема полягає в тому, що це дає помилкові позитиви. Вона повертає істину 9, 35, 37, 38, наприклад .
— Геобіц

@Geobits на жаль, я навіть не розумів, що це виправить, коли отримаю шанс.
— GamrCorps

1

C ++, 61 байт

Я думаю, що поточна відповідь на C ++ є неправильною: вона повертає просте значення для всіх парних чисел, наприклад 4. Відмова: Я не зміг використати згаданий компілятор, тому я використав g ++ 4.8.4. Проблема полягає у використанні бінарного оператора AND замість логічного AND, який використовується для перерви на початку, коли кількість дужок, що закриваються, перевищує кількість відкритих дужок. Такий підхід може працювати, якщо trueйого представити у вигляді слова із справжнім бітовим малюнком. У моїй системі, і, мабуть, у більшості інших систем, trueрівнозначно 1; лише один біт правдивий. Крім того, n/=2коротше, ніж n>>=1. Ось покращена версія як функція:

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

0

𝔼𝕊𝕄𝕚𝕟 (дуже неконкурентно), 6 символів / 8 байт

!ïⓑĦⅩ

Try it here (Firefox only).

Я вирішив переглянути цю проблему через дуже-дуже довгий час. 𝔼𝕊𝕄𝕚𝕟 стало набагато краще.

Причина цього є окремою відповіддю в тому, що дві версії майже повністю відрізняються.

Пояснення

Перетворює вхід у двійковий, рекурсивно замінює екземпляри 10, після чого перевіряє, чи є результат порожнім рядком.


0

C # 98 байт

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

відкрити для будь-яких пропозицій. Мені подобається цей виклик, навіть якщо він старий

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.