Создать таблицу XOR


21

Вступление

XOR - это цифровой логический элемент, который реализует эксклюзив или. В большинстве случаев это отображается как ^. Четыре возможных результата в двоичном виде:

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

Это также можно рассматривать как сложение по модулю 2 в двоичном виде. В десятичном формате нам нужно преобразовать десятичное число в двоичное, 35 = 100011и. 25 = 11001Чтобы вычислить значение XOR, мы помещаем их друг на друга:

100011
 11001 ^
--------
111010  = 58 in decimal

Задача : если задано целочисленное значение N больше 1, выведите таблицу XOR с размером N + 1. Например, N = 5:

 0 1 2 3 4 5
 1 0 3 2 5 4
 2 3 0 1 6 7
 3 2 1 0 7 6
 4 5 6 7 0 1
 5 4 7 6 1 0

Вы можете видеть, что перед каждым числом есть один пробел, потому что наибольшая сумма в таблице имеет длину 1. Однако, если мы возьмем N = 9, мы получим следующую сетку:

  0  1  2  3  4  5  6  7  8  9
  1  0  3  2  5  4  7  6  9  8
  2  3  0  1  6  7  4  5 10 11
  3  2  1  0  7  6  5  4 11 10
  4  5  6  7  0  1  2  3 12 13
  5  4  7  6  1  0  3  2 13 12
  6  7  4  5  2  3  0  1 14 15
  7  6  5  4  3  2  1  0 15 14
  8  9 10 11 12 13 14 15  0  1
  9  8 11 10 13 12 15 14  1  0

Наибольшее значение имеет длину 2, поэтому значение выравнивается по правому краю на длину 3 (наибольшая длина + 1).

Правила:

  • Начальные пробелы не являются обязательными, только если используются (или не используются) последовательно
  • Вы должны вывести таблицу в форме, показанной выше.
  • Заполнение между столбцами должно быть как можно меньше
  • Это , поэтому выигрывает представление с наименьшим количеством байтов!

Сколько отступов допускается между столбцами? Только минимально возможная сумма?
Мартин Эндер

@ MartinBüttner Да, минимально возможная сумма. Я добавлю это в описание.
Аднан

Соответствующий codegolf.stackexchange.com/questions/67183/…
edc65

Глядя на примерыoutput an XOR table with the size N+1
edc65

Каково максимальное значение для N? ... (для N == 1000000 размер таблицы будет около 10 терабайт)
edc65

Ответы:


12

MATL , 10 байт

0i2$:tXgZ~

Компилятор (и, в частности, эта программа) теперь, кажется, работает в Octave, хотя все еще нуждается в некоторой доработке. Вы можете временно использовать этот коммит GitHub .

