Skip to main content
deleted 7 characters in body
Source Link
kaya3
  • 549
  • 2
  • 9

Python 3, 89 bytes

a=0
for c in input():a=b'147223453614'[ord(c)%3*4+a%4]^(a&4)
print('-'[:a&4]+'1ijk'[a%4])

Try it online!

It encodes the unit quaternions 1, i, j, k, -1, -i, -j, -k as the numbers 0..7 respectively, so that a%4 represents one of 1, i, j, k, and a&4 represents whether the value is negated.

The loop works by accumulating a result in the variable a, multiplying one quaternion from the input on each iteration, much like you'd write a = 1; for x in numbers: a *= x to compute a product normally.

The byte-string b'147223453614' encodes a multiplication table for i, j, k multiplied by 1, i, j, k. Indexing a byte-string gives the ASCII values as integers, but we only care about the lowest 3 bits and, conveniently, the ASCII value of each digit 0..7 has the correct lowest 3 bits, so this is practically like indexing a list of integers. The table is 3x4 instead of 8x8 because the firstone operand (from the user input) can only be i, j or k, and we can ignore the sign from the secondother operand (the accumulator variable) and deal with the sign afterwards.

The expression ord(c)%3 converts the ASCII characters i, j, k into 0, 1, 2 respectively; the ASCII values of i, j and k are correct for this modulo 3. (If they weren't, the multiplication table could be changed.) The ^(a&4) part XORs the result with the third bit of a, swapping the sign of the result from the multiplication table if this operand was negative, since we ignored the sign before.

The output uses string slicing to conditionally print the minus sign ('-'[:4] conveniently isn't an error in Python).

Python 3, 89 bytes

a=0
for c in input():a=b'147223453614'[ord(c)%3*4+a%4]^(a&4)
print('-'[:a&4]+'1ijk'[a%4])

Try it online!

It encodes the unit quaternions 1, i, j, k, -1, -i, -j, -k as the numbers 0..7 respectively, so that a%4 represents one of 1, i, j, k, and a&4 represents whether the value is negated.

The loop works by accumulating a result in the variable a, multiplying one quaternion from the input on each iteration, much like you'd write a = 1; for x in numbers: a *= x to compute a product normally.

The byte-string b'147223453614' encodes a multiplication table for i, j, k multiplied by 1, i, j, k. Indexing a byte-string gives the ASCII values as integers, but we only care about the lowest 3 bits and, conveniently, the ASCII value of each digit 0..7 has the correct lowest 3 bits, so this is practically like indexing a list of integers. The table is 3x4 instead of 8x8 because the first operand (from the user input) can only be i, j or k, and we can ignore the sign from the second operand (the accumulator variable) and deal with the sign afterwards.

The expression ord(c)%3 converts the ASCII characters i, j, k into 0, 1, 2 respectively; the ASCII values of i, j and k are correct for this modulo 3. (If they weren't, the multiplication table could be changed.) The ^(a&4) part XORs the result with the third bit of a, swapping the sign of the result from the multiplication table if this operand was negative, since we ignored the sign before.

The output uses string slicing to conditionally print the minus sign ('-'[:4] conveniently isn't an error in Python).

Python 3, 89 bytes

a=0
for c in input():a=b'147223453614'[ord(c)%3*4+a%4]^(a&4)
print('-'[:a&4]+'1ijk'[a%4])

Try it online!

It encodes the unit quaternions 1, i, j, k, -1, -i, -j, -k as the numbers 0..7 respectively, so that a%4 represents one of 1, i, j, k, and a&4 represents whether the value is negated.

The loop works by accumulating a result in the variable a, multiplying one quaternion from the input on each iteration, much like you'd write a = 1; for x in numbers: a *= x to compute a product normally.

The byte-string b'147223453614' encodes a multiplication table for i, j, k multiplied by 1, i, j, k. Indexing a byte-string gives the ASCII values as integers, but we only care about the lowest 3 bits and, conveniently, the ASCII value of each digit 0..7 has the correct lowest 3 bits, so this is practically like indexing a list of integers. The table is 3x4 instead of 8x8 because one operand (from the user input) can only be i, j or k, and we can ignore the sign from the other operand (the accumulator variable) and deal with the sign afterwards.

The expression ord(c)%3 converts the ASCII characters i, j, k into 0, 1, 2 respectively; the ASCII values of i, j and k are correct for this modulo 3. (If they weren't, the multiplication table could be changed.) The ^(a&4) part XORs the result with the third bit of a, swapping the sign of the result from the multiplication table if this operand was negative, since we ignored the sign before.

The output uses string slicing to conditionally print the minus sign ('-'[:4] conveniently isn't an error in Python).

Source Link
kaya3
  • 549
  • 2
  • 9

Python 3, 89 bytes

a=0
for c in input():a=b'147223453614'[ord(c)%3*4+a%4]^(a&4)
print('-'[:a&4]+'1ijk'[a%4])

Try it online!

It encodes the unit quaternions 1, i, j, k, -1, -i, -j, -k as the numbers 0..7 respectively, so that a%4 represents one of 1, i, j, k, and a&4 represents whether the value is negated.

The loop works by accumulating a result in the variable a, multiplying one quaternion from the input on each iteration, much like you'd write a = 1; for x in numbers: a *= x to compute a product normally.

The byte-string b'147223453614' encodes a multiplication table for i, j, k multiplied by 1, i, j, k. Indexing a byte-string gives the ASCII values as integers, but we only care about the lowest 3 bits and, conveniently, the ASCII value of each digit 0..7 has the correct lowest 3 bits, so this is practically like indexing a list of integers. The table is 3x4 instead of 8x8 because the first operand (from the user input) can only be i, j or k, and we can ignore the sign from the second operand (the accumulator variable) and deal with the sign afterwards.

The expression ord(c)%3 converts the ASCII characters i, j, k into 0, 1, 2 respectively; the ASCII values of i, j and k are correct for this modulo 3. (If they weren't, the multiplication table could be changed.) The ^(a&4) part XORs the result with the third bit of a, swapping the sign of the result from the multiplication table if this operand was negative, since we ignored the sign before.

The output uses string slicing to conditionally print the minus sign ('-'[:4] conveniently isn't an error in Python).