15
\$\begingroup\$

You've been called to implement an image detection routine for the ASCII dice roller. Write a program or function so that each time two ASCII dice are rolled, you return the total value shown. To make things trickier, sometimes defective ASCII dice get into the system which have the spots in the wrong positions. That's a possible indicator of fraud, so we need to call a supervisor if that happens.

Input

Lines of text (array of arrays, single string with newlines, stdin, etc) representing two dice side by side in this format:

 ---   ---
|o o| |o  |
|o o| |   |
|o o| |  o|
 ---   ---

Each die is 5x5 characters, with 3 - on the top and bottom, 3 | on each side, and spaces in the corners and filling the middle. The spots are o characters. There is one space between the two dice.

Each die may be rotated. (This only visibly affects the 6, 2 and 3.)

You can assume the structure of the two dice (the | and - and spaces) is correct, and that each face will contain only spaces and o. There may be any number of spots on each face from 0 to 9.

The correct layouts of spots on each die face are as follows:

 ---
|o o|
|o o|
|o o|
 ---
 ---
|ooo|
|   |
|ooo|
 ---
 ---
|o o|
| o |
|o o|
 ---
 ---
|o o|
|   |
|o o|
 ---
 ---
|o  |
| o |
|  o|
 ---
 ---
|  o|
| o |
|o  |
 ---
 ---
|o  |
|   |
|  o|
 ---
 ---
|  o|
|   |
|o  |
 ---
 ---
|   |
| o |
|   |
 ---

Output

If the spots on both faces matches a correct layout (including rotations), return the sum of the two values (8 in the example above). Otherwise, return anything other than a number between 2 and 12. It is acceptable for your program to throw an exception or crash (but not hang) or produce no output in this case.

Scoring

Code golf. Standard rules apply.

Sample data

 ---   ---
|  o| |o  |
|   | |   |
|o  | |  o|
 ---   ---
=> 4

 ---   ---
| o | |o  |
|   | |   |
| o | |  o|
 ---   ---
=> 0

 ---   ---
|o o| |   |
| o | | o |
|o o| |   |
 ---   ---
=> 6

 ---   ---
|  o| |   |
| o | | o |
|o o| |   |
 ---   ---
=> 0

 ---   ---
|   | |   |
|   | | o |
|   | |   |
 ---   ---
=> 0

 ---   ---
|ooo| |o  |
|   | | o |
|ooo| |  o|
 ---   ---
=> 9


 ---   ---
|o o| |  o|
| o | | o |
|o o| |o  |
 ---   ---
=> 8


 ---   ---
|ooo| |o  |
|   | | o |
|o o| |  o|
 ---   ---
=> 0

\$\endgroup\$
5
  • \$\begingroup\$ Too a combination of two questions \$\endgroup\$
    – l4m2
    Commented May 16 at 1:05
  • 7
    \$\begingroup\$ The reason it incorporates validation is because otherwise it's trivial to count the number of spots. \$\endgroup\$ Commented May 16 at 3:31
  • 1
    \$\begingroup\$ Related. \$\endgroup\$
    – Arnauld
    Commented May 16 at 5:38
  • \$\begingroup\$ Can we take input padded so each line is the same length? \$\endgroup\$
    – Jordan
    Commented May 16 at 17:53
  • \$\begingroup\$ Yep, sure. Didn't mean to make them different. \$\endgroup\$ Commented May 17 at 13:14

13 Answers 13

5
\$\begingroup\$

JavaScript (Node.js), 108 bytes

a=>(g=p=>[12,1,y=11,13].every(k=>(s+=e=a[p+k]+2^2||y%11%k)<7&&a[y+=e*k,p-k]+2^e,s=a[p]+1^1)*s||+g)(25)+g(31)

Try it online!

a=>(
    g=p=>
    [12,1,y=11,13].every(
        k=>(
            s+=e=         // 'o'+2^2 = 'o2'^2 = NaN^2 = 2
            a[p+k]+2^2    // ' '+2^2 = ' 2'^2 =   2^2 = 0
            ||y%11%k      // If any empty on corner,
        )<7&&             // then all empty on edge
        a[y+=e*k          // @k=12 y%11=0; y%11+=e
                          // @k=1 y%11%k=0; y%11+=e
                          // @k=11 y%11 shows; y%11+=0
                          // @k=13 y%11 shows; y%11+=whatever
        ,p-k]+2^e         // Besides, it needs center symmetry
        ,s=a[p]+1^1       // Initial value
    )*s||+g               // If failed test or zero, NaNify
)(25)+g(31)               // Two centers
\$\endgroup\$
1
  • \$\begingroup\$ +g => $ that crash on invalid, I'd leave NaN so easier tested \$\endgroup\$
    – l4m2
    Commented May 17 at 6:06
