\$\begingroup\$

Ruby flavour, 75 74 bytes

Thanks to jimmy23013 for saving 1 byte.

^(?!(.{9}*(.|(.)){,8}|.*(\g<2>.{8})*|.{27}?.{3}?(\g<2>{3}.{6}){,2}.?.?)\3).

Test it here.

Now that it's finally beaten, I can share my own solution. :) I discovered an interesting (maybe new?) regex technique in the process (the (.|(.)){,8}\3 part), which would probably be unbeatable in cases where this can't be combined with other parts of the regex (as was the case in jimmy23013's answer).

Explanation

Like the other short answers I'm using a negative lookahead which searches for duplicates in rows, columns or blocks. The basic building block of the solution is this:

(.|(.))...\3

Note that the \3 is reused between three different alternatives (which all use group 3 for duplicate detection).

That group on the left (which is group 2 , containing group 3 ) is used for any position that can contain the first half of a duplicate digit (within a group that must not contain duplicate digits). Then ... is something that gets us the the next position where such a digit might occur (if necessary) and \3 tries to find the second half of the duplicate via backreference. The reason this works is backtracking. When the engine first matches (.|(.)) it will simply use . every time and not capture anything. Now the \3 at the end fails. But now the engine will gradually try using (.) instead of . for individual matches. Ultimately, if there's a duplicate, it will find the combination where (.) was last used on the first digit of the duplicate (such that the capture isn't overwritten later), and then uses some more . to bridge the gap to the backreference. If there is a duplicate, backtracking will always find it.

Let's look at the three different parts where this is used:

.{9}*(.|(.)){,8}

This checks for duplicates in some row. First we skip to any row with .{9}* . Then we match up to 8 characters (i.e. anything in that row except the last digit) using the optional duplicate capture and try to find the \3 after it.

.*(\g<2>.{8})*

This looks for duplicates in some column. First, note that \g<2> is a subroutine call, so this is the same as:

.*((.|(.)).{8})*

where the two groups we've just inserted are still referred to as 2 and 3 .

Here, the .* simply skips as far as necessary (it would be sufficient to match up to 8 characters here, but that costs more bytes). Then the outer group matches one complete row (which may wrap across two physical rows) at a time, optionally capturing the first character. The \3 will be looked for right after this, which ensures vertical alignment between the capture and the backreference.

Finally, checking the blocks:

.{27}?.{3}?(\g<2>{3}.{6}){,2}.?.?

Again, the \g<2> is a subroutine call, so this is the same as:

.{27}?.{3}?((.|(.)){3}.{6}){,2}.?.?

To verify the blocks, note that since we've already checked all the rows and columns, we only need to check four of the 3x3 blocks. When we know that all rows and columns as well as these 3x3 blocks are correct:

XX. XX. ...

Then we know that there can't possibly be duplicates in the remaining blocks. Hence I'm only checking these four blocks. Furthermore, note that we don't have to look for duplicates within the same row of a 3x3 block. It's enough to find the first half of the duplicate in one row and search for the second half in a row further down.

Now for the code itself, we first skip to the beginning of one of the four blocks with .{27}?.{3}? (optionally skip three rows, optionally skip three columns). Then we try to match up to two of the rows of the 3x3 block with the same trick we used for the rows earlier:

(.|(.)){3}.{6}

We allow but don't require capturing of any of the 3 cells in the current row of the 3x3 block and then skip to the next row with .{6} . Finally, we try to find a duplicate in either of the 3 cells of the row we end up on:

.?.?

And that's it.