Densely packed decimal (DPD) to decimal











up vote
21
down vote

favorite
2













For nandgame fans: Please try out DPD to decimal in logic gates too!




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













    For nandgame fans: Please try out DPD to decimal in logic gates too!




    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






      For nandgame fans: Please try out DPD to decimal in logic gates too!




      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
















      For nandgame fans: Please try out DPD to decimal in logic gates too!




      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 Nov 26 at 1:05

























      asked Nov 22 at 0:04









      Bubbler

      6,164759




      6,164759






















          11 Answers
          11






          active

          oldest

          votes

















          up vote
          12
          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
            Nov 23 at 11:19


















          up vote
          10
          down vote














          Python 3, 229 ... 97 96 bytes





          lambda a:[[a&6,a>>4&6,a>>7&6,8][b"  eW7B]Oys"[~a&8or~a&6or~6|a>>4]%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" eW7B]Oys"[ 10 char string; where to get high bits for
          indicator values 1-8. 0th,1st chars not used.
          ~a&8 or ~a&6 or ~6|a>>4] 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 1 and 8) as follows:


            • If a5 == 0, the indicator is 8 (originally 0, but using 8 instead saves a byte)

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

            • Otherwise the indicator is 2*a7a8 + 1 (actually calculated as a negative number).




          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
            Nov 22 at 19:43










          • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
            – lirtosiast
            Nov 23 at 20:01










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










          • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
            – lirtosiast
            Nov 23 at 21:53




















          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
            Nov 22 at 11:15






          • 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
            Nov 24 at 2:04


















          up vote
          8
          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
            Nov 22 at 13:59










          • @MCCCS Your code seems to be 138 bytes as well.
            – nwellnhof
            Nov 22 at 16:36


















          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
                  Nov 23 at 1:26










                • @Neil You're right, it is, thanks.
                  – Οurous
                  Nov 23 at 1:29


















                up vote
                1
                down vote













                Perl 5, 195 bytes



                sub f{$n=shift;@p=((map{($n>>$_&3)*2}(8,5,1)),8);for(16390,28935,29005,227791,29108,225788,226803,228863){return 2*$n&256|$n&17|$p[$_>>4&3]<<8|$p[$_/4&3]<<4|$p[$_&3]if($_>>12&$n/2)==($_>>6&63);}}


                Try it online



                I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?



                Explanation of the code



                In a more readable version, the code intention should become apparent:



                sub dpd {
                my $n = shift;
                my $v=2*($n&128)|$n&17;
                my @p=((map{($n>>$_&3)*2}(8,5,1)),8);
                for (16390,28935,29005,227791,29108,225788,226803,228863) {
                return $v |$p[$_>>4&3]<<8|$p[$_>>2&3]<<4|$p[$_&3]
                if(($_>>12&$n/2)==($_>>6&63));
                }
                }


                In the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.




                • The first 6 bits are an appropriate bit mask for the bits 1 (=h) to 6 (=d) of the input (bit 4 = f is redundant, but it simplifies the evaluation code to have it included).

                • The next 6 bits are the value bits for this bit mask. The values are checked on all places where the bit mask has a 1 value.

                • The following 3*2 bits contain the indices for the array @p for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.

                • The array @p is constructed from bits 9-8, 6-5, 3-2 of the input, and the number 8 as fourth member

                • The bits at position 7,4 and 0 of the input are transferred directly into bits 8,4 and 0 of the result.


                For example, the first number in the list, 16390, which is 100000000000110 as a bit field, carries the following information:



                000100 : bit mask says: only consider bit 3 of the input
                000000 : bit values say: bit 3 should be 0
                00 : use '0ab' as higher bits of first digit
                01 : use '0de' as higher bits of second digit
                10 : use '0gh' as higher bits of third digit





                share|improve this answer




























                  up vote
                  0
                  down vote














                  05AB1E, 104 103 bytes



                  •3γã•S£©4èUXтÌ‹X111QVY®2èDˆTQ*~i0®нëт}®1èY¯`*i0®нëY_Xт>Ê*i0¯`ëт]®3èY¯`_*X110Q~i0®нëXт›iYiтë0¯`ëX]®θJ4ôC


                  Definitely not the right language for this kind of challenge, but ah well..

                  Input as string, output as list of three digits.



                  Try it online or verify all test cases.



                  Explanation:



                  We have the following eight scenarios to consider:



                       1st 2nd 3rd 4th 5th 6th                          1st digit    2nd digit    3rd digit
                  1. ab c de f 0gh i → 0abc 0def 0ghi → '0'+1st 2nd '0'+3rd 4th 5th 6th
                  2. ab c de f 100 i → 0abc 0def 100i → '0'+1st 2nd '0'+3rd 4th 5th 6th
                  3. ab c gh f 101 i → 0abc 100f 0ghi → '0'+1st 2nd '100' 4th '0'+3rd 6th
                  4. gh c de f 110 i → 100c 0def 0ghi → '100' 2nd '0'+3rd 4th '0'+1st 6th
                  5. gh c 00 f 111 i → 100c 100f 0ghi → '100' 2nd '100' 4th '0'+1st 6th
                  6. de c 01 f 111 i → 100c 0def 100i → '100' 2nd '0'+1st 4th '100' 6th
                  7. ab c 10 f 111 i → 0abc 100f 100i → '0'+1st 2nd '100' 4th '100' 6th
                  8. xx c 11 f 111 i → 100c 100f 100i → '100' 2nd '100' 4th '100' 6th


                  I first split the (implicit) input into chunks of size [2,1,2,1,3,1] and store that list in the register:





                  •3γã•     # Push compressed integer 212131
                  S # Convert it to a list of digits
                  £ # Split the (implicit) input in chunks of that size
                  © # Store it in the register (without popping)


                  See this 05AB1E tip of mine (section How to compress large integers?) to understand why •3γã• is 212131



                  Now we're first going to built the 0s and 1s for the first digit of the output. Scenarios 1,2,3,7 use '0'+1st+2nd; and scenarios 4,5,6,8 use '100'+2nd:



                  4è                    # Take the 5th item of the list
                  U # Pop and store it in variable `X`
                  XтÌ‹ # Check if `X` is below 102
                  ~ # OR
                  X111Q # `X` is equal to 111
                  VY # And store that result in variable `Y`
                  * # and
                  ®2è # Get the 3rd item from the list of the register
                  Dˆ # Push it to the global array
                  TQ # And check if it's equal to 10
                  i # If the combined check above is truthy (exactly 1):
                  0 # Push 0 to the stack
                  ®н # Push the 1st item of the list to the stack
                  ë # Else:
                  т # Push 100 to the stack
                  } # Close the if-else
                  ®1è # And push the 2nd item of the list to the stack


                  Then we're going to built the 0s and 1s for the second digit of the output. Scenarios 1,2,4 use '0'+3rd+4th; scenarios 3,5,7,8 use '100'+4th; and scenario 6 uses '0'+1st+4th:



                  Y                # Push `Y` (check if `X` equals 111)
                  * # and
                  ¯` # Push the item from the global array (3rd item of the list)
                  i # If both checks above are truthy (exactly 1):
                  0 # Push 0 to the stack
                  ®н # Push the 1st item of the list to the stack
                  ë # Else:
                  Y_ # Push inverted `Y` (check if `X` does NOT equal 111)
                  * # and
                  Xт>Ê # Check if `X` (5th item of the list) does NOT equal 101
                  i # If both checks above are truthy (exactly 1):
                  0 # Push 0 to the stack
                  ¯` # Push the item from the global array (3rd item of the list)
                  ë # Else:
                  т # Push 100 to the stack
                  ] # Close both if-else cases
                  ®3è # And push the 4th item of the list to the stack


                  Then we're going to built the 0s and 1s for the third digit of the output. Scenarios 1,2 use 5th+6th; scenario 3 uses '0'+3rd+6th; scenarios 4,5 use '0'+1st+6th; and scenarios 6,7,8 use '100'+6th:



                  Y           #  Push `Y` (check if `X` equals 111)
                  * # and
                  ¯`_ # Check if the item from the global array (3rd item of the list) is exactly 0
                  ~ # OR
                  X110Q # Check if `X` (5th item of the list) equals 110
                  i # If the combined check above is truthy (exactly 1):
                  0 # Push 0 to the stack
                  ®н # Push the 1st item of the list to the stack
                  ë # Else:
                  Xт›i # If `X` (5th item of the list) is larger than 100 (so 101/110/111):
                  Yi # If `Y` (if `X` equals 111):
                  т # Push 100 to the stack
                  ë # Else:
                  0 # Push 0 to the stack
                  ¯` # Push the item from the global array (3rd item of the list)
                  ë # Else:
                  X # Push `X` (5th item of the list) to the stack
                  ] # Close all if-else cases
                  ®θ # And push the last (6th) item of the list to the stack


                  Now we have all 0s and 1s on the stack, so we can convert it to the three output digits:



                  J     # Join the entire stack together
                  4ô # Split it into parts of size 4
                  C # Convert each part from binary to an integer (and output implicitly)





                  share|improve this answer






























                    up vote
                    0
                    down vote














                    Jelly, 51 bytes



                    “¬Y-‘D¤ịȦƤS4x;“€-Y‘D¤ị$Ḅ;0,-4,5s3ḣ2SAœ?ɗ@/Ḥ+“¤©½‘ị$


                    Try it online!






                    share|improve this answer





















                      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

























                      11 Answers
                      11






                      active

                      oldest

                      votes








                      11 Answers
                      11






                      active

                      oldest

                      votes









                      active

                      oldest

                      votes






                      active

                      oldest

                      votes








                      up vote
                      12
                      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
                        Nov 23 at 11:19















                      up vote
                      12
                      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
                        Nov 23 at 11:19













                      up vote
                      12
                      down vote










                      up vote
                      12
                      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 Nov 23 at 12:58

























                      answered Nov 22 at 14:30









                      Arnauld

                      70.3k686296




                      70.3k686296








                      • 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
                        Nov 23 at 11:19














                      • 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
                        Nov 23 at 11:19








                      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
                      Nov 23 at 11:19




                      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
                      Nov 23 at 11:19










                      up vote
                      10
                      down vote














                      Python 3, 229 ... 97 96 bytes





                      lambda a:[[a&6,a>>4&6,a>>7&6,8][b"  eW7B]Oys"[~a&8or~a&6or~6|a>>4]%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" eW7B]Oys"[ 10 char string; where to get high bits for
                      indicator values 1-8. 0th,1st chars not used.
                      ~a&8 or ~a&6 or ~6|a>>4] 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 1 and 8) as follows:


                        • If a5 == 0, the indicator is 8 (originally 0, but using 8 instead saves a byte)

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

                        • Otherwise the indicator is 2*a7a8 + 1 (actually calculated as a negative number).




                      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
                        Nov 22 at 19:43










                      • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                        – lirtosiast
                        Nov 23 at 20:01










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










                      • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                        – lirtosiast
                        Nov 23 at 21:53

















                      up vote
                      10
                      down vote














                      Python 3, 229 ... 97 96 bytes





                      lambda a:[[a&6,a>>4&6,a>>7&6,8][b"  eW7B]Oys"[~a&8or~a&6or~6|a>>4]%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" eW7B]Oys"[ 10 char string; where to get high bits for
                      indicator values 1-8. 0th,1st chars not used.
                      ~a&8 or ~a&6 or ~6|a>>4] 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 1 and 8) as follows:


                        • If a5 == 0, the indicator is 8 (originally 0, but using 8 instead saves a byte)

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

                        • Otherwise the indicator is 2*a7a8 + 1 (actually calculated as a negative number).




                      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
                        Nov 22 at 19:43










                      • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                        – lirtosiast
                        Nov 23 at 20:01










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










                      • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                        – lirtosiast
                        Nov 23 at 21:53















                      up vote
                      10
                      down vote










                      up vote
                      10
                      down vote










                      Python 3, 229 ... 97 96 bytes





                      lambda a:[[a&6,a>>4&6,a>>7&6,8][b"  eW7B]Oys"[~a&8or~a&6or~6|a>>4]%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" eW7B]Oys"[ 10 char string; where to get high bits for
                      indicator values 1-8. 0th,1st chars not used.
                      ~a&8 or ~a&6 or ~6|a>>4] 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 1 and 8) as follows:


                        • If a5 == 0, the indicator is 8 (originally 0, but using 8 instead saves a byte)

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

                        • Otherwise the indicator is 2*a7a8 + 1 (actually calculated as a negative number).




                      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 ... 97 96 bytes





                      lambda a:[[a&6,a>>4&6,a>>7&6,8][b"  eW7B]Oys"[~a&8or~a&6or~6|a>>4]%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" eW7B]Oys"[ 10 char string; where to get high bits for
                      indicator values 1-8. 0th,1st chars not used.
                      ~a&8 or ~a&6 or ~6|a>>4] 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 1 and 8) as follows:


                        • If a5 == 0, the indicator is 8 (originally 0, but using 8 instead saves a byte)

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

                        • Otherwise the indicator is 2*a7a8 + 1 (actually calculated as a negative number).




                      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 Nov 25 at 6:52

























                      answered Nov 22 at 7:43









                      lirtosiast

                      15.6k436107




                      15.6k436107








                      • 1




                        You can used a bytestring b"..." to replace converting with ord.
                        – xnor
                        Nov 22 at 19:43










                      • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                        – lirtosiast
                        Nov 23 at 20:01










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










                      • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                        – lirtosiast
                        Nov 23 at 21:53
















                      • 1




                        You can used a bytestring b"..." to replace converting with ord.
                        – xnor
                        Nov 22 at 19:43










                      • @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                        – lirtosiast
                        Nov 23 at 20:01










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










                      • @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                        – lirtosiast
                        Nov 23 at 21:53










                      1




                      1




                      You can used a bytestring b"..." to replace converting with ord.
                      – xnor
                      Nov 22 at 19:43




                      You can used a bytestring b"..." to replace converting with ord.
                      – xnor
                      Nov 22 at 19:43












                      @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                      – lirtosiast
                      Nov 23 at 20:01




                      @nwellnhof Ha, I just found the same thing! Will credit you anyway.
                      – lirtosiast
                      Nov 23 at 20:01












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




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












                      @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                      – lirtosiast
                      Nov 23 at 21:53






                      @nwellnhof I think a modulo chain is the way to go here, but if not yours would certainly work.
                      – lirtosiast
                      Nov 23 at 21:53












                      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
                        Nov 22 at 11:15






                      • 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
                        Nov 24 at 2:04















                      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
                        Nov 22 at 11:15






                      • 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
                        Nov 24 at 2:04













                      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 Nov 24 at 9:12

























                      answered Nov 22 at 2:31









                      Shieru Asakoto

                      2,380314




                      2,380314








                      • 1




                        (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                        – tsh
                        Nov 22 at 11:15






                      • 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
                        Nov 24 at 2:04














                      • 1




                        (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                        – tsh
                        Nov 22 at 11:15






                      • 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
                        Nov 24 at 2:04








                      1




                      1




                      (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                      – tsh
                      Nov 22 at 11:15




                      (!i|!d|e) -> i+l!=5; (d|e|!h) -> h+l!=1
                      – tsh
                      Nov 22 at 11:15




                      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
                      Nov 24 at 2:04




                      (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
                      Nov 24 at 2:04










                      up vote
                      8
                      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
                        Nov 22 at 13:59










                      • @MCCCS Your code seems to be 138 bytes as well.
                        – nwellnhof
                        Nov 22 at 16:36















                      up vote
                      8
                      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
                        Nov 22 at 13:59










                      • @MCCCS Your code seems to be 138 bytes as well.
                        – nwellnhof
                        Nov 22 at 16:36













                      up vote
                      8
                      down vote










                      up vote
                      8
                      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 Nov 23 at 11:45

























                      answered Nov 22 at 0:30









                      nwellnhof

                      6,3231125




                      6,3231125












                      • 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
                        Nov 22 at 13:59










                      • @MCCCS Your code seems to be 138 bytes as well.
                        – nwellnhof
                        Nov 22 at 16:36


















                      • 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
                        Nov 22 at 13:59










                      • @MCCCS Your code seems to be 138 bytes as well.
                        – nwellnhof
                        Nov 22 at 16:36
















                      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
                      Nov 22 at 13:59




                      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
                      Nov 22 at 13:59












                      @MCCCS Your code seems to be 138 bytes as well.
                      – nwellnhof
                      Nov 22 at 16:36




                      @MCCCS Your code seems to be 138 bytes as well.
                      – nwellnhof
                      Nov 22 at 16:36










                      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 Nov 22 at 15:38

























                          answered Nov 22 at 14:04









                          G B

                          7,5961328




                          7,5961328






















                              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 Nov 23 at 9:28

























                                  answered Nov 22 at 9:45









                                  Neil

                                  78.5k744175




                                  78.5k744175






















                                      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 Nov 22 at 14:43









                                          TFeld

                                          13.7k21239




                                          13.7k21239






















                                              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
                                                Nov 23 at 1:26










                                              • @Neil You're right, it is, thanks.
                                                – Οurous
                                                Nov 23 at 1:29















                                              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
                                                Nov 23 at 1:26










                                              • @Neil You're right, it is, thanks.
                                                – Οurous
                                                Nov 23 at 1:29













                                              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 Nov 23 at 1:48

























                                              answered Nov 22 at 23:08









                                              Οurous

                                              6,07311032




                                              6,07311032












                                              • In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                                – Neil
                                                Nov 23 at 1:26










                                              • @Neil You're right, it is, thanks.
                                                – Οurous
                                                Nov 23 at 1:29


















                                              • In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                                – Neil
                                                Nov 23 at 1:26










                                              • @Neil You're right, it is, thanks.
                                                – Οurous
                                                Nov 23 at 1:29
















                                              In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                              – Neil
                                              Nov 23 at 1:26




                                              In i*(9*e+19*d+i*...), that second i* looks unnecessary.
                                              – Neil
                                              Nov 23 at 1:26












                                              @Neil You're right, it is, thanks.
                                              – Οurous
                                              Nov 23 at 1:29




                                              @Neil You're right, it is, thanks.
                                              – Οurous
                                              Nov 23 at 1:29










                                              up vote
                                              1
                                              down vote













                                              Perl 5, 195 bytes



                                              sub f{$n=shift;@p=((map{($n>>$_&3)*2}(8,5,1)),8);for(16390,28935,29005,227791,29108,225788,226803,228863){return 2*$n&256|$n&17|$p[$_>>4&3]<<8|$p[$_/4&3]<<4|$p[$_&3]if($_>>12&$n/2)==($_>>6&63);}}


                                              Try it online



                                              I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?



                                              Explanation of the code



                                              In a more readable version, the code intention should become apparent:



                                              sub dpd {
                                              my $n = shift;
                                              my $v=2*($n&128)|$n&17;
                                              my @p=((map{($n>>$_&3)*2}(8,5,1)),8);
                                              for (16390,28935,29005,227791,29108,225788,226803,228863) {
                                              return $v |$p[$_>>4&3]<<8|$p[$_>>2&3]<<4|$p[$_&3]
                                              if(($_>>12&$n/2)==($_>>6&63));
                                              }
                                              }


                                              In the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.




                                              • The first 6 bits are an appropriate bit mask for the bits 1 (=h) to 6 (=d) of the input (bit 4 = f is redundant, but it simplifies the evaluation code to have it included).

                                              • The next 6 bits are the value bits for this bit mask. The values are checked on all places where the bit mask has a 1 value.

                                              • The following 3*2 bits contain the indices for the array @p for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.

                                              • The array @p is constructed from bits 9-8, 6-5, 3-2 of the input, and the number 8 as fourth member

                                              • The bits at position 7,4 and 0 of the input are transferred directly into bits 8,4 and 0 of the result.


                                              For example, the first number in the list, 16390, which is 100000000000110 as a bit field, carries the following information:



                                              000100 : bit mask says: only consider bit 3 of the input
                                              000000 : bit values say: bit 3 should be 0
                                              00 : use '0ab' as higher bits of first digit
                                              01 : use '0de' as higher bits of second digit
                                              10 : use '0gh' as higher bits of third digit





                                              share|improve this answer

























                                                up vote
                                                1
                                                down vote













                                                Perl 5, 195 bytes



                                                sub f{$n=shift;@p=((map{($n>>$_&3)*2}(8,5,1)),8);for(16390,28935,29005,227791,29108,225788,226803,228863){return 2*$n&256|$n&17|$p[$_>>4&3]<<8|$p[$_/4&3]<<4|$p[$_&3]if($_>>12&$n/2)==($_>>6&63);}}


                                                Try it online



                                                I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?



                                                Explanation of the code



                                                In a more readable version, the code intention should become apparent:



                                                sub dpd {
                                                my $n = shift;
                                                my $v=2*($n&128)|$n&17;
                                                my @p=((map{($n>>$_&3)*2}(8,5,1)),8);
                                                for (16390,28935,29005,227791,29108,225788,226803,228863) {
                                                return $v |$p[$_>>4&3]<<8|$p[$_>>2&3]<<4|$p[$_&3]
                                                if(($_>>12&$n/2)==($_>>6&63));
                                                }
                                                }


                                                In the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.




                                                • The first 6 bits are an appropriate bit mask for the bits 1 (=h) to 6 (=d) of the input (bit 4 = f is redundant, but it simplifies the evaluation code to have it included).

                                                • The next 6 bits are the value bits for this bit mask. The values are checked on all places where the bit mask has a 1 value.

                                                • The following 3*2 bits contain the indices for the array @p for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.

                                                • The array @p is constructed from bits 9-8, 6-5, 3-2 of the input, and the number 8 as fourth member

                                                • The bits at position 7,4 and 0 of the input are transferred directly into bits 8,4 and 0 of the result.


                                                For example, the first number in the list, 16390, which is 100000000000110 as a bit field, carries the following information:



                                                000100 : bit mask says: only consider bit 3 of the input
                                                000000 : bit values say: bit 3 should be 0
                                                00 : use '0ab' as higher bits of first digit
                                                01 : use '0de' as higher bits of second digit
                                                10 : use '0gh' as higher bits of third digit





                                                share|improve this answer























                                                  up vote
                                                  1
                                                  down vote










                                                  up vote
                                                  1
                                                  down vote









                                                  Perl 5, 195 bytes



                                                  sub f{$n=shift;@p=((map{($n>>$_&3)*2}(8,5,1)),8);for(16390,28935,29005,227791,29108,225788,226803,228863){return 2*$n&256|$n&17|$p[$_>>4&3]<<8|$p[$_/4&3]<<4|$p[$_&3]if($_>>12&$n/2)==($_>>6&63);}}


                                                  Try it online



                                                  I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?



                                                  Explanation of the code



                                                  In a more readable version, the code intention should become apparent:



                                                  sub dpd {
                                                  my $n = shift;
                                                  my $v=2*($n&128)|$n&17;
                                                  my @p=((map{($n>>$_&3)*2}(8,5,1)),8);
                                                  for (16390,28935,29005,227791,29108,225788,226803,228863) {
                                                  return $v |$p[$_>>4&3]<<8|$p[$_>>2&3]<<4|$p[$_&3]
                                                  if(($_>>12&$n/2)==($_>>6&63));
                                                  }
                                                  }


                                                  In the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.




                                                  • The first 6 bits are an appropriate bit mask for the bits 1 (=h) to 6 (=d) of the input (bit 4 = f is redundant, but it simplifies the evaluation code to have it included).

                                                  • The next 6 bits are the value bits for this bit mask. The values are checked on all places where the bit mask has a 1 value.

                                                  • The following 3*2 bits contain the indices for the array @p for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.

                                                  • The array @p is constructed from bits 9-8, 6-5, 3-2 of the input, and the number 8 as fourth member

                                                  • The bits at position 7,4 and 0 of the input are transferred directly into bits 8,4 and 0 of the result.


                                                  For example, the first number in the list, 16390, which is 100000000000110 as a bit field, carries the following information:



                                                  000100 : bit mask says: only consider bit 3 of the input
                                                  000000 : bit values say: bit 3 should be 0
                                                  00 : use '0ab' as higher bits of first digit
                                                  01 : use '0de' as higher bits of second digit
                                                  10 : use '0gh' as higher bits of third digit





                                                  share|improve this answer












                                                  Perl 5, 195 bytes



                                                  sub f{$n=shift;@p=((map{($n>>$_&3)*2}(8,5,1)),8);for(16390,28935,29005,227791,29108,225788,226803,228863){return 2*$n&256|$n&17|$p[$_>>4&3]<<8|$p[$_/4&3]<<4|$p[$_&3]if($_>>12&$n/2)==($_>>6&63);}}


                                                  Try it online



                                                  I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?



                                                  Explanation of the code



                                                  In a more readable version, the code intention should become apparent:



                                                  sub dpd {
                                                  my $n = shift;
                                                  my $v=2*($n&128)|$n&17;
                                                  my @p=((map{($n>>$_&3)*2}(8,5,1)),8);
                                                  for (16390,28935,29005,227791,29108,225788,226803,228863) {
                                                  return $v |$p[$_>>4&3]<<8|$p[$_>>2&3]<<4|$p[$_&3]
                                                  if(($_>>12&$n/2)==($_>>6&63));
                                                  }
                                                  }


                                                  In the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.




                                                  • The first 6 bits are an appropriate bit mask for the bits 1 (=h) to 6 (=d) of the input (bit 4 = f is redundant, but it simplifies the evaluation code to have it included).

                                                  • The next 6 bits are the value bits for this bit mask. The values are checked on all places where the bit mask has a 1 value.

                                                  • The following 3*2 bits contain the indices for the array @p for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.

                                                  • The array @p is constructed from bits 9-8, 6-5, 3-2 of the input, and the number 8 as fourth member

                                                  • The bits at position 7,4 and 0 of the input are transferred directly into bits 8,4 and 0 of the result.


                                                  For example, the first number in the list, 16390, which is 100000000000110 as a bit field, carries the following information:



                                                  000100 : bit mask says: only consider bit 3 of the input
                                                  000000 : bit values say: bit 3 should be 0
                                                  00 : use '0ab' as higher bits of first digit
                                                  01 : use '0de' as higher bits of second digit
                                                  10 : use '0gh' as higher bits of third digit






                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Nov 26 at 11:40









                                                  rplantiko

                                                  1112




                                                  1112






















                                                      up vote
                                                      0
                                                      down vote














                                                      05AB1E, 104 103 bytes



                                                      •3γã•S£©4èUXтÌ‹X111QVY®2èDˆTQ*~i0®нëт}®1èY¯`*i0®нëY_Xт>Ê*i0¯`ëт]®3èY¯`_*X110Q~i0®нëXт›iYiтë0¯`ëX]®θJ4ôC


                                                      Definitely not the right language for this kind of challenge, but ah well..

                                                      Input as string, output as list of three digits.



                                                      Try it online or verify all test cases.



                                                      Explanation:



                                                      We have the following eight scenarios to consider:



                                                           1st 2nd 3rd 4th 5th 6th                          1st digit    2nd digit    3rd digit
                                                      1. ab c de f 0gh i → 0abc 0def 0ghi → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                      2. ab c de f 100 i → 0abc 0def 100i → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                      3. ab c gh f 101 i → 0abc 100f 0ghi → '0'+1st 2nd '100' 4th '0'+3rd 6th
                                                      4. gh c de f 110 i → 100c 0def 0ghi → '100' 2nd '0'+3rd 4th '0'+1st 6th
                                                      5. gh c 00 f 111 i → 100c 100f 0ghi → '100' 2nd '100' 4th '0'+1st 6th
                                                      6. de c 01 f 111 i → 100c 0def 100i → '100' 2nd '0'+1st 4th '100' 6th
                                                      7. ab c 10 f 111 i → 0abc 100f 100i → '0'+1st 2nd '100' 4th '100' 6th
                                                      8. xx c 11 f 111 i → 100c 100f 100i → '100' 2nd '100' 4th '100' 6th


                                                      I first split the (implicit) input into chunks of size [2,1,2,1,3,1] and store that list in the register:





                                                      •3γã•     # Push compressed integer 212131
                                                      S # Convert it to a list of digits
                                                      £ # Split the (implicit) input in chunks of that size
                                                      © # Store it in the register (without popping)


                                                      See this 05AB1E tip of mine (section How to compress large integers?) to understand why •3γã• is 212131



                                                      Now we're first going to built the 0s and 1s for the first digit of the output. Scenarios 1,2,3,7 use '0'+1st+2nd; and scenarios 4,5,6,8 use '100'+2nd:



                                                      4è                    # Take the 5th item of the list
                                                      U # Pop and store it in variable `X`
                                                      XтÌ‹ # Check if `X` is below 102
                                                      ~ # OR
                                                      X111Q # `X` is equal to 111
                                                      VY # And store that result in variable `Y`
                                                      * # and
                                                      ®2è # Get the 3rd item from the list of the register
                                                      Dˆ # Push it to the global array
                                                      TQ # And check if it's equal to 10
                                                      i # If the combined check above is truthy (exactly 1):
                                                      0 # Push 0 to the stack
                                                      ®н # Push the 1st item of the list to the stack
                                                      ë # Else:
                                                      т # Push 100 to the stack
                                                      } # Close the if-else
                                                      ®1è # And push the 2nd item of the list to the stack


                                                      Then we're going to built the 0s and 1s for the second digit of the output. Scenarios 1,2,4 use '0'+3rd+4th; scenarios 3,5,7,8 use '100'+4th; and scenario 6 uses '0'+1st+4th:



                                                      Y                # Push `Y` (check if `X` equals 111)
                                                      * # and
                                                      ¯` # Push the item from the global array (3rd item of the list)
                                                      i # If both checks above are truthy (exactly 1):
                                                      0 # Push 0 to the stack
                                                      ®н # Push the 1st item of the list to the stack
                                                      ë # Else:
                                                      Y_ # Push inverted `Y` (check if `X` does NOT equal 111)
                                                      * # and
                                                      Xт>Ê # Check if `X` (5th item of the list) does NOT equal 101
                                                      i # If both checks above are truthy (exactly 1):
                                                      0 # Push 0 to the stack
                                                      ¯` # Push the item from the global array (3rd item of the list)
                                                      ë # Else:
                                                      т # Push 100 to the stack
                                                      ] # Close both if-else cases
                                                      ®3è # And push the 4th item of the list to the stack


                                                      Then we're going to built the 0s and 1s for the third digit of the output. Scenarios 1,2 use 5th+6th; scenario 3 uses '0'+3rd+6th; scenarios 4,5 use '0'+1st+6th; and scenarios 6,7,8 use '100'+6th:



                                                      Y           #  Push `Y` (check if `X` equals 111)
                                                      * # and
                                                      ¯`_ # Check if the item from the global array (3rd item of the list) is exactly 0
                                                      ~ # OR
                                                      X110Q # Check if `X` (5th item of the list) equals 110
                                                      i # If the combined check above is truthy (exactly 1):
                                                      0 # Push 0 to the stack
                                                      ®н # Push the 1st item of the list to the stack
                                                      ë # Else:
                                                      Xт›i # If `X` (5th item of the list) is larger than 100 (so 101/110/111):
                                                      Yi # If `Y` (if `X` equals 111):
                                                      т # Push 100 to the stack
                                                      ë # Else:
                                                      0 # Push 0 to the stack
                                                      ¯` # Push the item from the global array (3rd item of the list)
                                                      ë # Else:
                                                      X # Push `X` (5th item of the list) to the stack
                                                      ] # Close all if-else cases
                                                      ®θ # And push the last (6th) item of the list to the stack


                                                      Now we have all 0s and 1s on the stack, so we can convert it to the three output digits:



                                                      J     # Join the entire stack together
                                                      4ô # Split it into parts of size 4
                                                      C # Convert each part from binary to an integer (and output implicitly)





                                                      share|improve this answer



























                                                        up vote
                                                        0
                                                        down vote














                                                        05AB1E, 104 103 bytes



                                                        •3γã•S£©4èUXтÌ‹X111QVY®2èDˆTQ*~i0®нëт}®1èY¯`*i0®нëY_Xт>Ê*i0¯`ëт]®3èY¯`_*X110Q~i0®нëXт›iYiтë0¯`ëX]®θJ4ôC


                                                        Definitely not the right language for this kind of challenge, but ah well..

                                                        Input as string, output as list of three digits.



                                                        Try it online or verify all test cases.



                                                        Explanation:



                                                        We have the following eight scenarios to consider:



                                                             1st 2nd 3rd 4th 5th 6th                          1st digit    2nd digit    3rd digit
                                                        1. ab c de f 0gh i → 0abc 0def 0ghi → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                        2. ab c de f 100 i → 0abc 0def 100i → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                        3. ab c gh f 101 i → 0abc 100f 0ghi → '0'+1st 2nd '100' 4th '0'+3rd 6th
                                                        4. gh c de f 110 i → 100c 0def 0ghi → '100' 2nd '0'+3rd 4th '0'+1st 6th
                                                        5. gh c 00 f 111 i → 100c 100f 0ghi → '100' 2nd '100' 4th '0'+1st 6th
                                                        6. de c 01 f 111 i → 100c 0def 100i → '100' 2nd '0'+1st 4th '100' 6th
                                                        7. ab c 10 f 111 i → 0abc 100f 100i → '0'+1st 2nd '100' 4th '100' 6th
                                                        8. xx c 11 f 111 i → 100c 100f 100i → '100' 2nd '100' 4th '100' 6th


                                                        I first split the (implicit) input into chunks of size [2,1,2,1,3,1] and store that list in the register:





                                                        •3γã•     # Push compressed integer 212131
                                                        S # Convert it to a list of digits
                                                        £ # Split the (implicit) input in chunks of that size
                                                        © # Store it in the register (without popping)


                                                        See this 05AB1E tip of mine (section How to compress large integers?) to understand why •3γã• is 212131



                                                        Now we're first going to built the 0s and 1s for the first digit of the output. Scenarios 1,2,3,7 use '0'+1st+2nd; and scenarios 4,5,6,8 use '100'+2nd:



                                                        4è                    # Take the 5th item of the list
                                                        U # Pop and store it in variable `X`
                                                        XтÌ‹ # Check if `X` is below 102
                                                        ~ # OR
                                                        X111Q # `X` is equal to 111
                                                        VY # And store that result in variable `Y`
                                                        * # and
                                                        ®2è # Get the 3rd item from the list of the register
                                                        Dˆ # Push it to the global array
                                                        TQ # And check if it's equal to 10
                                                        i # If the combined check above is truthy (exactly 1):
                                                        0 # Push 0 to the stack
                                                        ®н # Push the 1st item of the list to the stack
                                                        ë # Else:
                                                        т # Push 100 to the stack
                                                        } # Close the if-else
                                                        ®1è # And push the 2nd item of the list to the stack


                                                        Then we're going to built the 0s and 1s for the second digit of the output. Scenarios 1,2,4 use '0'+3rd+4th; scenarios 3,5,7,8 use '100'+4th; and scenario 6 uses '0'+1st+4th:



                                                        Y                # Push `Y` (check if `X` equals 111)
                                                        * # and
                                                        ¯` # Push the item from the global array (3rd item of the list)
                                                        i # If both checks above are truthy (exactly 1):
                                                        0 # Push 0 to the stack
                                                        ®н # Push the 1st item of the list to the stack
                                                        ë # Else:
                                                        Y_ # Push inverted `Y` (check if `X` does NOT equal 111)
                                                        * # and
                                                        Xт>Ê # Check if `X` (5th item of the list) does NOT equal 101
                                                        i # If both checks above are truthy (exactly 1):
                                                        0 # Push 0 to the stack
                                                        ¯` # Push the item from the global array (3rd item of the list)
                                                        ë # Else:
                                                        т # Push 100 to the stack
                                                        ] # Close both if-else cases
                                                        ®3è # And push the 4th item of the list to the stack


                                                        Then we're going to built the 0s and 1s for the third digit of the output. Scenarios 1,2 use 5th+6th; scenario 3 uses '0'+3rd+6th; scenarios 4,5 use '0'+1st+6th; and scenarios 6,7,8 use '100'+6th:



                                                        Y           #  Push `Y` (check if `X` equals 111)
                                                        * # and
                                                        ¯`_ # Check if the item from the global array (3rd item of the list) is exactly 0
                                                        ~ # OR
                                                        X110Q # Check if `X` (5th item of the list) equals 110
                                                        i # If the combined check above is truthy (exactly 1):
                                                        0 # Push 0 to the stack
                                                        ®н # Push the 1st item of the list to the stack
                                                        ë # Else:
                                                        Xт›i # If `X` (5th item of the list) is larger than 100 (so 101/110/111):
                                                        Yi # If `Y` (if `X` equals 111):
                                                        т # Push 100 to the stack
                                                        ë # Else:
                                                        0 # Push 0 to the stack
                                                        ¯` # Push the item from the global array (3rd item of the list)
                                                        ë # Else:
                                                        X # Push `X` (5th item of the list) to the stack
                                                        ] # Close all if-else cases
                                                        ®θ # And push the last (6th) item of the list to the stack


                                                        Now we have all 0s and 1s on the stack, so we can convert it to the three output digits:



                                                        J     # Join the entire stack together
                                                        4ô # Split it into parts of size 4
                                                        C # Convert each part from binary to an integer (and output implicitly)





                                                        share|improve this answer

























                                                          up vote
                                                          0
                                                          down vote










                                                          up vote
                                                          0
                                                          down vote










                                                          05AB1E, 104 103 bytes



                                                          •3γã•S£©4èUXтÌ‹X111QVY®2èDˆTQ*~i0®нëт}®1èY¯`*i0®нëY_Xт>Ê*i0¯`ëт]®3èY¯`_*X110Q~i0®нëXт›iYiтë0¯`ëX]®θJ4ôC


                                                          Definitely not the right language for this kind of challenge, but ah well..

                                                          Input as string, output as list of three digits.



                                                          Try it online or verify all test cases.



                                                          Explanation:



                                                          We have the following eight scenarios to consider:



                                                               1st 2nd 3rd 4th 5th 6th                          1st digit    2nd digit    3rd digit
                                                          1. ab c de f 0gh i → 0abc 0def 0ghi → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                          2. ab c de f 100 i → 0abc 0def 100i → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                          3. ab c gh f 101 i → 0abc 100f 0ghi → '0'+1st 2nd '100' 4th '0'+3rd 6th
                                                          4. gh c de f 110 i → 100c 0def 0ghi → '100' 2nd '0'+3rd 4th '0'+1st 6th
                                                          5. gh c 00 f 111 i → 100c 100f 0ghi → '100' 2nd '100' 4th '0'+1st 6th
                                                          6. de c 01 f 111 i → 100c 0def 100i → '100' 2nd '0'+1st 4th '100' 6th
                                                          7. ab c 10 f 111 i → 0abc 100f 100i → '0'+1st 2nd '100' 4th '100' 6th
                                                          8. xx c 11 f 111 i → 100c 100f 100i → '100' 2nd '100' 4th '100' 6th


                                                          I first split the (implicit) input into chunks of size [2,1,2,1,3,1] and store that list in the register:





                                                          •3γã•     # Push compressed integer 212131
                                                          S # Convert it to a list of digits
                                                          £ # Split the (implicit) input in chunks of that size
                                                          © # Store it in the register (without popping)


                                                          See this 05AB1E tip of mine (section How to compress large integers?) to understand why •3γã• is 212131



                                                          Now we're first going to built the 0s and 1s for the first digit of the output. Scenarios 1,2,3,7 use '0'+1st+2nd; and scenarios 4,5,6,8 use '100'+2nd:



                                                          4è                    # Take the 5th item of the list
                                                          U # Pop and store it in variable `X`
                                                          XтÌ‹ # Check if `X` is below 102
                                                          ~ # OR
                                                          X111Q # `X` is equal to 111
                                                          VY # And store that result in variable `Y`
                                                          * # and
                                                          ®2è # Get the 3rd item from the list of the register
                                                          Dˆ # Push it to the global array
                                                          TQ # And check if it's equal to 10
                                                          i # If the combined check above is truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ®н # Push the 1st item of the list to the stack
                                                          ë # Else:
                                                          т # Push 100 to the stack
                                                          } # Close the if-else
                                                          ®1è # And push the 2nd item of the list to the stack


                                                          Then we're going to built the 0s and 1s for the second digit of the output. Scenarios 1,2,4 use '0'+3rd+4th; scenarios 3,5,7,8 use '100'+4th; and scenario 6 uses '0'+1st+4th:



                                                          Y                # Push `Y` (check if `X` equals 111)
                                                          * # and
                                                          ¯` # Push the item from the global array (3rd item of the list)
                                                          i # If both checks above are truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ®н # Push the 1st item of the list to the stack
                                                          ë # Else:
                                                          Y_ # Push inverted `Y` (check if `X` does NOT equal 111)
                                                          * # and
                                                          Xт>Ê # Check if `X` (5th item of the list) does NOT equal 101
                                                          i # If both checks above are truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ¯` # Push the item from the global array (3rd item of the list)
                                                          ë # Else:
                                                          т # Push 100 to the stack
                                                          ] # Close both if-else cases
                                                          ®3è # And push the 4th item of the list to the stack


                                                          Then we're going to built the 0s and 1s for the third digit of the output. Scenarios 1,2 use 5th+6th; scenario 3 uses '0'+3rd+6th; scenarios 4,5 use '0'+1st+6th; and scenarios 6,7,8 use '100'+6th:



                                                          Y           #  Push `Y` (check if `X` equals 111)
                                                          * # and
                                                          ¯`_ # Check if the item from the global array (3rd item of the list) is exactly 0
                                                          ~ # OR
                                                          X110Q # Check if `X` (5th item of the list) equals 110
                                                          i # If the combined check above is truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ®н # Push the 1st item of the list to the stack
                                                          ë # Else:
                                                          Xт›i # If `X` (5th item of the list) is larger than 100 (so 101/110/111):
                                                          Yi # If `Y` (if `X` equals 111):
                                                          т # Push 100 to the stack
                                                          ë # Else:
                                                          0 # Push 0 to the stack
                                                          ¯` # Push the item from the global array (3rd item of the list)
                                                          ë # Else:
                                                          X # Push `X` (5th item of the list) to the stack
                                                          ] # Close all if-else cases
                                                          ®θ # And push the last (6th) item of the list to the stack


                                                          Now we have all 0s and 1s on the stack, so we can convert it to the three output digits:



                                                          J     # Join the entire stack together
                                                          4ô # Split it into parts of size 4
                                                          C # Convert each part from binary to an integer (and output implicitly)





                                                          share|improve this answer















                                                          05AB1E, 104 103 bytes



                                                          •3γã•S£©4èUXтÌ‹X111QVY®2èDˆTQ*~i0®нëт}®1èY¯`*i0®нëY_Xт>Ê*i0¯`ëт]®3èY¯`_*X110Q~i0®нëXт›iYiтë0¯`ëX]®θJ4ôC


                                                          Definitely not the right language for this kind of challenge, but ah well..

                                                          Input as string, output as list of three digits.



                                                          Try it online or verify all test cases.



                                                          Explanation:



                                                          We have the following eight scenarios to consider:



                                                               1st 2nd 3rd 4th 5th 6th                          1st digit    2nd digit    3rd digit
                                                          1. ab c de f 0gh i → 0abc 0def 0ghi → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                          2. ab c de f 100 i → 0abc 0def 100i → '0'+1st 2nd '0'+3rd 4th 5th 6th
                                                          3. ab c gh f 101 i → 0abc 100f 0ghi → '0'+1st 2nd '100' 4th '0'+3rd 6th
                                                          4. gh c de f 110 i → 100c 0def 0ghi → '100' 2nd '0'+3rd 4th '0'+1st 6th
                                                          5. gh c 00 f 111 i → 100c 100f 0ghi → '100' 2nd '100' 4th '0'+1st 6th
                                                          6. de c 01 f 111 i → 100c 0def 100i → '100' 2nd '0'+1st 4th '100' 6th
                                                          7. ab c 10 f 111 i → 0abc 100f 100i → '0'+1st 2nd '100' 4th '100' 6th
                                                          8. xx c 11 f 111 i → 100c 100f 100i → '100' 2nd '100' 4th '100' 6th


                                                          I first split the (implicit) input into chunks of size [2,1,2,1,3,1] and store that list in the register:





                                                          •3γã•     # Push compressed integer 212131
                                                          S # Convert it to a list of digits
                                                          £ # Split the (implicit) input in chunks of that size
                                                          © # Store it in the register (without popping)


                                                          See this 05AB1E tip of mine (section How to compress large integers?) to understand why •3γã• is 212131



                                                          Now we're first going to built the 0s and 1s for the first digit of the output. Scenarios 1,2,3,7 use '0'+1st+2nd; and scenarios 4,5,6,8 use '100'+2nd:



                                                          4è                    # Take the 5th item of the list
                                                          U # Pop and store it in variable `X`
                                                          XтÌ‹ # Check if `X` is below 102
                                                          ~ # OR
                                                          X111Q # `X` is equal to 111
                                                          VY # And store that result in variable `Y`
                                                          * # and
                                                          ®2è # Get the 3rd item from the list of the register
                                                          Dˆ # Push it to the global array
                                                          TQ # And check if it's equal to 10
                                                          i # If the combined check above is truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ®н # Push the 1st item of the list to the stack
                                                          ë # Else:
                                                          т # Push 100 to the stack
                                                          } # Close the if-else
                                                          ®1è # And push the 2nd item of the list to the stack


                                                          Then we're going to built the 0s and 1s for the second digit of the output. Scenarios 1,2,4 use '0'+3rd+4th; scenarios 3,5,7,8 use '100'+4th; and scenario 6 uses '0'+1st+4th:



                                                          Y                # Push `Y` (check if `X` equals 111)
                                                          * # and
                                                          ¯` # Push the item from the global array (3rd item of the list)
                                                          i # If both checks above are truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ®н # Push the 1st item of the list to the stack
                                                          ë # Else:
                                                          Y_ # Push inverted `Y` (check if `X` does NOT equal 111)
                                                          * # and
                                                          Xт>Ê # Check if `X` (5th item of the list) does NOT equal 101
                                                          i # If both checks above are truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ¯` # Push the item from the global array (3rd item of the list)
                                                          ë # Else:
                                                          т # Push 100 to the stack
                                                          ] # Close both if-else cases
                                                          ®3è # And push the 4th item of the list to the stack


                                                          Then we're going to built the 0s and 1s for the third digit of the output. Scenarios 1,2 use 5th+6th; scenario 3 uses '0'+3rd+6th; scenarios 4,5 use '0'+1st+6th; and scenarios 6,7,8 use '100'+6th:



                                                          Y           #  Push `Y` (check if `X` equals 111)
                                                          * # and
                                                          ¯`_ # Check if the item from the global array (3rd item of the list) is exactly 0
                                                          ~ # OR
                                                          X110Q # Check if `X` (5th item of the list) equals 110
                                                          i # If the combined check above is truthy (exactly 1):
                                                          0 # Push 0 to the stack
                                                          ®н # Push the 1st item of the list to the stack
                                                          ë # Else:
                                                          Xт›i # If `X` (5th item of the list) is larger than 100 (so 101/110/111):
                                                          Yi # If `Y` (if `X` equals 111):
                                                          т # Push 100 to the stack
                                                          ë # Else:
                                                          0 # Push 0 to the stack
                                                          ¯` # Push the item from the global array (3rd item of the list)
                                                          ë # Else:
                                                          X # Push `X` (5th item of the list) to the stack
                                                          ] # Close all if-else cases
                                                          ®θ # And push the last (6th) item of the list to the stack


                                                          Now we have all 0s and 1s on the stack, so we can convert it to the three output digits:



                                                          J     # Join the entire stack together
                                                          4ô # Split it into parts of size 4
                                                          C # Convert each part from binary to an integer (and output implicitly)






                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited 9 hours ago

























                                                          answered 10 hours ago









                                                          Kevin Cruijssen

                                                          34.6k554182




                                                          34.6k554182






















                                                              up vote
                                                              0
                                                              down vote














                                                              Jelly, 51 bytes



                                                              “¬Y-‘D¤ịȦƤS4x;“€-Y‘D¤ị$Ḅ;0,-4,5s3ḣ2SAœ?ɗ@/Ḥ+“¤©½‘ị$


                                                              Try it online!






                                                              share|improve this answer

























                                                                up vote
                                                                0
                                                                down vote














                                                                Jelly, 51 bytes



                                                                “¬Y-‘D¤ịȦƤS4x;“€-Y‘D¤ị$Ḅ;0,-4,5s3ḣ2SAœ?ɗ@/Ḥ+“¤©½‘ị$


                                                                Try it online!






                                                                share|improve this answer























                                                                  up vote
                                                                  0
                                                                  down vote










                                                                  up vote
                                                                  0
                                                                  down vote










                                                                  Jelly, 51 bytes



                                                                  “¬Y-‘D¤ịȦƤS4x;“€-Y‘D¤ị$Ḅ;0,-4,5s3ḣ2SAœ?ɗ@/Ḥ+“¤©½‘ị$


                                                                  Try it online!






                                                                  share|improve this answer













                                                                  Jelly, 51 bytes



                                                                  “¬Y-‘D¤ịȦƤS4x;“€-Y‘D¤ị$Ḅ;0,-4,5s3ḣ2SAœ?ɗ@/Ḥ+“¤©½‘ị$


                                                                  Try it online!







                                                                  share|improve this answer












                                                                  share|improve this answer



                                                                  share|improve this answer










                                                                  answered 16 mins ago









                                                                  Dennis

                                                                  185k32295732




                                                                  185k32295732






























                                                                      draft saved

                                                                      draft discarded




















































                                                                      If this is an answer to a challenge…




                                                                      • …Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.


                                                                      • …Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
                                                                        Explanations of your answer make it more interesting to read and are very much encouraged.


                                                                      • …Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.



                                                                      More generally…




                                                                      • …Please make sure to answer the question and provide sufficient detail.


                                                                      • …Avoid asking for help, clarification or responding to other answers (use comments instead).






                                                                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                                      Please pay close attention to the following guidance:


                                                                      • Please be sure to answer the question. Provide details and share your research!

                                                                      But avoid



                                                                      • Asking for help, clarification, or responding to other answers.

                                                                      • Making statements based on opinion; back them up with references or personal experience.


                                                                      To learn more, see our tips on writing great answers.




                                                                      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

                                                                      Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                                                                      ComboBox Display Member on multiple fields

                                                                      Is it possible to collect Nectar points via Trainline?