Изменить (30 марта '16) : Попробуйте онлайн!

пример

>> matl 0i2$:tXgZ~
> 9
0  1  2  3  4  5  6  7  8  9
1  0  3  2  5  4  7  6  9  8
2  3  0  1  6  7  4  5 10 11
3  2  1  0  7  6  5  4 11 10
4  5  6  7  0  1  2  3 12 13
5  4  7  6  1  0  3  2 13 12
6  7  4  5  2  3  0  1 14 15
7  6  5  4  3  2  1  0 15 14
8  9 10 11 12 13 14 15  0  1
9  8 11 10 13 12 15 14  1  0

объяснение

0i2$:       % vector 0, 1, 2, ... up to input number
t           % duplicate
Xg          % nd-grid
Z~          % bitxor

Скоро
выйдет

... ну, надеюсь. Есть идеи по этому поводу ?
Луис Мендо

5
Определенно правильный инструмент для работы. +1
спагетто

1
После некоторых настроек компилятор работает в Octave (4.0.0). Мне нужно больше тестировать, но все программы, которые я пробовал, включая эту, работают. Пока я выкладываю новый релиз, вот ссылка на текущий коммит GitHub для запуска этого кода в Octave. Язык не изменился (он все еще выпускает 5.0.0), поэтому это раньше, чем это испытание
Луис Мендо

5

Утилиты Bash + BSD, 45

eval echo \$[{0..$1}^{0..$1}]|rs -jg1 $[$1+1]

Я долго ждал, чтобы найти применение rs. Это кажется хорошим. rsвозможно, потребуется установить в системах Linux. Но он работает прямо из коробки на OS X.

  • $1расширяется до N, и, следовательно, echo \$[{0..$1}^{0..$1}]расширяется доecho $[{0..N}^{0..N}]
  • Это тогда evalред:
  • Расширение скобок расширяется до $[0^0] $[0^1] $[0^2] ... $[0^N] ... $[N^N]
  • Это серия арифметических расширений xor, которые расширяются до одной строки
  • rs(изменить) изменить эту строку в N + 1 строк. -jправо оправдывает и -g1дает ширину желоба 1. Это гарантирует, что итоговая выходная таблица имеет минимальную ширину между столбцами.

Я проверил до N = 1000, что заняло 3,8 секунды. Большое N теоретически возможно, хотя bash не хватит памяти в какой-то момент при использовании памяти (N + 1) ² расширения скобки.


4

С 114 128 152

Редактировать Упрощенный подсчет пространства, вдохновленный работой Халеда Хунайфера

Функция переменного тока, которая соответствует спецификациям.

T(n){int i=0,j,x=1,d=0;while(x<=n)x+=x,++d;for(;i<=n;i++)for(j=0;j<=n;j++)printf("%*d%c",d*3/10+1,i^j,j<n?32:10);}

Попробуй вставь как ввод, по умолчанию 9

Меньше гольфа

T(n)
{
   int i=0, j, x=1,d=0;
   while(x<=n) x+=x,++d; // count the digits
   // each binary digit is approximately 0.3 decimal digit
   // this approximation is accurate enough for the task
   for(;i<=n;i++)
     for(j=0;j<=n;j++)
       printf("%*d%c",d*3/10+1,
              i^j,
              j < n ? 32:10); // space between columns, newline at end
}

3

JavaScript (ES6) 120 122

Редактировать 2 байта, сохраненных thx ETHпродукции

Анонимная функция. Примечание: число в таблице ограничено 7 цифрами, что более чем разумно, учитывая общий размер таблицы с учетом больших чисел

Теперь я должен найти более короткий способ получить максимальный размер столбцов, избегая логарифмов

n=>(a=Array(n+1).fill(-~Math.log10(2<<Math.log2(n)))).map((m,i)=>a.map((z,j)=>`       ${i^j}`.slice(~m)).join``).join`
`

Тестовое задание

f=n=>(a=Array(n+1).fill(-~Math.log10(2<<Math.log2(n)))).map((m,i)=>a.map((z,j)=>`       ${i^j}`.slice(~m)).join``).join`\n`

function update() {
  var v=+I.value
  O.textContent = f(v)
}  

update()
N: <input id=I type=number value=9 oninput='update()'>
<pre id=O></pre>


Круто, люблю использовать, ~mчтобы захватить дополнительное пространство. Использование строки шаблона может сохранить два байта:(z,j)=>`(7 spaces)${i^j}`.slice(~m)
ETHproductions

@ETHproductions 1) хорошее предложение, спасибо 2) как вам удалось поставить ... (я даже не могу спросить) ... символ (96) внутри 2 символа (96)?
edc65

Ага, вы просто используете несколько обратных кавычек, вот так: (ignore this padding) ``abc`def`` (ignore this too)abc`def
Появляется так

3

C, 149 байтов

int i=0,j,n,k=2;char b[256];scanf("%d",&n);while((k*=2)<=n);k^=k-1;while(i++<=n&&putchar(10))for(j=0;j<=n;j++)printf(" %*d",sprintf(b,"%d",k),i-1^j);
---------

Детальнее

#include <stdio.h>

int main()
{
    int i=0, j, n, k=2;
    char b[256] = { 0 };

    scanf("%d", &n);

    // find max xor value in the table
    while((k*=2)<=n); k^=k-1;

    printf("> %d ~ %d", k, sprintf(b,"%d",k));

    while(i++ <= n && putchar(10))
    {
        for(j = 0; j <= n;j++)
        {
            printf(" %*d", sprintf(b,"%d",k), (i-1)^j);
        }
    }

    return 0;
}

1
Как и в вашем java-посте, здесь нет попыток правильно выровнять столбцы. Это единственная сложная часть этой проблемы. Этот код дает неправильный вывод при вводе <8 или> 64.
edc65

@ edc65 Я узнал, как выровнять, значение max xor является двоичным 11..1по отношению к значимому во входном значении n, это можно сделать, сначала найдя ближайшую степень 2, а затем xor с предыдущим числом,0001 xor 1110 = 1111
Khaled.K

Хорошо, вы на правильном пути. Тем не менее, вы должны проверить больше: цикл с k дает неверный результат для n = 8 (и ваш короткий ответ не инициализирует локальную переменную i в 0)
edc65

Этот простой цикл должен сделать: for(k=1;k<=n;)k*=2;k--;. Теперь я вижу, что это намного короче, чем моя попытка C к тому же (моя лучше для производительности, но производительность не имеет значения в этом испытании)
edc65

@ edc65 вы должны сделать 2^k xor 2^k -1для max{2^k<=n}или 2^k -1для min{2^k>=n}. чтобы получить все 11..1там
Халед.К

3

C 103 байта