3
\$\begingroup\$

Charcoal, 50 bytes

F2?υ??ηζε?Φκ??ι÷?ν3I∧?υ№I?”)″GG0G¤E-??^≦”3?ι o№Συo

Try it online! Link is to verbose version of code. Explanation:

F2?υ??ηζε?Φκ??ι÷?ν3

Extract the pips from the dice.

I∧?υ№I?...3?ι o№Συo

Interpret the pips as binary, check that both results exist in a list of possible pip patterns, and if so output the total count of pips.

\$\endgroup\$
3
\$\begingroup\$

Python3, 323 bytes

lambda b:all(K:=[V(t)for t in zip(*[[[*map(int,j.replace(' ','0').replace('o','1'))]for j in re.findall('[o ]{3}',k)]for k in b.split('\n')[1:-1]])])and sum(K)
import re
V=lambda b:sum(L:=[sum(j)for j in zip(*b)])*((not(Y:=sum(L))%2 or b[1][1])and(Y<2 or(any(b[0])and any(b[2])))and L==L[::-1]and(L[1]<=L[2]or Y==1)and Y<7)

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think that this is incorrect. \$\endgroup\$ Commented May 16 at 11:47
  • \$\begingroup\$ 307 bytes \$\endgroup\$
    – ceilingcat
    Commented May 16 at 17:26
3
\$\begingroup\$

Jelly, 34 bytes

?”|O??m2??F?e“?4???4?eZ‘?¤??§§??2S

A monadic Link that accepts a list of characters (including the newline characters) and yields the count of pips if valid, otherwise 0.

Try it online! Or see the test-suite.

How?

