-- Binary, Decimal, Hexadecimal, Octal conversion
-- Author: Tim Kelly and Andrew Stacey
-- Websites: http://w...content-available-to-author-only...s.com/Lua/code/BinDecHex.shtml
-- http://w...content-available-to-author-only...u.no/~stacey/HowDidIDoThat/iPad/Codea.html
-- Licence: See below
--[[
/*
* Copyright (c) 2007 Tim Kelly/Dialectronics
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
--]]
--[[
Formatting suitable for Codea on iPad together with octal functions by
Andrew Stacey. Additions released under the original license.
--]]
local hex2bin = {
["0"] = "0000",
["1"] = "0001",
["2"] = "0010",
["3"] = "0011",
["4"] = "0100",
["5"] = "0101",
["6"] = "0110",
["7"] = "0111",
["8"] = "1000",
["9"] = "1001",
["a"] = "1010",
["b"] = "1011",
["c"] = "1100",
["d"] = "1101",
["e"] = "1110",
["f"] = "1111"
}
local bin2hex = {
["0000"] = "0",
["0001"] = "1",
["0010"] = "2",
["0011"] = "3",
["0100"] = "4",
["0101"] = "5",
["0110"] = "6",
["0111"] = "7",
["1000"] = "8",
["1001"] = "9",
["1010"] = "A",
["1011"] = "B",
["1100"] = "C",
["1101"] = "D",
["1110"] = "E",
["1111"] = "F"
}
local bin2oct = {
["000"] = "0",
["001"] = "1",
["010"] = "2",
["011"] = "3",
["100"] = "4",
["101"] = "5",
["110"] = "6",
["111"] = "7"
}
local oct2bin = {
["0"] = "000",
["1"] = "001",
["2"] = "010",
["3"] = "011",
["4"] = "100",
["5"] = "101",
["6"] = "110",
["7"] = "111"
}
-- These functions are big-endian and take up to 32 bits
-- Hex2Bin
-- Bin2Hex
-- Hex2Dec
-- Dec2Hex
-- Bin2Dec
-- Dec2Bin
function Hex2Bin(s)
-- s -> hexadecimal string
local ret = ""
local i = 0
for i in string.gfind(s, ".") do
i = string.lower(i)
ret = ret..hex2bin[i]
end
return ret
end
function Bin2Hex(s)
-- s -> binary string
local l = 0
local h = ""
local b = ""
local rem
l = string.len(s)
rem = l % 4
l = l-1
h = ""
-- need to prepend zeros to eliminate mod 4
if (rem > 0) then
s = string.rep("0", 4 - rem)..s
end
for i = 1, l, 4 do
b = string.sub(s, i, i+3)
h = h..bin2hex[b]
end
return h
end
function Bin2Oct(s)
-- s -> binary string
local l = 0
local h = ""
local b = ""
local rem
l = string.len(s)
rem = l % 3
l = l-1
h = ""
-- need to prepend zeros to eliminate mod 3
if (rem > 0) then
s = string.rep("0", 3 - rem)..s
end
for i = 1, l, 3 do
b = string.sub(s, i, i+2)
h = h..bin2oct[b]
end
return h
end
function Oct2Bin(s)
-- s -> octal string
local ret = ""
local i = 0
for i in string.gfind(s, ".") do
i = string.lower(i)
ret = ret..oct2bin[i]
end
return ret
end
function Bin2Dec(s)
-- s -> binary string
local num = 0
local ex = string.len(s) - 1
local l = 0
l = ex + 1
for i = 1, l do
b = string.sub(s, i, i)
if b == "1" then
num = num + 2^ex
end
ex = ex - 1
end
return string.format("%u", num)
end
function Dec2Bin(s, num)
-- s -> Base10 string
-- num -> string length to extend to
local n
if (num == nil) then
n = 0
else
n = num
end
s = string.format("%x", s)
s = Hex2Bin(s)
while string.len(s) < n do
s = "0"..s
end
return s
end
function Hex2Dec(s)
-- s -> hexadecimal string
local s = Hex2Bin(s)
return Bin2Dec(s)
end
function Dec2Hex(s)
-- s -> Base10 string
s = string.format("%x", s)
return s
end
function Hex2Oct(s)
-- s -> hexadecimal string
local s = Hex2Bin(s)
return Bin2Oct(s)
end
function Oct2Hex(s)
-- s -> Base8 string
local s = Oct2Bin(s)
return Bin2Hex(s)
end
function Dec2Oct(s)
-- s -> decimal string
s = string.format("%o", s)
return s
end
function Oct2Dec(s)
-- s -> Base10 string
local s = Oct2Bin(s)
return Bin2Dec(s)
end
-- These functions are big-endian and will extend to 32 bits
-- BMAnd
-- BMNAnd
-- BMOr
-- BMXOr
-- BMNot
function BMAnd(v, m)
-- v -> hex string to be masked
-- m -> hex string mask
-- s -> hex string as masked
-- bv -> binary string of v
-- bm -> binary string mask
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
local i = 0
local s = ""
while (string.len(bv) < 32) do
bv = "0000"..bv
end
while (string.len(bm) < 32) do
bm = "0000"..bm
end
for i = 1, 32 do
cv = string.sub(bv, i, i)
cm = string.sub(bm, i, i)
if cv == cm then
if cv == "1" then
s = s.."1"
else
s = s.."0"
end
else
s = s.."0"
end
end
return Bin2Hex(s)
end
function BMNAnd(v, m)
-- v -> hex string to be masked
-- m -> hex string mask
-- s -> hex string as masked
-- bv -> binary string of v
-- bm -> binary string mask
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
local i = 0
local s = ""
while (string.len(bv) < 32) do
bv = "0000"..bv
end
while (string.len(bm) < 32) do
bm = "0000"..bm
end
for i = 1, 32 do
cv = string.sub(bv, i, i)
cm = string.sub(bm, i, i)
if cv == cm then
if cv == "1" then
s = s.."0"
else
s = s.."1"
end
else
s = s.."1"
end
end
return Bin2Hex(s)
end
function BMOr(v, m)
-- v -> hex string to be masked
-- m -> hex string mask
-- s -> hex string as masked
-- bv -> binary string of v
-- bm -> binary string mask
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
local i = 0
local s = ""
while (string.len(bv) < 32) do
bv = "0000"..bv
end
while (string.len(bm) < 32) do
bm = "0000"..bm
end
for i = 1, 32 do
cv = string.sub(bv, i, i)
cm = string.sub(bm, i, i)
if cv == "1" then
s = s.."1"
elseif cm == "1" then
s = s.."1"
else
s = s.."0"
end
end
return Bin2Hex(s)
end
function BMXOr(v, m)
-- v -> hex string to be masked
-- m -> hex string mask
-- s -> hex string as masked
-- bv -> binary string of v
-- bm -> binary string mask
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
local i = 0
local s = ""
while (string.len(bv) < 32) do
bv = "0000"..bv
end
while (string.len(bm) < 32) do
bm = "0000"..bm
end
for i = 1, 32 do
cv = string.sub(bv, i, i)
cm = string.sub(bm, i, i)
if cv == "1" then
if cm == "0" then
s = s.."1"
else
s = s.."0"
end
elseif cm == "1" then
if cv == "0" then
s = s.."1"
else
s = s.."0"
end
else
-- cv and cm == "0"
s = s.."0"
end
end
return Bin2Hex(s)
end
function BMNot(v, m)
-- v -> hex string to be masked
-- m -> hex string mask
-- s -> hex string as masked
-- bv -> binary string of v
-- bm -> binary string mask
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
local i = 0
local s = ""
while (string.len(bv) < 32) do
bv = "0000"..bv
end
while (string.len(bm) < 32) do
bm = "0000"..bm
end
for i = 1, 32 do
cv = string.sub(bv, i, i)
cm = string.sub(bm, i, i)
if cm == "1" then
if cv == "1" then
-- turn off
s = s.."0"
else
-- turn on
s = s.."1"
end
else
-- leave untouched
s = s..cv
end
end
return Bin2Hex(s)
end
-- these functions shift right and left, adding zeros to lost or gained bits
-- returned values are 32 bits long
-- BShRight(v, nb)
-- BShLeft(v, nb)
function BShRight(v, nb)
-- v -> hexstring value to be shifted
-- nb -> number of bits to shift to the right
-- s -> binary string of v
local s = Hex2Bin(v)
while (string.len(s) < 32) do
s = "0000"..s
end
s = string.sub(s, 1, 32 - nb)
while (string.len(s) < 32) do
s = "0"..s
end
return Bin2Hex(s)
end
function BShLeft(v, nb)
-- v -> hexstring value to be shifted
-- nb -> number of bits to shift to the right
-- s -> binary string of v
local s = Hex2Bin(v)
while (string.len(s) < 32) do
s = "0000"..s
end
s = string.sub(s, nb + 1, 32)
while (string.len(s) < 32) do
s = s.."0"
end
return Bin2Hex(s)
end
print(Bin2Hex("11001010"))
LS0gQmluYXJ5LCBEZWNpbWFsLCBIZXhhZGVjaW1hbCwgT2N0YWwgY29udmVyc2lvbgotLSBBdXRob3I6IFRpbSBLZWxseSBhbmQgQW5kcmV3IFN0YWNleQotLSBXZWJzaXRlczogaHR0cDovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuY29tL0x1YS9jb2RlL0JpbkRlY0hleC5zaHRtbAotLSAgICAgICAgICAgaHR0cDovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnUubm8vfnN0YWNleS9Ib3dEaWRJRG9UaGF0L2lQYWQvQ29kZWEuaHRtbAotLSBMaWNlbmNlOiBTZWUgYmVsb3cKCi0tW1sKLyoKICogQ29weXJpZ2h0IChjKSAyMDA3IFRpbSBLZWxseS9EaWFsZWN0cm9uaWNzCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyAKICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIAogKiAiU29mdHdhcmUiKSwgIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyAKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCAKICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCAKICogcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIAogKiBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgCiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgCiAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiAKICogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIAogKiBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIAogKiBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgCiAqIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKi8KCi0tXV0KCi0tW1sKRm9ybWF0dGluZyBzdWl0YWJsZSBmb3IgQ29kZWEgb24gaVBhZCB0b2dldGhlciB3aXRoIG9jdGFsIGZ1bmN0aW9ucyBieQpBbmRyZXcgU3RhY2V5LiAgQWRkaXRpb25zIHJlbGVhc2VkIHVuZGVyIHRoZSBvcmlnaW5hbCBsaWNlbnNlLgotLV1dCgpsb2NhbCBoZXgyYmluID0gewogICAgICAgIFsiMCJdID0gIjAwMDAiLAogICAgICAgIFsiMSJdID0gIjAwMDEiLAogICAgICAgIFsiMiJdID0gIjAwMTAiLAogICAgICAgIFsiMyJdID0gIjAwMTEiLAogICAgICAgIFsiNCJdID0gIjAxMDAiLAogICAgICAgIFsiNSJdID0gIjAxMDEiLAogICAgICAgIFsiNiJdID0gIjAxMTAiLAogICAgICAgIFsiNyJdID0gIjAxMTEiLAogICAgICAgIFsiOCJdID0gIjEwMDAiLAogICAgICAgIFsiOSJdID0gIjEwMDEiLAogICAgICAgIFsiYSJdID0gIjEwMTAiLAogICAgICAgIFsiYiJdID0gIjEwMTEiLAogICAgICAgIFsiYyJdID0gIjExMDAiLAogICAgICAgIFsiZCJdID0gIjExMDEiLAogICAgICAgIFsiZSJdID0gIjExMTAiLAogICAgICAgIFsiZiJdID0gIjExMTEiCiAgICAgICAgfQoKCmxvY2FsIGJpbjJoZXggPSB7CiAgICBbIjAwMDAiXSA9ICIwIiwKICAgIFsiMDAwMSJdID0gIjEiLAogICAgWyIwMDEwIl0gPSAiMiIsCiAgICBbIjAwMTEiXSA9ICIzIiwKICAgIFsiMDEwMCJdID0gIjQiLAogICAgWyIwMTAxIl0gPSAiNSIsCiAgICBbIjAxMTAiXSA9ICI2IiwKICAgIFsiMDExMSJdID0gIjciLAogICAgWyIxMDAwIl0gPSAiOCIsCiAgICBbIjEwMDEiXSA9ICI5IiwKICAgIFsiMTAxMCJdID0gIkEiLAogICAgWyIxMDExIl0gPSAiQiIsCiAgICBbIjExMDAiXSA9ICJDIiwKICAgIFsiMTEwMSJdID0gIkQiLAogICAgWyIxMTEwIl0gPSAiRSIsCiAgICBbIjExMTEiXSA9ICJGIgp9Cgpsb2NhbCBiaW4yb2N0ID0gewogICAgWyIwMDAiXSA9ICIwIiwKICAgIFsiMDAxIl0gPSAiMSIsCiAgICBbIjAxMCJdID0gIjIiLAogICAgWyIwMTEiXSA9ICIzIiwKICAgIFsiMTAwIl0gPSAiNCIsCiAgICBbIjEwMSJdID0gIjUiLAogICAgWyIxMTAiXSA9ICI2IiwKICAgIFsiMTExIl0gPSAiNyIKfQoKbG9jYWwgb2N0MmJpbiA9IHsKICAgIFsiMCJdID0gIjAwMCIsCiAgICBbIjEiXSA9ICIwMDEiLAogICAgWyIyIl0gPSAiMDEwIiwKICAgIFsiMyJdID0gIjAxMSIsCiAgICBbIjQiXSA9ICIxMDAiLAogICAgWyI1Il0gPSAiMTAxIiwKICAgIFsiNiJdID0gIjExMCIsCiAgICBbIjciXSA9ICIxMTEiCn0KCgotLSBUaGVzZSBmdW5jdGlvbnMgYXJlIGJpZy1lbmRpYW4gYW5kIHRha2UgdXAgdG8gMzIgYml0cwoKLS0gSGV4MkJpbgotLSBCaW4ySGV4Ci0tIEhleDJEZWMKLS0gRGVjMkhleAotLSBCaW4yRGVjCi0tIERlYzJCaW4KCgpmdW5jdGlvbiBIZXgyQmluKHMpCgotLSBzIC0+IGhleGFkZWNpbWFsIHN0cmluZwoKbG9jYWwgcmV0ID0gIiIKbG9jYWwgaSA9IDAKCgogICAgZm9yIGkgaW4gc3RyaW5nLmdmaW5kKHMsICIuIikgZG8KICAgICAgICBpID0gc3RyaW5nLmxvd2VyKGkpCgogICAgICAgIHJldCA9IHJldC4uaGV4MmJpbltpXQoKICAgIGVuZAoKICAgIHJldHVybiByZXQKZW5kCgpmdW5jdGlvbiBCaW4ySGV4KHMpCgotLSBzIC0+IGJpbmFyeSBzdHJpbmcKCmxvY2FsIGwgPSAwCmxvY2FsIGggPSAiIgpsb2NhbCBiID0gIiIKbG9jYWwgcmVtCgpsID0gc3RyaW5nLmxlbihzKQpyZW0gPSBsICUgNApsID0gbC0xCmggPSAiIgoKICAgIC0tIG5lZWQgdG8gcHJlcGVuZCB6ZXJvcyB0byBlbGltaW5hdGUgbW9kIDQKICAgIGlmIChyZW0gPiAwKSB0aGVuCiAgICAgICAgcyA9IHN0cmluZy5yZXAoIjAiLCA0IC0gcmVtKS4ucwogICAgZW5kCgogICAgZm9yIGkgPSAxLCBsLCA0IGRvCiAgICAgICAgYiA9IHN0cmluZy5zdWIocywgaSwgaSszKQogICAgICAgIGggPSBoLi5iaW4yaGV4W2JdCiAgICBlbmQKCiAgICByZXR1cm4gaAoKZW5kCgpmdW5jdGlvbiBCaW4yT2N0KHMpCgotLSBzIC0+IGJpbmFyeSBzdHJpbmcKCmxvY2FsIGwgPSAwCmxvY2FsIGggPSAiIgpsb2NhbCBiID0gIiIKbG9jYWwgcmVtCgpsID0gc3RyaW5nLmxlbihzKQpyZW0gPSBsICUgMwpsID0gbC0xCmggPSAiIgoKICAgIC0tIG5lZWQgdG8gcHJlcGVuZCB6ZXJvcyB0byBlbGltaW5hdGUgbW9kIDMKICAgIGlmIChyZW0gPiAwKSB0aGVuCiAgICAgICAgcyA9IHN0cmluZy5yZXAoIjAiLCAzIC0gcmVtKS4ucwogICAgZW5kCgogICAgZm9yIGkgPSAxLCBsLCAzIGRvCiAgICAgICAgYiA9IHN0cmluZy5zdWIocywgaSwgaSsyKQogICAgICAgIGggPSBoLi5iaW4yb2N0W2JdCiAgICBlbmQKCiAgICByZXR1cm4gaAoKZW5kCgpmdW5jdGlvbiBPY3QyQmluKHMpCgotLSBzIC0+IG9jdGFsIHN0cmluZwoKbG9jYWwgcmV0ID0gIiIKbG9jYWwgaSA9IDAKCgogICAgZm9yIGkgaW4gc3RyaW5nLmdmaW5kKHMsICIuIikgZG8KICAgICAgICBpID0gc3RyaW5nLmxvd2VyKGkpCgogICAgICAgIHJldCA9IHJldC4ub2N0MmJpbltpXQoKICAgIGVuZAoKICAgIHJldHVybiByZXQKZW5kCgpmdW5jdGlvbiBCaW4yRGVjKHMpCgotLSBzIC0+IGJpbmFyeSBzdHJpbmcKCmxvY2FsIG51bSA9IDAKbG9jYWwgZXggPSBzdHJpbmcubGVuKHMpIC0gMQpsb2NhbCBsID0gMAoKICAgIGwgPSBleCArIDEKICAgIGZvciBpID0gMSwgbCBkbwogICAgICAgIGIgPSBzdHJpbmcuc3ViKHMsIGksIGkpCiAgICAgICAgaWYgYiA9PSAiMSIgdGhlbgogICAgICAgICAgICBudW0gPSBudW0gKyAyXmV4CiAgICAgICAgZW5kCiAgICAgICAgZXggPSBleCAtIDEKICAgIGVuZAoKICAgIHJldHVybiBzdHJpbmcuZm9ybWF0KCIldSIsIG51bSkKCmVuZAoKCgpmdW5jdGlvbiBEZWMyQmluKHMsIG51bSkKCi0tIHMgLT4gQmFzZTEwIHN0cmluZwotLSBudW0gIC0+IHN0cmluZyBsZW5ndGggdG8gZXh0ZW5kIHRvCgpsb2NhbCBuCgogICAgaWYgKG51bSA9PSBuaWwpIHRoZW4KICAgICAgICBuID0gMAogICAgZWxzZQogICAgICAgIG4gPSBudW0KICAgIGVuZAoKICAgIHMgPSBzdHJpbmcuZm9ybWF0KCIleCIsIHMpCgogICAgcyA9IEhleDJCaW4ocykKCiAgICB3aGlsZSBzdHJpbmcubGVuKHMpIDwgbiBkbwogICAgICAgIHMgPSAiMCIuLnMKICAgIGVuZAoKICAgIHJldHVybiBzCgplbmQKCgoKCmZ1bmN0aW9uIEhleDJEZWMocykKCi0tIHMgLT4gaGV4YWRlY2ltYWwgc3RyaW5nCgogICAgbG9jYWwgcyA9IEhleDJCaW4ocykKCiAgICByZXR1cm4gQmluMkRlYyhzKQoKZW5kCgoKCmZ1bmN0aW9uIERlYzJIZXgocykKCi0tIHMgLT4gQmFzZTEwIHN0cmluZwoKICAgIHMgPSBzdHJpbmcuZm9ybWF0KCIleCIsIHMpCgogICAgcmV0dXJuIHMKCmVuZAoKZnVuY3Rpb24gSGV4Mk9jdChzKQoKLS0gcyAtPiBoZXhhZGVjaW1hbCBzdHJpbmcKCiAgICBsb2NhbCBzID0gSGV4MkJpbihzKQoKICAgIHJldHVybiBCaW4yT2N0KHMpCgplbmQKCgoKZnVuY3Rpb24gT2N0MkhleChzKQoKLS0gcyAtPiBCYXNlOCBzdHJpbmcKCiAgICBsb2NhbCBzID0gT2N0MkJpbihzKQoKICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCmZ1bmN0aW9uIERlYzJPY3QocykKCi0tIHMgLT4gZGVjaW1hbCBzdHJpbmcKCiAgICBzID0gc3RyaW5nLmZvcm1hdCgiJW8iLCBzKQoKICAgIHJldHVybiBzCgplbmQKCgoKZnVuY3Rpb24gT2N0MkRlYyhzKQoKLS0gcyAtPiBCYXNlMTAgc3RyaW5nCgogICAgbG9jYWwgcyA9IE9jdDJCaW4ocykKCiAgICByZXR1cm4gQmluMkRlYyhzKQoKZW5kCgotLSBUaGVzZSBmdW5jdGlvbnMgYXJlIGJpZy1lbmRpYW4gYW5kIHdpbGwgZXh0ZW5kIHRvIDMyIGJpdHMKCi0tIEJNQW5kCi0tIEJNTkFuZAotLSBCTU9yCi0tIEJNWE9yCi0tIEJNTm90CgoKZnVuY3Rpb24gQk1BbmQodiwgbSkKCi0tIHYgICAgLT4gaGV4IHN0cmluZyB0byBiZSBtYXNrZWQKLS0gbSAgICAtPiBoZXggc3RyaW5nIG1hc2sKCi0tIHMgICAgLT4gaGV4IHN0cmluZyBhcyBtYXNrZWQKCi0tIGJ2ICAgLT4gYmluYXJ5IHN0cmluZyBvZiB2Ci0tIGJtICAgLT4gYmluYXJ5IHN0cmluZyBtYXNrCgpsb2NhbCBidiA9IEhleDJCaW4odikKbG9jYWwgYm0gPSBIZXgyQmluKG0pCgpsb2NhbCBpID0gMApsb2NhbCBzID0gIiIKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYnYpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBidiA9ICIwMDAwIi4uYnYKICAgICAgICBlbmQKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYm0pIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBibSA9ICIwMDAwIi4uYm0KICAgICAgICBlbmQKCgogICAgICAgIGZvciBpID0gMSwgMzIgZG8KICAgICAgICAgICAgICAgIGN2ID0gc3RyaW5nLnN1YihidiwgaSwgaSkKICAgICAgICAgICAgICAgIGNtID0gc3RyaW5nLnN1YihibSwgaSwgaSkKICAgICAgICAgICAgICAgIGlmIGN2ID09IGNtIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCgogICAgICAgICAgICAgICAgZW5kCiAgICAgICAgZW5kCgogICAgICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCgpmdW5jdGlvbiBCTU5BbmQodiwgbSkKCi0tIHYgICAgLT4gaGV4IHN0cmluZyB0byBiZSBtYXNrZWQKLS0gbSAgICAtPiBoZXggc3RyaW5nIG1hc2sKCi0tIHMgICAgLT4gaGV4IHN0cmluZyBhcyBtYXNrZWQKCi0tIGJ2ICAgLT4gYmluYXJ5IHN0cmluZyBvZiB2Ci0tIGJtICAgLT4gYmluYXJ5IHN0cmluZyBtYXNrCgpsb2NhbCBidiA9IEhleDJCaW4odikKbG9jYWwgYm0gPSBIZXgyQmluKG0pCgpsb2NhbCBpID0gMApsb2NhbCBzID0gIiIKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYnYpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBidiA9ICIwMDAwIi4uYnYKICAgICAgICBlbmQKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYm0pIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBibSA9ICIwMDAwIi4uYm0KICAgICAgICBlbmQKCgogICAgICAgIGZvciBpID0gMSwgMzIgZG8KICAgICAgICAgICAgICAgIGN2ID0gc3RyaW5nLnN1YihidiwgaSwgaSkKICAgICAgICAgICAgICAgIGNtID0gc3RyaW5nLnN1YihibSwgaSwgaSkKICAgICAgICAgICAgICAgIGlmIGN2ID09IGNtIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCgogICAgICAgICAgICAgICAgZW5kCiAgICAgICAgZW5kCgogICAgICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCgoKZnVuY3Rpb24gQk1Pcih2LCBtKQoKLS0gdiAgICAtPiBoZXggc3RyaW5nIHRvIGJlIG1hc2tlZAotLSBtICAgIC0+IGhleCBzdHJpbmcgbWFzawoKLS0gcyAgICAtPiBoZXggc3RyaW5nIGFzIG1hc2tlZAoKLS0gYnYgICAtPiBiaW5hcnkgc3RyaW5nIG9mIHYKLS0gYm0gICAtPiBiaW5hcnkgc3RyaW5nIG1hc2sKCmxvY2FsIGJ2ID0gSGV4MkJpbih2KQpsb2NhbCBibSA9IEhleDJCaW4obSkKCmxvY2FsIGkgPSAwCmxvY2FsIHMgPSAiIgoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihidikgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJ2ID0gIjAwMDAiLi5idgogICAgICAgIGVuZAoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihibSkgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJtID0gIjAwMDAiLi5ibQogICAgICAgIGVuZAoKCiAgICAgICAgZm9yIGkgPSAxLCAzMiBkbwogICAgICAgICAgICAgICAgY3YgPSBzdHJpbmcuc3ViKGJ2LCBpLCBpKQogICAgICAgICAgICAgICAgY20gPSBzdHJpbmcuc3ViKGJtLCBpLCBpKQogICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICBlbHNlaWYgY20gPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzLi4iMCIKICAgICAgICAgICAgICAgIGVuZAogICAgICAgIGVuZAoKICAgICAgICByZXR1cm4gQmluMkhleChzKQoKZW5kCgpmdW5jdGlvbiBCTVhPcih2LCBtKQoKLS0gdiAgICAtPiBoZXggc3RyaW5nIHRvIGJlIG1hc2tlZAotLSBtICAgIC0+IGhleCBzdHJpbmcgbWFzawoKLS0gcyAgICAtPiBoZXggc3RyaW5nIGFzIG1hc2tlZAoKLS0gYnYgICAtPiBiaW5hcnkgc3RyaW5nIG9mIHYKLS0gYm0gICAtPiBiaW5hcnkgc3RyaW5nIG1hc2sKCmxvY2FsIGJ2ID0gSGV4MkJpbih2KQpsb2NhbCBibSA9IEhleDJCaW4obSkKCmxvY2FsIGkgPSAwCmxvY2FsIHMgPSAiIgoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihidikgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJ2ID0gIjAwMDAiLi5idgogICAgICAgIGVuZAoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihibSkgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJtID0gIjAwMDAiLi5ibQogICAgICAgIGVuZAoKCiAgICAgICAgZm9yIGkgPSAxLCAzMiBkbwogICAgICAgICAgICAgICAgY3YgPSBzdHJpbmcuc3ViKGJ2LCBpLCBpKQogICAgICAgICAgICAgICAgY20gPSBzdHJpbmcuc3ViKGJtLCBpLCBpKQogICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgY20gPT0gIjAiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgZWxzZWlmIGNtID09ICIxIiB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGN2ID09ICIwIiB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMuLiIxIgogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMuLiIwIgogICAgICAgICAgICAgICAgICAgICAgICBlbmQKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgLS0gY3YgYW5kIGNtID09ICIwIgogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICBlbmQKICAgICAgICBlbmQKCiAgICAgICAgcmV0dXJuIEJpbjJIZXgocykKCmVuZAoKCmZ1bmN0aW9uIEJNTm90KHYsIG0pCgotLSB2ICAgIC0+IGhleCBzdHJpbmcgdG8gYmUgbWFza2VkCi0tIG0gICAgLT4gaGV4IHN0cmluZyBtYXNrCgotLSBzICAgIC0+IGhleCBzdHJpbmcgYXMgbWFza2VkCgotLSBidiAgIC0+IGJpbmFyeSBzdHJpbmcgb2YgdgotLSBibSAgIC0+IGJpbmFyeSBzdHJpbmcgbWFzawoKbG9jYWwgYnYgPSBIZXgyQmluKHYpCmxvY2FsIGJtID0gSGV4MkJpbihtKQoKbG9jYWwgaSA9IDAKbG9jYWwgcyA9ICIiCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKGJ2KSA8IDMyKSBkbwogICAgICAgICAgICAgICAgYnYgPSAiMDAwMCIuLmJ2CiAgICAgICAgZW5kCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKGJtKSA8IDMyKSBkbwogICAgICAgICAgICAgICAgYm0gPSAiMDAwMCIuLmJtCiAgICAgICAgZW5kCgoKICAgICAgICBmb3IgaSA9IDEsIDMyIGRvCiAgICAgICAgICAgICAgICBjdiA9IHN0cmluZy5zdWIoYnYsIGksIGkpCiAgICAgICAgICAgICAgICBjbSA9IHN0cmluZy5zdWIoYm0sIGksIGkpCiAgICAgICAgICAgICAgICBpZiBjbSA9PSAiMSIgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICBpZiBjdiA9PSAiMSIgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIHR1cm4gb2ZmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMuLiIwIgogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gdHVybiBvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzLi4iMSIKICAgICAgICAgICAgICAgICAgICAgICAgZW5kCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIC0tIGxlYXZlIHVudG91Y2hlZAogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uY3YKCiAgICAgICAgICAgICAgICBlbmQKICAgICAgICBlbmQKCiAgICAgICAgcmV0dXJuIEJpbjJIZXgocykKCmVuZAoKCi0tIHRoZXNlIGZ1bmN0aW9ucyBzaGlmdCByaWdodCBhbmQgbGVmdCwgYWRkaW5nIHplcm9zIHRvIGxvc3Qgb3IgZ2FpbmVkIGJpdHMKLS0gcmV0dXJuZWQgdmFsdWVzIGFyZSAzMiBiaXRzIGxvbmcKCi0tIEJTaFJpZ2h0KHYsIG5iKQotLSBCU2hMZWZ0KHYsIG5iKQoKCmZ1bmN0aW9uIEJTaFJpZ2h0KHYsIG5iKQoKLS0gdiAgICAtPiBoZXhzdHJpbmcgdmFsdWUgdG8gYmUgc2hpZnRlZAotLSBuYiAgIC0+IG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0IHRvIHRoZSByaWdodAoKLS0gcyAgICAtPiBiaW5hcnkgc3RyaW5nIG9mIHYKCmxvY2FsIHMgPSBIZXgyQmluKHYpCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKHMpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBzID0gIjAwMDAiLi5zCiAgICAgICAgZW5kCgogICAgICAgIHMgPSBzdHJpbmcuc3ViKHMsIDEsIDMyIC0gbmIpCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKHMpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBzID0gIjAiLi5zCiAgICAgICAgZW5kCgogICAgICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCmZ1bmN0aW9uIEJTaExlZnQodiwgbmIpCgotLSB2ICAgIC0+IGhleHN0cmluZyB2YWx1ZSB0byBiZSBzaGlmdGVkCi0tIG5iICAgLT4gbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQgdG8gdGhlIHJpZ2h0CgotLSBzICAgIC0+IGJpbmFyeSBzdHJpbmcgb2YgdgoKbG9jYWwgcyA9IEhleDJCaW4odikKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4ocykgPCAzMikgZG8KICAgICAgICAgICAgICAgIHMgPSAiMDAwMCIuLnMKICAgICAgICBlbmQKCiAgICAgICAgcyA9IHN0cmluZy5zdWIocywgbmIgKyAxLCAzMikKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4ocykgPCAzMikgZG8KICAgICAgICAgICAgICAgIHMgPSBzLi4iMCIKICAgICAgICBlbmQKCiAgICAgICAgcmV0dXJuIEJpbjJIZXgocykKCmVuZAoKCnByaW50KEJpbjJIZXgoIjExMDAxMDEwIikp