Внедрить бинарные операторы INTERCAL


29

Язык компилятора без произносимой аббревиатуры, сокращенно INTERCAL , является уникальным языком программирования. Среди его невоспроизводимых качеств - бинарные операторы.

Два бинарных оператора INTERCAL - это чередование (также известное как mingle ) и select . Чередование представляется с изменением (¢), а выделение представляется с помощью sqiggle (~).

Чередование работает, беря два числа в диапазоне 0-65535 и чередуя их биты. Например:

234 ¢ 4321
234   = 0000011101010
4321  = 1000011100001
Result: 01000000001111110010001001
Output: 16841865

Выбор работает, беря два числа в диапазоне 0-65535, беря биты в первом операнде, которые находятся в том же положении, что и 1 во втором операнде, и упаковывая эти биты справа.

2345 ~ 7245
2345  = 0100100101001
7245  = 1110001001101
Taken : 010   0  10 1
Result: 0100101
Output: 37

В этом задании вам будет дано двоичное выражение с использованием операции чередования или выбора. Вы должны вычислить результат, используя как можно меньше байтов.

Выражение будет дано в виде строки, разделенной пробелами, состоящей из целого числа в 0-65535, пробела или ¢или ~пробела и целого числа в 0-65535.

Вход и выход могут быть через любую стандартную систему (STDIN, функция, командная строка и т. Д.). Стандартные лазейки запрещены.

Примеры:

5 ¢ 6
54

5 ~ 6
2

51234 ¢ 60003
4106492941

51234 ~ 60003
422

Это код гольф - побеждает меньше байтов. Удачи.

РЕДАКТИРОВАТЬ: Поскольку некоторые языки не поддерживают символ изменения (¢) INTERCAL, вы можете использовать вместо него символ больших денег ($) со штрафом в 5 байт.


10
Это немного сурово наказывает людей за использование знака доллара. Это то, что не может помочь.
бета-распад

9
Я только что понял, что CLWNPA отлично произносим на валлийском языке. W произносится как U на испанском или OO на английском.
Уровень Река Сент-

9
Я не получаю штраф 5 байт. C-INTERCAL использует $.
kirbyfan64sos

13
О чем вы все спорите? $ Явно дороже, чем ¢. Что, вы хотите 99 ¢ даром?
Макс

6
Я не думал, что INTERCAL позволит вам вводить числа с десятичными цифрами. Тебе не нужно писать FIVE ONE TWO THREE FOUR? И не должно ли вывод быть в римских цифрах?
Нейт Элдридж

Ответы:


9

Pyth, 32 31 29 байт

isummFdG}\~zCm.[Z16jvd2%2cz)2

Попробуйте онлайн: Regular Input / Test Suite

Спасибо @isaacg за отыгрывание одного байта.

Объяснение:

                         cz)   split input at spaces
                       %2      only take every second item (the numbers)
             m                 map each number d to:
                    vd           convert d to int
                   j  2          convert to base 2
              .[Z16              pad zeros at the left
            C                  zip
  u     }\~z                   apply the following function ("~" in input) times:
   m   G                         map each pair d to:
    mFd                          convert [x,0] to [] and [x,1] to [x]
 s                             take sum (unfold all lists)
i                           2  convert back from base 2 and print

Вы можете сохранить один байт путем изменения hMfeTв , smmFdа затем перемещение Дубликат sза пределами троичной. Кроме того, ваш текущий код составляет 32 байта, а не 33.
isaacg

@isaacg Вау. Я бы никогда не подумал, что это умный гольф. Спасибо. И да, во время написания объяснения играл в гольф в последнюю минуту и ​​не обновлял количество байтов.
Якуб

2
Интересно видеть ответы Pyth и CJam, почти всегда с одинаковым количеством байтов, но Pyth часто опережает CJam
Kametrixom

13

Python 2, 115 112 байт

x,y,z=input().split()
d=y<""
f=lambda a,b:a+b and(b%2+5&4-d)*f(a/2,b/2)+(a%2*2+b%2)/3**d
print f(int(x),int(z))

Строка во второй строке содержит один непечатаемый символ \x7d, следующий символ после ~.

