12
\$\begingroup\$

I have a hardware that has a 32-bit input register. The register has the following characteristics:

  • The 32-bit register consists of eight 4-bit fields.
  • Each 4-bit field holds a value in signed-magnitude; it can hold an integer between -7 and +7 inclusive, including -0 and +0 (signed zeroes).

For example, the hexadecimal value 0xABCD1234 represents the field values [-2, -3, -4, -5, +1, +2, +3, +4]. In fact, one hex digit represents one 4-bit value with the following mapping:

Hex    |  Input value
---------------------
0 ~ 7  |  +0 ~ +7
8 ~ F  |  -0 ~ -7

In order to operate this hardware, I figured that the most natural inputs would be 8 consecutive increasing values, treating -0 and +0 as distinct. So the input values will be one of the following:

field values for 8 fields        => 32-bit register value
[-7, -6, -5, -4, -3, -2, -1, -0] => 0xFEDCBA98 (offset -4)
[-6, -5, -4, -3, -2, -1, -0, +0] => 0xEDCBA980 (offset -3)
...
[-3, -2, -1, -0, +0, +1, +2, +3] => 0xBA980123 (balanced, offset 0)
...
[+0, +1, +2, +3, +4, +5, +6, +7] => 0x01234567 (offset +4)

I define the input 0xBA980123 as balanced, and the other inputs have an offset from the balanced input. The balanced input itself has offset 0.

Task

Given the offset, output the desired value for the input register for my hardware as described above.

Input and output

The input (offset) is an integer between -4 and 4 inclusive. You can take it as a string, optionally with explicit sign (e.g. +4).

You can output the result value as an integer or a string. If you choose to output as a string (either returning or printing), you can use base 2, 8, 10 or 16. In case of hexadecimal, mixing upper- and lowercase letters are allowed. Base prefixes (e.g. 0b or 0x), leading zeros, and leading/trailing whitespaces are also allowed.

You may use signed 32-bit values for output instead (imagine the values being used in a C program); in that case, the output values will be subtracted by 2^32, except for the input +4.

Scoring

The standard rules apply. The shortest code in bytes wins.

All test cases

There are only nine possible inputs, so here is the list of all input/output values your program/function needs to support.

input =>  output hex | decimal    | signed 32bit
-4    =>  0xFEDCBA98 | 4275878552 | -19088744
-3    =>  0xEDCBA980 | 3989547392 | -305419904
-2    =>  0xDCBA9801 | 3703216129 | -591751167
-1    =>  0xCBA98012 | 3416883218 | -878084078
 0    =>  0xBA980123 | 3130523939 | -1164443357
 1    =>  0xA9801234 | 2843742772 | -1451224524
 2    =>  0x98012345 | 2550211397 | -1744755899
 3    =>  0x80123456 | 2148676694 | -2146290602
 4    =>  0x01234567 | 19088743   | 19088743
\$\endgroup\$
  • \$\begingroup\$ It seems you've gone a long way to accept many base representation outputs, are lists of the place values as integers acceptable? (e.g. 0 -> [11,10,9,8,0,1,2,3] as a raw hexadecimal notation) \$\endgroup\$ – Jonathan Allan Oct 29 at 0:35
  • 1
    \$\begingroup\$ @JonathanAllan Sorry, but I feel like it's a bit of stretch. \$\endgroup\$ – Bubbler Oct 29 at 0:43
  • \$\begingroup\$ It is somewhat more natural than a string IMO, but OK, a 2 byte cost to convert from base 16 to an integer for Jelly it is. \$\endgroup\$ – Jonathan Allan Oct 29 at 0:50

16 Answers 16

3
\$\begingroup\$

Jelly, 14 bytes

12_r8Ḋ;8Ḷ¤ḣ8ḅ⁴

A monadic Link accepting an integer which yields an integer.

Try it online!

How?

