WeixiangYan/CodeTransOcean huggingface dataset:
Task: Numbers which are the cube roots of the product of their proper divisors








VB: Imports System

Module Module1
    Function dc8(ByVal n As Integer) As Boolean
        Dim count, p, d As Integer, res As Integer = 1
        While (n And 1) = 0 : n >>= 1 : res += 1 :  End While
        count = 1 : While n Mod 3 = 0 : n \= 3 : count += 1 : End While
        p = 5 : d = 4 : While p * p <= n
            res *= count : count = 1
            While n Mod p = 0 : n \= p : count += 1 : End While
            d = 6 - d : p += d
        End While
        If n > 1 Then Return res * count = 4
        Return res * count = 8
    End Function

    Sub Main(ByVal args As String())
        Console.WriteLine("First 50 numbers which are the cube roots of the products of " _
                          & "their proper divisors:")
        Dim n As Integer = 1, count As Integer = 0, lmt As Integer = 500
        While count < 5e6
            If n = 1 OrElse dc8(n) Then
                count += 1 : If count <= 50 Then
                    Console.Write("{0,3}{1}", n, If(count Mod 10 = 0, vbLf, " "))
                ElseIf count = lmt Then
                    Console.Write("{0,16:n0}th: {1:n0}" & vbLf, count, n) : lmt *= 10
                End If
            End If
            n += 1
        End While
    End Sub
End Module
Task: Sierpinski square curve








VB: option explicit


