Створіть таблицю 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 Так, мінімально можлива сума. Я додам це до опису.
Аднан


Дивлячись на прикладиoutput an XOR table with the size N+1
edc65

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

Відповіді:


12

MATL , 10 байт

0i2$:tXgZ~

Зараз компілятор (і зокрема ця програма), здається, працює в Octave, хоча все ще потребує певного вдосконалення. Ви можете тимчасово використовувати цю команду GitHub .

Редагувати (30 березня 1616 р.) : Спробуйте в Інтернеті!

Приклад

>> 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, хоча в якийсь момент у баші не вистачить пам'яті з використанням (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);}

Спробуй це вставити n як вхід, за замовчуванням 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 ETHproductions

Анонімна функція. Примітка: число в таблиці обмежено 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) як вам вдалося поставити ... (я навіть не можу його запитати) ... char (96) всередині 2 char (96)?
edc65

Ага, ти просто використовуєш кілька підказок, як-от так: (ignore this padding) ``abc`def`` (ignore this too)Показує так:abc`def
ETHproductions

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 post, немає спроб правильно вирівняти стовпці. Це єдина складна частина цього виклику. Цей код дає неправильний вихід при введенні <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--;. Тепер я бачу, що це набагато коротше, ніж моя спроба С до того ж (моя краща для продуктивності, але продуктивність не має значення в цьому виклику)
edc65,

@ edc65, що потрібно зробити 2^k xor 2^k -1для max{2^k<=n}або 2^k -1для min{2^k>=n}. щоб потрапити всіх 11..1туди
Khaled.K

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
Ласкаво просимо до головоломки програмування та коду для гольфу! Як я бачу, ваша відповідь, як на жаль, багато інших тут, повністю пропускає точку вирівнювання стовпців.
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 байт

enter image description here

MathCAD обробляє вбудовані таблиці легко - але не має абсолютно ні бітових Xor, ні десяткових до двійкових або двійкових до десяткових перетворювачів. Функції for повторюють можливі значення. Місце i, a2, Xa та Xb утримується. Цикл while активно перетворюється на двійкове, а при перетворенні на бінарне також виконує функцію xor (маленький хрестик з колом навколо нього). Він зберігає двійкове число в базовому номері 10, що складається з 0 і 1. Потім це перетворюється, перш ніж зберігатися в матриці M за допомогою функції підсумовування.

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


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

Пітон 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

Математика, 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"")))

Безголівки:

(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

Caché 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
Ласкаво просимо до головоломки програмування та коду для гольфу! Як я бачу, Ваша відповідь, як на жаль, багато інших тут, повністю не вистачає точки вирівнювання стовпців.
кіт


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

Маленький базовий , 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.