12_r8Ḋ;8Ḷ¤ḣ8ḅ⁴ - Link: integer N     e.g. 4              or     -2
12             - literal twelve           12                     12
  _            - subtract N               8                      14
    8          - literal eight            8                      8
   r           - inclusive range          [8]                    [14,13,12,11,10,9,8]
     Ḋ         - dequeue                  []                     [13,12,11,10,9,8]
         ¤     - nilad followed by link(s) as a nilad:
       8       -   literal eight = 8
        Ḷ      -   lowered range = [0..7]
      ;        - concatenate              [0,1,2,3,4,5,6,7]      [13,12,11,10,9,8,0,1,2,3,4,5,6,7]
           8   - literal eight            8                      8
          ḣ    - head to index            [0,1,2,3,4,5,6,7]      [13,12,11,10,9,8,0,1]
             ⁴ - literal sixteen          16                     16
            ḅ  - to integer from base     3130523939             3703216129
\$\endgroup\$
3
\$\begingroup\$

Ruby, 30 bytes

Simple and clean. Outputs a substring of the larger with the right offset because it seemed cheaper than any method I could think of that calculated it properly.

->o{"FEDCBA9801234567"[o+4,8]}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ If you would believe it, I came up with the exact same idea that you did, just about a minute later \$\endgroup\$ – Embodiment of Ignorance Oct 29 at 1:46
  • \$\begingroup\$ @EmbodimentofIgnorance I believe it. This seemed like the easiest option right off the bat, anyways, so it's literally a matter of who sees the challenge first haha \$\endgroup\$ – Value Ink Oct 29 at 1:47
  • 4
    \$\begingroup\$ Am I missing something or should it be FEDCBA...? \$\endgroup\$ – Gnudiff Oct 29 at 13:30
2
\$\begingroup\$

JavaScript (Node.js), 38 bytes

n=>~(p=19088743)*16**(n+4)|p*16**(n-4)

Try it online!

In two's complement representation, 0xfedcba98 is "not 0x01234567 (19088743)". We first shift 0xfedcba98 \$ 4(n+4) \$ bits left, and shift 0x01234567 \$ 4(4-n) \$ bits right. Then use bit or to add them up.

JavaScript do not support n << 32, so we use n * 2 ** 32 instead. And bitwise or in JavaScript automatically convert operand to int32. The two float value trimed to int32 and calculated the result.


Another not quite interesting answer:

JavaScript (Node.js), 35 bytes

n=>'FEDCBA9801234567'.substr(4+n,8)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

C (gcc), 35 32 bytes

f(n){n=0xFEDCBA99l*~0u>>16-4*n;}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 20 bytes

Nθ⭆…⁻θ⁴⁺θ⁴⎇‹ι⁰⍘⁻⁷ιφι

Try it online! Link is to verbose version of code. Outputs 8 hex digits. Explanation:

Nθ                      Input the offset
  ⭆…                    Map and join over range
    ⁻θ⁴                 From offset - 4 (inclusive)
       ⁺θ⁴              To offset + 4 (exclusive)
          ⎇‹ι⁰          If current value is negative
              ⍘⁻⁷ιφ     Then subtract from 7 and convert to hex
                   ι    Else use directly as digit
                        Implicitly print
\$\endgroup\$
1
\$\begingroup\$

Haskell, 38 bytes

f n=take 8$drop(n+4)"FDECBA9801234567"

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Python 3, 60 56 52 37 bytes

lambda n:"FEDCBA9801234567"[4+n:12+n]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ +1. I had basically the same idea: lambda n:"FEDCBA9801234567"[4+n:][:8] (Same length) \$\endgroup\$ – pizzapants184 Oct 29 at 21:31
  • \$\begingroup\$ @pizzapants184 i find your solution even more elegant :) \$\endgroup\$ – Delta Oct 30 at 5:56
1
\$\begingroup\$

05AB1E, 12 11 bytes