Все надежды на хорошую одиночную лямбду рушатся форматом ввода. Там, вероятно, лучший способ читать на входе. Ввод как "51234 ¢ 60003"через STDIN.

Функция fобъединяет следующие две рекурсивные функции:

g=lambda a,b:a+b and 4*g(a/2,b/2)+a%2*2+b%2    # ¢
h=lambda a,b:a+b and(b%2+1)*h(a/2,b/2)+a*b%2   # ~

(-3 байта с помощью @xnor)


1
+1 за первый действительно конкурентоспособный ответ Python. Мне было интересно, почему вы беспокоились о лямбде и не просто использовали выражение, но, похоже, там какая-то рекурсия? Я не знаю Python, я с нетерпением жду объяснения.
Уровень Река Сент-

Какое-то отличное избиение! Я смотрю на сжатие выражения постоянного члена. Выражение (a%2*2+b%2)/3**dсохраняет 3 символа, но использует дополнение d=1-c. У вас есть способ сделать -~(3*c|b%2)с дополнением? В худшем случае он теряет 2 символа с 3-3*d. Кроме того, формат and-~x+yможет быть andy-~xдлинным, yначиная с символа или числа.
xnor

@ xnor Понял (b%2+5&4-d). Благодарность!
Sp3000

11

CJam, 31 байт

rrc\r]{i2bF0e[}%(7=\zf{_)*?~}2b

Попробуйте онлайн в интерпретаторе CJam .

Как это работает

rr                              e# Read two tokens from STDIN.
  c\                            e# Cast the second to char and swap with the first.
    r                           e# Read a third token from STDIN.
     ]                          e# Wrap everything in an array.
      {       }%                e# For all three elements:
       i2b                      e#   Cast to int and convert to base 2.
          F0e[                  e#   Left-pad with zeroes to complete 15 digits.
                (               e# Shift out the first base 2 array.
                 7=             e# Select its eighth MSB (1 for '¢', 0 for '~').
                   \            e# Swap with the array of base 2 arrays.
                    z           e# Zip to transpose rows with columns.
                     f{     }   e# For each pair of base 2 digits:
                                e#   Push the bit, then the pair.
                       _        e#   Copy the pair.
                        )       e#   Pop the second digit.
                         *      e#   Repeat the first digit that many times.
                          ?     e#   Ternary if. Select the pair if the bit is
                                e#    truthy, the repeated first bit if it's falsy.
                           ~    e#   Dump the selected array on the stack.
                             2b e# Convert from base 2 to integer.

8

JavaScript (ES6), 103 117 119 124

Редактировать теперь работает с числами вместо строк

(не считая пробелов, переносов и комментариев)

Протестируйте выполнение сниппета в любом браузере, совместимом с EcmaScript 6 (в частности, не Chrome, не MSIE. Я тестировал на Firefox, Safari 9 мог пойти)

I=s=>
  (i=>{
    for(m=r=0,[a,o,b]=s.split` `;i>0;i<<=1) // loop until bit 31 of i is set
      o>'~'?r+=(b&i)*i+(a&i)*2*i:b&i?r+=(a&i)>>m:++m
  })(1)||r


// TEST
out=x=>O.innerHTML+=x+'\n\n';

[ ['234 ¢ 4321', 16841865], ['2345 ~ 7245', 37]
, ['5 ¢ 6', 54], ['5 ~ 6', 2]
, ['51234 ¢ 60003',4106492941], ['51234 ~ 60003', 422]]
.forEach(([i,o,r=I(i)])=>{
  out('Test '+ (o==r?'OK':'Fail')+'\nInput:    '+ i+'\nResult:   '+r+'\nExpected: '+o)})
<pre id=O></pre>


5

Matlab, 119 113 байтов

function f(s)
t=dec2bin(str2double(strsplit(s,{'¢' '~'}))');u=any(s>'~');[~u u]*bin2dec({t(1,t(2,:)==49) t(:)'})

Ungolfed:

