13
\$\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 '19 at 0:35
  • 1
    \$\begingroup\$ @JonathanAllan Sorry, but I feel like it's a bit of stretch. \$\endgroup\$ – Bubbler Oct 29 '19 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 '19 at 0:50

17 Answers 17

4
\$\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!

| improve this answer | |
\$\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 '19 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 '19 at 1:47
  • 4
    \$\begingroup\$ Am I missing something or should it be FEDCBA...? \$\endgroup\$ – Gnudiff Oct 29 '19 at 13:30
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
| improve this answer | |
\$\endgroup\$
3
\$\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!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

C (gcc), 35 32 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Python 3, 60 56 52 37 bytes

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

Try it online!

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

APL (Dyalog Unicode), 23 22 bytes (SBCS)

8↑('FEDCBA98',⎕D)↓⍨4+⊢

Try it online!

First time trying to use APL for golf. Any suggestions for improvement would be greatly appreciated. I put s← in the code field for testing purposes; is there a better way to do that?

(Edit: Removed the s← and saved a byte thanks to Bubbler)

| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Haskell, 38 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 12 11 bytes

4Ø4Ÿα7݇hJ

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can remove the trailing J and just output as a list of characters, can you not? \$\endgroup\$ – Kevin Cruijssen Nov 4 '19 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
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Bash, 35

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

Try it online!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I believe the last 8 in line 1 is unnecessary. \$\endgroup\$ – 79037662 Oct 29 '19 at 18:07
  • \$\begingroup\$ @79037662, thanks! not sure how that one crept in! \$\endgroup\$ – Digital Trauma Oct 29 '19 at 19:31
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
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

PHP, 38 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Keg, 19 bytes (SBCS)

7Ï89AFɧ(¿4+|")^(8|_

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Turns out the 22 byter I gave earlier was kinda broken. Fixed 22 byter \$\endgroup\$ – Lyxal Oct 30 '19 at 3:59
  • \$\begingroup\$ 19 bytes \$\endgroup\$ – Lyxal Dec 18 '19 at 9:14
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!

| improve this answer | |
\$\endgroup\$
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!

| improve this answer | |
\$\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.