const pi180= 0.01745329251994329576923690768489 
const pi=3.1415926535897932384626433832795 
class turtle
   
   dim fso
   dim fn
   dim svg
   
   dim iang  
   dim ori   
   dim incr
   dim pdown
   dim clr
   dim x
   dim y

   public property let orient(n):ori = n*pi180 :end property
   public property let iangle(n):iang= n*pi180 :end property
   public sub pd() : pdown=true: end sub 
   public sub pu()  :pdown=FALSE :end sub 
   
   public sub rt(i)  
     ori=ori - i*iang:
     
   end sub 
   public sub lt(i):  
     ori=(ori + i*iang) 
     
   end sub
   
   public sub bw(l)
      x= x+ cos(ori+pi)*l*incr
      y= y+ sin(ori+pi)*l*incr
     
   end sub 
   
   public sub fw(l)
      dim x1,y1 
      x1=x + cos(ori)*l*incr
      y1=y + sin(ori)*l*incr
      if pdown then line x,y,x1,y1
      x=x1:y=y1
   end sub
   
   Private Sub Class_Initialize()  
      setlocale "us" 
      initsvg
      x=400:y=400:incr=100
      ori=90*pi180
      iang=90*pi180
      clr=0
      pdown=true
   end sub
   
   Private Sub Class_Terminate()   
      disply
   end sub
   
   private sub line (x,y,x1,y1)
      svg.WriteLine "<line x1=""" & x & """ y1= """& y & """ x2=""" & x1& """ y2=""" & y1 & """/>"
   end sub 

   private sub disply()
       dim shell
       svg.WriteLine "</svg></body></html>"
       svg.close
       Set shell = CreateObject("Shell.Application") 
       shell.ShellExecute fn,1,False
   end sub 

   private sub initsvg()
     dim scriptpath
     Set fso = CreateObject ("Scripting.Filesystemobject")
     ScriptPath= Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName, "\"))
     fn=Scriptpath & "SIERP.HTML"
     Set svg = fso.CreateTextFile(fn,True)
     if SVG IS nothing then wscript.echo "Can
     svg.WriteLine "<!DOCTYPE html>" &vbcrlf & "<html>" &vbcrlf & "<head>"
     svg.writeline "<style>" & vbcrlf & "line {stroke:rgb(255,0,0);stroke-width:.5}" &vbcrlf &"</style>"
     svg.writeline "</head>"&vbcrlf & "<body>"
     svg.WriteLine "<svg xmlns=""http://www.w3.org/2000/svg"" width=""800"" height=""800"" viewBox=""0 0 800 800"">" 
   end sub 
end class

















const raiz2=1.4142135623730950488016887242097
sub media_sierp (niv,sz)
   if niv=0 then x.fw sz: exit sub 
   media_sierp niv-1,sz
   x.lt 1
   x.fw sz*raiz2
   x.lt 1
    media_sierp niv-1,sz
   x.rt 2
   x.fw sz
   x.rt 2
  media_sierp niv-1,sz
   x.lt 1
   x.fw sz*raiz2
   x.lt 1 
    media_sierp niv-1,sz
end sub    












sub sierp(niv,sz)
   media_sierp niv,sz
   x.rt 2
   x.fw sz
   x.rt 2
   media_sierp niv,sz
   x.rt 2
   x.fw sz
   x.rt 2
end sub   
     
dim x
set x=new turtle
x.iangle=45
x.orient=0
x.incr=1
x.x=100:x.y=270

sierp 5,4
set x=nothing
Task: Tree from nesting levels








VB: Sub ShowTree(List() As Integer)
    Dim As Integer I, NestLevel = 0
    For I = 0 To Ubound(List)
        While List(I) < NestLevel
            Print "]";
            NestLevel -= 1
        Wend
        If List(I) = 0 Then 
            Print 
            Elseif I <> Lbound(List) Then Print ", ";
        End If
        While List(I) > NestLevel
            Print "[";
            NestLevel += 1
        Wend
        If NestLevel <> 0 Then Print NestLevel;
    Next I
End Sub

Dim As Integer list(0 To ...) = {0}
ShowTree(list())
Dim As Integer list0(0 To ...) = {1, 2, 4, 0}
ShowTree(list0())
Dim As Integer list1(0 To ...) = {3, 1, 3, 1, 0}
ShowTree(list1())
Dim As Integer list2(0 To ...) = {1, 2, 3, 1, 0}
ShowTree(list2())
Dim As Integer list3(0 To ...) = {3, 2, 1, 3, 0}
ShowTree(list3())
Dim As Integer list4(0 To ...) = {3, 3, 3, 1, 1, 3, 3, 3, 0}
ShowTree(list4())
Dim As Integer list5(0 To ...) = {1, 2, 4, 2, 2, 1, 0}
ShowTree(list5())

Sleep
Task: Calmo numbers








VB: include "isprime.kbs"

for n = 1 to 1000-1
	if isCalmo(n) then print n; " ";
next n
end

function isCalmo(n)
	limite = sqr(n)
	cont = 0: SumD = 0: SumQ = 0: k = 0: q = 0
	d = 2
	do
		q = n/d
		if n mod d = 0 then
			cont += 1
			SumD += d
			SumQ += q
			if cont = 3 then
				k += 3
				if not IsPrime(SumD) then return False
				if not IsPrime(SumQ) then return False
				cont = 0: SumD = 0: SumQ = 0
			end if
		end if
		d += 1
	until d >= limite
	if cont <> 0 or k = 0 then return False
	return True
end function
Task: Solve hanging lantern problem








VB: Dim n As Integer, c As Integer
Dim a() As Integer

Private Sub Command1_Click()
    Dim res As Integer
    If c < n Then Label3.Caption = "Please input completely.": Exit Sub
    res = getLantern(a())
    Label3.Caption = "Result：" + Str(res)
End Sub

Private Sub Text1_Change()
    If Val(Text1.Text) <> 0 Then
        n = Val(Text1.Text)
        ReDim a(1 To n) As Integer
    End If
End Sub


Private Sub Text2_KeyPress(KeyAscii As Integer)
    If KeyAscii = Asc(vbCr) Then
        If Val(Text2.Text) = 0 Then Exit Sub
        c = c + 1
        If c > n Then Exit Sub
        a(c) = Val(Text2.Text)
        List1.AddItem Str(a(c))
        Text2.Text = ""
    End If
End Sub

Function getLantern(arr() As Integer) As Integer
    Dim res As Integer, i As Integer
    For i = 1 To n
        If arr(i) <> 0 Then
            arr(i) = arr(i) - 1
            res = res + getLantern(arr())
            arr(i) = arr(i) + 1
        End If
    Next i
    If res = 0 Then res = 1
    getLantern = res
End Function
Task: Pseudo-random numbers_PCG32


C++: #include <array>
#include <iostream>

class PCG32 {
private:
    const uint64_t N = 6364136223846793005;
    uint64_t state = 0x853c49e6748fea9b;
    uint64_t inc = 0xda3e39cb94b95bdb;
public:
    uint32_t nextInt() {
        uint64_t old = state;
        state = old * N + inc;
        uint32_t shifted = (uint32_t)(((old >> 18) ^ old) >> 27);
        uint32_t rot = old >> 59;
        return (shifted >> rot) | (shifted << ((~rot + 1) & 31));
    }

    double nextFloat() {
        return ((double)nextInt()) / (1LL << 32);
    }

    void seed(uint64_t seed_state, uint64_t seed_sequence) {
        state = 0;
        inc = (seed_sequence << 1) | 1;
        nextInt();
        state = state + seed_state;
        nextInt();
    }
};

int main() {
    auto r = new PCG32();

    r->seed(42, 54);
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << r->nextInt() << '\n';
    std::cout << '\n';

    std::array<int, 5> counts{ 0, 0, 0, 0, 0 };
    r->seed(987654321, 1);
    for (size_t i = 0; i < 100000; i++) {
        int j = (int)floor(r->nextFloat() * 5.0);
        counts[j]++;
    }

    std::cout << "The counts for 100,000 repetitions are:\n";
    for (size_t i = 0; i < counts.size(); i++) {
        std::cout << "  " << i << " : " << counts[i] << '\n';
    }

    return 0;
}
Task: Pseudo-random numbers_Xorshift star


C++: #include <array>
#include <cstdint>
#include <iostream>

class XorShiftStar {
private:
    const uint64_t MAGIC = 0x2545F4914F6CDD1D;
    uint64_t state;
public:
    void seed(uint64_t num) {
        state = num;
    }

    uint32_t next_int() {
        uint64_t x;
        uint32_t answer;

        x = state;
        x = x ^ (x >> 12);
        x = x ^ (x << 25);
        x = x ^ (x >> 27);
        state = x;
        answer = ((x * MAGIC) >> 32);

        return answer;
    }

    float next_float() {
        return (float)next_int() / (1LL << 32);
    }
};

int main() {
    auto rng = new XorShiftStar();
    rng->seed(1234567);
    std::cout << rng->next_int() << '\n';
    std::cout << rng->next_int() << '\n';
    std::cout << rng->next_int() << '\n';
    std::cout << rng->next_int() << '\n';
    std::cout << rng->next_int() << '\n';
    std::cout << '\n';

    std::array<int, 5> counts = { 0, 0, 0, 0, 0 };
    rng->seed(987654321);
    for (int i = 0; i < 100000; i++) {
        int j = (int)floor(rng->next_float() * 5.0);
        counts[j]++;
    }
    for (size_t i = 0; i < counts.size(); i++) {
        std::cout << i << ": " << counts[i] << '\n';
    }

    return 0;
}
Task: Distinct power numbers


C++: #include <iostream>
#include <set>
#include <cmath>

int main() {
    std::set<int> values;
    for (int a=2; a<=5; a++)
        for (int b=2; b<=5; b++)
            values.insert(std::pow(a, b));
    
    for (int i : values)
        std::cout << i << " ";
    
    std::cout << std::endl;
    return 0;
}
Task: Next highest int from digits


C++: #include <algorithm>
#include <iostream>
#include <sstream>

#include <gmpxx.h>

using integer = mpz_class;

std::string to_string(const integer& n) {
    std::ostringstream out;
    out << n;
    return out.str();
}

integer next_highest(const integer& n) {
    std::string str(to_string(n));
    if (!std::next_permutation(str.begin(), str.end()))
        return 0;
    return integer(str);
}

int main() {
    for (integer n : {0, 9, 12, 21, 12453, 738440, 45072010, 95322020})
        std::cout << n << " -> " << next_highest(n) << '\n';
    integer big("9589776899767587796600");
    std::cout << big << " -> " << next_highest(big) << '\n';
    return 0;
}
Task: Joystick position


C++: #include <stdio.h>
#include <stdlib.h>

void clear() {
	for(int n = 0;n < 10; n++) {
		printf("\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\r\n\r\n\r\n");
	}
}

#define UP    "00^00\r\n00|00\r\n00000\r\n"
#define DOWN  "00000\r\n00|00\r\n00v00\r\n"
#define LEFT  "00000\r\n<--00\r\n00000\r\n"
#define RIGHT "00000\r\n00-->\r\n00000\r\n"
#define HOME  "00000\r\n00+00\r\n00000\r\n"

int main() {
	clear();
	system("stty raw");

	printf(HOME);
	printf("space to exit; wasd to move\r\n");
	char c = 1;

	while(c) {
		c = getc(stdin);
		clear();

		switch (c)
		{
			case 'a':
				printf(LEFT);
				break;
			case 'd':
				printf(RIGHT);
				break;
			case 'w':
				printf(UP);
				break;
			case 's':
				printf(DOWN);
				break;
			case ' ':
				c = 0;
				break;
			default:
				printf(HOME);
		};

		printf("space to exit; wasd key to move\r\n");
	}

	system("stty cooked");
	system("clear"); 
	return 1;
}
Task: Nimber arithmetic


C++: #include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>


uint32_t hpo2(uint32_t n) {
    return n & -n;
}


uint32_t lhpo2(uint32_t n) {
    uint32_t q = 0, m = hpo2(n);
    for (; m % 2 == 0; m >>= 1, ++q) {}
    return q;
}


uint32_t nimsum(uint32_t x, uint32_t y) {
    return x ^ y;
}


uint32_t nimprod(uint32_t x, uint32_t y) {
    if (x < 2 || y < 2)
        return x * y;
    uint32_t h = hpo2(x);
    if (x > h)
        return nimprod(h, y) ^ nimprod(x ^ h, y);
    if (hpo2(y) < y)
        return nimprod(y, x);
    uint32_t xp = lhpo2(x), yp = lhpo2(y);
    uint32_t comp = xp & yp;
    if (comp == 0)
        return x * y;
    h = hpo2(comp);
    return nimprod(nimprod(x >> h, y >> h), 3 << (h - 1));
}

void print_table(uint32_t n, char op, std::function<uint32_t(uint32_t, uint32_t)> func) {
    std::cout << ' ' << op << " |";
    for (uint32_t a = 0; a <= n; ++a)
        std::cout << std::setw(3) << a;
    std::cout << "\n--- -";
    for (uint32_t a = 0; a <= n; ++a)
        std::cout << "---";
    std::cout << '\n';
    for (uint32_t b = 0; b <= n; ++b) {
        std::cout << std::setw(2) << b << " |";
        for (uint32_t a = 0; a <= n; ++a)
            std::cout << std::setw(3) << func(a, b);
        std::cout << '\n';
    }
}

int main() {
    print_table(15, '+', nimsum);
    printf("\n");
    print_table(15, '*', nimprod);
    const uint32_t a = 21508, b = 42689;
    std::cout << '\n';
    std::cout << a << " + " << b << " = " << nimsum(a, b) << '\n';
    std::cout << a << " * " << b << " = " << nimprod(a, b) << '\n';
    return 0;
}
Task: Text completion


C++: #include <algorithm>
#include <fstream>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>


int levenshtein_distance(const std::string& str1, const std::string& str2) {
    size_t m = str1.size(), n = str2.size();
    std::vector<int> cost(n + 1);
    std::iota(cost.begin(), cost.end(), 0);
    for (size_t i = 0; i < m; ++i) {
        cost[0] = i + 1;
        int prev = i;
        for (size_t j = 0; j < n; ++j) {
            int c = (str1[i] == str2[j]) ? prev
                : 1 + std::min(std::min(cost[j + 1], cost[j]), prev);
            prev = cost[j + 1];
            cost[j + 1] = c;
        }
    }
    return cost[n];
}

template <typename T>
void print_vector(const std::vector<T>& vec) {
    auto i = vec.begin();
    if (i == vec.end())
        return;
    std::cout << *i++;
    for (; i != vec.end(); ++i)
        std::cout << ", " << *i;
}

int main(int argc, char** argv) {
    if (argc != 3) {
        std::cerr << "usage: " << argv[0] << " dictionary word\n";
        return EXIT_FAILURE;
    }
    std::ifstream in(argv[1]);
    if (!in) {
        std::cerr << "Cannot open file " << argv[1] << '\n';
        return EXIT_FAILURE;
    }
    std::string word(argv[2]);
    if (word.empty()) {
        std::cerr << "Word must not be empty\n";
        return EXIT_FAILURE;
    }
    constexpr size_t max_dist = 4;
    std::vector<std::string> matches[max_dist + 1];
    std::string match;
    while (getline(in, match)) {
        int distance = levenshtein_distance(word, match);
        if (distance <= max_dist)
            matches[distance].push_back(match);
    }
    for (size_t dist = 0; dist <= max_dist; ++dist) {
        if (matches[dist].empty())
            continue;
        std::cout << "Words at Levenshtein distance of " << dist
            << " (" << 100 - (100 * dist)/word.size()
            << "% similarity) from '" << word << "':\n";
        print_vector(matches[dist]);
        std::cout << "\n\n";
    }
    return EXIT_SUCCESS;
}
Task: Longest substrings without repeating characters


C++: #include <iostream>
#include <fstream>
#include <set>
#include <sstream>
#include <string>
#include <vector>

std::vector<std::string> longest_substrings_without_repeats(const std::string& str) {
    size_t max_length = 0;
    std::vector<std::string> result;
    size_t length = str.size();
    for (size_t offset = 0; offset < length; ++offset) {
        std::set<char> characters;
        size_t len = 0;
        for (; offset + len < length; ++len) {
            if (characters.find(str[offset + len]) != characters.end())
                break;
            characters.insert(str[offset + len]);
        }
        if (len > max_length) {
            result.clear();
            max_length = len;
        }
        if (len == max_length)
            result.push_back(str.substr(offset, max_length));
    }
    return result;
}

void print_strings(const std::vector<std::string>& strings) {
    std::cout << "[";
    for (size_t i = 0, n = strings.size(); i < n; ++i) {
        if (i > 0)
            std::cout << ", ";
        std::cout << '\'' << strings[i] << '\'';
    }
    std::cout << "]";
}

void test1() {
    for (std::string str : { "xyzyabcybdfd", "xyzyab", "zzzzz", "a", "thisisastringtest", "" }) {
        std::cout << "Input: '" << str << "'\nResult: ";
        print_strings(longest_substrings_without_repeats(str));
        std::cout << "\n\n";
    }
}

std::string slurp(std::istream& in) {
    std::ostringstream out;
    out << in.rdbuf();
    return out.str();
}

void test2(const std::string& filename) {
    std::ifstream in(filename);
    if (!in) {
        std::cerr << "Cannot open file '" << filename << "'.\n";
        return;
    }
    std::cout << "Longest substring with no repeats found in '" << filename << "': ";
    print_strings(longest_substrings_without_repeats(slurp(in)));
    std::cout << "\n";
}

int main() {
    test1();
    test2("unixdict.txt");
}
Task: Fermat numbers


C++: #include <iostream>
#include <vector>
#include <boost/integer/common_factor.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/miller_rabin.hpp>

typedef boost::multiprecision::cpp_int integer;

integer fermat(unsigned int n) {
    unsigned int p = 1;
    for (unsigned int i = 0; i < n; ++i)
        p *= 2;
    return 1 + pow(integer(2), p);
}

inline void g(integer& x, const integer& n) {
    x *= x;
    x += 1;
    x %= n;
}

integer pollard_rho(const integer& n) {
    integer x = 2, y = 2, d = 1, z = 1;
    int count = 0;
    for (;;) {
        g(x, n);
        g(y, n);
        g(y, n);
        d = abs(x - y);
        z = (z * d) % n;
        ++count;
        if (count == 100) {
            d = gcd(z, n);
            if (d != 1)
                break;
            z = 1;
            count = 0;
        }
    }
    if (d == n)
        return 0;
    return d;
}

std::vector<integer> get_prime_factors(integer n) {
    std::vector<integer> factors;
    for (;;) {
        if (miller_rabin_test(n, 25)) {
            factors.push_back(n);
            break;
        }
        integer f = pollard_rho(n);
        if (f == 0) {
            factors.push_back(n);
            break;
        }
        factors.push_back(f);
        n /= f;
    }
    return factors;
}

void print_vector(const std::vector<integer>& factors) {
    if (factors.empty())
        return;
    auto i = factors.begin();
    std::cout << *i++;
    for (; i != factors.end(); ++i)
        std::cout << ", " << *i;
    std::cout << '\n';
}

int main() {
    std::cout << "First 10 Fermat numbers:\n";
    for (unsigned int i = 0; i < 10; ++i)
        std::cout << "F(" << i << ") = " << fermat(i) << '\n';
    std::cout << "\nPrime factors:\n";
    for (unsigned int i = 0; i < 9; ++i) {
        std::cout << "F(" << i << "): ";
        print_vector(get_prime_factors(fermat(i)));
    }
    return 0;
}
Task: Two bullet roulette


C++: #include <array>
#include <iomanip>
#include <iostream>
#include <random>
#include <sstream>

class Roulette {
private:
    std::array<bool, 6> cylinder;

    std::mt19937 gen;
    std::uniform_int_distribution<> distrib;

    int next_int() {
        return distrib(gen);
    }

    void rshift() {
        std::rotate(cylinder.begin(), cylinder.begin() + 1, cylinder.end());
    }

    void unload() {
        std::fill(cylinder.begin(), cylinder.end(), false);
    }

    void load() {
        while (cylinder[0]) {
            rshift();
        }
        cylinder[0] = true;
        rshift();
    }

    void spin() {
        int lim = next_int();
        for (int i = 1; i < lim; i++) {
            rshift();
        }
    }

    bool fire() {
        auto shot = cylinder[0];
        rshift();
        return shot;
    }

public:
    Roulette() {
        std::random_device rd;
        gen = std::mt19937(rd());
        distrib = std::uniform_int_distribution<>(1, 6);

        unload();
    }

    int method(const std::string &s) {
        unload();
        for (auto c : s) {
            switch (c) {
            case 'L':
                load();
                break;
            case 'S':
                spin();
                break;
            case 'F':
                if (fire()) {
                    return 1;
                }
                break;
            }
        }
        return 0;
    }
};

std::string mstring(const std::string &s) {
    std::stringstream ss;
    bool first = true;

    auto append = [&ss, &first](const std::string s) {
        if (first) {
            first = false;
        } else {
            ss << ", ";
        }
        ss << s;
    };

    for (auto c : s) {
        switch (c) {
        case 'L':
            append("load");
            break;
        case 'S':
            append("spin");
            break;
        case 'F':
            append("fire");
            break;
        }
    }

    return ss.str();
}

void test(const std::string &src) {
    const int tests = 100000;
    int sum = 0;

    Roulette r;
    for (int t = 0; t < tests; t++) {
        sum += r.method(src);
    }

    double pc = 100.0 * sum / tests;

    std::cout << std::left << std::setw(40) << mstring(src) << " produces " << pc << "% deaths.\n";
}

int main() {
    test("LSLSFSF");
    test("LSLSFF");
    test("LLSFSF");
    test("LLSFF");

    return 0;
}
Task: Sierpinski curve


C++: 
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>

class sierpinski_curve {
public:
    void write(std::ostream& out, int size, int length, int order);
private:
    static std::string rewrite(const std::string& s);
    void line(std::ostream& out);
    void execute(std::ostream& out, const std::string& s);
    double x_;
    double y_;
    int angle_;
    int length_;
};

void sierpinski_curve::write(std::ostream& out, int size, int length, int order) {
    length_ = length;
    x_ = length/std::sqrt(2.0);
    y_ = 2 * x_;
    angle_ = 45;
    out << "<svg xmlns='http:
        << size << "' height='" << size << "'>\n";
    out << "<rect width='100%' height='100%' fill='white'/>\n";
    out << "<path stroke-width='1' stroke='black' fill='none' d='";
    std::string s = "F--XF--F--XF";
    for (int i = 0; i < order; ++i)
        s = rewrite(s);
    execute(out, s);
    out << "'/>\n</svg>\n";
}

std::string sierpinski_curve::rewrite(const std::string& s) {
    std::string t;
    for (char c : s) {
        if (c == 'X')
            t += "XF+G+XF--F--XF+G+X";
        else
            t += c;
    }
    return t;
}

void sierpinski_curve::line(std::ostream& out) {
    double theta = (3.14159265359 * angle_)/180.0;
    x_ += length_ * std::cos(theta);
    y_ -= length_ * std::sin(theta);
    out << " L" << x_ << ',' << y_;
}

void sierpinski_curve::execute(std::ostream& out, const std::string& s) {
    out << 'M' << x_ << ',' << y_;
    for (char c : s) {
        switch (c) {
        case 'F':
        case 'G':
            line(out);
            break;
        case '+':
            angle_ = (angle_ + 45) % 360;
            break;
        case '-':
            angle_ = (angle_ - 45) % 360;
            break;
        }
    }
}

int main() {
    std::ofstream out("sierpinski_curve.svg");
    if (!out) {
        std::cerr << "Cannot open output file\n";
        return 1;
    }
    sierpinski_curve s;
    s.write(out, 545, 7, 5);
    return 0;
}