Densely packed decimal (DPD) to decimal











up vote
21
down vote

favorite
2












Background



Densely packed decimal (DPD) is a way to efficiently store decimal digits in binary. It stores three decimal digits (000 to 999) in 10 bits, which is much more efficient than naive BCD (which stores one digit in 4 bits).



Notations




  • The lowercase letters a to i are the bits that are copied to the decimal representation.


  • 0 and 1 are the exact bits in the input or output bit patterns.


  • x bits are ignored in the conversion.


Conversion table



The following is the conversion table from 10 bits of DPD to three decimal digits. Each decimal digit is represented as 4-bit binary (BCD). Both sides are written left to right from the most significant digit to the least.



Bits                 =>  Decimal         (Digit range)
a b c d e f 0 g h i => 0abc 0def 0ghi (0-7) (0-7) (0-7)
a b c d e f 1 0 0 i => 0abc 0def 100i (0–7) (0–7) (8–9)
a b c g h f 1 0 1 i => 0abc 100f 0ghi (0–7) (8–9) (0–7)
g h c d e f 1 1 0 i => 100c 0def 0ghi (8–9) (0–7) (0–7)
g h c 0 0 f 1 1 1 i => 100c 100f 0ghi (8–9) (8–9) (0–7)
d e c 0 1 f 1 1 1 i => 100c 0def 100i (8–9) (0–7) (8–9)
a b c 1 0 f 1 1 1 i => 0abc 100f 100i (0–7) (8–9) (8–9)
x x c 1 1 f 1 1 1 i => 100c 100f 100i (8–9) (8–9) (8–9)


Task



Convert 10 bits of DPD to 3 digits of decimal.



Test cases



DPD           Decimal
0000000101 005
0001100011 063
0001111001 079
0000011010 090
0001011110 098
1010111010 592
0011001101 941
1100111111 879
1110001110 986
0011111111 999
1111111111 999 * Output is same regardless of the `x` bits


Input



The default input format is a list of 10 bits. The bits should follow the exact order above, or the reverse of it. You may choose to use an equivalent string or integer representation instead. Unlike my other challenges, reordering or using nested structures is not allowed.



For the input [1, 1, 0, 0, 0, 1, 0, 1, 0, 0], the following formats are allowed:




  • List of bits: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]

  • String: "1100010100"

  • Binary integer: 788 or 0b1100010100

  • Decimal integer: 1100010100

  • Reversed: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1] and reversed in any other formats above


The following formats are NOT allowed:




  • Arbitrary reordering of bits: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]

  • Nested structures: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]] or [0b110, 0b001, 0b0100]


Output



The default output format is a list of 3 decimal digits. Each digit should be represented as 0 to 9, either an integer or a character. As in input, you can choose string or integer representation. If you choose integer representation, leading zeroes can be omitted.



Scoring & winning criterion



Standard code-golf rules apply. The shortest program or function in bytes for each language wins.










