# Validate Sudoku on a Mobius Strip

@BeastlyGerbil presents, the world's very first MOBIUS SUDOKU:

(The left most square backs onto the right most square, and the middle squares back onto each other. The ends are then attached as indicated.)

RULES:

• Normal sudoku rules apply for rows and boxes - boxes are split into groups of 3 indicated by the thicker lines.
• This means that each row must contain the numbers 1 - 9 without repetition.
• Columns ‘wrap around’ over the edge of the mobius strip – 6 cells per column as a result, normal sudoku rules apply on these 6 cells.
• No number will ever be orthogonally adjacent to itself, including across the thicker borders separating the sets of 3 boxes.
• There are 18 total boxes, and as a result 18 total middle cells. There are 2 of each number, 1-9, in the middle cells.

Note: If you need additional information or references for "normal" sudoku, here is a great resource.

#### 👂 Input

Your input will be a collection of integers in $$\[1,9]\$$, representing each side of a completed strip respectively. Here, collection means whatever type of collection works to meet your needs, so long as you accept a value for every square (front and back). You can use comma delimited lists, arrays, arrays of arrays, n-dimensional arrays, lists, etc. For example in C# using a comma delimited list:

4,6,1,8,5,3,7,9,2,4,8,1,3,9,7,6,5,2,6,4,2,8,1,9,5,3,7,2,7,8,4,9,1,6,5,3,6,7,5,1,4,2,9,3,8,3,8,9,7,2,5,6,1,4,9,5,3,6,2,7,4,1,8,2,9,3,5,8,6,7,1,4,5,7,1,4,6,3,9,8,2,1,9,4,2,8,5,6,3,7,1,9,2,5,7,4,6,3,8,5,7,2,9,8,1,4,3,6,5,6,2,7,3,9,8,1,4,7,6,8,3,2,9,4,5,1,6,8,1,5,4,3,2,9,7,3,7,8,1,4,6,5,9,2,3,4,5,1,6,8,9,2,7,4,3,9,6,7,2,5,8,1

Note: You must tell us how to input the data.

#### 📢 Output

Your output should represent whether or not the provided input is a valid solution using your languages truthy/falsy, with respect to this answer:

if (x) {
print "x is truthy";
}
else {
print "x is falsy";
}


If it results in a runtime or a compile-time error then x is neither truthy nor falsy.

For example in C#, when provided the above input, the expected output is:

true

#### ✔️ Test Cases

Your test inputs will represent both valid and invalid solutions to include the original puzzle's solution:

Test Case 1: 0
Test Case 2: 4,6,1,8,5,3,7,9,2,4,8,1,3,9,7,6,5,2,6,4,2,8,1,9,5,3,7,2,7,8,4,9,1,6,5,3,6,7,5,1,4,2,9,3,8,3,8,9,7,2,5,6,1,4,9,5,3,6,2,7,4,1,8,2,9,3,5,8,6,7,1,4,5,7,1,4,6,3,9,8,2,1,9,4,2,8,5,6,3,7,1,9,2,5,7,4,6,3,8,5,7,2,9,8,1,4,3,6,5,6,2,7,3,9,8,1,4,7,6,8,3,2,9,4,5,1,6,8,1,5,4,3,2,9,7,3,7,8,1,4,6,5,9,2,3,4,5,1,6,8,9,2,7,4,3,9,6,7,2,5,8,1
Test Case 3: 8,8,8,8,8,8,7,9,2,4,8,1,3,9,7,6,5,2,6,4,2,8,1,9,5,3,7,2,7,8,4,9,1,6,5,3,6,7,5,1,4,2,9,3,8,3,8,9,7,2,5,6,1,4,9,5,3,6,2,7,4,1,8,2,9,3,5,8,6,7,1,4,5,7,1,4,6,3,9,8,2,1,9,4,2,8,5,6,3,7,1,9,2,5,7,4,6,3,8,5,7,2,9,8,1,4,3,6,5,6,2,7,3,9,8,1,4,7,6,8,3,2,9,4,5,1,6,8,1,5,4,3,2,9,7,3,7,8,1,4,6,5,9,2,3,4,5,1,6,8,9,2,7,4,3,9,6,7,2,5,8,1

