Submission 3f058ba1...

ChallengeString search
Submitter0x1dba1131000664b...
Submitted at2018-17-27
Gas used79862
/**
 * 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 IndexOf {
    /**
     * @dev Returns the index of the first occurrence of `needle` in `haystack`,
     *      or -1 if `needle` is not found in `haystack`.
     *
     * Input strings may be of any length <2^255.
     *
     * @param haystack The string to search.
     * @param needle The string to search for.
     * @return The index of `needle` in `haystack`, or -1 if not found.
     */
    function indexOf(string haystack, string needle) external pure returns(int) {
        haystack;
        needle;
        assembly {
            let _haystack := add(calldataload(4), 4)
            let _needle := add(calldataload(36), 4)
            function checkNeedle(haystackP, niddleP, niddleLen, mask) -> found {
                found := 1
                let niddlePEnd
                for {
                    niddlePEnd := sub(add(niddleP, niddleLen), 31)
                } and(lt(niddleP, niddlePEnd), found) {
                    haystackP := add(haystackP, 32)
                    niddleP := add(niddleP, 32)
                } {
                    found := eq(calldataload(haystackP), calldataload(niddleP))
                }
                niddlePEnd := add(niddlePEnd,31)
                if and(lt(niddleP, niddlePEnd), found) {
                    let v1 := and(calldataload(haystackP), mask)
                    let v2 := and(calldataload(niddleP), mask)
                    found := eq(v1, v2)
                }

            }

            let needleStart := add(_needle, 32)
            let l1 := calldataload(_haystack)
            let l2 := calldataload(_needle)
            if eq(l2,0) {
                mstore(0,0)
                return(0,0x20)
            }
            if eq(l1,0) {
                mstore(0,0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
                return(0,0x20)
            }
            if gt(l2, l1) {
                mstore(0,0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
                return(0,0x20)
            }

            let mask := not(sub(exp(0x100, sub(32,and(l2, 0x1F))),1))

            let c := and(calldataload(add(_needle,1)), 0xff)
            c := add(mul(c, 0x100), c)
            c := add(mul(c, 0x10000), c)
            c := add(mul(c, 0x100000000), c)
            c := add(mul(c, 0x10000000000000000), c)
            c := add(mul(c, 0x100000000000000000000000000000000), c)

            for {
                let p := add(_haystack, 32)
                let pend := sub(add(p,l1), sub(l2, 1))
            } lt(p, pend) {
                p := add(p, 32)
            } {
                let s := calldataload(p)
                let x := xor(s,c)
                x := or(div(x, 16), x)
                x := or(div(x, 4), x)
                x := or(div(x, 1), x)
                x := and(not(x), 0x0101010101010101010101010101010101010101010101010101010101010101)
                if gt(x, 0) {
                    if gt(and(x,                 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000), 0) {
                        if gt(and(x,             0xffffffffffffffff000000000000000000000000000000000000000000000000), 0) {
                            if gt(and(x,         0xffffffff00000000000000000000000000000000000000000000000000000000), 0) {
                                if gt(and(x,     0xffff000000000000000000000000000000000000000000000000000000000000), 0) {
                                    if gt(and(x, 0xff00000000000000000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(p, needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 32))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x00ff000000000000000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,1), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 31))) return(0,0x20) }
                                    }
                                }
                                if gt(and(x,     0x0000ffff00000000000000000000000000000000000000000000000000000000), 0) {
                                    if gt(and(x, 0x0000ff0000000000000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,2), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 30))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x000000ff00000000000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,3), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 29))) return(0,0x20) }
                                    }
                                }
                            }
                            if gt(and(x,         0x00000000ffffffff000000000000000000000000000000000000000000000000), 0) {
                                if gt(and(x,     0x00000000ffff0000000000000000000000000000000000000000000000000000), 0) {
                                    if gt(and(x, 0x00000000ff000000000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,4), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 28))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x0000000000ff0000000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,5), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 27))) return(0,0x20) }
                                    }
                                }
                                if gt(and(x,     0x000000000000ffff000000000000000000000000000000000000000000000000), 0) {
                                    if gt(and(x, 0x000000000000ff00000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,6), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 26))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x00000000000000ff000000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,7), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 25))) return(0,0x20) }
                                    }
                                }
                            }
                        }
                        if gt(and(x,             0x0000000000000000ffffffffffffffff00000000000000000000000000000000), 0) {
                            if gt(and(x,         0x0000000000000000ffffffff0000000000000000000000000000000000000000), 0) {
                                if gt(and(x,     0x0000000000000000ffff00000000000000000000000000000000000000000000), 0) {
                                    if gt(and(x, 0x0000000000000000ff0000000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,8), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 24))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x000000000000000000ff00000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,9), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 23))) return(0,0x20) }
                                    }
                                }
                                if gt(and(x,     0x00000000000000000000ffff0000000000000000000000000000000000000000), 0) {
                                    if gt(and(x, 0x00000000000000000000ff000000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,10), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 22))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x0000000000000000000000ff0000000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,11), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 21))) return(0,0x20) }
                                    }
                                }
                            }
                            if gt(and(x,         0x000000000000000000000000ffffffff00000000000000000000000000000000), 0) {
                                if gt(and(x,     0x000000000000000000000000ffff000000000000000000000000000000000000), 0) {
                                    if gt(and(x, 0x000000000000000000000000ff00000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,12), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 20))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x00000000000000000000000000ff000000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,13), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 19))) return(0,0x20) }
                                    }
                                }
                                if gt(and(x,     0x0000000000000000000000000000ffff00000000000000000000000000000000), 0) {
                                    if gt(and(x, 0x0000000000000000000000000000ff0000000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,14), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 18))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x000000000000000000000000000000ff00000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,15), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 17))) return(0,0x20) }
                                    }
                                }
                            }
                        }
                    }
                    if gt(and(x,                 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff), 0) {
                        if gt(and(x,             0x00000000000000000000000000000000ffffffffffffffff0000000000000000), 0) {
                            if gt(and(x,         0x00000000000000000000000000000000ffffffff000000000000000000000000), 0) {
                                if gt(and(x,     0x00000000000000000000000000000000ffff0000000000000000000000000000), 0) {
                                    if gt(and(x, 0x00000000000000000000000000000000ff000000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,16), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 16))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x0000000000000000000000000000000000ff0000000000000000000000000000), 0) {
                                        if checkNeedle(add(p,17), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 15))) return(0,0x20) }
                                    }
                                }
                                if gt(and(x,     0x000000000000000000000000000000000000ffff000000000000000000000000), 0) {
                                    if gt(and(x, 0x000000000000000000000000000000000000ff00000000000000000000000000), 0) {
                                        if checkNeedle(add(p,18), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 14))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x00000000000000000000000000000000000000ff000000000000000000000000), 0) {
                                        if checkNeedle(add(p,19), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 13))) return(0,0x20) }
                                    }
                                }
                            }
                            if gt(and(x,         0x0000000000000000000000000000000000000000ffffffff0000000000000000), 0) {
                                if gt(and(x,     0x0000000000000000000000000000000000000000ffff00000000000000000000), 0) {
                                    if gt(and(x, 0x0000000000000000000000000000000000000000ff0000000000000000000000), 0) {
                                        if checkNeedle(add(p,20), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 12))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x000000000000000000000000000000000000000000ff00000000000000000000), 0) {
                                        if checkNeedle(add(p,21), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 11))) return(0,0x20) }
                                    }
                                }
                                if gt(and(x,     0x00000000000000000000000000000000000000000000ffff0000000000000000), 0) {
                                    if gt(and(x, 0x00000000000000000000000000000000000000000000ff000000000000000000), 0) {
                                        if checkNeedle(add(p,22), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 10))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x0000000000000000000000000000000000000000000000ff0000000000000000), 0) {
                                        if checkNeedle(add(p,23), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 9))) return(0,0x20) }
                                    }
                                }
                            }
                        }
                        if gt(and(x,             0x000000000000000000000000000000000000000000000000ffffffffffffffff), 0) {
                            if gt(and(x,         0x000000000000000000000000000000000000000000000000ffffffff00000000), 0) {
                                if gt(and(x,     0x000000000000000000000000000000000000000000000000ffff000000000000), 0) {
                                    if gt(and(x, 0x000000000000000000000000000000000000000000000000ff00000000000000), 0) {
                                        if checkNeedle(add(p,24), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 8))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x00000000000000000000000000000000000000000000000000ff000000000000), 0) {
                                        if checkNeedle(add(p,25), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 7))) return(0,0x20) }
                                    }
                                }
                                if gt(and(x,     0x0000000000000000000000000000000000000000000000000000ffff00000000), 0) {
                                    if gt(and(x, 0x0000000000000000000000000000000000000000000000000000ff0000000000), 0) {
                                        if checkNeedle(add(p,26), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 6))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x000000000000000000000000000000000000000000000000000000ff00000000), 0) {
                                        if checkNeedle(add(p,27), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 5))) return(0,0x20) }
                                    }
                                }
                            }
                            if gt(and(x,         0x00000000000000000000000000000000000000000000000000000000ffffffff), 0) {
                                if gt(and(x,     0x00000000000000000000000000000000000000000000000000000000ffff0000), 0) {
                                    if gt(and(x, 0x00000000000000000000000000000000000000000000000000000000ff000000), 0) {
                                        if checkNeedle(add(p,28), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 4))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x0000000000000000000000000000000000000000000000000000000000ff0000), 0) {
                                        if checkNeedle(add(p,29), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 3))) return(0,0x20) }
                                    }

                                }
                                if gt(and(x,     0x000000000000000000000000000000000000000000000000000000000000ffff), 0) {
                                    if gt(and(x, 0x000000000000000000000000000000000000000000000000000000000000ff00), 0) {
                                        if checkNeedle(add(p,30), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 2))) return(0,0x20) }
                                    }
                                    if gt(and(x, 0x00000000000000000000000000000000000000000000000000000000000000ff), 0) {
                                        if checkNeedle(add(p,31), needleStart, l2, mask) { mstore(0, sub(p, add(_haystack, 1))) return(0,0x20) }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            mstore(0,0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            return(0,0x20)

        }
    }

}