function f(s)                                     % input s is a string
t = dec2bin(str2double(strsplit(s,{'¢' '~'}))');  % get the two numbers and convert to
                                                  % two-row char array of zeros of ones
u = any(s>'~');                                   % 1 indicates '¢'; 0 indicates '~'
[~u u]*bin2dec({t(1,t(2,:)==49) t(:)'})           % compute both results and display
                                                  % that indicated by u

Примеры:

>> f('234 ¢ 4321')
ans =
    16841865

>> f('2345 ~ 7245')
ans =
    37

5

R 145 байтов

s=scan(,"");a=as.double(c(s[1],s[3]));i=intToBits;cat(packBits(if(s[2]=="~")c(i(a[1])[i(a[2])>0],i(0))[1:32] else c(rbind(i(a[2]),i(a[1]))),"i"))

Ungolfed + объяснение:

# Read a string from STDIN and split it on spaces
s <- scan(, "")

# Convert the operands to numeric
a <- as.double(c(s[1], s[3]))

o <- if (s[2] == "~") {
    # Get the bits of the first operand corresponding to ones in
    # the second, right pad with zeros, and truncate to 32 bits
    c(intToBits(a[1])[intToBits(a[2]) == 1], intToBits(0))[1:32]
} else {
    # Interleave the arrays of bits of the operands
    c(rbind(intToBits(a[2]), intToBits(a[1])))
}

# Make an integer from the raw bits and print  it to STDOUT
cat(packBits(o, "integer"))

5

Python 3, 174 166 148 126

Довольно просто, строковые операции, затем преобразование обратно в целое число.

Ограничено числами, которые в двоичном коде имеют 99 цифр (максимум 2 ^ 99-1 = 633825300114114700748351602687).

Спасибо, Sp3000 и Vioz!

a,o,b=input().split()
print(int(''.join([(i+j,i[:j>'0'])[o>'~']for i,j in zip(*[bin(int(j))[2:].zfill(99)for j in(a,b)])]),2))

Или 165 символов без ограничения:

a,o,b=input().split()
a,b=[bin(int(j))[2:]for j in(a,b)]
print(int(''.join([(i if j=='1'else'')if o=='~'else i+j for i,j in zip(a.zfill(len(b)),b.zfill(len(a)))]),2))

Ungolfed:

a, op, b = input().split()
a, b = [bin(int(j))[2:] for j in(a,b)] #convert to int (base 10), then to binary, remove leading '0b'
m = max(len(a), len(b))
a = a.zfill(m) #fill with leading zeroes
b = b.zfill(m)
if op == '~':
    ret = [i if j=='1' else'' for i, j in zip(a, b)]
else:
    ret = [i + j for i, j in zip(a, b)]
ret = ''.join(ret) #convert to string
ret = int(ret, 2) #convert to integer from base 2
print(ret)

2
Вы можете использовать zfillвместо rjustдополнения нулями
Sp3000

Максимальное количество входов - 16 бит, а выходов - 32 бита. 99 битов более чем достаточно.
Исаак

Я знаю, но так как «99» принимает столько же символов, сколько и «16», нет смысла ограничивать его.
Транг Оул

1
Еще несколько: 1) Вам не нужно сохранять a,b, просто поместите его zipс *(i if j=='1'else'') -> i[:j>'0']if/else
символом сплат

1
Мое решение в конечном итоге слишком близко к вашим, так вот , как коротким , как я мог бы получить ваши (126 байт).
Каде

4

Pyth, 43 байта

Часть меня нервничает, когда отправляет такой длинный ответ Пита на вопрос Исаака ...: oP

J.(Kczd1Am.BvdKiu?qJ\~u+G?qeH\1hHk+VGHk.iGH2

Explaination:

                                               Implicit: z=input(), k='', d=' '
   Kczd                                        Split z on spaces, store in K
J.(    1                                       Remove centre element from K, store in J
         m    K                                For each d in K
          .Bvd                                 Evaluate as int, convert to binary string
        A                                      Store pair in G and H
                                               ~ processing:
                                 +VGH          Create vectorised pairs ([101, 110] -> [11, 01, 10])
                     u               k         Reduce this series, starting with empty string
                        ?qeH\1                 If 2nd digit == 1...
                              hHk              ... take the 1st digit, otherwise take ''
                      +G                       Concatenate
                                      .iGH     ¢ processing: interleave G with H
                ?qJ\~                          If J == ~, take ~ processing, otherwise take ¢
               i                          2    Convert from binary to decimal

4
Мне нравится твоя аватарка! :)
kirbyfan64sos

2
@ kirbyfan64sos Голубой Кирби - лучший Кирби: о)
Сок

3

C 127 123 байта + 5 штрафов = 128

scanfсчитает символ Unicode более чем одним символом, что сильно усложняет ситуацию, поэтому я применяю 5-байтовый штраф за использование $.

a,b,q,x,i;main(){scanf("%d %c %d",&a,&q,&b);for(i=65536;i/=2;)q%7?x=x*4|a/i*2&2|b/i&1:b/i&1&&(x=x*2|a/i&1);printf("%u",x);}

Изменения по сравнению с оригинальной версией:

- Тест на $ или ~ был изменен с q&2на q%7. Это инвертирует значения true / false, что позволяет коду для оператора $ идти перед тем, :что означает, что набор скобок может быть удален.

- iЦикл теперь отсчитывает в степенях 2, что длиннее, но допускает >>замену /и сохраняет некоторые скобки.

Оригинальная версия 127 байт

a,b,q,x,i;
main(){
  scanf("%d %c %d",&a,&q,&b);
  for(i=16;i--;)
    q&2?
      b>>i&1&&(x=x*2|a>>i&1):    // ~ operator. && used as conditional: code after it is executed only if code before returns truthy.
      (x=x*4|(a>>i&1)*2|b>>i&1); // $ operator
  printf("%u",x);
}

Я пошел с одной петлей с условностями внутри, чтобы избежать накладных расходов на две петли. В обоих случаях я смещаю права битов операндов вплоть до 1-го бита и строю результат от старшего к младшему значащему биту, смещая его влево (умножая на 2 или 4).


Я сделал это для вас: main (a, b, q, x, i) {scanf ("% d% c% d", & a, & q, & b); for (i = 16; i -;) q & 2? б >> я & 1 && (х = х * 2 | а >> я & 1) :( х = х * 4 | (а >> я & 1) * 2 | B >> я & 1); Е ( "% U", х);} Я попробовал сыграть в гольф >> i & 1 parts, но не смог найти экономически эффективный способ сделать это. Однако я смог сохранить 1 символ, поместив определения переменных в main. Примечание: не проверено.
Лямбда-бета

@LamdaBeta спасибо, я не смог найти макрос для >> i & 1, но мне удалось поиграть в него другим способом. Размещение переменных в качестве аргументов mainпричин qповреждает на моей машине, что странно. Я ожидаю, что настоящая проблема с scanf, но из-за этого я оставил их как обычные декларации.
Уровень Река Сент-

Я не думал об этом. Вы правы, д будет поврежден. Причина в том, что, хотя мы узнаем, что main принимает два аргумента, количество аргументов командной строки и массив самих аргументов, большинство систем фактически предоставляют третий аргумент (обычно называемый char * envp []), который описывает среду кода запускается (предоставление доступа к EG: переменные окружения). Таким образом, третьему значению в main также может быть присвоено значение системой, на этот раз scanf невиновен.
Лямбда-бета,

@steveverill Я думаю, что вы также можете удалить 5-байтовый штраф. Я только что проверил ваш код (используя ALT + 155, чтобы сделать ¢), и он, кажется, работает нормально. :)
LambdaBeta

@LambdaBeta на самом деле эксперименты показывают, что это комбинация обоих. При обычном объявлении qгарантированно будет ноль, но при объявлении в качестве параметра функции qсодержится 32-битный мусор. Это не было бы проблемой , если я назначен на значение q, но scanfс "%c"только переписывает младшие 8 бит мусора, оставляя другие 24 неопределенные. Мне может повезти на другом компиляторе!
Уровень Река Сент-

3

К5, 53 52 байта

{b/({,/x,'y};{x@&y})[*"~"=y][b\.x;(b:20#2)\.z]}." "\

53-байтовая версия:

{b/({,/x,'y};{x@&y})[*"¢~"?y][b\.x;(b:20#2)\.z]}." "\

Все еще нужно немного больше игры в гольф.



3

Хаскелл, 77

g=(`mod`2)
h=(`div`2)
0¢0=0
a¢b=g a+2*b¢h a
a?0=0
a?b=g a*g b+(1+g b)*h a?h b

ввод дается путем применения ввода к функциям / операторам ?и ¢определяется в коде (Haskell не может определить оператор ~по техническим причинам).

в основном работает старый рекурсивный подход.


2

J, 173

f=:|."1@(>@(|.&.>)@(#:@{:;#:@{.))
m=:2&#.@:,@:|:@:|.@:f
s=:2&#.@#/@:f
a=:{&a.@-.
(1!:2)&2(s@".@:a&126)^:(126 e.i)((m@".@:a&194 162)^:(1 e.194 162 E.i)i=._1}.(a.i.((1!:1)3)))

ожидает одну строку ввода

ожидается завершение ввода после новой строки с EOF


2

Javascript ES6 (3 аргумента) 141 138 136 121 119 байт

b=x=>(65536|x).toString`2`
f=(x,o,y)=>+eval(`'0b'+(b(y)+b(x)).replace(/^1|${o=='~'?1:'(.)'}(?=.{16}(.)())|./g,'$2$1')`)

Тест:

;[f(234,'¢',4321),f(2345,'~',7245)]=="16841865,37"

Javascript ES6 (1 аргумент) 135 133 байта

b=x=>(65536|x).toString`2`
f=s=>([x,o,y]=s.split` `)|eval(`'0b'+(b(y)+b(x)).replace(/^1|${o=='~'?1:'(.)'}(?=.{16}(.)())|./g,'$2$1')`)

Тест:

;[f('234 ¢ 4321'),f('2345 ~ 7245')]=="16841865,37"

PS: Новая строка считается за 1 байт, поскольку она может быть заменена на ;.


1
0x10000 == 65536 (за исключением 2 символов)
edc65

@ edc65, я обновил ответ.
Qwertiy

2
65536 | x, чтобы избежать ~~
edc65

Допускается только вторая версия - входные данные должны быть в форме строки, разделенной пробелом.
Исаак

@isaacg, хорошо. Но я не хочу удалять первый по историческим причинам.
Qwertiy

2

Python 3, 157 байт

a,x,y=input().split()
i=int
b=bin
print(i(''.join(([c for c,d in zip(b(i(a)),b(i(y)))if d=='1'],[c+d for c,d in zip(b(i(a))[2:],b(i(y))[2:])])['¢'==x]),2))

Полную и пояснительную версию можно найти на моей наклейке .


Вы можете использовать несколько символов, удалив пробелы вокруг оператора «==», перед «if» и передав «base» в качестве позиционного аргумента.
Транг Оул

Спасибо, что и некоторые другие сохранили 15 символов! но удвоенный способ форматирования возврата еще слишком велик.
Оливер Фридрих

Кроме того, вы используете 4 пробела на отступ? Одного (или вкладки) достаточно.
Транг Оул

2
@BeowulfOF Если не указано иное, вы можете отправить полную программу или функцию. Как правило, то, что короче, будет зависеть от того, как ваш язык анализирует конкретные входные данные для задания (например, ruby ​​неожиданно неуклюжий с числами из stdin). У вас также есть два возможных способа вывода: стандартный вывод или возвращаемое значение, которые применимы к обоим (хотя возвращаемые значения из программ встречаются редко.)
Уровень Ривер Сент-

1
Вы, кажется, используете eтолько один раз, не могли бы вы просто встроить это?
Кевин Браун

0

Mathematica, 155 байт

f=IntegerDigits[#,2,16]&;
g=#~FromDigits~2&;
¢=g[f@#~Riffle~f@#2]&;
s=g@Cases[Thread@{f@#,f@#2},{x_,1}->x]&;
ToExpression@StringReplace[#,{" "->"~","~"->"s"}]&

Оценивает анонимную функцию, принимающую строку в качестве входных данных. Добавлены разрывы строк для ясности.

fи gпреобразовать в / из базы 2. Riffleделает именно то, что должно чередоваться . Я хотел использовать Selectдля выбора, но Casesлучше, к сожалению. Последняя строка немного обманчива; изменяются пробелы, ~которым является инфиксный оператор Mathematica, а затем строка eval'd.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.