Y(n){int i,j=n++;char*f="%2u";while(j/=8)++f[1];for(;j<n;++j,puts(""))for(i=0;i<n;++i)printf(f,i^j);}

1
Добро пожаловать в Программирование Пазлов и Code Golf! Из того, что я вижу, ваш ответ, как, к сожалению, многие другие здесь, полностью пропускает точку выравнивания столбцов.
edc65

Попробуйте это с вводом 5 (слишком много места между столбцами) или 65 (слишком мало)
edc65

это было бы нормально, наконец, до 512, наконец, здесь ...
Рос

3

Желе неконкурентоспособное

7 байт. Этот ответ не является конкурирующим, поскольку он использует функции, которые устарели.

0r©^'®G

Попробуйте онлайн!

Как это устроено

0r©^'®G  Main link. Input: n (integer)

0r       Range; yield [0, ..., n].
  ©      Save the range in the register.

     ®   Yield the range from the register.
   ^'    XOR each integer in the left argument with each integer in the right one.
      G  Grid; separate rows by newlines, columns by spaces, with a fixed width for
         all columns. Since the entries are numeric, align columns to the right.

2
Поздравляю с вашим 1000-м ответом :)
Аднан

3

R, 38 байт

Обычно R требует много байтов только для форматирования вывода. В этом случае все наоборот. outerкоторый обычно относится к внешнему произведению двух массивов, может ли при наличии функции выполнять это через поля векторов. В этом случае мы применяем побитовую функцию XOR bitwXor.

names(x)=x=1:scan();outer(x,x,bitwXor)

2

CJam, 29 27 байт

ri:X),_ff{^s2X2b,#s,)Se[}N*

Проверьте это здесь.

объяснение

ri      e# Read input and convert to integer.
:X      e# Store in X.
),      e# Get range [0 1 ... X].
_ff{    e# Nested map over all repeated pairs from that range...
  ^     e#   XOR.
  s     e#   Convert to string.
  2     e#   Push 2.
  X2b,  e#   Get the length of the base-2 representation of X. This is the same as getting
        e#   getting the base-2 integer logarithm and incrementing it.
  #     e#   Raise 2 to that power. This rounds X up to the next power of 2.
  s,    e#   Convert to string and get length to determine column width.
  )     e#   Increment for additional padding.
  Se[   e#   Pad string of current cell from the left with spaces.
}
N*      e# Join with linefeeds.

Ну, это было быстро, ха-ха
Аднан

2

MathCAD, 187 байт

введите описание изображения здесь

MathCAD легко обрабатывает встроенные таблицы - но не имеет абсолютно ни побитового Xor, ни десятичных в двоичные, ни двоичных в десятичные преобразователи. Функции for перебирают возможные значения. I, a2, Xa и Xb занимают место. Цикл while активно преобразуется в двоичный, а при преобразовании в двоичный также выполняет функцию xor (маленький крестик с кружком вокруг него). Он хранит двоичное число в числе base-10, состоящем из 0 и 1. Затем он преобразуется перед сохранением в М-матрице с помощью функции суммирования.

Это может быть легко исправлено (если только путем замены местозаполнителей на более короткие), но я решил опубликовать его и посмотреть, сможет ли кто-нибудь сыграть в гольф в двоично-десятичном преобразователе больше, чем что-либо еще.


2

k4, 50 байтов

{-1@" "/:'(-|//#:''x)$x:$2/:''~x=/:\:x:0b\:'!1+x;}

Например:

  {-1@" "/:'(-|//#:''x)$x:$2/:''~x=/:\:x:0b\:'!1+x;}9
 0  1  2  3  4  5  6  7  8  9
 1  0  3  2  5  4  7  6  9  8
 2  3  0  1  6  7  4  5 10 11
 3  2  1  0  7  6  5  4 11 10
 4  5  6  7  0  1  2  3 12 13
 5  4  7  6  1  0  3  2 13 12
 6  7  4  5  2  3  0  1 14 15
 7  6  5  4  3  2  1  0 15 14
 8  9 10 11 12 13 14 15  0  1
 9  8 11 10 13 12 15 14  1  0

2

Python 3, 133 131 байт

import math
n=int(input())
r,p=range(n+1),print
for y in r:[p(end='%%%dd '%len(str(2**int(math.log2(n)+1)-1))%(x^y))for x in r];p()

1

Mathematica, 108 байт

