Submission 7e550dba...

ChallengeRemove duplicate elements
Submitter0x1dba1131000664b...
Submitted at2018-02-30
Gas used278268
/**
 * 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/
 *
 * Author: Jordi Baylina
 */

pragma solidity 0.4.24;

contract Unique {
    /**
     * @dev Removes all but the first occurrence of each element from a list of
     *      integers, preserving the order of original elements, and returns the list.
     *
     * The input list may be of any length.
     *
     * @param input The list of integers to uniquify.
     * @return The input list, with any duplicate elements removed.
     *
     */
    function uniquify(uint[] input) public pure returns(uint[]) {
        input;
        assembly {
//            let _input := add(calldataload(4), 4)
            let _input := input

            let hashLen:= 0x400
            let l := mload(_input)
            let out := mload(0x40)
//            let out := 0
            let pout := add(out,0x40)   // One for the length and one for output variable
            let t0 := add(pout,add(mul(l, 0x20),0x40))
//            mstore(0x40, t0)
            let zeroUsed
            for {
                let p:= add(_input, 32)
                let lastp:= add(p, mul(l,32))
            } lt(p, lastp) {
                p:= add(p,32)
            } {
                let x:= mload(p)
                switch x
                case 0 {
                    if eq(zeroUsed,0) {
                        mstore(pout, 0)
                        pout := add(pout,32)
                        zeroUsed := 1
                    }
                }
                default {
                    let t
                    let d
                    let r
                    for {
//                        let s := sha3(p,0x20)
                        let s := x
                        t := t0
                        d := mul(mod(s,hashLen),32)
                        r := mload(add(t,d))
                    } and(gt(r,0), not(eq(x, r))) {
                        s := div(s, hashLen)
                        d := mul(mod(s, hashLen),32)
                        t := add(t, mul(hashLen,32))
                        r := mload(add(t,d))
                    } {}
                    if eq(r,0) {
                        mstore(add(t,d), x)
                        mstore(pout, x)
                        pout:=add(pout,32)
                    }
                }
            }

            mstore(out, 0x20)
            mstore(add(out, 0x20), sub(div(sub(pout, out), 0x20), 2))
            return(out, sub(pout,out))
        }
    }
}