11
\$\begingroup\$

The (slightly harder, but still easy) sequel of Generate input for this hardware.

Background

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 correctly operate this hardware, the 8 field values must be strictly increasing from left (most significant) to right (least significant). For signed zeros, -0 is considered to be less than +0.

The following are the examples of valid inputs:

field values for 8 fields        => 32-bit register value
[-7, -6, -5, -4, -3, -2, -1, -0] => 0xFEDCBA98
[+0, +1, +2, +3, +4, +5, +6, +7] => 0x01234567
[-7, -4, -3, -2, -0, +1, +3, +4] => 0xFCBA8134
[-2, -1, -0, +0, +3, +4, +5, +7] => 0xA9803457

The following are the examples of invalid ones:

field values for 8 fields        => 32-bit register value
[+7, +6, +5, +4, +3, +2, +1, +0] => 0x76543210 // not increasing
[-2, -1, -0, -0, +1, +2, +3, +4] => 0xA9881234 // not strictly increasing, due to duplicates
[-3, -2, -1, +0, -0, +1, +2, +3] => 0xBA908123 // +0 is greater than -0

Task

Given the register value, determine if it is a valid input to the hardware.

Input and output

The input (the register value) is an unsigned 32-bit integer. You can take it as an integer, a string, or a list of digits. A string or list of digits can be in base 2, 8, 10 or 16, least-significant-digit-first or most-significant-digit-first, with or without leading zeros or base prefixes.

For example, if an input value is 0x01234567, possible representations in base 16 include "0x01234567", "01234567", "1234567", "76543210" (reversed order of digits), [0, 1, 2, 3, 4, 5, 6, 7], [7, 6, 5, 4, 3, 2, 1, 0].

The output is a boolean, indicating whether the given input is valid or not. You can choose to output either:

  • Any of the truthy/falsy values as defined by the language of your choice
    • The actual result values may differ between inputs (e.g. output 1 for a truthy input and 2 for another truthy one).
    • Swapping truthy and falsy values is not allowed.
  • Any two distinct constant values for true/false respectively
    • In this case, the result values should exactly be one of the two constant values.

Scoring

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

Test cases

Expected output: Valid

0xFEDCBA98
0xEDCBA980
0x80123456
0x01234567
0xFCB98037
0xEDB12345

Expected output: Invalid

0x76543210
0x1A2B3C4D
0x12345678
0xBA988123
0xBA908123
0x00123456
0xB9882347
0xDC914556
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Is the 0x required in the input? \$\endgroup\$
    – Value Ink
    Commented Nov 1, 2019 at 0:29
  • \$\begingroup\$ @ValueInk No, it's not required. \$\endgroup\$
    – Bubbler
    Commented Nov 1, 2019 at 0:39
  • \$\begingroup\$ In case anyone wants to make us of it, the expression (~n/8&2**32/15)*7^n reverses the hex digits 0-7, putting the digits of a valid input n into "normal" decreasing order in hex. \$\endgroup\$
    – xnor
    Commented Nov 1, 2019 at 6:33

9 Answers 9

6
\$\begingroup\$

Python 2, 52 bytes

lambda s:eval("'EDCBA9801234567'.find(%r)<"*8%s+'s')

Try it online!

Takes input as a tuple like ('F', 'E', 'D', 'C', 'B', 'A', '9', '8').

The idea is to produce out and evaluate a long chain of inequalities like:

'EDCBA9801234567'.find('F')<'EDCBA9801234567'.find('E')<'EDCBA9801234567'.find('D')<'EDCBA9801234567'.find('C')<'EDCBA9801234567'.find('B')<'EDCBA9801234567'.find('A')<'EDCBA9801234567'.find('9')<'EDCBA9801234567'.find('8')<s

The s at the end of the chain takes care of the extra trailing < symbol by giving an always-true comparison of "number < string" in Python 2 logic.

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

Ruby -n, 36 bytes

Outputs 1 if valid, nil if not.

p~/xF?E?D?C?B?A?9?8?#{[*0..7]*??}?$/

Try it online!

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

F# (.NET Core), 91 bytes

 [for i:char in n->"EDCBA9801234567".IndexOf(i)]|>List.pairwise|>List.forall(fun(x,y)->x<y)

Try it online!

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

Jelly, 9 bytes

N>¡€7I>0Ạ

Try it online!

A monadic link taking a list of bass 16 digits and returning 1 for true and 0 for false.

Explanation

  ¡€      | For each digit, if:
 >  7     | - Greater than 7
          | Then:
N         | - Negate
     I    | Increments between each digit
      >0  | Greater than 0
        Ạ | All
\$\endgroup\$
2
\$\begingroup\$

Perl 6, 25 24 bytes

{[>] ((8 X>$_)X*7)Z+^$_}

Try it online!

Takes a list of integers.

Explanation

{                      }  # Anonymous block
     (           )Z+^$_   # XOR input values with
      (8 X>$_)X*7         #   7 if value < 8, reversing sort order
                          #   0 otherwise, keeping value unchanged
 [>]  # All values strictly decreasing?
\$\endgroup\$
1
\$\begingroup\$

PHP (7.4), 54 bytes

fn($a)=>preg_match(_.join('.*',$a)._,FEDCBA9801234567)

Try it online!

Input is array of digits in base 16 (example: ['F','E','D','C','B','A','9','8']);

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

05AB1E, 17 bytes

Σ•_ćúθœιu0•hSk}ÙQ

Try it online!

Explanation:

Σ             }             # Sort by 
             k              # the index of each char of the input in...
 •_ćúθœιu0•hS               # [7...0,9,8,A...F]
               Ù            # remove duplicates 
                Q           # and check that it's not changed
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 8 bytes

H8(вÆü‹P

Try it online! or validate all test cases.

Input is a list of hex digits. Output is 1 for truthy, 0 for falsy.

H          # convert from hex
 8(в       # convert to base -8
    Æ      # reduce by subtraction
     ü‹    # pairwise less-than
       P   # product
\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 53 bytes

f=([a,...b])=>b<f||g(a)>g(b[0])&f(b)
g=x=>x<8?x-8+g:x

Try it online!

Python 3.8 (pre-release), 44 bytes

lambda s:eval("((t:=0x%c)^-(t>7))<"*8%s+'9')

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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