algorithm self describing sequence - andstudy/forge GitHub Wiki
- μ¬μ΄λ¬Έμ μΈμ€ μμλλ°, μ© μ¬μ΄κ±΄ μλλκ΅°μ. μ«μ λ²μκ° κ°μ₯ ν° κ±Έλ¦Όλ μ΄μμ΅λλ€.
- μ΅λ μ λ ₯κ°μ΄ 20μ΅ μ΄κΈ° λλ¬Έμ 20μ΅μ λ°°μ΄μ κ°κ°μ κ²°κ³Όλ₯Ό 미리 ꡬν΄λλ λ°©λ²μΌλ‘ μ²μμ μ κ·Ό νμΌλ λ°°μ΄μ ν¬κΈ°κ° 0xffffffffλ₯Ό λμκΈ° λλ¬Έμ μ»΄νμΌ μλ¬.
- λ°°μ΄μ λκ°λ‘ μͺΌκ°μ ν΄λ³΄μμ§λ§ μ€ν μμμ΄ μ νμ΄ λμ΄μ μλ¬.
- μ¬μ€ μ΄κ±΄ μ»΄νμΌ μ±κ³΅νλλΌλ μ€νμκ°μ΄ λ§€μ° ν¬κΈ° λλ¬Έμ (μΌλ°μ μΌλ‘ Big-O λ‘ νννμλ μ΅λκ°μ λν κ²°κ³Όκ° 1μ΅μ΄ λμΌλ©΄ μκ°μ΄κ³Όκ° λ¨μ΄μ§λλ€, 10μ΅μ΄μλ;) λΆκ°λ₯ν λ°©λ²μ΄μμ΅λλ€.
- κ²°κ΅μ μμΌλ‘ μκ°μ νμ΅λλ€. 1μ΄ μμνλ μ«μ, 2κ° μμνλ μ«μ, 3μ΄ μμνλ μ«μ, μ΄λ°μμΌλ‘ μ μ₯νλ©΄ λ°°μ΄μ ν¬κΈ°λ₯Ό λ§€μ° λ§μ΄ κ°μμν¬ μ μκ±°λ μ.
- νμ§λ§ μ΄ λ°©λ²λ ν¨μ λ΄λΆμ μμΌλ©΄ μ€νν¬κΈ° μ΄κ³Όλ‘ μ»΄νμΌ μλλκ΅°μ, κ·Έλμ μ μμΌλ‘ λμμ΅λλ€.
- μ¬ννΌ.... νλ€κ² Solvedλ°μλ€μ
#include <iostream>
using namespace std;
int Set[1000000];
int main()
{
Set[1] = 1;
Set[2] = 2;
Set[3] = 4;
Set[4] = 6;
Set[5] = 9;
int remember = 1;
for( int i = 6; i < 1000000; i++ )
{
int Temp = Set[i-1];
int j;
for( j = remember; j < i; j++ )
{
if( Set[j+1] >= i ) break;
}
Set[i] = Temp + j;
remember = j;
}
int in;
while( cin >> in )
{
if( in == 0 ) break;
int i;
for(i = 1; i < 1000000; i++ )
{
if( Set[i+1] > in ) break;
}
cout << i << endl;
}
return 0;
}
- μ΅μ’ μ μΌλ‘λ λͺμ€ μλλ μ½λμ§λ§ μμ² κ³ μνμ΅λλ€.
- μ€κ³λ λλ²μ΄λ λ€μ§μκ³ μ.
- TDDλ μ μλμ κ³ μΉκ³ μ€ννκ³ κ³ μΉκ³ μ€ννκ³ λ°λ³΅μ λͺμ λΉ μ§ κΈ°λΆμ΄μμ.
- ν° μ μΌλ μ±λ₯μ΄ μ’ λ¨μ΄μ§λ€μ.
' $Id: SelfDescribingSequence.vb 121 2008-03-04 05:18:53Z μ ν¬μ’
$
Public Class SelfDescribingSequence
Private _sequence As Dictionary(Of Integer, Integer) = New Dictionary(Of Integer, Integer)
Function GetValue(ByVal k As Integer) As Integer
Dim key As Integer = 1
Dim value As Integer = 1
While True
If Not _sequence.ContainsKey(key) Then
_sequence.Add(key, value)
End If
key = key + GetValueCount(value)
If key > k Then Exit While
value = value + 1
End While
Return value
End Function
Private Function GetValueCount(ByVal value As Integer) As Integer
While Not _sequence.ContainsKey(value)
value -= 1
End While
Return _sequence(value)
End Function
End Class
<TestClass()> _
Public Class SelfDescribingSequenceTest
<TestMethod()> _
Public Sub GetValueTestInit()
Dim sds As SelfDescribingSequence = New SelfDescribingSequence
Assert.AreEqual(1, sds.GetValue(1))
Assert.AreEqual(2, sds.GetValue(2))
Assert.AreEqual(2, sds.GetValue(3))
End Sub
<TestMethod()> _
Public Sub GetValueTestSmall()
Dim sds As SelfDescribingSequence = New SelfDescribingSequence
Assert.AreEqual(5, sds.GetValue(10))
Assert.AreEqual(8, sds.GetValue(22))
End Sub
<TestMethod()> _
Public Sub GetValueTestLarge()
Dim sds As SelfDescribingSequence = New SelfDescribingSequence
Assert.AreEqual(21, sds.GetValue(100))
Assert.AreEqual(356, sds.GetValue(9999))
Assert.AreEqual(1684, sds.GetValue(123456))
End Sub
<TestMethod()> _
Public Sub GetValueTestHuge()
Dim sds As SelfDescribingSequence = New SelfDescribingSequence
Assert.AreEqual(438744, sds.GetValue(1000000000))
Assert.AreEqual(673365, sds.GetValue(2000000000))
End Sub
End Class
μ΄κ² λ¬΄μ¨ μμ΄μΈμ§ μ΄ν΄νλ λ°μλ§ 1μκ°μ΄ λ κ±Έλ Έλ€μ. λ¨Έλ¦¬κ° κ΅³μ κ±° κ°μ κ±±μ μ΄μμ.
-- Library
function fwrite(fmt, ...)
return io.write(string.format(fmt, unpack(arg)))
end
function swrite(fmt, ...)
return string.format(fmt, unpack(arg))
end
function SwapBySize(i1, i2)
if (i2 < i1) then
return i2, i1
end
return i1, i2
end
function IsBetween(i, i1, i2)
i1, i2 = SwapBySize(i1, i2)
return i1 <= i and i <= i2
end
function PrintTable(t)
fwrite("%s\n", ConvertTableToString(t))
end
function ConvertTableToString(t)
s = "["
for _, k in pairs(t) do
s = s..tostring(k)..' '
end
s = s .. "]"
return s
end
function pack(...)
return arg
end
function PushBackTable(t, a, n)
for _ = 1, n do
t[#t + 1] = a
end
return t
end
-- UnitTest
UnitTest = {test = 0, success = 0, failed = 0}
function UnitTest:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function UnitTest:ShowResult()
if UnitTest.failed == 0 then
fwrite("Success : %d tests passed\n", UnitTest.success)
else
fwrite("Failed : %d in tests %d\n", UnitTest.failed, UnitTest.test)
end
end
function Check(name, actual)
UnitTest.test = UnitTest.test + 1
if not actual then
fwrite("Check Failed in %s\n", name)
UnitTest.failed = UnitTest.failed + 1
else
UnitTest.success = UnitTest.success + 1
end
end
function CheckEqual(name, expect, actual)
UnitTest.test = UnitTest.test + 1
if (expect ~= actual) then
fwrite("CheckEqual Failed in %s. %s expected but actual is %s\n", name, tostring(expect), tostring(actual))
UnitTest.failed = UnitTest.failed + 1
else
UnitTest.success = UnitTest.success + 1
end
end
function CheckArrayEqual(name, expect, actual)
UnitTest.test = UnitTest.test + 1
local fail = false
if (#expect == #actual) then
for k, v in pairs(expect) do
if (actual[k] ~= v) then
fail = true
break
end
end
else
fail = true
end
if (fail) then
fwrite("CheckArrayEqual Failed in %s. %s expected but actual is %s\n", name, ConvertTableToString(expect), ConvertTableToString(actual))
UnitTest.failed = UnitTest.failed + 1
else
UnitTest.success = UnitTest.success + 1
end
end
-- Algorithm
GSeq = {Nums = {1, 2}, k = 3, v = 3}
function GSeq:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function GSeq:GetNearSeq(num)
for i = 0, num do
if (self.Nums[num - i] ~= nil) then
return self.Nums[num - i]
end
end
assert(0)
return -1
end
-- k μ μμΉλ μμ§ μμ΄μ λ§λ€μ§ μμ μ΅μ΄μ key λ₯Ό κ°λ¦¬ν€κ³
-- v μ μμΉλ λ°λ‘ μ΄μ μ μ²λ¦¬ν μμ΄μ λ§μ§λ§ μμΉλ₯Ό κ°λ¦¬ν¨λ€.
-- μ¦, λ€μ μμ΄μ k λΆν° μμνκ³ ,
-- k λΌλ μ«μλ₯Ό v + 1 μμΉμμλΆν° f(k) λ§νΌ μΆκ°ν΄ μ£Όλ©΄ λλ€.
function GSeq:GetF(num)
while (self.v < num) do
self.Nums[self.v + 1] = self.k
if (self.Nums[self.k] ~= nil) then
self.v = self.v + self.Nums[self.k]
else
-- λ°λ‘ μ΄μ λ
μμ μ°Ύλλ€.
self.v = self.v + self:GetNearSeq(self.k)
end
self.k = self.k + 1
end
return self:GetNearSeq(num)
end
-- test part
do
local t = {1, 2, 3}
local k = PushBackTable(t, 6, 2)
CheckArrayEqual("PushBackTable", {1, 2, 3, 6, 6}, k)
end
do
local testSet =
{
4, 3,
5, 3,
6, 4,
7, 4,
8, 4,
9, 5
}
for i = 1, #testSet, 2 do
CheckEqual("GetF _ "..testSet[i], testSet[i + 1], GSeq:GetF(testSet[i]))
end
end
do
CheckEqual("GetF 1", 21, GSeq:GetF(100))
CheckEqual("GetF 1", 356, GSeq:GetF(9999))
CheckEqual("GetF 1", 1684, GSeq:GetF(123456))
-- 첫 λ°©λ²μΌλ‘ νμ λλ λ©λͺ¨λ¦¬κ° λΆμ‘±νλ€κ³ λμλ€. λ ...
-- μ΄μ νλ§ μ°μΌλ©΄μ μ§ννμ.
CheckEqual("GetF 1", 438744, GSeq:GetF(1000000000))
end
UnitTest:ShowResult()
-- input part
while 1 do
local count = io.read("*number")
if count == nil then
break
end
end