4Ø4Ÿα7݇hJ

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You can remove the trailing J and just output as a list of characters, can you not? \$\endgroup\$ – Kevin Cruijssen Nov 4 at 9:40
1
\$\begingroup\$

Gaia, 12 11 bytes

11⁻7N8…+8<h

Try it online!

Test suite

11⁻          11 - input
   7N        Downward range from result to 7 (excluding 7, empty list if first number is 7)
     8…+     Append the range 0-7 (inclusive)
        8<   First 8 numbers
          h  Convert from hexadecimal
\$\endgroup\$
1
\$\begingroup\$

Perl 6, 28 26 bytes

{:16[11-$_...^7,|^($_+4)]}

Try it online!

Explanation

{                        }  # Anonymous block
     11-$_...^7             # Range 11-n down to 7 exclusive
               ,|^($_+4)    # Followed by range 0 to n+4 exclusive
 :16[                   ]   # Convert from base 16
\$\endgroup\$
1
\$\begingroup\$

Keg, 37 22 bytes (SBCS)

Push & roll

\0\7ɧ^89AFɧ(¿4+|")(8|,

Try it online!

Explanation

\0\7ɧ                  # Push range 0..7
     ^                 # Reverse the stack
      89               # Push 8 & 9
        AFɧ            # Push range 'A' .. 'F'
           (¿4+        # Repeat input+4 times:
               |")     #     Move TOS to the bottom
                  (8|, # Output the 8 TOSes
# No implicit output

Fixed version, works in range outside of -4...4

\0\9ɧ^""AFɧ(¿4+|")(8|,

TIO

\$\endgroup\$
  • \$\begingroup\$ Turns out the 22 byter I gave earlier was kinda broken. Fixed 22 byter \$\endgroup\$ – Jono 2906 Oct 30 at 3:59
  • \$\begingroup\$ Well, by broken, I mean it didn't work for values outside of the -4 <= n < 4 range. Still, I recommend placing in the alternate 22 byter \$\endgroup\$ – Jono 2906 Oct 30 at 4:02
1
\$\begingroup\$

PHP, 38 bytes

<?=substr(FEDCBA9801234567,4+$argn,8);

Try it online!

\$\endgroup\$
1
\$\begingroup\$

W, 27 25 bytes

11Zr4Zrg7N0gjzFEDCBA98zrx

Wren, 40 bytes

Fn.new{|a|"FEDCBA9801234567"[a+4..a+11]}

Try it online!

Simply a port of most other answers.

Wren, 70 67 bytes

Horribly long answer; outputs to STDOUT.

Fn.new{|a|
for(i in a..a+7)System.write("4567FDECBA980123"[i%16])
}

Try it online!

Explanation

Fn.new{                                                // New anonymous function
       |a|                                             // with parameter a
                                                       // newline because this is
                                                       // not an expression
for(i in a..a+7)                                       // For every item in the range
                                                       // from a to a+7
                                                       // (Select 8 items in the string)
                System.write("4567FDECBA980123"        // Output the string
                                               [i%16]  // with the index of i modulo'd by 16.
                                                       // Moduloing maps the items in
                                                       // the iteration back to the start
                                                       // of the string.
)                                                      // Pretty self-explanatory.
}                                                      // no need to explain this
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 42 bytes

f=(o,n=8)=>n&&f(o-1,n-1)*16+(o<-3?4-o:o+3)

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Bash, 35

  • 1 byte saved thanks to @79037662.
s=FEDCBA9801234567
echo ${s:$1+4:8}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ I believe the last 8 in line 1 is unnecessary. \$\endgroup\$ – 79037662 Oct 29 at 18:07
  • \$\begingroup\$ @79037662, thanks! not sure how that one crept in! \$\endgroup\$ – Digital Trauma Oct 29 at 19:31
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 38 bytes

x=>"FEDCBA9801234567".Substring(x+4,8)

Each valid output is just a rotation of the string FEDCBA9801234567

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.