sophuwu.site > crls   
              200
            
             #include <stdio.h>
#include <string>
#include <cstring>
#include <filesystem>
#include <sys/stat.h>
#include <vector>

void panic(std::string s) {
    fprintf(stderr, "Fatal error: %s\n", s.c_str());
    exit(1);
}

struct rgb {
    double r, g, b;

    void clamp() {
        if (r > 255) r = 255; else if (r < 0) r = 0;
        if (g > 255) g = 255; else if (g < 0) g = 0;
        if (b > 255) b = 255; else if (b < 0) b = 0;
    }

    std::string str(char sep = ';') {
        clamp();
        return std::to_string((int)r) + sep + std::to_string((int)g) + sep + std::to_string((int)b);
    }

    void set(double rr, double gg, double bb) {r = rr;g = gg;b = bb; clamp();}
    void set(rgb c) {r = c.r;g = c.g;b = c.b; clamp();}

    void print(std::string s) {printf("\033[38;2;%sm%s\033[0m", str().c_str(), s.c_str());}
    void printAt(std::string s, int x, int y) {printf("\033[%d;%dH\033[38;2;%sm%s\033[0m", y, x, str().c_str(), s.c_str());}
    void setPx(int x, int y) {printf("\033[%d;%dH\033[48;2;%sm \033[0m", y, x, str().c_str());}

    double operator[](int i) {
        switch (i%3) {
            case 0: return r;
            case 1: return g;
            case 2: return b;
        }
        return 0;
    }
    void indexAdd(int i, double v) {
        switch (i%3) {
            case 0: r += v; break;
            case 1: g += v; break;
            case 2: b += v; break;
        }
        clamp();
    }
};

struct rainbow {
    rgb c;
    double s = 0; // step

    void init(int len) {
        if (len == 0) panic("Divison by zero.");
        c.set(255, 0, 0);
        s = 5.0*255.0 / (double)len;
    }

    void next() {
        if (s == 0) panic("Empty infinity loop. Rainbow not initialized.");
        for (int i = 0; i < 3; i++) {
            if ((c[i+1]==0||c[i+1]==255)&&(c[i+2]==0||c[i+2]==255)) {
                if (c[i+1]==0&&c[i+2]==255) c.indexAdd(i, s);
                else if (c[i+1]==255&&c[i+2]==0) c.indexAdd(i, -s);
            }
        }
    }
    void print(std::string s) {c.print(s);}
    void print2d(std::string s, int len = 30) {
        rainbow r;
        r.init(len);
        r.c.set(c);
        for (int i = 0; i < s.length(); i++) {
            r.print(s.substr(i, 1));
            r.next();
        }
    }
};

std::string getpath(int argc, char* argv[]) {
    std::string path = std::filesystem::current_path();
    if (argc > 1) {
        if (argv[1][0] == '/') path = std::string(argv[1]);
        else path += "/" + std::string(argv[1]);
    }
    return path;
}

struct diritem {
    std::string name;
    std::string size;
    std::string str() {return size + name + "\n";}
};

std::string convsize(int n) {
    float f = n;
    char c[] = " KMGT";
    int i = 0;
    for (;f > 999; i++) f /= 1000;
    if (i > 4) return " >1.00 P  ";
    n = 100*f;
    std::string s = "";
    for (; n > 0; n /= 10) s = std::to_string(n%10) + s;
    for (; s.length() < 5; s = " " + s);
    return s.substr(0, 3) + "." + s.substr(3, 2) + " " + c[i] + "  ";
}

int getdir(std::vector<diritem>& files, std::vector<diritem>& folders, std::string path) {
    int len = 0, i= 0;
    for (const auto& entry : std::filesystem::directory_iterator(path)) {
        diritem item;
        item.name = entry.path().filename().string();
        len += item.name.length();
        i++;
        if (std::filesystem::is_directory(entry.path())) {
            item.name += "/";
            item.size = "Folder    ";
            folders.push_back(item);
            continue;
        } else if (std::filesystem::exists(entry.path()))
            item.size = convsize(std::filesystem::file_size(entry.path()));
        else item.size = convsize(0);
        files.push_back(item);
    }
    len /= i;
    return len*10;
}

int charcmp(char a, char b) {
    if (a > 96) a-=32;
    if (b > 96) b-=32;
    if (b == a) return 2;
    return a>b;
}

int strcomp(std::string a, std::string b) {
    int len = a.length();
    if (b.length()<len) len=b.length();
    char c[len] = "";
    strncat(c, a.c_str(),len);
    char d[len] = "";
    strncat(d,b.c_str(),len);
    int cmp;
    for (int i = 0; i < len; i++) {
        cmp = charcmp(c[i], d[i]);
        if (cmp != 2) return cmp;
    }
    return b.length()<a.length();
}

void sortdir(std::vector<diritem> list, std::vector<std::string>& newlist){
    std::string comp;
    for (;list.size()!=0;) {
        int ii=0;
        comp = list[0].name;
        for (int i = 1; i < list.size(); i++) {
            if (strcomp(comp, list[i].name)) {
                ii = i;
                comp = list[i].name;
            }
        }
        newlist.push_back(list[ii].str());
        list.erase(list.begin()+ii);
    }
}

int main(int argc, char* argv[]) {
    rainbow r;
    r.init(30);

    std::string path = getpath(argc, argv);

    r.print2d(path+"\n\n", path.length());
    r.next();

    if (!std::filesystem::exists(path) || !std::filesystem::is_directory(path)) {
        r.print2d(" Directory not found.\n\n");
        return 1;
    }

    std::vector<diritem> files;
    std::vector<diritem> folders;
    int len = getdir(files, folders, path);
    std::vector<std::string> dirlist;
    sortdir(folders, dirlist);
    sortdir(files,dirlist);

    if (dirlist.size()<30) r.init(dirlist.size());

    for (int i = 0; i < dirlist.size(); i++) {
        r.print2d(dirlist[i], len);
        r.next();
    }
    r.print2d("\nFolders / Files / Total: " + std::to_string(folders.size()) + '/' + std::to_string(files.size()) + '/' + std::to_string(folders.size()+files.size()) + '\n', len);

    return 0;
}