Your outputs should be (again, in C# for example):

Test Case 1: false
Test Case 2: true
Test Case 3: false

Here's a screenshot of the solved grid for reference:

#### 🏅 Scoring

This is so smallest solution in bytes wins.

#### 📝 Final Note

This challenge is inspired by this puzzle crafted by @BeastlyGerbil. If you like this challenge, go show some love for the original puzzle too!

• You might want to clarify what is meant by "rows" in "Normal sudoku rules apply for rows", since it is not immediately apparent. Sep 27 at 17:13
• @WheatWizard added a nested bullet and a subscript note containing a link to "normal" sudoku rules. Does that help? Sep 27 at 17:22
• That's good but my actual concern was what "row" meant. Here it seems to mean nine cells between two extra thick bars, whereas is common speech it usually just means any horizontal line of cells. Sep 27 at 17:55
• We need a challenge for solving Mobius strip sudoku puzzles! Sep 27 at 19:10
• Could you add some more truthy test cases, as well as some test cases which are correct for the 3x3 blocks; 1x9 'rows' and 6x1 Mobius columns, but incorrect for one of the two two rules: i.e. two of the same adjacent numbers with a thick border between them; or where the 18 middle cells aren't containing the 1-9 numbers twice each. Sep 28 at 13:35

# 05AB1E, 54 47 bytes

3δôø˜©‚˜9ôI2äí«ø«D€ÙQIÂí‚øε˜Ć}D€ÔQ®9ô€Ås9L¢<PP


Takes the input as a 6x27 matrix, kinda like the reference screenshot of the grid.
Outputs 1 for truthy, or another integer (usually 0) as falsey.

Explanation:

Step 1: Transform the input-matrix to a (flattened) list of blocks:

 δ          # Map over each row of the (implicit) input-matrix
3 ô         #  Split the inner list into parts of size 3
ø        # Zip/transpose this matrix; swapping rows/columns
˜       # Flatten it
©      # Store this list in variable ® (without popping)


Step 2: Pair it with the flattened input and split both the 'rows' and blocks into parts of size 9:

      ‚     # Pair it together with the (implicit) input-matrix
˜    # Flatten it to a list of integers
9ô  # Split it into parts of size 9


Step 3: Get all Mobius columns, and merge those to the same list:

I           # Push the input-matrix again
2ä         # Split it into 2 equal-sized parts
# Pop and push both separated to the stack
í       # Reverse each inner list of the second matrix
«      # Merge the two lists back together again
ø     # Zip/transpose this matrix; swapping rows/columns
«    # Merge it to the earlier list of nonets
# (We now have a list of all 'rows'; all blocks; and all Mobius columns)


Step 4: Check for each 'row', block, and Mobius column that they only contain unique digits:

D           # Duplicate the list of lists
€Ù         # Uniquify each inner list
Q        # Check that it's still equal to the list of lists


Step 5: Connect the Mobius rows as shown by the colors in the challenge description, including wrap-around:

I           # Push the input-matrix again
Â          # Bifurcate it, short for Duplicate & Reverse copy
í         # Reverse each inner row of this reversed copy as well
‚        # Pair it with the input-matrix
ø       # Zip/transpose; creating pairs of the rows of the two matrices
ε      # Map over the pair of lists:
˜     #  Flatten it to a single connected row
Ć    #  Enclose it, appending its own first item
}      # Close the map


Step 6: Check that these connected Mobius rows doesn't contain any adjacent pair of digits that are the same:

      D     # Duplicate it
€Ô   # Connected-uniquify each inner list in this duplicate
Q  # Check if both matrices are still the same


Step 7: Check if the center cells of each block all combined contain each positive digit twice:

®           # Push the list of variable ®
9ô         # Split it into parts of size 9 to get a list of blocks
€Ås      # Only leave the center cell value for each block-list
9L¢   # Count for each value in [1,2,3,4,5,6,7,8,9] how many time it occurs in
# this list of block center cells
<  # Decrease each by 1
P # Take the product of this list (1 if all counts were 2;
# another integer (0, negative, or positive) if a count wasn't 2)


