algorithm the stern brocot number system - andstudy/forge GitHub Wiki
- ๊ทธ๋ํ๋ฅผ ์ ๋ค์ฌ๋ค ๋ณด๋ฉด ์ซ์์ ๋ฐฐ์ด์ ๊ท์น์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค. ํ์ง๋ง ํ์ด์ "์ฐธ๊ณ ๋ก, ์ ๋ฆฌ์ m/n๊ณผ p/q์ ๋์๋ฅผ ๋น๊ตํ๋๋ฐ ์ค์ ๋ก m์ n์ผ๋ก, p๋ฅผ q๋ก ๋๋์ด ์ค์ ๋ณ์์ ๋์ ํ๋ ์ผ์ ํ์ง ๋ง์." ๋ผ๊ณ ๋์ด ์๋๋ฐ.... ์ ์ค์ ๋ก ๋๋์์ต๋๋ค ๋จ float์ผ๋ก ํ๋ฉด ์ ๋๋ก ๋น๊ต๊ฐ ๋ ๊บผ ๊ฐ์ง ์์ double๋ก ํ์ด์.
- UVa์์๋ Accepted๋ฅผ ๋ฐ์์ง๋ง (UVa์์๋ Solved๋ฅผ Accepted๋ผ๊ณ ํํํฉ๋๋ค) PC์์๋ Presentation Error๋ฅผ ๋ฐ์์ต๋๋ค. ์ ๋ฒ์๋ ๋น์ทํ ๋ฌธ์ ๋ก ๋ฉ์ผ ๋ณด๋ธ์ ์ด ์์๋๋ฐ MD5๋ฌธ์ ๋ผ๊ณ ํ๋๊ฑฐ ๊ฐ์๋ฐ. ์ด๋ฒ์๋ ๋ฉ์ผ ๋ณด๋์ผ๋ ๋ช์ผ ์ด๋ด๋ก ๊ณ ์ณ์ง๊บผ๋ผ ์๊ฐํด์.
๋ต์ฅ์ด ์์ต๋๋ค.
Hello,
there were a mistake with the md5sum check, as some time in the past we fixed the 'correct' output and the people in charge, possibly forgot to actualize the database. Sorry and thanks. Take a look in a few minutes, as now we are rejudging all the submissions. I hope yours will get a 'Solved' verdict.
Miguel
- ์ด์ Solved๋ผ๊ณ ๋จ๋ค์
#include <iostream>
using namespace std;
struct Number
{
int numerator;
int denominator;
double GetRatio()
{
if( denominator == 0 ) return -1;
return ((double)numerator)/denominator;
}
bool operator!=(Number& rhs)
{
return (rhs.numerator!=numerator)||(rhs.denominator!=denominator);
}
Number operator+(Number& rhs)
{
Number Temp = *this;
Temp.numerator += rhs.numerator;
Temp.denominator += rhs.denominator;
return Temp;
}
};
int main()
{
int n, d;
while( cin >> n >> d )
{
if( n == 1 && d == 1 ) break;
Number Input = {n, d}, Now = {1, 1};
Number LeftNumber = {0, 1}, RightNumber = {1, 0};
while( Now != Input )
{
if(Input.GetRatio() > Now.GetRatio())
{
cout << "R";
LeftNumber = Now;
Now = Now+RightNumber;
}
else
{
cout << "L";
RightNumber = Now;
Now = Now+LeftNumber;
}
}
cout << endl;
}
}
- ํธ๋ฆฌ๋ผ๋ ๊ฐ๋
์ ๋์ฌ ํ์ฐธ ํค๋งธ์
- Mastojun๋ ์ฝ๋๋ณด๊ณ ์์ OTL
- ์ ์ถ๋ ฅ ์ฒ๋ฆฌ๋ ๋์ถฉ ํ์. ์ข ๋ฃ ์กฐ๊ฑด ์ฒ๋ฆฌํ์ง ์์.
- ํ ์คํธ์ฝ๋๋ ๋๋ฌด ๊ธธ์ด์ ๋บ์
' $Id: SternBrocotTree.vb 111 2008-02-26 01:37:22Z ์ ํฌ์ข
$
Public Class SternBrocotTree
Private _root As Node
ReadOnly Property Root() As Node
Get
If _root Is Nothing Then
_root = TreeMaker.CreateRoot()
End If
Return _root
End Get
End Property
Function GetPath(ByVal aRational As Rational) As String
Dim path As String = ""
Dim aNode As Node = Root
While aRational <> aNode.Rational
If aRational < aNode.Rational Then
path += "L"
aNode = aNode.Left
ElseIf aRational > aNode.Rational Then
path += "R"
aNode = aNode.Right
End If
End While
Return path
End Function
End Class
' $Id: Rational.vb 109 2008-02-26 01:16:04Z ์ ํฌ์ข
$
Public Class Rational
Sub New(ByVal numerator As Integer, ByVal denominator As Integer)
_numerator = numerator
_denominator = denominator
End Sub
Sub New(ByVal leftVal As Rational, ByVal rightVal As Rational)
_numerator = leftVal.Numerator + rightVal.Numerator
_denominator = leftVal.Denominator + rightVal.Denominator
End Sub
Private _numerator As Integer
ReadOnly Property Numerator() As Integer
Get
Return _numerator
End Get
End Property
Private _denominator As Integer
ReadOnly Property Denominator() As Integer
Get
Return _denominator
End Get
End Property
Shared Operator <(ByVal leftVal As Rational, ByVal rightVal As Rational) As Boolean
If leftVal = rightVal Then
Return False
Else
Return Not (leftVal > rightVal)
End If
End Operator
Shared Operator >(ByVal leftVal As Rational, ByVal rightVal As Rational) As Boolean
Return (leftVal.Numerator * rightVal.Denominator) > (rightVal.Numerator * leftVal.Denominator)
End Operator
Shared Operator =(ByVal leftVal As Rational, ByVal rightVal As Rational) As Boolean
Return (leftVal.Numerator * rightVal.Denominator) = (rightVal.Numerator * leftVal.Denominator)
End Operator
Shared Operator <>(ByVal leftVal As Rational, ByVal rightVal As Rational) As Boolean
Return Not (leftVal = rightVal)
End Operator
Overrides Function Equals(ByVal compared As Object) As Boolean
Return Me = compared
End Function
End Class
' $Id: Node.vb 113 2008-02-26 02:06:51Z ์ ํฌ์ข
$
Public Class Node
Private _left As Node
ReadOnly Property Left() As Node
Get
If _left Is Nothing Then
_left = TreeMaker.CreateLeftNode(Me)
End If
Return _left
End Get
End Property
Private _right As Node
ReadOnly Property Right() As Node
Get
If _right Is Nothing Then
_right = TreeMaker.CreateRightNode(Me)
End If
Return _right
End Get
End Property
Private _rational As Rational
Property Rational() As Rational
Get
Return _rational
End Get
Set(ByVal value As Rational)
_rational = value
End Set
End Property
End Class
' $Id: TreeMaker.vb 113 2008-02-26 02:06:51Z ์ ํฌ์ข
$
Module TreeMaker
Private _rationals As List(Of Rational)
Sub InitRationals()
_rationals = New List(Of Rational)
_rationals.Add(New Rational(0, 1))
_rationals.Add(New Rational(1, 1))
_rationals.Add(New Rational(1, 0))
End Sub
Function CreateRoot() As Node
InitRationals()
Dim root As Node = New Node
root.Rational = _rationals(1)
Return root
End Function
Function CreateLeftRational(ByVal parentRational As Rational) As Rational
Dim matchIndex As Integer = _rationals.IndexOf(parentRational)
Dim left As Rational = _rationals(matchIndex - 1)
Dim leftRational As Rational = New Rational(left, parentRational)
_rationals.Insert(matchIndex, leftRational)
Return leftRational
End Function
Function CreateRightRational(ByVal parentRational As Rational) As Rational
Dim matchIndex As Integer = _rationals.IndexOf(parentRational)
Dim right As Rational = _rationals(matchIndex + 1)
Dim rightRational As Rational = New Rational(parentRational, right)
_rationals.Insert(matchIndex + 1, rightRational)
Return rightRational
End Function
Function CreateLeftNode(ByVal parentNode As Node) As Node
Dim left As Node = New Node
left.Rational = CreateLeftRational(parentNode.Rational)
Return left
End Function
Function CreateRightNode(ByVal parentNode As Node) As Node
Dim right As Node = New Node
right.Rational = CreateRightRational(parentNode.Rational)
Return right
End Function
End Module
Module ModuleMain
Sub Main()
While True
Dim input As String = Console.ReadLine()
Dim tree As SternBrocotTree = New SternBrocotTree
Dim rational As Rational = GetRationalFromInput(input)
Console.WriteLine(tree.GetPath(rational))
End While
End Sub
Function GetRationalFromInput(ByVal input As String) As Rational
Dim separator() As Char = {" "c}
Dim strs() As String = input.Split(separator, StringSplitOptions.RemoveEmptyEntries)
Dim numerator As Integer = Integer.Parse(strs(0))
Dim denominator As Integer = Integer.Parse(strs(1))
Return New Rational(numerator, denominator)
End Function
End Module
-
ํ์ด
- ๋ถ์๋ฅผ ๋ํ๋ด๋ FraExpress ๋ฅผ ์ด์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํจ
- ๋ถ์ ๊ฐ์ ํฌ๊ธฐ ๋น๊ต๋ ๋ถ์ ๋ถ๋ชจ ํญ์ด๋์ ํตํด ๋น๊ตํ์๋ค. ์์ซ์ ๋น๊ต๋ฅผ ํผํจ
- a/b ์ x/y์ ๋น๊ต๋ ay ์ bx์ ๊ฐ์ ๋น๊ต๋ฅผ ํตํด ๊ตฌํ๋ค
- ์ค์ ํธ๋ฆฌ ์ํ๋ 1/1๋ก๋ถํฐ ํ์ฌ ๋
ธ๋ ๊ฐ๋ณด๋ค ํฌ๋ฉด ์ค๋ฅธ์ชฝ ์์ผ๋ฉด ์ผ์ชฝ์ผ๋ก ์ด๋ ๋๊ฒ ๊ตฌํ ํ์๋ค
- ์ด๋ ์์ ์ ํ์ฌ ๋ ธ๋,์ผ์ชฝ ๋ ธ๋,์ค๋ฅธ์ชฝ ๋ ธ๋์ ๋ณ๊ฒฝ์ผ๋ก ๊ตฌํ
-
์์ค
import java.io.IOException; public class Main implements Runnable { static String ReadLn(int maxLength) { // utility function to read from // stdin, // Provided by Programming-challenges, edit for style only byte line[] = new byte[maxLength]; int length = 0; int input = -1; try { while (length < maxLength) {// Read untill maxlength input = System.in.read(); if ((input < 0) || (input == '\n')) break; // or untill end of line ninput line[length++] += input; } if ((input < 0) && (length == 0)) return null; // eof return new String(line, 0, length); } catch (IOException e) { return null; } } public static void main(String[] args) { Main main = new Main(); main.run(); } public void run() { while(true){ String line = ReadLn(255).trim(); if(line == null || line.equals("1 1")){ break; } String [] strSplit = line.split(" "); if(strSplit.length!=2){ break; } String result = SBTreeTravelResult(new FraExpress( Integer.parseInt(strSplit[0]), Integer.parseInt(strSplit[1]))); System.out.println(result); } } public String SBTreeTravelResult(FraExpress searchVal) { FraExpress curNode = new FraExpress(1, 1); FraExpress leftNode = new FraExpress(0, 1); FraExpress rightNode = new FraExpress(1, 0); StringBuilder builder = new StringBuilder(); while (curNode.compareTo(searchVal) != 0) { int compareResult = searchVal.compareTo(curNode); if (compareResult > 0) { // ์ฐพ์ ๊ฐ์ด ํ์ฌ ๋ ธ๋๋ณด๋ค ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ์ผ๋ก ์์นญ builder.append("R"); leftNode = curNode; curNode = curNode.add(rightNode); } else if (compareResult < 0) { // ์ฐพ์ ๊ฐ์ด ํ์ฌ ๋ ธ๋๋ณด๋ค ์์ผ๋ฉด ์ผ์ชฝ์ผ๋ก ์์นญ builder.append("L"); rightNode = curNode;// ํ์ฌ ๋ ธ๋๋ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋๋จ curNode = curNode.add(leftNode); } else { // ํ์ ๋ ธ๋๊ฐ์ด ์ฐพ๋ ๊ฐ์ด๋ฉด ๊ฒ์ ์ข ๋ฃ break; } } return builder.toString(); } } class FraExpress implements Comparable<FraExpress> { private int denominator; // ๋ถ์ private int numerator; // ๋ถ๋ชจ public FraExpress(int denominator, int numerator) { this.denominator = denominator; this.numerator = numerator; } public int compareTo(FraExpress o) { /** * x a -- ์ -- ์ ๋น๊ต๋ xb ์ ay์ ๋น๊ต์ ๊ฐ๋ค y b */ int left = this.denominator * o.numerator; int right = this.numerator * o.denominator; if (left < right) return -1; else if (left > right) return 1; else return 0; } public FraExpress add(FraExpress addend) { return new FraExpress(this.denominator + addend.denominator, this.numerator + addend.numerator); } } -
ํ ์คํธ ์ผ์ด์ค
import junit.framework.TestCase; public class SternBrocot extends TestCase { public void testFraExpressCompare(){ FraExpress a = new FraExpress(1,2); FraExpress b = new FraExpress(1,1); FraExpress c = new FraExpress(2,1); assertEquals(0,a.compareTo(a)); assertEquals(-1,a.compareTo(b)); // a<b assertEquals(1,b.compareTo(a)); // b<a assertEquals(-1,a.compareTo(c)); // a<c } public void testSBTreeTravelResult(){ Main main = new Main(); assertEquals("LRRL", main.SBTreeTravelResult(new FraExpress(5,7))); assertEquals("RRLRRLRLLLLRLRRR", main.SBTreeTravelResult(new FraExpress(878 ,323))); } }
- ์คํด-๋ธ๋ก์ฝง ์ซ์ ์์คํ ์ด Binary Search Tree ์ธ ๊ฒ์ ์์์ฑ๋ ๋ฌธ์
-
Left(m/n), Current(m+M/n+N), Right(M/N) ์ ์ฌ๊ท๋ก ๋๋ ธ๋ค.
- ์
๋ ฅ๊ฐ์ ํฌ๊ธฐ๊ฐ ์๋นํ(?) ํด ๋ ์ฌ๊ท ํธ์ถ์ ํ๋ฉด ์คํ ์ค๋ฒ ํ๋ก์ฐ๊ฐ ๋ฐ์ํ ์ ์๋ค.
-
Solver2๋ฅผ C++๋ก ํฌํ ํ๊ณ ํ ์คํธ ํด๋ณธ๊ฒฐ๊ณผ, Debug๋ชจ๋๋ก ๋๋ฆฌ๋ฉด StackOverflow, Relase๋ชจ๋๋ก ๋๋ฆฌ๋ฉด ์ ๋๋ก ์ํ๋ฉ๋๋ค. ๊ผฌ๋ฆฌ์ฌ๊ท๊ฐ ๋์ํ๋๋ฏ ํ๋ฐ.. C#์ Debug๋กํ๋ , Release๋ก ํ๋ ๋ป์ด๋ฒ๋ฆฌ๋๊ตฐ์ (.NET 2005๋ก ํ ์คํธํ์ด์)
-
C# ์๋ Tail Recursion ์ด ๊ตฌํ ์๋์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
-
๊ทธ๋ฌ๊ณ ๋ณด๋ .NET ๊ฐ์ ๋จธ์ ์ค๋ฒํ๋ก์ฐ ๋ด์ ์ฃฝ์ธ๋ค๊ณ ํ์ ๋ ์ด ๋ฐฉ๋ฒ์ ์ผ์๋ค์
-
http://blogs.msdn.com/abhinaba/archive/2007/07/27/tail-recursion-on-net.aspx
-
์ ์๋ฃ๋ฅผ ์์ฝํ๋ฉด ".NET ์๋ Tail-Recursion IL ๋ช ๋ น์ด ์์ง๋ง, C#์์๋ ์ง์ํ์ง ์๋๋ค" ๋ญํจ ^^;
int TestFun() { return TestFun(); }
-
- ์
๋ ฅ๊ฐ์ ํฌ๊ธฐ๊ฐ ์๋นํ(?) ํด ๋ ์ฌ๊ท ํธ์ถ์ ํ๋ฉด ์คํ ์ค๋ฒ ํ๋ก์ฐ๊ฐ ๋ฐ์ํ ์ ์๋ค.
-
์์ ๊ฐ์ ์ฝ๋๋ก๋ ํ ์คํธ ํด๋ดค๋๋ฐ ๋ง์ฐฌ๊ฐ์ง์ ๊ฒฐ๊ณผ๊ฐ ๋์ต๋๋ค. Debug๋ชจ๋๋ ๊ผฌ๋ฆฌ์ฌ๊ท๊ฐ ์๋๋๊ฑด์ง.... ์๋๋ฉด C++ Release๋ชจ๋๋ ์คํ์ฉ๋์ด ์ฌํ์๋๊ฑด์ง....;;;
-
์คํ ์ฌ์ฉ๋์ ์ค์ด๋ ค๊ณ ๋ ธ๋ ฅํ์ผ๋..
-
๊ฒฐ๊ตญ Iteration ๋ฒ์ ๋ ๋ง๋ค์๋ค ^^
- scheme ์ผ๋ก ํ๊ธฐ ๋ฑ ์ข์ ๋ฌธ์ ๋ผ๋ ์๊ฐ.. ๋ง ^^;
- Tail Recursion ์ ๋ง๋ค๋ ค๊ณ ํ๋๋ฐ ์ถ๋ ฅ ๋๋ฌธ์ ๋ถ๊ฐ
using System;
using System.Collections.Generic;
using System.Text;
namespace Scort
{
class Solver
{
int m;
int n;
public Solver(int m, int n)
{
this.m = m;
this.n = n;
}
// invariant : the fraction must be existed between 0/1 and 1/0
public void Traverse(int lM, int lN, int rM, int rN)
{
// l(left) c(center) r(Right)
int cM = lM + rM;
int cN = lN + rN;
// c์ ์ผ์ชฝ
if (cM * n > m * cN)
{
Console.Write("L");
Traverse(lM, lN, cM, cN);
}
// c์ ์ค๋ฅธ์ชฝ
else if (cM * n < m * cN)
{
Console.Write("R");
Traverse(cM, cN, rM, rN);
}
}
public void Run()
{
if (m > 0 && n > 0)
{
Traverse(0, 1, 1, 0);
Console.WriteLine();
}
}
}
}
namespace Scort
{
class Solver2
{
int m, n;
int lM, lN, rM, rN;
int cM, cN;
public Solver2(int m, int n)
{
this.m = m;
this.n = n;
lM = 0; lN = 1;
rM = 1; rN = 0;
}
public void Traverse()
{
cM = lM + rM;
cN = lN + rN;
if (cM * n > m * cN)
{
Console.Write("L");
rM = cM;
rN = cN;
Traverse();
}
else if (cM * n < m * cN)
{
Console.Write("R");
lM = cM;
lN = cN;
Traverse();
}
}
public void Run()
{
if (m > 0 && n > 0)
{
Traverse();
Console.WriteLine();
}
}
}
}
namespace Scort
{
class Solver3
{
int m, n;
int lM, lN, rM, rN;
int cM, cN;
public Solver3(int m, int n)
{
this.m = m;
this.n = n;
lM = 0; lN = 1;
rM = 1; rN = 0;
}
public bool Traverse()
{
cM = lM + rM;
cN = lN + rN;
if (cM * n > m * cN)
{
Console.Write("L");
rM = cM;
rN = cN;
return false;
}
else if (cM * n < m * cN)
{
Console.Write("R");
lM = cM;
lN = cN;
return false;
}
return true;
}
public void Run()
{
if (m > 0 && n > 0)
{
while(true)
{
if( Traverse() == true )
{
break;
}
}
Console.WriteLine();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Scort
{
class Program
{
static void Main(string[] args)
{
// ๋์ผ๋ก ์ ๋ํ
์คํธ.. ํํ
// Recursion
Solver solver = new Solver(878,323);
solver.Run();
// ์คํ ๋ ์ฐ๋ Recursion
Solver2 solver2 = new Solver2(878, 323);
solver2.Run();
// Iteration
Solver3 solver3 = new Solver3(878, 323);
solver3.Run();
solver3 = new Solver3(2007777777, 3);
solver3.Run();
}
}
}
-
ํ๊ธ๋ก ์ฝ๋ฉ ํด๋ดค์ต๋๋ค. -0-
- ์ฌ๊ท๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐ
-
์ฝ๋
public class Main { private StringBuilder result ; public String SBTreeTravelResult(๋ถ์ ์ฐพ์๊ฐ) { ๋ถ์ ์ค๋ฅธ์ชฝ = new ๋ถ์(1,0); ๋ถ์ ์ผ์ชฝ = new ๋ถ์(0,1); result = new StringBuilder(); SBTreeTravelResult(์ฐพ์๊ฐ, ์ค๋ฅธ์ชฝ,์ผ์ชฝ); return result.toString(); } private void SBTreeTravelResult(๋ถ์ ์ฐพ์๊ฐ, ๋ถ์ ์ค๋ฅธ์ชฝ, ๋ถ์ ์ผ์ชฝ) { ๋ถ์ ํ์ฌ๋ ธ๋ = ์ค๋ฅธ์ชฝ.add(์ผ์ชฝ); if(์ฐพ์๊ฐ.compareTo(ํ์ฌ๋ ธ๋) ==0){ return ; } if(์ฐพ์๊ฐ.compareTo(ํ์ฌ๋ ธ๋) >0){ ์ผ์ชฝ = ํ์ฌ๋ ธ๋; result.append("R"); }else if(์ฐพ์๊ฐ.compareTo(ํ์ฌ๋ ธ๋) <0){ ์ค๋ฅธ์ชฝ = ํ์ฌ๋ ธ๋; result.append("L"); } SBTreeTravelResult(์ฐพ์๊ฐ, ์ค๋ฅธ์ชฝ, ์ผ์ชฝ); } } -
๋ถ์
public class ๋ถ์ implements Comparable<๋ถ์>{ private int ๋ถ๋ชจ; private int ๋ถ์; public ๋ถ์(int ๋ถ์, int ๋ถ๋ชจ) { this.๋ถ์ = ๋ถ์; this.๋ถ๋ชจ = ๋ถ๋ชจ; } public int compareTo(๋ถ์ ๋น๊ต๋์) { long ๊ฐ= ๋น๊ต๋์.๋ถ๋ชจ * this.๋ถ์; long ๋ = this.๋ถ๋ชจ * ๋น๊ต๋์.๋ถ์; if(๊ฐ == ๋){ return 0; }else if(๊ฐ > ๋ ){ return 1; }else{ return -1; } } public ๋ถ์ add(๋ถ์ ๋ง์) { int ๋ถ์ = this.๋ถ์ + ๋ง์.๋ถ์; int ๋ถ๋ชจ = this.๋ถ๋ชจ + ๋ง์.๋ถ๋ชจ; return new ๋ถ์(๋ถ์,๋ถ๋ชจ); } } -
ํ ์คํธ
import junit.framework.TestCase; public class MainTestCase extends TestCase { public void test๋ถ์๋น๊ตํ๊ธฐ(){ ๋ถ์ bun1 = new ๋ถ์(3,4); ๋ถ์ bun2 = new ๋ถ์(3,4); ๋ถ์ bun3 = new ๋ถ์(1,2); ๋ถ์ bun4 = new ๋ถ์(1,1); assertEquals(0, bun1.compareTo(bun2)); assertEquals(1, bun1.compareTo(bun3)); assertEquals(-1, bun3.compareTo(bun4)); } public void test๊ฒฐ๊ณผ๊ณ์ฐ(){ Main main = new Main(); assertEquals("LRRL", main.SBTreeTravelResult(new ๋ถ์(5,7))); assertEquals("RRLRRLRLLLLRLRRR", main.SBTreeTravelResult(new ๋ถ์(878 ,323))); } }