Rotation invariant fingerprinting
Imagine we have some polyomino and would like to uniquely identify them, however the polyominos can be rotated, so blindly hashing them won't give us the same fingerprint for a piece and a rotation thereof (in general).
For example if we have the L-tetromino
x
x
xx
we would like it to have the same fingerprint as any of these:
xx
x x xxx
xxx , x or x
Note: We only allow rotations on the plane (ie. they are one-sided polyominos) and therefore the following polyomino would be a different one:
x
x
xx
Challenge
The task for this challenge is to implement a fingerprinting-function/program which takes an $mtimes n$ Boolean/$0,1$-valued matrix/list of lists/string/.. encoding a polyomino and returns a string - the fingerprint of a polyomino. The fingerprint must be equal for all of the possible rotations (in general 4).
Input / Output
$m geq 1$ and $n geq 1$ (ie. no empty polyomino)- you're guaranteed that $m,n$ are as small as possible (ie. all $0$ are trimmed to fit $m$ and $n$
- you're guaranteed that the input is
- simply connected
- has no holes
- output must be a string which is the same for each possible rotation of a polyomino
Examples
Here are some equivalence classes, for each class the fingerprint must be the same & for any two polyominos from two distinct classes they must differ.
The rotations of the L-tetromino from the example:
[[1,0],[1,0],[1,1]]
[[0,0,1],[1,1,1]]
[[1,1],[0,1],[0,1]]
[[1,1,1],[1,0,0]]
The J-tetromino:
[[0,1],[0,1],[1,1]]
[[1,1,1],[0,0,1]]
[[1,1],[1,0],[1,0]]
[[1,0,0],[1,1,1]]
The unit polyomino:
[[1]]
A $5times 1$ bar:
[[1,1,1,1,1]]
[[1],[1],[1],[1],[1]]
A $2times 2$ corner:
[[1,1],[1,0]]
[[1,0],[1,1]]
[[0,1],[1,1]]
[[1,1],[0,1]]
W-pentomino:
[[1,0,0],[1,1,0],[0,1,1]]
[[0,0,1],[0,1,1],[1,1,0]]
[[1,1,0],[0,1,1],[0,0,1]]
[[0,1,1],[1,1,0],[1,0,0]]
code-golf array-manipulation hashing polyomino
add a comment |
Imagine we have some polyomino and would like to uniquely identify them, however the polyominos can be rotated, so blindly hashing them won't give us the same fingerprint for a piece and a rotation thereof (in general).
For example if we have the L-tetromino
x
x
xx
we would like it to have the same fingerprint as any of these:
xx
x x xxx
xxx , x or x
Note: We only allow rotations on the plane (ie. they are one-sided polyominos) and therefore the following polyomino would be a different one:
x
x
xx
Challenge
The task for this challenge is to implement a fingerprinting-function/program which takes an $mtimes n$ Boolean/$0,1$-valued matrix/list of lists/string/.. encoding a polyomino and returns a string - the fingerprint of a polyomino. The fingerprint must be equal for all of the possible rotations (in general 4).
Input / Output
$m geq 1$ and $n geq 1$ (ie. no empty polyomino)- you're guaranteed that $m,n$ are as small as possible (ie. all $0$ are trimmed to fit $m$ and $n$
- you're guaranteed that the input is
- simply connected
- has no holes
- output must be a string which is the same for each possible rotation of a polyomino
Examples
Here are some equivalence classes, for each class the fingerprint must be the same & for any two polyominos from two distinct classes they must differ.
The rotations of the L-tetromino from the example:
[[1,0],[1,0],[1,1]]
[[0,0,1],[1,1,1]]
[[1,1],[0,1],[0,1]]
[[1,1,1],[1,0,0]]
The J-tetromino:
[[0,1],[0,1],[1,1]]
[[1,1,1],[0,0,1]]
[[1,1],[1,0],[1,0]]
[[1,0,0],[1,1,1]]
The unit polyomino:
[[1]]
A $5times 1$ bar:
[[1,1,1,1,1]]
[[1],[1],[1],[1],[1]]
A $2times 2$ corner:
[[1,1],[1,0]]
[[1,0],[1,1]]
[[0,1],[1,1]]
[[1,1],[0,1]]
W-pentomino:
[[1,0,0],[1,1,0],[0,1,1]]
[[0,0,1],[0,1,1],[1,1,0]]
[[1,1,0],[0,1,1],[0,0,1]]
[[0,1,1],[1,1,0],[1,0,0]]
code-golf array-manipulation hashing polyomino
Related.
– BMO
Dec 16 '18 at 17:20
If I always output""
(the empty string), have I satisfied all the requirements?
– Daniel Wagner
Dec 17 '18 at 12:13
@DanielWagner: "[..] for any two polyominos from two distinct classes [the fingerprints] must differ" - so no, that would be invalid.
– BMO
Dec 17 '18 at 14:59
Is outputting all possible rotations of an array, consistently sorted valid? Example
– Shaggy
Dec 17 '18 at 17:12
1
@Shaggy: Yes, that would meet all the criteria.
– BMO
Dec 17 '18 at 17:15
add a comment |
Imagine we have some polyomino and would like to uniquely identify them, however the polyominos can be rotated, so blindly hashing them won't give us the same fingerprint for a piece and a rotation thereof (in general).
For example if we have the L-tetromino
x
x
xx
we would like it to have the same fingerprint as any of these:
xx
x x xxx
xxx , x or x
Note: We only allow rotations on the plane (ie. they are one-sided polyominos) and therefore the following polyomino would be a different one:
x
x
xx
Challenge
The task for this challenge is to implement a fingerprinting-function/program which takes an $mtimes n$ Boolean/$0,1$-valued matrix/list of lists/string/.. encoding a polyomino and returns a string - the fingerprint of a polyomino. The fingerprint must be equal for all of the possible rotations (in general 4).
Input / Output
$m geq 1$ and $n geq 1$ (ie. no empty polyomino)- you're guaranteed that $m,n$ are as small as possible (ie. all $0$ are trimmed to fit $m$ and $n$
- you're guaranteed that the input is
- simply connected
- has no holes
- output must be a string which is the same for each possible rotation of a polyomino
Examples
Here are some equivalence classes, for each class the fingerprint must be the same & for any two polyominos from two distinct classes they must differ.
The rotations of the L-tetromino from the example:
[[1,0],[1,0],[1,1]]
[[0,0,1],[1,1,1]]
[[1,1],[0,1],[0,1]]
[[1,1,1],[1,0,0]]
The J-tetromino:
[[0,1],[0,1],[1,1]]
[[1,1,1],[0,0,1]]
[[1,1],[1,0],[1,0]]
[[1,0,0],[1,1,1]]
The unit polyomino:
[[1]]
A $5times 1$ bar:
[[1,1,1,1,1]]
[[1],[1],[1],[1],[1]]
A $2times 2$ corner:
[[1,1],[1,0]]
[[1,0],[1,1]]
[[0,1],[1,1]]
[[1,1],[0,1]]
W-pentomino:
[[1,0,0],[1,1,0],[0,1,1]]
[[0,0,1],[0,1,1],[1,1,0]]
[[1,1,0],[0,1,1],[0,0,1]]
[[0,1,1],[1,1,0],[1,0,0]]
code-golf array-manipulation hashing polyomino
Imagine we have some polyomino and would like to uniquely identify them, however the polyominos can be rotated, so blindly hashing them won't give us the same fingerprint for a piece and a rotation thereof (in general).
For example if we have the L-tetromino
x
x
xx
we would like it to have the same fingerprint as any of these:
xx
x x xxx
xxx , x or x
Note: We only allow rotations on the plane (ie. they are one-sided polyominos) and therefore the following polyomino would be a different one:
x
x
xx
Challenge
The task for this challenge is to implement a fingerprinting-function/program which takes an $mtimes n$ Boolean/$0,1$-valued matrix/list of lists/string/.. encoding a polyomino and returns a string - the fingerprint of a polyomino. The fingerprint must be equal for all of the possible rotations (in general 4).
Input / Output
$m geq 1$ and $n geq 1$ (ie. no empty polyomino)- you're guaranteed that $m,n$ are as small as possible (ie. all $0$ are trimmed to fit $m$ and $n$
- you're guaranteed that the input is
- simply connected
- has no holes
- output must be a string which is the same for each possible rotation of a polyomino
Examples
Here are some equivalence classes, for each class the fingerprint must be the same & for any two polyominos from two distinct classes they must differ.
The rotations of the L-tetromino from the example:
[[1,0],[1,0],[1,1]]
[[0,0,1],[1,1,1]]
[[1,1],[0,1],[0,1]]
[[1,1,1],[1,0,0]]
The J-tetromino:
[[0,1],[0,1],[1,1]]
[[1,1,1],[0,0,1]]
[[1,1],[1,0],[1,0]]
[[1,0,0],[1,1,1]]
The unit polyomino:
[[1]]
A $5times 1$ bar:
[[1,1,1,1,1]]
[[1],[1],[1],[1],[1]]
A $2times 2$ corner:
[[1,1],[1,0]]
[[1,0],[1,1]]
[[0,1],[1,1]]
[[1,1],[0,1]]
W-pentomino:
[[1,0,0],[1,1,0],[0,1,1]]
[[0,0,1],[0,1,1],[1,1,0]]
[[1,1,0],[0,1,1],[0,0,1]]
[[0,1,1],[1,1,0],[1,0,0]]
code-golf array-manipulation hashing polyomino
code-golf array-manipulation hashing polyomino
asked Dec 16 '18 at 17:20
BMOBMO
11.7k22188
11.7k22188
Related.
– BMO
Dec 16 '18 at 17:20
If I always output""
(the empty string), have I satisfied all the requirements?
– Daniel Wagner
Dec 17 '18 at 12:13
@DanielWagner: "[..] for any two polyominos from two distinct classes [the fingerprints] must differ" - so no, that would be invalid.
– BMO
Dec 17 '18 at 14:59
Is outputting all possible rotations of an array, consistently sorted valid? Example
– Shaggy
Dec 17 '18 at 17:12
1
@Shaggy: Yes, that would meet all the criteria.
– BMO
Dec 17 '18 at 17:15
add a comment |
Related.
– BMO
Dec 16 '18 at 17:20
If I always output""
(the empty string), have I satisfied all the requirements?
– Daniel Wagner
Dec 17 '18 at 12:13
@DanielWagner: "[..] for any two polyominos from two distinct classes [the fingerprints] must differ" - so no, that would be invalid.
– BMO
Dec 17 '18 at 14:59
Is outputting all possible rotations of an array, consistently sorted valid? Example
– Shaggy
Dec 17 '18 at 17:12
1
@Shaggy: Yes, that would meet all the criteria.
– BMO
Dec 17 '18 at 17:15
Related.
– BMO
Dec 16 '18 at 17:20
Related.
– BMO
Dec 16 '18 at 17:20
If I always output
""
(the empty string), have I satisfied all the requirements?– Daniel Wagner
Dec 17 '18 at 12:13
If I always output
""
(the empty string), have I satisfied all the requirements?– Daniel Wagner
Dec 17 '18 at 12:13
@DanielWagner: "[..] for any two polyominos from two distinct classes [the fingerprints] must differ" - so no, that would be invalid.
– BMO
Dec 17 '18 at 14:59
@DanielWagner: "[..] for any two polyominos from two distinct classes [the fingerprints] must differ" - so no, that would be invalid.
– BMO
Dec 17 '18 at 14:59
Is outputting all possible rotations of an array, consistently sorted valid? Example
– Shaggy
Dec 17 '18 at 17:12
Is outputting all possible rotations of an array, consistently sorted valid? Example
– Shaggy
Dec 17 '18 at 17:12
1
1
@Shaggy: Yes, that would meet all the criteria.
– BMO
Dec 17 '18 at 17:15
@Shaggy: Yes, that would meet all the criteria.
– BMO
Dec 17 '18 at 17:15
add a comment |
8 Answers
8
active
oldest
votes
Python 2, 48 bytes
f=lambda l,z=5:z and max(l,f(zip(*l)[::-1],z-1))
Try it online!
Takes the largest of the four rotations in terms of list comparison. Based on FlipTack's solution.
The code uses Python 2's ability to compare objects of different types. The base case value of 0
is harmless for max
because it's smaller than any list. Also, zip
produces a list of tuples while the input is a list of lists, but tuples are bigger than lists so the input list-of-lists is never a contender. This is why we rotate 5 times rather than 4, so that we get back to a tuplified version of the initial list. (Taking a list of tuples would also work, if that's an allowed form of input.)
add a comment |
Python 3, 63 bytes
def f(m):M=;exec("m=[*zip(*m[::-1])];M+=m,;"*4);return min(M)
Try it online!
Finds the rotation with the lexographical minimum, and prints that.
A lambda form comes in at the same byte count:
lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M[-4:])
Try it online!
Rewriting as alambda
can get you to 58.lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)
. Works becauseexec
always returnsNone
.
– nedla2004
Dec 16 '18 at 17:54
@nedla2004 That can only be run once, and then gets dodgy asM
is already populated...
– FlipTack
Dec 16 '18 at 17:55
@nedla2004 ... but accounting for the problem withM[-4:]
can get you to the same byte count.
– FlipTack
Dec 16 '18 at 18:10
I see, the test I was using was just checking inputs with the same "hash", so I never ran into that. That makes sense.
– nedla2004
Dec 16 '18 at 18:11
add a comment |
Jelly, 5 bytes
ZU$ƬṂ
Try it online!
Full program.
Simply generates all possible rotations and picks the lexicographical minimum.
Note that singleton lists aren't wrapped in in the output. That doesn't matter, since the only case where singleton lists would exist in the input would be a vertical line (including the unit polyomino), which is the same as a horizontal line with the same size (where the ones aren't wrapped). The only case where the outer
will not exist either is the unit polyomino.
when i read the challenge i knew this would happen :)
– ngn
Dec 16 '18 at 18:18
add a comment |
Clean, 136 bytes
import StdEnv,Data.List
r=reverse;t=transpose;f=flatten
$l=[if((a==b)==(c==d))'x''X'\a<-f l&b<-f(r(map r l))&c<-f(r(t l))&d<-f(t(r l))]
Try it online!
Includes test verifier.
add a comment |
K (ngn/k), 16 bytes
{a@*<a:3{+|x}x}
Try it online!
min of rotations
{
}
function with argument x
{+|x}
rotate, i.e. reverse (|
) and transpose (+
)
3{
}
apply 3 times preserving intermediate results; this returns a list of the 4 rotations
a:
assign to a
<
ascend (compute the sort-ascending permutation)
*
first
a@
index a
with that
add a comment |
Japt -g
, 6 bytes
4Æ=zÃñ
Try it
:Implicit input of 2d-array U
4Æ :Map the range [0,4)
z : Rotate U 90 degrees
= : Reassign to U
à :End map
ñ :Sort
:Implicit output of first element
Is the-g
flag necessary? Sort should mean that all initial rotations end up with the same list so that full list should work fine as the fingerprint unless I'm missing something.
– Kamil Drakari
Dec 17 '18 at 15:58
@KamilDrakari, you could well be right - like I said, I'm not sure I fully understood the challenge. No harm leaving it in, though, it's not costing any bytes.
– Shaggy
Dec 17 '18 at 17:11
@KamilDrakari: It is not necessary, but it's no harm either as it's not counted towards the bytecount.
– BMO
Dec 17 '18 at 17:17
add a comment |
J, 16 bytes
-2 bytes thanks to Shaggy
[:/:~|.@|:^:(<4)
Try it online!
J, 18 bytes
0{[:/:~|.@|:^:(<4)
Try it online!
Returns the first item in the list of the lexicograpically sorted rotations of the polyomino.
Explanation:
^:(<4) - do the verb on the left 4 times, storing all the steps
|.@|: - tranpose and reverse
/:~ - sort up the 4 matrices
[: - cap the fork
0{ - take the first matrix
@Shaggy Thanks!
– Galen Ivanov
Dec 17 '18 at 18:02
add a comment |
05AB1E, 10 8 bytes
3FÂø})Σ˜
-2 bytes thanks to @Shaggy.
Try it online or verify all test cases.
Explanation:
3F } # Loop 3 times
 # Bifurcate (short for Duplicate & Reverse) the top of the stack
# (which is the input-matrix implicitly the first iteration)
ø # Transpose: swap rows/columns
) # After the loop, wrap everything on the stack in a list
Σ˜ # Sort this list of matrices by their flattened array (and output implicitly)
NOTE: Taking the minimum with ß
or W
will implicitly flatten, so will output 0
. And sorting with {
doesn't seem to work for a list of matrices, which is why I use Σ˜
instead.
1
@Shaggy Thanks! :) In that case the last two bytes can be removed, since the}
is done implicitly if nothing comes after it.
– Kevin Cruijssen
Dec 17 '18 at 17:31
1
Today I learned something about 05AB1E! :) It's the same in Japt.
– Shaggy
Dec 17 '18 at 18:35
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f177662%2frotation-invariant-fingerprinting%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
Python 2, 48 bytes
f=lambda l,z=5:z and max(l,f(zip(*l)[::-1],z-1))
Try it online!
Takes the largest of the four rotations in terms of list comparison. Based on FlipTack's solution.
The code uses Python 2's ability to compare objects of different types. The base case value of 0
is harmless for max
because it's smaller than any list. Also, zip
produces a list of tuples while the input is a list of lists, but tuples are bigger than lists so the input list-of-lists is never a contender. This is why we rotate 5 times rather than 4, so that we get back to a tuplified version of the initial list. (Taking a list of tuples would also work, if that's an allowed form of input.)
add a comment |
Python 2, 48 bytes
f=lambda l,z=5:z and max(l,f(zip(*l)[::-1],z-1))
Try it online!
Takes the largest of the four rotations in terms of list comparison. Based on FlipTack's solution.
The code uses Python 2's ability to compare objects of different types. The base case value of 0
is harmless for max
because it's smaller than any list. Also, zip
produces a list of tuples while the input is a list of lists, but tuples are bigger than lists so the input list-of-lists is never a contender. This is why we rotate 5 times rather than 4, so that we get back to a tuplified version of the initial list. (Taking a list of tuples would also work, if that's an allowed form of input.)
add a comment |
Python 2, 48 bytes
f=lambda l,z=5:z and max(l,f(zip(*l)[::-1],z-1))
Try it online!
Takes the largest of the four rotations in terms of list comparison. Based on FlipTack's solution.
The code uses Python 2's ability to compare objects of different types. The base case value of 0
is harmless for max
because it's smaller than any list. Also, zip
produces a list of tuples while the input is a list of lists, but tuples are bigger than lists so the input list-of-lists is never a contender. This is why we rotate 5 times rather than 4, so that we get back to a tuplified version of the initial list. (Taking a list of tuples would also work, if that's an allowed form of input.)
Python 2, 48 bytes
f=lambda l,z=5:z and max(l,f(zip(*l)[::-1],z-1))
Try it online!
Takes the largest of the four rotations in terms of list comparison. Based on FlipTack's solution.
The code uses Python 2's ability to compare objects of different types. The base case value of 0
is harmless for max
because it's smaller than any list. Also, zip
produces a list of tuples while the input is a list of lists, but tuples are bigger than lists so the input list-of-lists is never a contender. This is why we rotate 5 times rather than 4, so that we get back to a tuplified version of the initial list. (Taking a list of tuples would also work, if that's an allowed form of input.)
answered Dec 16 '18 at 19:01
xnorxnor
89.8k18184439
89.8k18184439
add a comment |
add a comment |
Python 3, 63 bytes
def f(m):M=;exec("m=[*zip(*m[::-1])];M+=m,;"*4);return min(M)
Try it online!
Finds the rotation with the lexographical minimum, and prints that.
A lambda form comes in at the same byte count:
lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M[-4:])
Try it online!
Rewriting as alambda
can get you to 58.lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)
. Works becauseexec
always returnsNone
.
– nedla2004
Dec 16 '18 at 17:54
@nedla2004 That can only be run once, and then gets dodgy asM
is already populated...
– FlipTack
Dec 16 '18 at 17:55
@nedla2004 ... but accounting for the problem withM[-4:]
can get you to the same byte count.
– FlipTack
Dec 16 '18 at 18:10
I see, the test I was using was just checking inputs with the same "hash", so I never ran into that. That makes sense.
– nedla2004
Dec 16 '18 at 18:11
add a comment |
Python 3, 63 bytes
def f(m):M=;exec("m=[*zip(*m[::-1])];M+=m,;"*4);return min(M)
Try it online!
Finds the rotation with the lexographical minimum, and prints that.
A lambda form comes in at the same byte count:
lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M[-4:])
Try it online!
Rewriting as alambda
can get you to 58.lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)
. Works becauseexec
always returnsNone
.
– nedla2004
Dec 16 '18 at 17:54
@nedla2004 That can only be run once, and then gets dodgy asM
is already populated...
– FlipTack
Dec 16 '18 at 17:55
@nedla2004 ... but accounting for the problem withM[-4:]
can get you to the same byte count.
– FlipTack
Dec 16 '18 at 18:10
I see, the test I was using was just checking inputs with the same "hash", so I never ran into that. That makes sense.
– nedla2004
Dec 16 '18 at 18:11
add a comment |
Python 3, 63 bytes
def f(m):M=;exec("m=[*zip(*m[::-1])];M+=m,;"*4);return min(M)
Try it online!
Finds the rotation with the lexographical minimum, and prints that.
A lambda form comes in at the same byte count:
lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M[-4:])
Try it online!
Python 3, 63 bytes
def f(m):M=;exec("m=[*zip(*m[::-1])];M+=m,;"*4);return min(M)
Try it online!
Finds the rotation with the lexographical minimum, and prints that.
A lambda form comes in at the same byte count:
lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M[-4:])
Try it online!
edited Dec 16 '18 at 18:03
answered Dec 16 '18 at 17:46
FlipTackFlipTack
9,13334089
9,13334089
Rewriting as alambda
can get you to 58.lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)
. Works becauseexec
always returnsNone
.
– nedla2004
Dec 16 '18 at 17:54
@nedla2004 That can only be run once, and then gets dodgy asM
is already populated...
– FlipTack
Dec 16 '18 at 17:55
@nedla2004 ... but accounting for the problem withM[-4:]
can get you to the same byte count.
– FlipTack
Dec 16 '18 at 18:10
I see, the test I was using was just checking inputs with the same "hash", so I never ran into that. That makes sense.
– nedla2004
Dec 16 '18 at 18:11
add a comment |
Rewriting as alambda
can get you to 58.lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)
. Works becauseexec
always returnsNone
.
– nedla2004
Dec 16 '18 at 17:54
@nedla2004 That can only be run once, and then gets dodgy asM
is already populated...
– FlipTack
Dec 16 '18 at 17:55
@nedla2004 ... but accounting for the problem withM[-4:]
can get you to the same byte count.
– FlipTack
Dec 16 '18 at 18:10
I see, the test I was using was just checking inputs with the same "hash", so I never ran into that. That makes sense.
– nedla2004
Dec 16 '18 at 18:11
Rewriting as a
lambda
can get you to 58. lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)
. Works because exec
always returns None
.– nedla2004
Dec 16 '18 at 17:54
Rewriting as a
lambda
can get you to 58. lambda m,M=:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)
. Works because exec
always returns None
.– nedla2004
Dec 16 '18 at 17:54
@nedla2004 That can only be run once, and then gets dodgy as
M
is already populated...– FlipTack
Dec 16 '18 at 17:55
@nedla2004 That can only be run once, and then gets dodgy as
M
is already populated...– FlipTack
Dec 16 '18 at 17:55
@nedla2004 ... but accounting for the problem with
M[-4:]
can get you to the same byte count.– FlipTack
Dec 16 '18 at 18:10
@nedla2004 ... but accounting for the problem with
M[-4:]
can get you to the same byte count.– FlipTack
Dec 16 '18 at 18:10
I see, the test I was using was just checking inputs with the same "hash", so I never ran into that. That makes sense.
– nedla2004
Dec 16 '18 at 18:11
I see, the test I was using was just checking inputs with the same "hash", so I never ran into that. That makes sense.
– nedla2004
Dec 16 '18 at 18:11
add a comment |
Jelly, 5 bytes
ZU$ƬṂ
Try it online!
Full program.
Simply generates all possible rotations and picks the lexicographical minimum.
Note that singleton lists aren't wrapped in in the output. That doesn't matter, since the only case where singleton lists would exist in the input would be a vertical line (including the unit polyomino), which is the same as a horizontal line with the same size (where the ones aren't wrapped). The only case where the outer
will not exist either is the unit polyomino.
when i read the challenge i knew this would happen :)
– ngn
Dec 16 '18 at 18:18
add a comment |
Jelly, 5 bytes
ZU$ƬṂ
Try it online!
Full program.
Simply generates all possible rotations and picks the lexicographical minimum.
Note that singleton lists aren't wrapped in in the output. That doesn't matter, since the only case where singleton lists would exist in the input would be a vertical line (including the unit polyomino), which is the same as a horizontal line with the same size (where the ones aren't wrapped). The only case where the outer
will not exist either is the unit polyomino.
when i read the challenge i knew this would happen :)
– ngn
Dec 16 '18 at 18:18
add a comment |
Jelly, 5 bytes
ZU$ƬṂ
Try it online!
Full program.
Simply generates all possible rotations and picks the lexicographical minimum.
Note that singleton lists aren't wrapped in in the output. That doesn't matter, since the only case where singleton lists would exist in the input would be a vertical line (including the unit polyomino), which is the same as a horizontal line with the same size (where the ones aren't wrapped). The only case where the outer
will not exist either is the unit polyomino.
Jelly, 5 bytes
ZU$ƬṂ
Try it online!
Full program.
Simply generates all possible rotations and picks the lexicographical minimum.
Note that singleton lists aren't wrapped in in the output. That doesn't matter, since the only case where singleton lists would exist in the input would be a vertical line (including the unit polyomino), which is the same as a horizontal line with the same size (where the ones aren't wrapped). The only case where the outer
will not exist either is the unit polyomino.
edited Dec 16 '18 at 17:43
answered Dec 16 '18 at 17:37
Erik the OutgolferErik the Outgolfer
31.4k429103
31.4k429103
when i read the challenge i knew this would happen :)
– ngn
Dec 16 '18 at 18:18
add a comment |
when i read the challenge i knew this would happen :)
– ngn
Dec 16 '18 at 18:18
when i read the challenge i knew this would happen :)
– ngn
Dec 16 '18 at 18:18
when i read the challenge i knew this would happen :)
– ngn
Dec 16 '18 at 18:18
add a comment |
Clean, 136 bytes
import StdEnv,Data.List
r=reverse;t=transpose;f=flatten
$l=[if((a==b)==(c==d))'x''X'\a<-f l&b<-f(r(map r l))&c<-f(r(t l))&d<-f(t(r l))]
Try it online!
Includes test verifier.
add a comment |
Clean, 136 bytes
import StdEnv,Data.List
r=reverse;t=transpose;f=flatten
$l=[if((a==b)==(c==d))'x''X'\a<-f l&b<-f(r(map r l))&c<-f(r(t l))&d<-f(t(r l))]
Try it online!
Includes test verifier.
add a comment |
Clean, 136 bytes
import StdEnv,Data.List
r=reverse;t=transpose;f=flatten
$l=[if((a==b)==(c==d))'x''X'\a<-f l&b<-f(r(map r l))&c<-f(r(t l))&d<-f(t(r l))]
Try it online!
Includes test verifier.
Clean, 136 bytes
import StdEnv,Data.List
r=reverse;t=transpose;f=flatten
$l=[if((a==b)==(c==d))'x''X'\a<-f l&b<-f(r(map r l))&c<-f(r(t l))&d<-f(t(r l))]
Try it online!
Includes test verifier.
answered Dec 16 '18 at 21:42
ΟurousΟurous
6,54211033
6,54211033
add a comment |
add a comment |
K (ngn/k), 16 bytes
{a@*<a:3{+|x}x}
Try it online!
min of rotations
{
}
function with argument x
{+|x}
rotate, i.e. reverse (|
) and transpose (+
)
3{
}
apply 3 times preserving intermediate results; this returns a list of the 4 rotations
a:
assign to a
<
ascend (compute the sort-ascending permutation)
*
first
a@
index a
with that
add a comment |
K (ngn/k), 16 bytes
{a@*<a:3{+|x}x}
Try it online!
min of rotations
{
}
function with argument x
{+|x}
rotate, i.e. reverse (|
) and transpose (+
)
3{
}
apply 3 times preserving intermediate results; this returns a list of the 4 rotations
a:
assign to a
<
ascend (compute the sort-ascending permutation)
*
first
a@
index a
with that
add a comment |
K (ngn/k), 16 bytes
{a@*<a:3{+|x}x}
Try it online!
min of rotations
{
}
function with argument x
{+|x}
rotate, i.e. reverse (|
) and transpose (+
)
3{
}
apply 3 times preserving intermediate results; this returns a list of the 4 rotations
a:
assign to a
<
ascend (compute the sort-ascending permutation)
*
first
a@
index a
with that
K (ngn/k), 16 bytes
{a@*<a:3{+|x}x}
Try it online!
min of rotations
{
}
function with argument x
{+|x}
rotate, i.e. reverse (|
) and transpose (+
)
3{
}
apply 3 times preserving intermediate results; this returns a list of the 4 rotations
a:
assign to a
<
ascend (compute the sort-ascending permutation)
*
first
a@
index a
with that
edited Dec 17 '18 at 13:57
answered Dec 16 '18 at 18:42
ngnngn
6,94112559
6,94112559
add a comment |
add a comment |
Japt -g
, 6 bytes
4Æ=zÃñ
Try it
:Implicit input of 2d-array U
4Æ :Map the range [0,4)
z : Rotate U 90 degrees
= : Reassign to U
à :End map
ñ :Sort
:Implicit output of first element
Is the-g
flag necessary? Sort should mean that all initial rotations end up with the same list so that full list should work fine as the fingerprint unless I'm missing something.
– Kamil Drakari
Dec 17 '18 at 15:58
@KamilDrakari, you could well be right - like I said, I'm not sure I fully understood the challenge. No harm leaving it in, though, it's not costing any bytes.
– Shaggy
Dec 17 '18 at 17:11
@KamilDrakari: It is not necessary, but it's no harm either as it's not counted towards the bytecount.
– BMO
Dec 17 '18 at 17:17
add a comment |
Japt -g
, 6 bytes
4Æ=zÃñ
Try it
:Implicit input of 2d-array U
4Æ :Map the range [0,4)
z : Rotate U 90 degrees
= : Reassign to U
à :End map
ñ :Sort
:Implicit output of first element
Is the-g
flag necessary? Sort should mean that all initial rotations end up with the same list so that full list should work fine as the fingerprint unless I'm missing something.
– Kamil Drakari
Dec 17 '18 at 15:58
@KamilDrakari, you could well be right - like I said, I'm not sure I fully understood the challenge. No harm leaving it in, though, it's not costing any bytes.
– Shaggy
Dec 17 '18 at 17:11
@KamilDrakari: It is not necessary, but it's no harm either as it's not counted towards the bytecount.
– BMO
Dec 17 '18 at 17:17
add a comment |
Japt -g
, 6 bytes
4Æ=zÃñ
Try it
:Implicit input of 2d-array U
4Æ :Map the range [0,4)
z : Rotate U 90 degrees
= : Reassign to U
à :End map
ñ :Sort
:Implicit output of first element
Japt -g
, 6 bytes
4Æ=zÃñ
Try it
:Implicit input of 2d-array U
4Æ :Map the range [0,4)
z : Rotate U 90 degrees
= : Reassign to U
à :End map
ñ :Sort
:Implicit output of first element
edited Dec 17 '18 at 17:19
answered Dec 16 '18 at 20:24
ShaggyShaggy
19.2k21666
19.2k21666
Is the-g
flag necessary? Sort should mean that all initial rotations end up with the same list so that full list should work fine as the fingerprint unless I'm missing something.
– Kamil Drakari
Dec 17 '18 at 15:58
@KamilDrakari, you could well be right - like I said, I'm not sure I fully understood the challenge. No harm leaving it in, though, it's not costing any bytes.
– Shaggy
Dec 17 '18 at 17:11
@KamilDrakari: It is not necessary, but it's no harm either as it's not counted towards the bytecount.
– BMO
Dec 17 '18 at 17:17
add a comment |
Is the-g
flag necessary? Sort should mean that all initial rotations end up with the same list so that full list should work fine as the fingerprint unless I'm missing something.
– Kamil Drakari
Dec 17 '18 at 15:58
@KamilDrakari, you could well be right - like I said, I'm not sure I fully understood the challenge. No harm leaving it in, though, it's not costing any bytes.
– Shaggy
Dec 17 '18 at 17:11
@KamilDrakari: It is not necessary, but it's no harm either as it's not counted towards the bytecount.
– BMO
Dec 17 '18 at 17:17
Is the
-g
flag necessary? Sort should mean that all initial rotations end up with the same list so that full list should work fine as the fingerprint unless I'm missing something.– Kamil Drakari
Dec 17 '18 at 15:58
Is the
-g
flag necessary? Sort should mean that all initial rotations end up with the same list so that full list should work fine as the fingerprint unless I'm missing something.– Kamil Drakari
Dec 17 '18 at 15:58
@KamilDrakari, you could well be right - like I said, I'm not sure I fully understood the challenge. No harm leaving it in, though, it's not costing any bytes.
– Shaggy
Dec 17 '18 at 17:11
@KamilDrakari, you could well be right - like I said, I'm not sure I fully understood the challenge. No harm leaving it in, though, it's not costing any bytes.
– Shaggy
Dec 17 '18 at 17:11
@KamilDrakari: It is not necessary, but it's no harm either as it's not counted towards the bytecount.
– BMO
Dec 17 '18 at 17:17
@KamilDrakari: It is not necessary, but it's no harm either as it's not counted towards the bytecount.
– BMO
Dec 17 '18 at 17:17
add a comment |
J, 16 bytes
-2 bytes thanks to Shaggy
[:/:~|.@|:^:(<4)
Try it online!
J, 18 bytes
0{[:/:~|.@|:^:(<4)
Try it online!
Returns the first item in the list of the lexicograpically sorted rotations of the polyomino.
Explanation:
^:(<4) - do the verb on the left 4 times, storing all the steps
|.@|: - tranpose and reverse
/:~ - sort up the 4 matrices
[: - cap the fork
0{ - take the first matrix
@Shaggy Thanks!
– Galen Ivanov
Dec 17 '18 at 18:02
add a comment |
J, 16 bytes
-2 bytes thanks to Shaggy
[:/:~|.@|:^:(<4)
Try it online!
J, 18 bytes
0{[:/:~|.@|:^:(<4)
Try it online!
Returns the first item in the list of the lexicograpically sorted rotations of the polyomino.
Explanation:
^:(<4) - do the verb on the left 4 times, storing all the steps
|.@|: - tranpose and reverse
/:~ - sort up the 4 matrices
[: - cap the fork
0{ - take the first matrix
@Shaggy Thanks!
– Galen Ivanov
Dec 17 '18 at 18:02
add a comment |
J, 16 bytes
-2 bytes thanks to Shaggy
[:/:~|.@|:^:(<4)
Try it online!
J, 18 bytes
0{[:/:~|.@|:^:(<4)
Try it online!
Returns the first item in the list of the lexicograpically sorted rotations of the polyomino.
Explanation:
^:(<4) - do the verb on the left 4 times, storing all the steps
|.@|: - tranpose and reverse
/:~ - sort up the 4 matrices
[: - cap the fork
0{ - take the first matrix
J, 16 bytes
-2 bytes thanks to Shaggy
[:/:~|.@|:^:(<4)
Try it online!
J, 18 bytes
0{[:/:~|.@|:^:(<4)
Try it online!
Returns the first item in the list of the lexicograpically sorted rotations of the polyomino.
Explanation:
^:(<4) - do the verb on the left 4 times, storing all the steps
|.@|: - tranpose and reverse
/:~ - sort up the 4 matrices
[: - cap the fork
0{ - take the first matrix
edited Dec 17 '18 at 18:02
answered Dec 17 '18 at 8:09
Galen IvanovGalen Ivanov
6,41711032
6,41711032
@Shaggy Thanks!
– Galen Ivanov
Dec 17 '18 at 18:02
add a comment |
@Shaggy Thanks!
– Galen Ivanov
Dec 17 '18 at 18:02
@Shaggy Thanks!
– Galen Ivanov
Dec 17 '18 at 18:02
@Shaggy Thanks!
– Galen Ivanov
Dec 17 '18 at 18:02
add a comment |
05AB1E, 10 8 bytes
3FÂø})Σ˜
-2 bytes thanks to @Shaggy.
Try it online or verify all test cases.
Explanation:
3F } # Loop 3 times
 # Bifurcate (short for Duplicate & Reverse) the top of the stack
# (which is the input-matrix implicitly the first iteration)
ø # Transpose: swap rows/columns
) # After the loop, wrap everything on the stack in a list
Σ˜ # Sort this list of matrices by their flattened array (and output implicitly)
NOTE: Taking the minimum with ß
or W
will implicitly flatten, so will output 0
. And sorting with {
doesn't seem to work for a list of matrices, which is why I use Σ˜
instead.
1
@Shaggy Thanks! :) In that case the last two bytes can be removed, since the}
is done implicitly if nothing comes after it.
– Kevin Cruijssen
Dec 17 '18 at 17:31
1
Today I learned something about 05AB1E! :) It's the same in Japt.
– Shaggy
Dec 17 '18 at 18:35
add a comment |
05AB1E, 10 8 bytes
3FÂø})Σ˜
-2 bytes thanks to @Shaggy.
Try it online or verify all test cases.
Explanation:
3F } # Loop 3 times
 # Bifurcate (short for Duplicate & Reverse) the top of the stack
# (which is the input-matrix implicitly the first iteration)
ø # Transpose: swap rows/columns
) # After the loop, wrap everything on the stack in a list
Σ˜ # Sort this list of matrices by their flattened array (and output implicitly)
NOTE: Taking the minimum with ß
or W
will implicitly flatten, so will output 0
. And sorting with {
doesn't seem to work for a list of matrices, which is why I use Σ˜
instead.
1
@Shaggy Thanks! :) In that case the last two bytes can be removed, since the}
is done implicitly if nothing comes after it.
– Kevin Cruijssen
Dec 17 '18 at 17:31
1
Today I learned something about 05AB1E! :) It's the same in Japt.
– Shaggy
Dec 17 '18 at 18:35
add a comment |
05AB1E, 10 8 bytes
3FÂø})Σ˜
-2 bytes thanks to @Shaggy.
Try it online or verify all test cases.
Explanation:
3F } # Loop 3 times
 # Bifurcate (short for Duplicate & Reverse) the top of the stack
# (which is the input-matrix implicitly the first iteration)
ø # Transpose: swap rows/columns
) # After the loop, wrap everything on the stack in a list
Σ˜ # Sort this list of matrices by their flattened array (and output implicitly)
NOTE: Taking the minimum with ß
or W
will implicitly flatten, so will output 0
. And sorting with {
doesn't seem to work for a list of matrices, which is why I use Σ˜
instead.
05AB1E, 10 8 bytes
3FÂø})Σ˜
-2 bytes thanks to @Shaggy.
Try it online or verify all test cases.
Explanation:
3F } # Loop 3 times
 # Bifurcate (short for Duplicate & Reverse) the top of the stack
# (which is the input-matrix implicitly the first iteration)
ø # Transpose: swap rows/columns
) # After the loop, wrap everything on the stack in a list
Σ˜ # Sort this list of matrices by their flattened array (and output implicitly)
NOTE: Taking the minimum with ß
or W
will implicitly flatten, so will output 0
. And sorting with {
doesn't seem to work for a list of matrices, which is why I use Σ˜
instead.
edited Dec 17 '18 at 17:30
answered Dec 17 '18 at 9:41
Kevin CruijssenKevin Cruijssen
36k554189
36k554189
1
@Shaggy Thanks! :) In that case the last two bytes can be removed, since the}
is done implicitly if nothing comes after it.
– Kevin Cruijssen
Dec 17 '18 at 17:31
1
Today I learned something about 05AB1E! :) It's the same in Japt.
– Shaggy
Dec 17 '18 at 18:35
add a comment |
1
@Shaggy Thanks! :) In that case the last two bytes can be removed, since the}
is done implicitly if nothing comes after it.
– Kevin Cruijssen
Dec 17 '18 at 17:31
1
Today I learned something about 05AB1E! :) It's the same in Japt.
– Shaggy
Dec 17 '18 at 18:35
1
1
@Shaggy Thanks! :) In that case the last two bytes can be removed, since the
}
is done implicitly if nothing comes after it.– Kevin Cruijssen
Dec 17 '18 at 17:31
@Shaggy Thanks! :) In that case the last two bytes can be removed, since the
}
is done implicitly if nothing comes after it.– Kevin Cruijssen
Dec 17 '18 at 17:31
1
1
Today I learned something about 05AB1E! :) It's the same in Japt.
– Shaggy
Dec 17 '18 at 18:35
Today I learned something about 05AB1E! :) It's the same in Japt.
– Shaggy
Dec 17 '18 at 18:35
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f177662%2frotation-invariant-fingerprinting%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Related.
– BMO
Dec 16 '18 at 17:20
If I always output
""
(the empty string), have I satisfied all the requirements?– Daniel Wagner
Dec 17 '18 at 12:13
@DanielWagner: "[..] for any two polyominos from two distinct classes [the fingerprints] must differ" - so no, that would be invalid.
– BMO
Dec 17 '18 at 14:59
Is outputting all possible rotations of an array, consistently sorted valid? Example
– Shaggy
Dec 17 '18 at 17:12
1
@Shaggy: Yes, that would meet all the criteria.
– BMO
Dec 17 '18 at 17:15