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\$ Commented Nov 1, 2019 at 0:29
  • \$\begingroup\$ @ValueInk No, it's not required. \$\endgroup\$ 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\$ 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\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.