?”|O??m2??F?e“...‘?¤??§§??2S - Link: list of characters, Dice
?”|                          - split at '|' characters
   O                         - ordinals
    ?                        - mod two -> 'o' -> 1, ' ' -> 0 (others, don't care)
     ?                       - dequeue
      m2                     - every other element
        ??                   - split into odd and even indexed elements
                    ??       - keep those for which:
          F                  -   flatten
           ?                 -   convert from binary -> ID
                   ¤         -   nilad followed by link(s) as a nilad:
             “...‘           -     code-page indices -> [16,52,16,173,16,52,16,24,90]
                  ?          -     cumulative sums -> [16,68,84,257,273,325,341,365,455]
            e                -   {ID} exists in {that}?
                      §      - sums
                       §     - sums -> Pip-counts of valid dice
                        ?    - cumulative sums
                         ?2  - tail from 1-index two
                                -> [sum(Pip-count)] if both valid, [] otherwise
                           S - sum -> sum(Pip-count) if both valid, zero otherwise
\$\endgroup\$
3
\$\begingroup\$

Ruby, 120 bytes

-11 bytes thanks to Value Ink

Takes an array of arrays of characters as input. Raises an error on invalid inputs.

->a{b=a[1,3].transpose
[1,7].sum{[16,p,68,257,84,273,325,p,341,p,365,455].index(b[_1,3].join.tr(" o","01").to_i 2)/2+1}}

Attempt This Online!

\$\endgroup\$
6
  • \$\begingroup\$ What do you mean about padded input? \$\endgroup\$ Commented May 16 at 22:59
  • \$\begingroup\$ @SteveBennett In your example input the first and last lines are shorter than the rest. I asked above if it’s okay to pad them with spaces. It’s no longer relevant for my solution, though. \$\endgroup\$
    – Jordan
    Commented May 16 at 23:42
  • 1
    \$\begingroup\$ I got -6 bytes by replacing the hash with fetching the index of an array: [16,p,68,257,84,273,325,p,341,p,365,455].index(_1.join.tr(" o","01").to_i 2)/2+1 \$\endgroup\$
    – Value Ink
    Commented May 22 at 0:18
  • \$\begingroup\$ @ValueInk Nice work. Thanks! \$\endgroup\$
    – Jordan
    Commented May 22 at 0:39
  • \$\begingroup\$ One more save I just thought of for -5. Ruby, 120 bytes: [1,7].sum{[...].index(b[_1,3].join \$\endgroup\$
    – Value Ink
    Commented May 22 at 4:16
2
\$\begingroup\$

APL+WIN, 89 bytes

Prompts for a 5x11 matrix of the two dice. Outputs the two dice together with the sum of the spots for qualifying dice or zero.

d←??d?r←3⊥j←+?(5 ˉ5↑d)='o'?l←3⊥i←+?(5 5↑d)='o'?(+/i,j)×2=+/8>¨(?9 30 39 60 69 78 90)?¨r l

Try it online! Thanks to Dyalog Classic

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

J, 97 bytes

[:(*@*/*1#.,@#:)365 455 341 325 273 81 257 68 16([+/@:*=/)[:(_9#.\'o'=[:,3}.@|.])@|:'|'-."1~}.@}:

Try it online!

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

Python, 115 bytes

lambda s:all('o'in(r:=(4*s)[k:~9:12])>r[1]<r[2:]>r[5]<r==r[::-1]!='  'in r[6::5]+r[5:7]for k in b'HN')*s.count('o')

Attempt This Online!

Python, 116 bytes

lambda s:all('o'in(r:=(3*s)[k:~9:12])>r[1]<r[2:]>r[5]<r==r[::-1]!='  'in r[6::5]+r[5:7]for k in(13,19))*s.count('o')

Attempt This Online!

Python, 119 bytes

lambda s:all('o'in(r:=(3*s[13:48])[k::12])>r[3]<r[2:]>r[1]<r==r[::-1]!='  'in r[4::3]+r[3:5]for k in(0,6))*s.count('o')

Attempt This Online!

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

05AB1E, 43 bytes

3L12*2Yδ+?D6+?èeêDJCU?O?G?=?Zb°7(ú??AвX?P*

Input as a multi-line string.

Try it online or verify all test cases.

Explanation:

3L              # Push list [1,2,3]
  12*           # Multiply each by 12: [12,24,36]
     2Y         # Push list [0,1,2]
       δ        # Apply double-vectorized on both lists:
        +       #  Add them together
         ?      # Flatten this list of lists: [12,13,14,24,25,26,36,37,38]
D               # Duplicate this list
 6+             # Add 6 to each: [18,19,20,30,31,32,42,43,44]
?               # Pair the two lists together
 è              # Get the characters at those indices in the (implicit) input-string
  eê            # != " " on each character (0 if " "; 1 if "o")
D               # Duplicate this pair of bit-lists
 J              # Join the inner lists together in the copy
  C             # Convert from binary-strings to base-10 integers
   U            # Pop and store this pair of integers into variable `X`
 ?              # Flatten the pair of bit-lists
  O             # Sum all together
   ?G?=?Zb°7(ú? # Push compressed integer 76186575295082998979527
     ?Aв        # Convert it to base-512 as list: [16,68,84,257,273,325,341,365,455]
        X       # Push pair `X`
         ?P     # Check that both values of `X` are in this list
           *    # Multiply that check to the earlier sum
                # (after which the result is output implicitly)

See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why ?G?=?Zb°7(ú? is 76186575295082998979527 and ?G?=?Zb°7(ú??Aв is [16,68,84,257,273,325,341,365,455].

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

Python3, 177 133 bytes

Updated answer upon realizing the problem states it is acceptable to raise an Exception in the invalid format case.

lambda s:sum({365:6,455:6,341:5,325:4,273:3,84:3,257:2,68:2,16:1}[sum(ord(s[44-i%3-i//3*12-z])%2<<i for i in range(9))]for z in[0,6])

Try it online!

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

Scooberty-Doo, 136 bytes

?”??4??????2???4e“?4??????“4?eZ???4341 325 [:,3}.27‘[:,??}?4¤??§§??2№?S??4f??43I∧υ?4??4;

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Welcome to Code Golf! Your TIO link leads to commata, which doesn't have a ? command, so it fails. are you able to link an interpreter for your language? \$\endgroup\$ Commented May 16 at 22:11
1
\$\begingroup\$

Maple, 190 bytes

proc(s)r:=$13..15;L:=[r,r+~12,r+~24];S:=subs("o"=1," "=0,[[seq(s[i],i=L)],[seq(s[i],i=L+~6)]]);`if`({(op@convert)~(S,base,2,512)[]}subset{365,455,341,325,273,84,257,68,16},add(op~(S)),0)end:

Slightly ungolfed:

f:=proc(s)
T:={365,455,341,325,273,84,257,68,16}; # coded valid faces
r:=$13..15;                            # generate ...
L:=[r,r+~12,r+~24];                    # positions of first die
S:=subs("o"=1," "=0,[[seq(s[i],i=L)],[seq(s[i],i=L+~6)]]);  # both dice as list of lists of 0s and 1s
`if`({(op@convert)~(S,base,2,512)[]}subset T,add(op~(S)),0) # check valid and add or return 0
end;

Acceptable faces are coded as bit patterns converted to decimal. The locations in the string with the 9 characters of each dice are extracted and converted to a list of lists of 0s and 1s. They are converted to decimal to check validity, and if valid are added; otherwise 0 is returned.

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

Perl 5 -p0, 104 bytes

map{($i++%2?$l:$r).=oct"0b".y/o /10/r}/...\|/g;$_=(2==grep/$l|$r/,707,555,525,505,421,124,401,104)*y/o//

Try it online!

\$\endgroup\$

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.