Step 8: Check if everything combined is truthy, and output the result:

P           # Check if the three are truthy by taking the product on the stack
# (after which the result is output implicitly)


See this for a step-by-step of the input to the output.

• Are "No number will ever be orthogonally adjacent to itself, including across the thicker borders separating the sets of 3 boxes." and "There are 18 total boxes, and as a result 18 total middle cells. There are 2 of each number, 1-9, in the middle cells." somehow redundant or does this check them in some way I haven't noticed? Sep 28 at 13:27
• @JonathanAllan Should be fixed now. I've also asked OP for some additional test cases. Sep 28 at 14:25
• Your connected uniquify check neglects the cells that become adjacent when the strip is connected into a loop. Sep 28 at 14:48
• @JonathanAllan Ugh.. Fixed again, thanks. Sep 28 at 15:37
• You're now only checking half of those connections - your "connected Mobius rows of the input-matrix" would need the first digit appended to the end of each (or have each be repeated if golfier). Sep 28 at 16:28

# Jelly, 44 bytes

s€3;"3/Ẏ;;ZFs9ƲQ€ƑȧZṙ3;"Ɗ;"IƲȦȧḊm3FƊ⁺ĠƊṁ€Ƒ2


A monadic Link that accepts a list of twenty-seven length six lists of integers that yields 1 if valid or 0 if not.

The input is a list of the twenty-seven columns starting with one adjacent to a bold border and reading around the strip, where each column reads in the same order as every other such that it starts at one edge of the Mobius-strip then reads one side followed by the other with wrapping (at the other edge of the Mobius-strip).

Try it online!

### How?

It's a long chain so I'll break it down...

s€3;"3/Ẏ;;ZFs9ƲQ€Ƒ - are all nonets, columns, and rows distinct sets?: columns
s€3                - split each column into threes
3/            - three-wise reduce by:
;"              -   zipped concatenation
Ẏ           - tighten -> the eighteen nonets
;          - concatenate with the twenty-seven columns
Ʋ    - last four links as a monad, f(columns):
Z        -   transpose
F       -   flatten
9     -   nine
s      -   split (flatten result) into slices of lenth (9)
-> the eighteen rows
;         - (nonets & columns) concatenate (rows)
Q€Ƒ - is invariant under deduplicate-each?
-> 1 if all nonets, columns, and rows are distinct sets
else 0

ȧZṙ3;"Ɗ;"IƲȦ - ...and there are no adjacent cells which are equal?
(note that the distinct sets check performed earlier automatically
checked rows & columns. Rows get checked again here as it is golfier)
Ʋ  - last four links as a monad, f(columns):
Z            -   transpose -> the six half-Mobius-strip-rows on the "front" and "back"
Ɗ       -   last three links as a monad, f(half-Mobius-strip-rows):
3          -     three
ṙ           -     rotate (half-Mobius-strip-rows) left by (3)
;"        -     zipped concatenation -> full-Mobius-strip-rows
;"    -   zipped concatenation with itself (to cater for row-wise wrapping)
I   -   incremental differences ([b-a, c-b, ...] for each)
ȧ             - (current check result) logial AND (that)
Ȧ - non-empty and contains no 0 when flattened?
-> 1 if all nonets, columns, and rows are distinct sets
AND no adjacent cells are equal
else 0

ȧḊm3FƊ⁺ĠƊ - ...if so get the middles of all nonets grouped by values, otherwise 0
Ɗ - last three links as a monad, f(columns):
Ɗ    -   last three links as a monad, g(columns):
Ḋ        -     dequeue
m3      -     modulo-3 slice
F     -     flatten
⁺   -   repeat -> g(that result) -> middles of all nonets
Ġ  -   group indices by value
ȧ         - (current check result) logial AND (that)
-> those groups if all nonets, columns, and rows are distinct sets
AND no adjacent cells are equal
else 0

ṁ€Ƒ2 - ...and the groups (or the 0 we have instead) are all length 2?
Ƒ  - is invariant under:
ṁ€ 2 -   mould each like [1,2]
-> 1 if a valid fill of an empty Mobius-strip-Sudoku
else 0
`