StringRiffle[Thread[Map[ToString,a=Array[BitXor,{#,#}+1,0],{2}]~StringPadLeft~IntegerLength@Max@a],"
"," "]&

Не обращайте внимания на ошибку, она просто Threadне знает, что делает.


1

Emacs Lisp, 193 байта

(defun x(n)(set'a 0)(set'n(1+ n))(while(< a n)(set'b 0)(while(< b n)(princ(format(format"%%%ss "(ceiling(log(expt 2(ceiling(log n 2)))10)))(logxor a b)))(set'b(1+ b)))(set'a(1+ a))(message"")))

Ungolfed:

(defun x(n)
  (set'a 0)
  (set'n(1+ n))
  (while(< a n)
    (set'b 0)
    (while(< b n)
      (princ
        (format
          ;; some format string magic to get the length of the longest
          ;; possible string as a format string
          (format "%%%ss " (ceiling(log(expt 2(ceiling(log n 2)))10)))
          (logxor a b)))
      (set'b(1+ b)))
    (set'a(1+ a))
    ;; new line
    (message"")))

Вывод направляется в *Message*буфер, который был бы , stdoutесли должны xбыли быть использованы внутри сценария.

(x 9)
 0  1  2  3  4  5  6  7  8  9 
 1  0  3  2  5  4  7  6  9  8 
 2  3  0  1  6  7  4  5 10 11 
 3  2  1  0  7  6  5  4 11 10 
 4  5  6  7  0  1  2  3 12 13 
 5  4  7  6  1  0  3  2 13 12 
 6  7  4  5  2  3  0  1 14 15 
 7  6  5  4  3  2  1  0 15 14 
 8  9 10 11 12 13 14 15  0  1 
 9  8 11 10 13 12 15 14  1  0

1

Python 2, 114 байт

Потребовалось некоторое время, чтобы найти способ сделать заполнение переменной ширины .format()(некоторые, а не много) и настроить его правильно, но я думаю, что теперь у меня есть все для спецификации. Можно было бы использовать больше гольфа в этом расчете ширины, хотя.

N=input()+1
for i in range(N):print''.join(' {n:>{w}}'.format(w=len(`2**(len(bin(N))-2)`),n=i^r)for r in range(N))

1

Cache ObjectScript , 127 байт

x(n)s w=$L(2**$bitfind($factor(n),1,100,-1))+1 f i=0:1:n { w $j(i,w) } f i=1:1:n { w !,$j(i,w) f j=1:1:n { w $j($zb(i,j,6),w) } }

Детальнее:

x(n)
 set w=$Length(2**$bitfind($factor(n),1,100,-1))+1
 for i=0:1:n {
     write $justify(i,w)
 }
 for i=1:1:n {
     write !,$justify(i,w)
     for j=1:1:n {
         write $justify($zboolean(i,j,6),w)
     }

 }

1

Пайк, 8 байт (неконкурирующий)

hD]UA.&P

Объяснение:

         - auto-add eval_or_not_input() to the stack
h        - increment the input
 D]      - Create a list containing [inp+1, inp+1]
   U     - Create a 2d range 
    A.^  - Deeply apply the XOR function to the range
       P - print it out prettily

Попробуй здесь


0

Python 2, 77 байт

n=input()+1
t=range(n)
for i in t: print "%3d"*n % tuple([x^i for x in t])

3
Добро пожаловать в Программирование Пазлов и Code Golf! Насколько я вижу, ваш ответ, как, к сожалению, и многие другие здесь, полностью пропускает точку выравнивания столбцов.
кот


0

Excel VBA, 95 байт

Функция анонимного непосредственного окна VBE, которая принимает данные из диапазона [A1]и выводит их на консоль.

For y=0To[A1]:For x=0To[A1]:z=x Xor y:?Spc([Len(2^-Int(-Log(A1,2)))]-Len(z))Str(z);:Next:?:Next

0

Small Basic , 499 байт

Скрипт, который принимает входные данные от TextWindowобъекта и выводит их в тот же

a=TextWindow.Read()
For y=0To a
For x=0To a
n=x
b()
z1=z
n=y
b()
l=Math.Max(Array.GetItemCount(z),Array.GetItemCount(z1))
o=0
For i=1To l
If z1[i]<>z[i]And(z[i]=1Or z1[i]=1)Then
z2=1
Else 
z2=0
EndIf
o=o+z2*Math.Power(2,i-1)
EndFor
TextWindow.Write(Text.GetSubText("      ",1,Text.GetLength(Math.Power(2,Math.Ceiling(Math.Log(a)/Math.Log(2))))-Text.GetLength(o))+o+" ")
EndFor
TextWindow.WriteLine("")
EndFor
Sub b
z=0
c=0  
While n>0
c=c+1
z[c]=Math.Remainder(n,2)
n=Math.Floor(n/2)
EndWhile
EndSub

Попробуйте на SmallBasic.com Использование Silverlight и, следовательно, должны быть запущены в IE или Edge

Выберите черную консоль, затем введите целое число ввода и нажмите Enter.


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