Submission db11d3ae...
/**
* This file is part of the 1st Solidity Gas Golfing Contest.
*
* This work is licensed under Creative Commons Attribution ShareAlike 3.0.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
pragma solidity 0.4.24;
contract Unique {
function () external payable { assembly {
// @author Remco Bloemen <[email protected]>
mstore(0x40, 0)
let i
let ptr
let index2
let iv
let index1
let last2 := 0
let last1 := 0
let vhash
i := calldataload(36)
jumpi(main512, gt(i, 128))
jumpi(main256, gt(i, 64))
jumpi(main128, gt(i, 0))
main0:
// Empty list
mstore(0, 32)
mstore(32, 0)
return(0, 64)
main128:
// Table size 97
ptr := 0xC60
i := 68
oloop128:
// Read value
vhash := not(calldataload(i))
// Check recent values
jumpi(seen128, or(eq(vhash, last1), eq(vhash, last2)))
last2 := last1
last1 := vhash
// Compute index 1
index1 := mul(mod(vhash, 97), 32)
// Read index 1
iv := mload(index1)
jumpi(unique1128, iszero(iv))
jumpi(seen128, eq(iv, vhash))
// Increment and test index 1
index1 := mod(add(index1, 32), 0xC20)
iv := mload(index1)
jumpi(unique1128, iszero(iv))
jumpi(seen128, eq(iv, vhash))
// Compute index 2
index2 := mul(mod(mul(vhash, 0x1b6d296aa8b7284041b9f0e36895d18399d8026b57a51e5af0ed54c3e03bd3a1), 97), 32)
// Read index 2
iv := mload(index2)
jumpi(unique2128, iszero(iv))
jumpi(seen128, eq(iv, vhash))
iloop128:
// Increment and test index 1
index1 := mod(add(index1, 32), 0xC20)
iv := mload(index1)
jumpi(unique1128, iszero(iv))
jumpi(seen128, eq(iv, vhash))
// Incerment and test index 2
index2 := mod(add(index2, 32), 0xC20)
iv := mload(index2)
jumpi(unique2128, iszero(iv))
jumpi(seen128, eq(iv, vhash))
// Increment and test index 1
index1 := mod(add(index1, 32), 0xC20)
iv := mload(index1)
jumpi(unique1128, iszero(iv))
jumpi(seen128, eq(iv, vhash))
// Incerment and test index 2
index2 := mod(add(index2, 32), 0xC20)
iv := mload(index2)
jumpi(unique2128, iszero(iv))
jumpi(seen128, eq(iv, vhash))
// Loop
jump(iloop128)
seen128:
// Resume loop
i := add(i, 32)
jumpi(oloop128, lt(i, calldatasize))
jump(oloop_end128)
unique2128:
// Add to the hash table
mstore(index2, vhash)
// Add to start of list
mstore(ptr, not(vhash))
ptr := add(ptr, 32)
// Resume loop
i := add(i, 32)
jumpi(oloop128, lt(i, calldatasize))
jump(oloop_end128)
unique1128:
// Add to the hash table
mstore(index1, vhash)
// Add to start of list
mstore(ptr, not(vhash))
ptr := add(ptr, 32)
// Resume loop
i := add(i, 32)
jumpi(oloop128, lt(i, calldatasize))
oloop_end128:
mstore(0xC20, 32)
mstore(0xC40, div(sub(ptr, 0xC60), 32))
return(0xC20, sub(ptr, 0xC20))
main256:
// Table size 193
ptr := 0x1860
i := 68
oloop256:
// Read value
vhash := not(calldataload(i))
// Check recent values
jumpi(seen256, or(eq(vhash, last1), eq(vhash, last2)))
last2 := last1
last1 := vhash
// Compute index 1
index1 := mul(mod(vhash, 193), 32)
// Read index 1
iv := mload(index1)
jumpi(unique1256, iszero(iv))
jumpi(seen256, eq(iv, vhash))
// Increment and test index 1
index1 := mod(add(index1, 32), 0x1820)
iv := mload(index1)
jumpi(unique1256, iszero(iv))
jumpi(seen256, eq(iv, vhash))
// Compute index 2
index2 := mul(mod(mul(vhash,
0x1b6d296aa8b7284041b9f0e36895d18399d8026b57a51e5af0ed54c3e03bd3a1
), 193), 32)
// Read index 2
iv := mload(index2)
jumpi(unique2256, iszero(iv))
jumpi(seen256, eq(iv, vhash))
iloop256:
// Increment and test index 1
index1 := mod(add(index1, 32), 0x1820)
iv := mload(index1)
jumpi(unique1256, iszero(iv))
jumpi(seen256, eq(iv, vhash))
// Incerment and test index 2
index2 := mod(add(index2, 32), 0x1820)
iv := mload(index2)
jumpi(unique2256, iszero(iv))
jumpi(seen256, eq(iv, vhash))
// Increment and test index 1
index1 := mod(add(index1, 32), 0x1820)
iv := mload(index1)
jumpi(unique1256, iszero(iv))
jumpi(seen256, eq(iv, vhash))
// Incerment and test index 2
index2 := mod(add(index2, 32), 0x1820)
iv := mload(index2)
jumpi(unique2256, iszero(iv))
jumpi(seen256, eq(iv, vhash))
// Loop
jump(iloop256)
seen256:
// Resume loop
i := add(i, 32)
jumpi(oloop256, lt(i, calldatasize))
jump(oloop_end256)
unique2256:
// Add to the hash table
mstore(index2, vhash)
// Add to start of list
mstore(ptr, not(vhash))
ptr := add(ptr, 32)
// Resume loop
i := add(i, 32)
jumpi(oloop256, lt(i, calldatasize))
jump(oloop_end256)
unique1256:
// Add to the hash table
mstore(index1, vhash)
// Add to start of list
mstore(ptr, not(vhash))
ptr := add(ptr, 32)
// Resume loop
i := add(i, 32)
jumpi(oloop256, lt(i, calldatasize))
oloop_end256:
mstore(0x1820, 32)
mstore(0x1840, div(sub(ptr, 0x1860), 32))
return(0x1820, sub(ptr, 0x1820))
main512:
ptr := 0x4040
i := 68
oloop512:
// Read value
vhash := not(calldataload(i))
// Check recent values
jumpi(seen512, or(eq(vhash, last1), eq(vhash, last2)))
last2 := last1
last1 := vhash
// Compute index 1
index1 := and(mul(vhash, 32), 0x3fe0)
// Read index 1
iv := mload(index1)
jumpi(unique1512, iszero(iv))
jumpi(seen512, eq(iv, vhash))
// Increment and test index 1
index1 := and(add(index1, 32), 0x3fe0)
iv := mload(index1)
jumpi(unique1512, iszero(iv))
jumpi(seen512, eq(iv, vhash))
// Compute index 2
index2 := and(div(mul(vhash,
0x1b6d296aa8b7284041b9f0e36895d18399d8026b57a51e5af0ed54c3e03bd3a1
), 0x1000000000000001), 0x0fe0)
// Read index 2
iv := mload(index2)
jumpi(unique2512, iszero(iv))
jumpi(seen512, eq(iv, vhash))
iloop512:
// Increment and test index 1
index1 := and(add(index1, 32), 0x3fe0)
iv := mload(index1)
jumpi(unique1512, iszero(iv))
jumpi(seen512, eq(iv, vhash))
// Incerment and test index 2
index2 := and(add(index2, 32), 0x3fe0)
iv := mload(index2)
jumpi(unique2512, iszero(iv))
jumpi(seen512, eq(iv, vhash))
// Increment and test index 1
index1 := and(add(index1, 32), 0x3fe0)
iv := mload(index1)
jumpi(unique1512, iszero(iv))
jumpi(seen512, eq(iv, vhash))
// Incerment and test index 2
index2 := and(add(index2, 32), 0x3fe0)
iv := mload(index2)
jumpi(unique2512, iszero(iv))
jumpi(seen512, eq(iv, vhash))
// Loop
jump(iloop512)
seen512:
// Resume loop
i := add(i, 32)
jumpi(oloop512, lt(i, calldatasize))
jump(oloop_end512)
unique2512:
// Add to the hash table
mstore(index2, vhash)
// Add to start of list
mstore(ptr, not(vhash))
ptr := add(ptr, 32)
// Resume loop
i := add(i, 32)
jumpi(oloop512, lt(i, calldatasize))
jump(oloop_end512)
unique1512:
// Add to the hash table
mstore(index1, vhash)
// Add to start of list
mstore(ptr, not(vhash))
ptr := add(ptr, 32)
// Resume loop
i := add(i, 32)
jumpi(oloop512, lt(i, calldatasize))
oloop_end512:
mstore(0x4000, 32)
mstore(0x4020, div(sub(ptr, 0x4040), 32))
return(0x4000, sub(ptr, 0x4000))
}}
}