share|improve this question




























    up vote
    21
    down vote

    favorite
    2












    Background



    Densely packed decimal (DPD) is a way to efficiently store decimal digits in binary. It stores three decimal digits (000 to 999) in 10 bits, which is much more efficient than naive BCD (which stores one digit in 4 bits).



    Notations




    • The lowercase letters a to i are the bits that are copied to the decimal representation.


    • 0 and 1 are the exact bits in the input or output bit patterns.


    • x bits are ignored in the conversion.


    Conversion table



    The following is the conversion table from 10 bits of DPD to three decimal digits. Each decimal digit is represented as 4-bit binary (BCD). Both sides are written left to right from the most significant digit to the least.



    Bits                 =>  Decimal         (Digit range)
    a b c d e f 0 g h i => 0abc 0def 0ghi (0-7) (0-7) (0-7)
    a b c d e f 1 0 0 i => 0abc 0def 100i (0–7) (0–7) (8–9)
    a b c g h f 1 0 1 i => 0abc 100f 0ghi (0–7) (8–9) (0–7)
    g h c d e f 1 1 0 i => 100c 0def 0ghi (8–9) (0–7) (0–7)
    g h c 0 0 f 1 1 1 i => 100c 100f 0ghi (8–9) (8–9) (0–7)
    d e c 0 1 f 1 1 1 i => 100c 0def 100i (8–9) (0–7) (8–9)
    a b c 1 0 f 1 1 1 i => 0abc 100f 100i (0–7) (8–9) (8–9)
    x x c 1 1 f 1 1 1 i => 100c 100f 100i (8–9) (8–9) (8–9)


    Task



    Convert 10 bits of DPD to 3 digits of decimal.



    Test cases



    DPD           Decimal
    0000000101 005
    0001100011 063
    0001111001 079
    0000011010 090
    0001011110 098
    1010111010 592
    0011001101 941
    1100111111 879
    1110001110 986
    0011111111 999
    1111111111 999 * Output is same regardless of the `x` bits


    Input



    The default input format is a list of 10 bits. The bits should follow the exact order above, or the reverse of it. You may choose to use an equivalent string or integer representation instead. Unlike my other challenges, reordering or using nested structures is not allowed.



    For the input [1, 1, 0, 0, 0, 1, 0, 1, 0, 0], the following formats are allowed:




    • List of bits: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]

    • String: "1100010100"

    • Binary integer: 788 or 0b1100010100

    • Decimal integer: 1100010100

    • Reversed: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1] and reversed in any other formats above


    The following formats are NOT allowed:




    • Arbitrary reordering of bits: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]

    • Nested structures: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]] or [0b110, 0b001, 0b0100]


    Output



    The default output format is a list of 3 decimal digits. Each digit should be represented as 0 to 9, either an integer or a character. As in input, you can choose string or integer representation. If you choose integer representation, leading zeroes can be omitted.



    Scoring & winning criterion



    Standard code-golf rules apply. The shortest program or function in bytes for each language wins.










    share|improve this question


























      up vote
      21
      down vote

      favorite
      2









      up vote
      21
      down vote

      favorite
      2






      2





      Background



      Densely packed decimal (DPD) is a way to efficiently store decimal digits in binary. It stores three decimal digits (000 to 999) in 10 bits, which is much more efficient than naive BCD (which stores one digit in 4 bits).



      Notations




      • The lowercase letters a to i are the bits that are copied to the decimal representation.


      • 0 and 1 are the exact bits in the input or output bit patterns.


      • x bits are ignored in the conversion.


      Conversion table



      The following is the conversion table from 10 bits of DPD to three decimal digits. Each decimal digit is represented as 4-bit binary (BCD). Both sides are written left to right from the most significant digit to the least.



      Bits                 =>  Decimal         (Digit range)
      a b c d e f 0 g h i => 0abc 0def 0ghi (0-7) (0-7) (0-7)
      a b c d e f 1 0 0 i => 0abc 0def 100i (0–7) (0–7) (8–9)
      a b c g h f 1 0 1 i => 0abc 100f 0ghi (0–7) (8–9) (0–7)
      g h c d e f 1 1 0 i => 100c 0def 0ghi (8–9) (0–7) (0–7)
      g h c 0 0 f 1 1 1 i => 100c 100f 0ghi (8–9) (8–9) (0–7)
      d e c 0 1 f 1 1 1 i => 100c 0def 100i (8–9) (0–7) (8–9)
      a b c 1 0 f 1 1 1 i => 0abc 100f 100i (0–7) (8–9) (8–9)
      x x c 1 1 f 1 1 1 i => 100c 100f 100i (8–9) (8–9) (8–9)


      Task



      Convert 10 bits of DPD to 3 digits of decimal.



      Test cases



      DPD           Decimal
      0000000101 005
      0001100011 063
      0001111001 079
      0000011010 090
      0001011110 098
      1010111010 592
      0011001101 941
      1100111111 879
      1110001110 986
      0011111111 999
      1111111111 999 * Output is same regardless of the `x` bits


      Input



      The default input format is a list of 10 bits. The bits should follow the exact order above, or the reverse of it. You may choose to use an equivalent string or integer representation instead. Unlike my other challenges, reordering or using nested structures is not allowed.



      For the input [1, 1, 0, 0, 0, 1, 0, 1, 0, 0], the following formats are allowed:




      • List of bits: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]

      • String: "1100010100"

      • Binary integer: 788 or 0b1100010100

      • Decimal integer: 1100010100

      • Reversed: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1] and reversed in any other formats above


      The following formats are NOT allowed:




      • Arbitrary reordering of bits: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]

      • Nested structures: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]] or [0b110, 0b001, 0b0100]


      Output



      The default output format is a list of 3 decimal digits. Each digit should be represented as 0 to 9, either an integer or a character. As in input, you can choose string or integer representation. If you choose integer representation, leading zeroes can be omitted.



      Scoring & winning criterion



      Standard code-golf rules apply. The shortest program or function in bytes for each language wins.










      share|improve this question















      Background



      Densely packed decimal (DPD) is a way to efficiently store decimal digits in binary. It stores three decimal digits (000 to 999) in 10 bits, which is much more efficient than naive BCD (which stores one digit in 4 bits).



      Notations




      • The lowercase letters a to i are the bits that are copied to the decimal representation.


      • 0 and 1 are the exact bits in the input or output bit patterns.


      • x bits are ignored in the conversion.


      Conversion table



      The following is the conversion table from 10 bits of DPD to three decimal digits. Each decimal digit is represented as 4-bit binary (BCD). Both sides are written left to right from the most significant digit to the least.



      Bits                 =>  Decimal         (Digit range)
      a b c d e f 0 g h i => 0abc 0def 0ghi (0-7) (0-7) (0-7)
      a b c d e f 1 0 0 i => 0abc 0def 100i (0–7) (0–7) (8–9)
      a b c g h f 1 0 1 i => 0abc 100f 0ghi (0–7) (8–9) (0–7)
      g h c d e f 1 1 0 i => 100c 0def 0ghi (8–9) (0–7) (0–7)
      g h c 0 0 f 1 1 1 i => 100c 100f 0ghi (8–9) (8–9) (0–7)
      d e c 0 1 f 1 1 1 i => 100c 0def 100i (8–9) (0–7) (8–9)
      a b c 1 0 f 1 1 1 i => 0abc 100f 100i (0–7) (8–9) (8–9)
      x x c 1 1 f 1 1 1 i => 100c 100f 100i (8–9) (8–9) (8–9)


      Task



      Convert 10 bits of DPD to 3 digits of decimal.



      Test cases



      DPD           Decimal
      0000000101 005
      0001100011 063
      0001111001 079
      0000011010 090
      0001011110 098
      1010111010 592
      0011001101 941
      1100111111 879
      1110001110 986
      0011111111 999
      1111111111 999 * Output is same regardless of the `x` bits


      Input



      The default input format is a list of 10 bits. The bits should follow the exact order above, or the reverse of it. You may choose to use an equivalent string or integer representation instead. Unlike my other challenges, reordering or using nested structures is not allowed.



      For the input [1, 1, 0, 0, 0, 1, 0, 1, 0, 0], the following formats are allowed:




      • List of bits: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]

      • String: "1100010100"

      • Binary integer: 788 or 0b1100010100

      • Decimal integer: 1100010100

      • Reversed: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1] and reversed in any other formats above


      The following formats are NOT allowed:




      • Arbitrary reordering of bits: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]

      • Nested structures: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]] or [0b110, 0b001, 0b0100]


      Output



      The default output format is a list of 3 decimal digits. Each digit should be represented as 0 to 9, either an integer or a character. As in input, you can choose string or integer representation. If you choose integer representation, leading zeroes can be omitted.



      Scoring & winning criterion



      Standard code-golf rules apply. The shortest program or function in bytes for each language wins.







      code-golf binary conversion






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited yesterday









      pizzapants184

      2,564716




      2,564716










      asked Nov 22 at 0:04









      Bubbler

      5,759757




      5,759757






















          8 Answers
          8






          active

          oldest

          votes

















          up vote
          11
          down vote













          JavaScript (ES6), 112 bytes



          All credit for this shorter version goes to @nwellnhof.



          Takes input as an integer. Returns an array of three decimal digits.



          n=>[(x=n>>4,y=x>>3,q=n/2&55,p=q%8)>5&&q-39?8|y&1:y,(p&5^5?x&6:q-23?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p%q<7?y&6:8)|n&1]


          Try it online!





          JavaScript (ES6), 118 117 bytes



          Takes input as an integer. Returns an array of three decimal digits.



          n=>[(x=n>>4&7,y=n>>7,p=n/2&7)>5&&p<7|x/2^2?8|y&1:y,(p<7?p-5?x:8:x/2^1?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p<7|x<2?y&6:8)|n&1]


          Try it online!



          How?



          Instead of trying to apply the 'official' algorithm, this code is based on some kind of reverse-engineering of the patterns that can be found in the expected results.



          Given the input integer $n$, we compute:



          $$begin{align}&x=leftlfloorfrac{n}{16}rightrfloor bmod 8\
          &y=leftlfloorfrac{n}{128}rightrfloor\
          &p=leftlfloorfrac{n}{2}rightrfloor bmod 8end{align}
          $$



          Example: first digit (hundreds)



          x     | 0                | 1                | 2                | 3               
          n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
          p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
          ------+------------------+------------------+------------------+-----------------
          y = 0 | 0000000000008888 | 0000000000008888 | 0000000000008888 | 0000000000008888
          y = 1 | 1111111111119999 | 1111111111119999 | 1111111111119999 | 1111111111119999
          y = 2 | 2222222222228888 | 2222222222228888 | 2222222222228888 | 2222222222228888
          y = 3 | 3333333333339999 | 3333333333339999 | 3333333333339999 | 3333333333339999
          y = 4 | 4444444444448888 | 4444444444448888 | 4444444444448888 | 4444444444448888
          y = 5 | 5555555555559999 | 5555555555559999 | 5555555555559999 | 5555555555559999
          y = 6 | 6666666666668888 | 6666666666668888 | 6666666666668888 | 6666666666668888
          y = 7 | 7777777777779999 | 7777777777779999 | 7777777777779999 | 7777777777779999

          x | 4 | 5 | 6 | 7
          n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
          p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
          ------+------------------+------------------+------------------+-----------------
          y = 0 | 0000000000008800 | 0000000000008800 | 0000000000008888 | 0000000000008888
          y = 1 | 1111111111119911 | 1111111111119911 | 1111111111119999 | 1111111111119999
          y = 2 | 2222222222228822 | 2222222222228822 | 2222222222228888 | 2222222222228888
          y = 3 | 3333333333339933 | 3333333333339933 | 3333333333339999 | 3333333333339999
          y = 4 | 4444444444448844 | 4444444444448844 | 4444444444448888 | 4444444444448888
          y = 5 | 5555555555559955 | 5555555555559955 | 5555555555559999 | 5555555555559999
          y = 6 | 6666666666668866 | 6666666666668866 | 6666666666668888 | 6666666666668888
          y = 7 | 7777777777779977 | 7777777777779977 | 7777777777779999 | 7777777777779999


          Algorithm:




          • If $p<6$, we have $d=y$

          • If $p=6$, we have $d=8+(ybmod2)$

          • If $p=7text{ AND }(x<4text{ OR }x>5)$, we have $d=8+(ybmod2)$

          • If $p=7text{ AND }(x=4text{ OR }x=5)$, we have $d=y$


          As JS code:



          p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y





          share|improve this answer



















          • 1




            Your approach is similar to my C answer which uses another temporary variable. After golfing my initial C solution a bit more, a port to JavaScript results in 112 bytes.
            – nwellnhof
            yesterday


















          up vote
          9
          down vote














          Python 3, 229 ... 102 98 bytes





          lambda a:[[a&6,a>>4&6,a>>7&6,8][b"yWeB7O]s"[a&8and(~a&6or a>>4&6|1)]%x&3]|a>>x%9&1for x in[7,4,9]]


          Try it online!



          -4 bytes by @xnor



          -6 bytes by @nwellnhof



          Formatted:



          h = lambda a:[
          [a&6,a>>4&6,a>>7&6,8][ List to take high bits from
          b"yWeB7O]s"[ 8 char string; where to get high bits for
          each of 8 possible indicator values
          a&8 and (~a&6 or a>>4&6|1)] Compute indicator (by @nwellnhof)
          %x&3] High bits of each digit
          | a >> x%9 & 1 bitwise OR with low bit of each digit
          for x in [7,4,9]]


          Explanation



          Because I originally wanted to implement this in Jelly, I take a different approach from most answers here, which is simple and perhaps suited to a golfing language. Though the golfed function takes an integer, let the input as a bit list be [a0,a1,...,a9]. Then we can derive three values from the input




          • The low bits [a2,a5,a9]: These will always be the low bits of [d0,d1,d2] respectively.

          • The high bits [2*a0a1,2*a3a4,2*a7a8,8]: The high bits of each digit will be one of these.

          • The indicator bits, [a3,a4,a5,a7,a8], determining how to get the high bits of each digit. We compute the indicator (between 0 and 7) as follows:


            • If a5 == 0, the indicator is 0

            • If a3 nand a4, the indicator is 6 - 2*a3a4

            • Otherwise the indicator is 2*a7a8 + 1.




          Then the nth digit can be elegantly computed as high_bits[arr[indicator][n]] | low_bits[n] by the table below, which is compressed into a string.



          arr = [
          [0,1,2],
          [3,1,2],
          [1,3,2],
          [2,1,3],
          [2,3,3],
          [3,2,3],
          [3,3,2],
          [3,3,3]
          ]





          share|improve this answer



















          • 1




            You can used a bytestring b"..." to replace converting with ord.
            – xnor
            2 days ago










          • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
            – lirtosiast
            yesterday










          • b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] saves another four bytes.
            – nwellnhof
            yesterday










          • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
            – lirtosiast
            yesterday




















          up vote
          9
          down vote














          JavaScript (Node.js), 126 119 117 112 111 bytes





          (a,b,c,d,e,f,g,h,i,j)=>[(g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c,(g&i?h+e-3?8:b:e)+f,(g?h<i?e:h>i*e?b:8:h*4+i*2)+j]


          Try it online!



          -5 bytes thanks @tsh (and 2 by myself) So l can make more effort than I expected.



          -2 more bytes using @tsh's technique!



          -5 bytes thanks @Arnauld



          -1 byte thanks @Neil



          Input as a list of 10 bits (as 10 arguments), output as a list of 3 digits.






          share|improve this answer



















          • 1




            (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
            – tsh
            2 days ago






          • 1




            (g?h-i|h&!e?h?b:e:8:h*4+i*2) -> (g?h<i?e:h>i*e?b:8:h*4+i*2) saves another byte. (I checked this time...)
            – Neil
            23 hours ago


















          up vote
          7
          down vote














          C (gcc), 138 129 bytes





          f(w){int t=w/2&55,s=t%8,v=w/16,u=v/8;w=((s<6|t==39?u:8|u%2)*10+v%2+(s&5^5?v&6:t-23?8:u&6))*10+w%2+(s<5?s*2:s<6?v&6:s%t<7?u&6:8);}


          Try it online!



          First extracts some bits into variables s and t, so that the eight rows of the conversion table can be identified by:



          1.  s < 4              u v w¹
          2. s = 4 u v 8¹
          3. s = 5 u 8 v
          4. s = 6 8 v u
          5. s = 7, t = 7 8 8 u
          6. s = 7, t = 23 8 u 8
          7. s = 7, t = 39 u 8 8
          8. s = 7, t = 55 8 8 8

          ¹ Can be computed with s*2


          Then sets up u and v with divisions (right shifts), so that u, v and the input w contain the lower three BCD bits in positions 0-2. The rest is bit shuffling depending on s and t. Two notable tricks are:



          s&5^5  // Rows 1, 2 and 4.
          s%t<7 // Rows 1-5.


          A port of Shieru Asakoto's Javascript solution is only 124 bytes:



          f(a,b,c,d,e,f,g,h,i,j){a=(((g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c)*10+(g&i?h+e-3?8:b:e)+f)*10+(g?h-i|h&!e?h?b:e:8:h*4+i*2)+j;}


          Try it online!






          share|improve this answer























          • I think it can be shortened to: f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
            – MCCCS
            2 days ago










          • @MCCCS Your code seems to be 138 bytes as well.
            – nwellnhof
            2 days ago


















          up vote
          5
          down vote














          Ruby, 153 ... 119 117 bytes





          ->n{n+=n&896;a,b,c=n&1536,n&96,n&14;"%x"%n+=c<9?0:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


          Try it online!



          How it works:



          ->n{n+=n&896;


          This is the starting point: convert to BCD by shifting 3 bits to the left, which works for most of the patterns.



          a,b,c=n&1536,n&96,n&14;


          Get the middle bits of each nibble (and one extra bit of the third nibble, but mask the least significant bit).



          "%x"%n+=c<9?0


          If the third digit is less than 10 (less than 9 because we never cared for the LSB anyway), we're set: this is plain BCD, we can output the hex without changing anything



          :2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


          Otherwise do some black magic by shifting bits around and adding magic numbers until we get the result we want.






          share|improve this answer






























            up vote
            5
            down vote














            Retina 0.8.2, 191 181 bytes



            (...)(...)
            :$1,$2;
            ..(.),11(.);111
            100$1,100$2;100
            (10|(..)(.,)01)(.);111
            100$3$2$4;100
            (..)(.),(00.);111
            100$2,1$3;0$1
            (..)((.{5});110|(.);101)
            100$3$4;$1
            1
            01
            +`10
            011
            .0+(1*)
            $.1


            Try it online! Link includes test cases. Edit: Saved 10 byte by not padding digits to 4 bits except where necessary. Explanation:



            (...)(...)
            :$1,$2;


            Insert separators so that each digit can be converted to decimal separately. This effectively handles the first two cases in the conversion table.



            ..(.),11(.);111
            100$1,100$2;100


            Handle the last (eighth) case in the conversion table.



            (10|(..)(.,)01)(.);111
            100$3$2$4;100


            Handle the sixth and seventh cases in the conversion table.



            (..)(.),(00.);111
            100$2,1$3;0$1


            Handle the fifth case in the conversion table.



            (..)((.{5});110|(.);101)
            100$3$4;$1


            Handle the third and fourth cases in the conversion table.



            1
            01
            +`10
            011
            .0+(1*)
            $.1


            Perform binary to decimal conversion.






            share|improve this answer






























              up vote
              2
              down vote














              Python 2, 157 bytes





              lambda a,b,c,d,e,f,g,h,i,j:[c+[a*4+b*2,8][g*h*~(d*~e*i)],f+[d*4+e*2,8,a*4+b*2][g*i+(d<e)*g*i*h],j+[h*4+i*2,[8,[a*4+b*2,d*4+e*2][h<i]][h^i or(h&i-(d|e))]][g]]


              Try it online!






              share|improve this answer




























                up vote
                2
                down vote














                Clean, 238 ... 189 bytes



                -2 bytes thanks to Neil



                import StdEnv
                $a b c d e f g h i j=100*(c+2*b+4*a)+10*(f+2*e+4*d)+j+2*i+4*h-2*(h*(99*b+198*a-394)+i*(9*e+18*d+h*(e+2*d-4+(b+2*a-4)*(1-10*e-100*d+110*e*d))-35)-4)*g+0^(e+d)*(2*b+4*a-8*i*h*g)


                Try it online!



                Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.






                share|improve this answer























                • In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                  – Neil
                  2 days ago










                • @Neil You're right, it is, thanks.
                  – Οurous
                  yesterday











                Your Answer





                StackExchange.ifUsing("editor", function () {
                return StackExchange.using("mathjaxEditing", function () {
                StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
                StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
                });
                });
                }, "mathjax-editing");

                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "200"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                convertImagesToLinks: false,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: null,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                 

                draft saved


                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f176371%2fdensely-packed-decimal-dpd-to-decimal%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                8 Answers
                8






                active

                oldest

                votes








                8 Answers
                8






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                11
                down vote













                JavaScript (ES6), 112 bytes



                All credit for this shorter version goes to @nwellnhof.



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4,y=x>>3,q=n/2&55,p=q%8)>5&&q-39?8|y&1:y,(p&5^5?x&6:q-23?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p%q<7?y&6:8)|n&1]


                Try it online!





                JavaScript (ES6), 118 117 bytes



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4&7,y=n>>7,p=n/2&7)>5&&p<7|x/2^2?8|y&1:y,(p<7?p-5?x:8:x/2^1?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p<7|x<2?y&6:8)|n&1]


                Try it online!



                How?



                Instead of trying to apply the 'official' algorithm, this code is based on some kind of reverse-engineering of the patterns that can be found in the expected results.



                Given the input integer $n$, we compute:



                $$begin{align}&x=leftlfloorfrac{n}{16}rightrfloor bmod 8\
                &y=leftlfloorfrac{n}{128}rightrfloor\
                &p=leftlfloorfrac{n}{2}rightrfloor bmod 8end{align}
                $$



                Example: first digit (hundreds)



                x     | 0                | 1                | 2                | 3               
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008888 | 0000000000008888 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119999 | 1111111111119999 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228888 | 2222222222228888 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339999 | 3333333333339999 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448888 | 4444444444448888 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559999 | 5555555555559999 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668888 | 6666666666668888 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779999 | 7777777777779999 | 7777777777779999 | 7777777777779999

                x | 4 | 5 | 6 | 7
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008800 | 0000000000008800 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119911 | 1111111111119911 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228822 | 2222222222228822 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339933 | 3333333333339933 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448844 | 4444444444448844 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559955 | 5555555555559955 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668866 | 6666666666668866 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779977 | 7777777777779977 | 7777777777779999 | 7777777777779999


                Algorithm:




                • If $p<6$, we have $d=y$

                • If $p=6$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x<4text{ OR }x>5)$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x=4text{ OR }x=5)$, we have $d=y$


                As JS code:



                p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y





                share|improve this answer



















                • 1




                  Your approach is similar to my C answer which uses another temporary variable. After golfing my initial C solution a bit more, a port to JavaScript results in 112 bytes.
                  – nwellnhof
                  yesterday















                up vote
                11
                down vote













                JavaScript (ES6), 112 bytes



                All credit for this shorter version goes to @nwellnhof.



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4,y=x>>3,q=n/2&55,p=q%8)>5&&q-39?8|y&1:y,(p&5^5?x&6:q-23?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p%q<7?y&6:8)|n&1]


                Try it online!





                JavaScript (ES6), 118 117 bytes



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4&7,y=n>>7,p=n/2&7)>5&&p<7|x/2^2?8|y&1:y,(p<7?p-5?x:8:x/2^1?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p<7|x<2?y&6:8)|n&1]


                Try it online!



                How?



                Instead of trying to apply the 'official' algorithm, this code is based on some kind of reverse-engineering of the patterns that can be found in the expected results.



                Given the input integer $n$, we compute:



                $$begin{align}&x=leftlfloorfrac{n}{16}rightrfloor bmod 8\
                &y=leftlfloorfrac{n}{128}rightrfloor\
                &p=leftlfloorfrac{n}{2}rightrfloor bmod 8end{align}
                $$



                Example: first digit (hundreds)



                x     | 0                | 1                | 2                | 3               
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008888 | 0000000000008888 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119999 | 1111111111119999 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228888 | 2222222222228888 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339999 | 3333333333339999 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448888 | 4444444444448888 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559999 | 5555555555559999 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668888 | 6666666666668888 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779999 | 7777777777779999 | 7777777777779999 | 7777777777779999

                x | 4 | 5 | 6 | 7
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008800 | 0000000000008800 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119911 | 1111111111119911 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228822 | 2222222222228822 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339933 | 3333333333339933 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448844 | 4444444444448844 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559955 | 5555555555559955 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668866 | 6666666666668866 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779977 | 7777777777779977 | 7777777777779999 | 7777777777779999


                Algorithm:




                • If $p<6$, we have $d=y$

                • If $p=6$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x<4text{ OR }x>5)$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x=4text{ OR }x=5)$, we have $d=y$


                As JS code:



                p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y





                share|improve this answer



















                • 1




                  Your approach is similar to my C answer which uses another temporary variable. After golfing my initial C solution a bit more, a port to JavaScript results in 112 bytes.
                  – nwellnhof
                  yesterday













                up vote
                11
                down vote










                up vote
                11
                down vote









                JavaScript (ES6), 112 bytes



                All credit for this shorter version goes to @nwellnhof.



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4,y=x>>3,q=n/2&55,p=q%8)>5&&q-39?8|y&1:y,(p&5^5?x&6:q-23?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p%q<7?y&6:8)|n&1]


                Try it online!





                JavaScript (ES6), 118 117 bytes



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4&7,y=n>>7,p=n/2&7)>5&&p<7|x/2^2?8|y&1:y,(p<7?p-5?x:8:x/2^1?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p<7|x<2?y&6:8)|n&1]


                Try it online!



                How?



                Instead of trying to apply the 'official' algorithm, this code is based on some kind of reverse-engineering of the patterns that can be found in the expected results.



                Given the input integer $n$, we compute:



                $$begin{align}&x=leftlfloorfrac{n}{16}rightrfloor bmod 8\
                &y=leftlfloorfrac{n}{128}rightrfloor\
                &p=leftlfloorfrac{n}{2}rightrfloor bmod 8end{align}
                $$



                Example: first digit (hundreds)



                x     | 0                | 1                | 2                | 3               
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008888 | 0000000000008888 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119999 | 1111111111119999 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228888 | 2222222222228888 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339999 | 3333333333339999 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448888 | 4444444444448888 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559999 | 5555555555559999 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668888 | 6666666666668888 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779999 | 7777777777779999 | 7777777777779999 | 7777777777779999

                x | 4 | 5 | 6 | 7
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008800 | 0000000000008800 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119911 | 1111111111119911 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228822 | 2222222222228822 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339933 | 3333333333339933 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448844 | 4444444444448844 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559955 | 5555555555559955 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668866 | 6666666666668866 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779977 | 7777777777779977 | 7777777777779999 | 7777777777779999


                Algorithm:




                • If $p<6$, we have $d=y$

                • If $p=6$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x<4text{ OR }x>5)$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x=4text{ OR }x=5)$, we have $d=y$


                As JS code:



                p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y





                share|improve this answer














                JavaScript (ES6), 112 bytes



                All credit for this shorter version goes to @nwellnhof.



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4,y=x>>3,q=n/2&55,p=q%8)>5&&q-39?8|y&1:y,(p&5^5?x&6:q-23?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p%q<7?y&6:8)|n&1]


                Try it online!





                JavaScript (ES6), 118 117 bytes



                Takes input as an integer. Returns an array of three decimal digits.



                n=>[(x=n>>4&7,y=n>>7,p=n/2&7)>5&&p<7|x/2^2?8|y&1:y,(p<7?p-5?x:8:x/2^1?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p<7|x<2?y&6:8)|n&1]


                Try it online!



                How?



                Instead of trying to apply the 'official' algorithm, this code is based on some kind of reverse-engineering of the patterns that can be found in the expected results.



                Given the input integer $n$, we compute:



                $$begin{align}&x=leftlfloorfrac{n}{16}rightrfloor bmod 8\
                &y=leftlfloorfrac{n}{128}rightrfloor\
                &p=leftlfloorfrac{n}{2}rightrfloor bmod 8end{align}
                $$



                Example: first digit (hundreds)



                x     | 0                | 1                | 2                | 3               
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008888 | 0000000000008888 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119999 | 1111111111119999 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228888 | 2222222222228888 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339999 | 3333333333339999 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448888 | 4444444444448888 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559999 | 5555555555559999 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668888 | 6666666666668888 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779999 | 7777777777779999 | 7777777777779999 | 7777777777779999

                x | 4 | 5 | 6 | 7
                n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
                p | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
                ------+------------------+------------------+------------------+-----------------
                y = 0 | 0000000000008800 | 0000000000008800 | 0000000000008888 | 0000000000008888
                y = 1 | 1111111111119911 | 1111111111119911 | 1111111111119999 | 1111111111119999
                y = 2 | 2222222222228822 | 2222222222228822 | 2222222222228888 | 2222222222228888
                y = 3 | 3333333333339933 | 3333333333339933 | 3333333333339999 | 3333333333339999
                y = 4 | 4444444444448844 | 4444444444448844 | 4444444444448888 | 4444444444448888
                y = 5 | 5555555555559955 | 5555555555559955 | 5555555555559999 | 5555555555559999
                y = 6 | 6666666666668866 | 6666666666668866 | 6666666666668888 | 6666666666668888
                y = 7 | 7777777777779977 | 7777777777779977 | 7777777777779999 | 7777777777779999


                Algorithm:




                • If $p<6$, we have $d=y$

                • If $p=6$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x<4text{ OR }x>5)$, we have $d=8+(ybmod2)$

                • If $p=7text{ AND }(x=4text{ OR }x=5)$, we have $d=y$


                As JS code:



                p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited yesterday

























                answered 2 days ago









                Arnauld

                69.6k586294




                69.6k586294








                • 1




                  Your approach is similar to my C answer which uses another temporary variable. After golfing my initial C solution a bit more, a port to JavaScript results in 112 bytes.
                  – nwellnhof
                  yesterday














                • 1




                  Your approach is similar to my C answer which uses another temporary variable. After golfing my initial C solution a bit more, a port to JavaScript results in 112 bytes.
                  – nwellnhof
                  yesterday








                1




                1




                Your approach is similar to my C answer which uses another temporary variable. After golfing my initial C solution a bit more, a port to JavaScript results in 112 bytes.
                – nwellnhof
                yesterday




                Your approach is similar to my C answer which uses another temporary variable. After golfing my initial C solution a bit more, a port to JavaScript results in 112 bytes.
                – nwellnhof
                yesterday










                up vote
                9
                down vote














                Python 3, 229 ... 102 98 bytes





                lambda a:[[a&6,a>>4&6,a>>7&6,8][b"yWeB7O]s"[a&8and(~a&6or a>>4&6|1)]%x&3]|a>>x%9&1for x in[7,4,9]]


                Try it online!



                -4 bytes by @xnor



                -6 bytes by @nwellnhof



                Formatted:



                h = lambda a:[
                [a&6,a>>4&6,a>>7&6,8][ List to take high bits from
                b"yWeB7O]s"[ 8 char string; where to get high bits for
                each of 8 possible indicator values
                a&8 and (~a&6 or a>>4&6|1)] Compute indicator (by @nwellnhof)
                %x&3] High bits of each digit
                | a >> x%9 & 1 bitwise OR with low bit of each digit
                for x in [7,4,9]]


                Explanation



                Because I originally wanted to implement this in Jelly, I take a different approach from most answers here, which is simple and perhaps suited to a golfing language. Though the golfed function takes an integer, let the input as a bit list be [a0,a1,...,a9]. Then we can derive three values from the input




                • The low bits [a2,a5,a9]: These will always be the low bits of [d0,d1,d2] respectively.

                • The high bits [2*a0a1,2*a3a4,2*a7a8,8]: The high bits of each digit will be one of these.

                • The indicator bits, [a3,a4,a5,a7,a8], determining how to get the high bits of each digit. We compute the indicator (between 0 and 7) as follows:


                  • If a5 == 0, the indicator is 0

                  • If a3 nand a4, the indicator is 6 - 2*a3a4

                  • Otherwise the indicator is 2*a7a8 + 1.




                Then the nth digit can be elegantly computed as high_bits[arr[indicator][n]] | low_bits[n] by the table below, which is compressed into a string.



                arr = [
                [0,1,2],
                [3,1,2],
                [1,3,2],
                [2,1,3],
                [2,3,3],
                [3,2,3],
                [3,3,2],
                [3,3,3]
                ]





                share|improve this answer



















                • 1




                  You can used a bytestring b"..." to replace converting with ord.
                  – xnor
                  2 days ago










                • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                  – lirtosiast
                  yesterday










                • b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] saves another four bytes.
                  – nwellnhof
                  yesterday










                • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                  – lirtosiast
                  yesterday

















                up vote
                9
                down vote














                Python 3, 229 ... 102 98 bytes





                lambda a:[[a&6,a>>4&6,a>>7&6,8][b"yWeB7O]s"[a&8and(~a&6or a>>4&6|1)]%x&3]|a>>x%9&1for x in[7,4,9]]


                Try it online!



                -4 bytes by @xnor



                -6 bytes by @nwellnhof



                Formatted:



                h = lambda a:[
                [a&6,a>>4&6,a>>7&6,8][ List to take high bits from
                b"yWeB7O]s"[ 8 char string; where to get high bits for
                each of 8 possible indicator values
                a&8 and (~a&6 or a>>4&6|1)] Compute indicator (by @nwellnhof)
                %x&3] High bits of each digit
                | a >> x%9 & 1 bitwise OR with low bit of each digit
                for x in [7,4,9]]


                Explanation



                Because I originally wanted to implement this in Jelly, I take a different approach from most answers here, which is simple and perhaps suited to a golfing language. Though the golfed function takes an integer, let the input as a bit list be [a0,a1,...,a9]. Then we can derive three values from the input




                • The low bits [a2,a5,a9]: These will always be the low bits of [d0,d1,d2] respectively.

                • The high bits [2*a0a1,2*a3a4,2*a7a8,8]: The high bits of each digit will be one of these.

                • The indicator bits, [a3,a4,a5,a7,a8], determining how to get the high bits of each digit. We compute the indicator (between 0 and 7) as follows:


                  • If a5 == 0, the indicator is 0

                  • If a3 nand a4, the indicator is 6 - 2*a3a4

                  • Otherwise the indicator is 2*a7a8 + 1.




                Then the nth digit can be elegantly computed as high_bits[arr[indicator][n]] | low_bits[n] by the table below, which is compressed into a string.



                arr = [
                [0,1,2],
                [3,1,2],
                [1,3,2],
                [2,1,3],
                [2,3,3],
                [3,2,3],
                [3,3,2],
                [3,3,3]
                ]





                share|improve this answer



















                • 1




                  You can used a bytestring b"..." to replace converting with ord.
                  – xnor
                  2 days ago










                • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                  – lirtosiast
                  yesterday










                • b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] saves another four bytes.
                  – nwellnhof
                  yesterday










                • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                  – lirtosiast
                  yesterday















                up vote
                9
                down vote










                up vote
                9
                down vote










                Python 3, 229 ... 102 98 bytes





                lambda a:[[a&6,a>>4&6,a>>7&6,8][b"yWeB7O]s"[a&8and(~a&6or a>>4&6|1)]%x&3]|a>>x%9&1for x in[7,4,9]]


                Try it online!



                -4 bytes by @xnor



                -6 bytes by @nwellnhof



                Formatted:



                h = lambda a:[
                [a&6,a>>4&6,a>>7&6,8][ List to take high bits from
                b"yWeB7O]s"[ 8 char string; where to get high bits for
                each of 8 possible indicator values
                a&8 and (~a&6 or a>>4&6|1)] Compute indicator (by @nwellnhof)
                %x&3] High bits of each digit
                | a >> x%9 & 1 bitwise OR with low bit of each digit
                for x in [7,4,9]]


                Explanation



                Because I originally wanted to implement this in Jelly, I take a different approach from most answers here, which is simple and perhaps suited to a golfing language. Though the golfed function takes an integer, let the input as a bit list be [a0,a1,...,a9]. Then we can derive three values from the input




                • The low bits [a2,a5,a9]: These will always be the low bits of [d0,d1,d2] respectively.

                • The high bits [2*a0a1,2*a3a4,2*a7a8,8]: The high bits of each digit will be one of these.

                • The indicator bits, [a3,a4,a5,a7,a8], determining how to get the high bits of each digit. We compute the indicator (between 0 and 7) as follows:


                  • If a5 == 0, the indicator is 0

                  • If a3 nand a4, the indicator is 6 - 2*a3a4

                  • Otherwise the indicator is 2*a7a8 + 1.




                Then the nth digit can be elegantly computed as high_bits[arr[indicator][n]] | low_bits[n] by the table below, which is compressed into a string.



                arr = [
                [0,1,2],
                [3,1,2],
                [1,3,2],
                [2,1,3],
                [2,3,3],
                [3,2,3],
                [3,3,2],
                [3,3,3]
                ]





                share|improve this answer















                Python 3, 229 ... 102 98 bytes





                lambda a:[[a&6,a>>4&6,a>>7&6,8][b"yWeB7O]s"[a&8and(~a&6or a>>4&6|1)]%x&3]|a>>x%9&1for x in[7,4,9]]


                Try it online!



                -4 bytes by @xnor



                -6 bytes by @nwellnhof



                Formatted:



                h = lambda a:[
                [a&6,a>>4&6,a>>7&6,8][ List to take high bits from
                b"yWeB7O]s"[ 8 char string; where to get high bits for
                each of 8 possible indicator values
                a&8 and (~a&6 or a>>4&6|1)] Compute indicator (by @nwellnhof)
                %x&3] High bits of each digit
                | a >> x%9 & 1 bitwise OR with low bit of each digit
                for x in [7,4,9]]


                Explanation



                Because I originally wanted to implement this in Jelly, I take a different approach from most answers here, which is simple and perhaps suited to a golfing language. Though the golfed function takes an integer, let the input as a bit list be [a0,a1,...,a9]. Then we can derive three values from the input




                • The low bits [a2,a5,a9]: These will always be the low bits of [d0,d1,d2] respectively.

                • The high bits [2*a0a1,2*a3a4,2*a7a8,8]: The high bits of each digit will be one of these.

                • The indicator bits, [a3,a4,a5,a7,a8], determining how to get the high bits of each digit. We compute the indicator (between 0 and 7) as follows:


                  • If a5 == 0, the indicator is 0

                  • If a3 nand a4, the indicator is 6 - 2*a3a4

                  • Otherwise the indicator is 2*a7a8 + 1.




                Then the nth digit can be elegantly computed as high_bits[arr[indicator][n]] | low_bits[n] by the table below, which is compressed into a string.



                arr = [
                [0,1,2],
                [3,1,2],
                [1,3,2],
                [2,1,3],
                [2,3,3],
                [3,2,3],
                [3,3,2],
                [3,3,3]
                ]






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited yesterday

























                answered 2 days ago









                lirtosiast

                15.6k436105




                15.6k436105








                • 1




                  You can used a bytestring b"..." to replace converting with ord.
                  – xnor
                  2 days ago










                • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                  – lirtosiast
                  yesterday










                • b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] saves another four bytes.
                  – nwellnhof
                  yesterday










                • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                  – lirtosiast
                  yesterday
















                • 1




                  You can used a bytestring b"..." to replace converting with ord.
                  – xnor
                  2 days ago










                • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                  – lirtosiast
                  yesterday










                • b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] saves another four bytes.
                  – nwellnhof
                  yesterday










                • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                  – lirtosiast
                  yesterday










                1




                1




                You can used a bytestring b"..." to replace converting with ord.
                – xnor
                2 days ago




                You can used a bytestring b"..." to replace converting with ord.
                – xnor
                2 days ago












                @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                – lirtosiast
                yesterday




                @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                – lirtosiast
                yesterday












                b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] saves another four bytes.
                – nwellnhof
                yesterday




                b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] saves another four bytes.
                – nwellnhof
                yesterday












                @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                – lirtosiast
                yesterday






                @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                – lirtosiast
                yesterday












                up vote
                9
                down vote














                JavaScript (Node.js), 126 119 117 112 111 bytes





                (a,b,c,d,e,f,g,h,i,j)=>[(g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c,(g&i?h+e-3?8:b:e)+f,(g?h<i?e:h>i*e?b:8:h*4+i*2)+j]


                Try it online!



                -5 bytes thanks @tsh (and 2 by myself) So l can make more effort than I expected.



                -2 more bytes using @tsh's technique!



                -5 bytes thanks @Arnauld



                -1 byte thanks @Neil



                Input as a list of 10 bits (as 10 arguments), output as a list of 3 digits.






                share|improve this answer



















                • 1




                  (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                  – tsh
                  2 days ago






                • 1




                  (g?h-i|h&!e?h?b:e:8:h*4+i*2) -> (g?h<i?e:h>i*e?b:8:h*4+i*2) saves another byte. (I checked this time...)
                  – Neil
                  23 hours ago















                up vote
                9
                down vote














                JavaScript (Node.js), 126 119 117 112 111 bytes





                (a,b,c,d,e,f,g,h,i,j)=>[(g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c,(g&i?h+e-3?8:b:e)+f,(g?h<i?e:h>i*e?b:8:h*4+i*2)+j]


                Try it online!



                -5 bytes thanks @tsh (and 2 by myself) So l can make more effort than I expected.



                -2 more bytes using @tsh's technique!



                -5 bytes thanks @Arnauld



                -1 byte thanks @Neil



                Input as a list of 10 bits (as 10 arguments), output as a list of 3 digits.






                share|improve this answer



















                • 1




                  (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                  – tsh
                  2 days ago






                • 1




                  (g?h-i|h&!e?h?b:e:8:h*4+i*2) -> (g?h<i?e:h>i*e?b:8:h*4+i*2) saves another byte. (I checked this time...)
                  – Neil
                  23 hours ago













                up vote
                9
                down vote










                up vote
                9
                down vote










                JavaScript (Node.js), 126 119 117 112 111 bytes





                (a,b,c,d,e,f,g,h,i,j)=>[(g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c,(g&i?h+e-3?8:b:e)+f,(g?h<i?e:h>i*e?b:8:h*4+i*2)+j]


                Try it online!



                -5 bytes thanks @tsh (and 2 by myself) So l can make more effort than I expected.



                -2 more bytes using @tsh's technique!



                -5 bytes thanks @Arnauld



                -1 byte thanks @Neil



                Input as a list of 10 bits (as 10 arguments), output as a list of 3 digits.






                share|improve this answer















                JavaScript (Node.js), 126 119 117 112 111 bytes





                (a,b,c,d,e,f,g,h,i,j)=>[(g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c,(g&i?h+e-3?8:b:e)+f,(g?h<i?e:h>i*e?b:8:h*4+i*2)+j]


                Try it online!



                -5 bytes thanks @tsh (and 2 by myself) So l can make more effort than I expected.



                -2 more bytes using @tsh's technique!



                -5 bytes thanks @Arnauld



                -1 byte thanks @Neil



                Input as a list of 10 bits (as 10 arguments), output as a list of 3 digits.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 16 hours ago

























                answered 2 days ago









                Shieru Asakoto

                2,330314




                2,330314








                • 1




                  (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                  – tsh
                  2 days ago






                • 1




                  (g?h-i|h&!e?h?b:e:8:h*4+i*2) -> (g?h<i?e:h>i*e?b:8:h*4+i*2) saves another byte. (I checked this time...)
                  – Neil
                  23 hours ago














                • 1




                  (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                  – tsh
                  2 days ago






                • 1




                  (g?h-i|h&!e?h?b:e:8:h*4+i*2) -> (g?h<i?e:h>i*e?b:8:h*4+i*2) saves another byte. (I checked this time...)
                  – Neil
                  23 hours ago








                1




                1




                (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                – tsh
                2 days ago




                (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                – tsh
                2 days ago




                1




                1




                (g?h-i|h&!e?h?b:e:8:h*4+i*2) -> (g?h<i?e:h>i*e?b:8:h*4+i*2) saves another byte. (I checked this time...)
                – Neil
                23 hours ago




                (g?h-i|h&!e?h?b:e:8:h*4+i*2) -> (g?h<i?e:h>i*e?b:8:h*4+i*2) saves another byte. (I checked this time...)
                – Neil
                23 hours ago










                up vote
                7
                down vote














                C (gcc), 138 129 bytes





                f(w){int t=w/2&55,s=t%8,v=w/16,u=v/8;w=((s<6|t==39?u:8|u%2)*10+v%2+(s&5^5?v&6:t-23?8:u&6))*10+w%2+(s<5?s*2:s<6?v&6:s%t<7?u&6:8);}


                Try it online!



                First extracts some bits into variables s and t, so that the eight rows of the conversion table can be identified by:



                1.  s < 4              u v w¹
                2. s = 4 u v 8¹
                3. s = 5 u 8 v
                4. s = 6 8 v u
                5. s = 7, t = 7 8 8 u
                6. s = 7, t = 23 8 u 8
                7. s = 7, t = 39 u 8 8
                8. s = 7, t = 55 8 8 8

                ¹ Can be computed with s*2


                Then sets up u and v with divisions (right shifts), so that u, v and the input w contain the lower three BCD bits in positions 0-2. The rest is bit shuffling depending on s and t. Two notable tricks are:



                s&5^5  // Rows 1, 2 and 4.
                s%t<7 // Rows 1-5.


                A port of Shieru Asakoto's Javascript solution is only 124 bytes:



                f(a,b,c,d,e,f,g,h,i,j){a=(((g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c)*10+(g&i?h+e-3?8:b:e)+f)*10+(g?h-i|h&!e?h?b:e:8:h*4+i*2)+j;}


                Try it online!






                share|improve this answer























                • I think it can be shortened to: f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
                  – MCCCS
                  2 days ago










                • @MCCCS Your code seems to be 138 bytes as well.
                  – nwellnhof
                  2 days ago















                up vote
                7
                down vote














                C (gcc), 138 129 bytes





                f(w){int t=w/2&55,s=t%8,v=w/16,u=v/8;w=((s<6|t==39?u:8|u%2)*10+v%2+(s&5^5?v&6:t-23?8:u&6))*10+w%2+(s<5?s*2:s<6?v&6:s%t<7?u&6:8);}


                Try it online!



                First extracts some bits into variables s and t, so that the eight rows of the conversion table can be identified by:



                1.  s < 4              u v w¹
                2. s = 4 u v 8¹
                3. s = 5 u 8 v
                4. s = 6 8 v u
                5. s = 7, t = 7 8 8 u
                6. s = 7, t = 23 8 u 8
                7. s = 7, t = 39 u 8 8
                8. s = 7, t = 55 8 8 8

                ¹ Can be computed with s*2


                Then sets up u and v with divisions (right shifts), so that u, v and the input w contain the lower three BCD bits in positions 0-2. The rest is bit shuffling depending on s and t. Two notable tricks are:



                s&5^5  // Rows 1, 2 and 4.
                s%t<7 // Rows 1-5.


                A port of Shieru Asakoto's Javascript solution is only 124 bytes:



                f(a,b,c,d,e,f,g,h,i,j){a=(((g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c)*10+(g&i?h+e-3?8:b:e)+f)*10+(g?h-i|h&!e?h?b:e:8:h*4+i*2)+j;}


                Try it online!






                share|improve this answer























                • I think it can be shortened to: f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
                  – MCCCS
                  2 days ago










                • @MCCCS Your code seems to be 138 bytes as well.
                  – nwellnhof
                  2 days ago













                up vote
                7
                down vote










                up vote
                7
                down vote










                C (gcc), 138 129 bytes





                f(w){int t=w/2&55,s=t%8,v=w/16,u=v/8;w=((s<6|t==39?u:8|u%2)*10+v%2+(s&5^5?v&6:t-23?8:u&6))*10+w%2+(s<5?s*2:s<6?v&6:s%t<7?u&6:8);}


                Try it online!



                First extracts some bits into variables s and t, so that the eight rows of the conversion table can be identified by:



                1.  s < 4              u v w¹
                2. s = 4 u v 8¹
                3. s = 5 u 8 v
                4. s = 6 8 v u
                5. s = 7, t = 7 8 8 u
                6. s = 7, t = 23 8 u 8
                7. s = 7, t = 39 u 8 8
                8. s = 7, t = 55 8 8 8

                ¹ Can be computed with s*2


                Then sets up u and v with divisions (right shifts), so that u, v and the input w contain the lower three BCD bits in positions 0-2. The rest is bit shuffling depending on s and t. Two notable tricks are:



                s&5^5  // Rows 1, 2 and 4.
                s%t<7 // Rows 1-5.


                A port of Shieru Asakoto's Javascript solution is only 124 bytes:



                f(a,b,c,d,e,f,g,h,i,j){a=(((g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c)*10+(g&i?h+e-3?8:b:e)+f)*10+(g?h-i|h&!e?h?b:e:8:h*4+i*2)+j;}


                Try it online!






                share|improve this answer















                C (gcc), 138 129 bytes





                f(w){int t=w/2&55,s=t%8,v=w/16,u=v/8;w=((s<6|t==39?u:8|u%2)*10+v%2+(s&5^5?v&6:t-23?8:u&6))*10+w%2+(s<5?s*2:s<6?v&6:s%t<7?u&6:8);}


                Try it online!



                First extracts some bits into variables s and t, so that the eight rows of the conversion table can be identified by:



                1.  s < 4              u v w¹
                2. s = 4 u v 8¹
                3. s = 5 u 8 v
                4. s = 6 8 v u
                5. s = 7, t = 7 8 8 u
                6. s = 7, t = 23 8 u 8
                7. s = 7, t = 39 u 8 8
                8. s = 7, t = 55 8 8 8

                ¹ Can be computed with s*2


                Then sets up u and v with divisions (right shifts), so that u, v and the input w contain the lower three BCD bits in positions 0-2. The rest is bit shuffling depending on s and t. Two notable tricks are:



                s&5^5  // Rows 1, 2 and 4.
                s%t<7 // Rows 1-5.


                A port of Shieru Asakoto's Javascript solution is only 124 bytes:



                f(a,b,c,d,e,f,g,h,i,j){a=(((g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c)*10+(g&i?h+e-3?8:b:e)+f)*10+(g?h-i|h&!e?h?b:e:8:h*4+i*2)+j;}


                Try it online!







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited yesterday

























                answered Nov 22 at 0:30









                nwellnhof

                6,2281125




                6,2281125












                • I think it can be shortened to: f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
                  – MCCCS
                  2 days ago










                • @MCCCS Your code seems to be 138 bytes as well.
                  – nwellnhof
                  2 days ago


















                • I think it can be shortened to: f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
                  – MCCCS
                  2 days ago










                • @MCCCS Your code seems to be 138 bytes as well.
                  – nwellnhof
                  2 days ago
















                I think it can be shortened to: f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
                – MCCCS
                2 days ago




                I think it can be shortened to: f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
                – MCCCS
                2 days ago












                @MCCCS Your code seems to be 138 bytes as well.
                – nwellnhof
                2 days ago




                @MCCCS Your code seems to be 138 bytes as well.
                – nwellnhof
                2 days ago










                up vote
                5
                down vote














                Ruby, 153 ... 119 117 bytes





                ->n{n+=n&896;a,b,c=n&1536,n&96,n&14;"%x"%n+=c<9?0:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                Try it online!



                How it works:



                ->n{n+=n&896;


                This is the starting point: convert to BCD by shifting 3 bits to the left, which works for most of the patterns.



                a,b,c=n&1536,n&96,n&14;


                Get the middle bits of each nibble (and one extra bit of the third nibble, but mask the least significant bit).



                "%x"%n+=c<9?0


                If the third digit is less than 10 (less than 9 because we never cared for the LSB anyway), we're set: this is plain BCD, we can output the hex without changing anything



                :2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                Otherwise do some black magic by shifting bits around and adding magic numbers until we get the result we want.






                share|improve this answer



























                  up vote
                  5
                  down vote














                  Ruby, 153 ... 119 117 bytes





                  ->n{n+=n&896;a,b,c=n&1536,n&96,n&14;"%x"%n+=c<9?0:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                  Try it online!



                  How it works:



                  ->n{n+=n&896;


                  This is the starting point: convert to BCD by shifting 3 bits to the left, which works for most of the patterns.



                  a,b,c=n&1536,n&96,n&14;


                  Get the middle bits of each nibble (and one extra bit of the third nibble, but mask the least significant bit).



                  "%x"%n+=c<9?0


                  If the third digit is less than 10 (less than 9 because we never cared for the LSB anyway), we're set: this is plain BCD, we can output the hex without changing anything



                  :2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                  Otherwise do some black magic by shifting bits around and adding magic numbers until we get the result we want.






                  share|improve this answer

























                    up vote
                    5
                    down vote










                    up vote
                    5
                    down vote










                    Ruby, 153 ... 119 117 bytes





                    ->n{n+=n&896;a,b,c=n&1536,n&96,n&14;"%x"%n+=c<9?0:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                    Try it online!



                    How it works:



                    ->n{n+=n&896;


                    This is the starting point: convert to BCD by shifting 3 bits to the left, which works for most of the patterns.



                    a,b,c=n&1536,n&96,n&14;


                    Get the middle bits of each nibble (and one extra bit of the third nibble, but mask the least significant bit).



                    "%x"%n+=c<9?0


                    If the third digit is less than 10 (less than 9 because we never cared for the LSB anyway), we're set: this is plain BCD, we can output the hex without changing anything



                    :2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                    Otherwise do some black magic by shifting bits around and adding magic numbers until we get the result we want.






                    share|improve this answer















                    Ruby, 153 ... 119 117 bytes





                    ->n{n+=n&896;a,b,c=n&1536,n&96,n&14;"%x"%n+=c<9?0:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                    Try it online!



                    How it works:



                    ->n{n+=n&896;


                    This is the starting point: convert to BCD by shifting 3 bits to the left, which works for most of the patterns.



                    a,b,c=n&1536,n&96,n&14;


                    Get the middle bits of each nibble (and one extra bit of the third nibble, but mask the least significant bit).



                    "%x"%n+=c<9?0


                    If the third digit is less than 10 (less than 9 because we never cared for the LSB anyway), we're set: this is plain BCD, we can output the hex without changing anything



                    :2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}


                    Otherwise do some black magic by shifting bits around and adding magic numbers until we get the result we want.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 2 days ago

























                    answered 2 days ago









                    G B

                    7,5561328




                    7,5561328






















                        up vote
                        5
                        down vote














                        Retina 0.8.2, 191 181 bytes



                        (...)(...)
                        :$1,$2;
                        ..(.),11(.);111
                        100$1,100$2;100
                        (10|(..)(.,)01)(.);111
                        100$3$2$4;100
                        (..)(.),(00.);111
                        100$2,1$3;0$1
                        (..)((.{5});110|(.);101)
                        100$3$4;$1
                        1
                        01
                        +`10
                        011
                        .0+(1*)
                        $.1


                        Try it online! Link includes test cases. Edit: Saved 10 byte by not padding digits to 4 bits except where necessary. Explanation:



                        (...)(...)
                        :$1,$2;


                        Insert separators so that each digit can be converted to decimal separately. This effectively handles the first two cases in the conversion table.



                        ..(.),11(.);111
                        100$1,100$2;100


                        Handle the last (eighth) case in the conversion table.



                        (10|(..)(.,)01)(.);111
                        100$3$2$4;100


                        Handle the sixth and seventh cases in the conversion table.



                        (..)(.),(00.);111
                        100$2,1$3;0$1


                        Handle the fifth case in the conversion table.



                        (..)((.{5});110|(.);101)
                        100$3$4;$1


                        Handle the third and fourth cases in the conversion table.



                        1
                        01
                        +`10
                        011
                        .0+(1*)
                        $.1


                        Perform binary to decimal conversion.






                        share|improve this answer



























                          up vote
                          5
                          down vote














                          Retina 0.8.2, 191 181 bytes



                          (...)(...)
                          :$1,$2;
                          ..(.),11(.);111
                          100$1,100$2;100
                          (10|(..)(.,)01)(.);111
                          100$3$2$4;100
                          (..)(.),(00.);111
                          100$2,1$3;0$1
                          (..)((.{5});110|(.);101)
                          100$3$4;$1
                          1
                          01
                          +`10
                          011
                          .0+(1*)
                          $.1


                          Try it online! Link includes test cases. Edit: Saved 10 byte by not padding digits to 4 bits except where necessary. Explanation:



                          (...)(...)
                          :$1,$2;


                          Insert separators so that each digit can be converted to decimal separately. This effectively handles the first two cases in the conversion table.



                          ..(.),11(.);111
                          100$1,100$2;100


                          Handle the last (eighth) case in the conversion table.



                          (10|(..)(.,)01)(.);111
                          100$3$2$4;100


                          Handle the sixth and seventh cases in the conversion table.



                          (..)(.),(00.);111
                          100$2,1$3;0$1


                          Handle the fifth case in the conversion table.



                          (..)((.{5});110|(.);101)
                          100$3$4;$1


                          Handle the third and fourth cases in the conversion table.



                          1
                          01
                          +`10
                          011
                          .0+(1*)
                          $.1


                          Perform binary to decimal conversion.






                          share|improve this answer

























                            up vote
                            5
                            down vote










                            up vote
                            5
                            down vote










                            Retina 0.8.2, 191 181 bytes



                            (...)(...)
                            :$1,$2;
                            ..(.),11(.);111
                            100$1,100$2;100
                            (10|(..)(.,)01)(.);111
                            100$3$2$4;100
                            (..)(.),(00.);111
                            100$2,1$3;0$1
                            (..)((.{5});110|(.);101)
                            100$3$4;$1
                            1
                            01
                            +`10
                            011
                            .0+(1*)
                            $.1


                            Try it online! Link includes test cases. Edit: Saved 10 byte by not padding digits to 4 bits except where necessary. Explanation:



                            (...)(...)
                            :$1,$2;


                            Insert separators so that each digit can be converted to decimal separately. This effectively handles the first two cases in the conversion table.



                            ..(.),11(.);111
                            100$1,100$2;100


                            Handle the last (eighth) case in the conversion table.



                            (10|(..)(.,)01)(.);111
                            100$3$2$4;100


                            Handle the sixth and seventh cases in the conversion table.



                            (..)(.),(00.);111
                            100$2,1$3;0$1


                            Handle the fifth case in the conversion table.



                            (..)((.{5});110|(.);101)
                            100$3$4;$1


                            Handle the third and fourth cases in the conversion table.



                            1
                            01
                            +`10
                            011
                            .0+(1*)
                            $.1


                            Perform binary to decimal conversion.






                            share|improve this answer















                            Retina 0.8.2, 191 181 bytes



                            (...)(...)
                            :$1,$2;
                            ..(.),11(.);111
                            100$1,100$2;100
                            (10|(..)(.,)01)(.);111
                            100$3$2$4;100
                            (..)(.),(00.);111
                            100$2,1$3;0$1
                            (..)((.{5});110|(.);101)
                            100$3$4;$1
                            1
                            01
                            +`10
                            011
                            .0+(1*)
                            $.1


                            Try it online! Link includes test cases. Edit: Saved 10 byte by not padding digits to 4 bits except where necessary. Explanation:



                            (...)(...)
                            :$1,$2;


                            Insert separators so that each digit can be converted to decimal separately. This effectively handles the first two cases in the conversion table.



                            ..(.),11(.);111
                            100$1,100$2;100


                            Handle the last (eighth) case in the conversion table.



                            (10|(..)(.,)01)(.);111
                            100$3$2$4;100


                            Handle the sixth and seventh cases in the conversion table.



                            (..)(.),(00.);111
                            100$2,1$3;0$1


                            Handle the fifth case in the conversion table.



                            (..)((.{5});110|(.);101)
                            100$3$4;$1


                            Handle the third and fourth cases in the conversion table.



                            1
                            01
                            +`10
                            011
                            .0+(1*)
                            $.1


                            Perform binary to decimal conversion.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited yesterday

























                            answered 2 days ago









                            Neil

                            78.1k744175




                            78.1k744175






















                                up vote
                                2
                                down vote














                                Python 2, 157 bytes





                                lambda a,b,c,d,e,f,g,h,i,j:[c+[a*4+b*2,8][g*h*~(d*~e*i)],f+[d*4+e*2,8,a*4+b*2][g*i+(d<e)*g*i*h],j+[h*4+i*2,[8,[a*4+b*2,d*4+e*2][h<i]][h^i or(h&i-(d|e))]][g]]


                                Try it online!






                                share|improve this answer

























                                  up vote
                                  2
                                  down vote














                                  Python 2, 157 bytes





                                  lambda a,b,c,d,e,f,g,h,i,j:[c+[a*4+b*2,8][g*h*~(d*~e*i)],f+[d*4+e*2,8,a*4+b*2][g*i+(d<e)*g*i*h],j+[h*4+i*2,[8,[a*4+b*2,d*4+e*2][h<i]][h^i or(h&i-(d|e))]][g]]


                                  Try it online!






                                  share|improve this answer























                                    up vote
                                    2
                                    down vote










                                    up vote
                                    2
                                    down vote










                                    Python 2, 157 bytes





                                    lambda a,b,c,d,e,f,g,h,i,j:[c+[a*4+b*2,8][g*h*~(d*~e*i)],f+[d*4+e*2,8,a*4+b*2][g*i+(d<e)*g*i*h],j+[h*4+i*2,[8,[a*4+b*2,d*4+e*2][h<i]][h^i or(h&i-(d|e))]][g]]


                                    Try it online!






                                    share|improve this answer













                                    Python 2, 157 bytes





                                    lambda a,b,c,d,e,f,g,h,i,j:[c+[a*4+b*2,8][g*h*~(d*~e*i)],f+[d*4+e*2,8,a*4+b*2][g*i+(d<e)*g*i*h],j+[h*4+i*2,[8,[a*4+b*2,d*4+e*2][h<i]][h^i or(h&i-(d|e))]][g]]


                                    Try it online!







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered 2 days ago









                                    TFeld

                                    13.7k21139




                                    13.7k21139






















                                        up vote
                                        2
                                        down vote














                                        Clean, 238 ... 189 bytes



                                        -2 bytes thanks to Neil



                                        import StdEnv
                                        $a b c d e f g h i j=100*(c+2*b+4*a)+10*(f+2*e+4*d)+j+2*i+4*h-2*(h*(99*b+198*a-394)+i*(9*e+18*d+h*(e+2*d-4+(b+2*a-4)*(1-10*e-100*d+110*e*d))-35)-4)*g+0^(e+d)*(2*b+4*a-8*i*h*g)


                                        Try it online!



                                        Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.






                                        share|improve this answer























                                        • In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                          – Neil
                                          2 days ago










                                        • @Neil You're right, it is, thanks.
                                          – Οurous
                                          yesterday















                                        up vote
                                        2
                                        down vote














                                        Clean, 238 ... 189 bytes



                                        -2 bytes thanks to Neil



                                        import StdEnv
                                        $a b c d e f g h i j=100*(c+2*b+4*a)+10*(f+2*e+4*d)+j+2*i+4*h-2*(h*(99*b+198*a-394)+i*(9*e+18*d+h*(e+2*d-4+(b+2*a-4)*(1-10*e-100*d+110*e*d))-35)-4)*g+0^(e+d)*(2*b+4*a-8*i*h*g)


                                        Try it online!



                                        Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.






                                        share|improve this answer























                                        • In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                          – Neil
                                          2 days ago










                                        • @Neil You're right, it is, thanks.
                                          – Οurous
                                          yesterday













                                        up vote
                                        2
                                        down vote










                                        up vote
                                        2
                                        down vote










                                        Clean, 238 ... 189 bytes



                                        -2 bytes thanks to Neil



                                        import StdEnv
                                        $a b c d e f g h i j=100*(c+2*b+4*a)+10*(f+2*e+4*d)+j+2*i+4*h-2*(h*(99*b+198*a-394)+i*(9*e+18*d+h*(e+2*d-4+(b+2*a-4)*(1-10*e-100*d+110*e*d))-35)-4)*g+0^(e+d)*(2*b+4*a-8*i*h*g)


                                        Try it online!



                                        Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.






                                        share|improve this answer















                                        Clean, 238 ... 189 bytes



                                        -2 bytes thanks to Neil



                                        import StdEnv
                                        $a b c d e f g h i j=100*(c+2*b+4*a)+10*(f+2*e+4*d)+j+2*i+4*h-2*(h*(99*b+198*a-394)+i*(9*e+18*d+h*(e+2*d-4+(b+2*a-4)*(1-10*e-100*d+110*e*d))-35)-4)*g+0^(e+d)*(2*b+4*a-8*i*h*g)


                                        Try it online!



                                        Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited yesterday

























                                        answered 2 days ago









                                        Οurous

                                        5,80311031




                                        5,80311031












                                        • In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                          – Neil
                                          2 days ago










                                        • @Neil You're right, it is, thanks.
                                          – Οurous
                                          yesterday


















                                        • In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                          – Neil
                                          2 days ago










                                        • @Neil You're right, it is, thanks.
                                          – Οurous
                                          yesterday
















                                        In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                        – Neil
                                        2 days ago




                                        In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                        – Neil
                                        2 days ago












                                        @Neil You're right, it is, thanks.
                                        – Οurous
                                        yesterday




                                        @Neil You're right, it is, thanks.
                                        – Οurous
                                        yesterday


















                                         

                                        draft saved


                                        draft discarded



















































                                         


                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f176371%2fdensely-packed-decimal-dpd-to-decimal%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        Mont Emei

                                        Province de Neuquén

                                        Soliste