Modern Art

Discussion in 'Programming' started by FlyingLlama, Apr 16, 2017.

  1. I made this class because i was bored, curious and tired, now i have no idea why it exists or what it means, so it must be art.
    In theory it can store more than 1 character per byte without any actual compression taking place.

    Code (Java):
    import java.util.Arrays;
    import java.util.TreeSet;
    import static terranova.util.MathUtils.*;
    /**
    Does stuff related to growing strings from seeds. Why did i waste precious minutes of my life creating this horror.
    */

    public class StringGarden
    {
       private int len;
       private char[] charset;
     
       public byte[] grow(String in)
       {
         char[] ch = in.toCharArray();
         int wchar=1;
         TreeSet<Character> cs = new TreeSet<>(); // because trees grow, right?
         for(char c : ch)
         {
           if(c > 256)
             wchar=2;
           cs.add(c);
         }
         int perm = (int)(0xFFFFFFFFL/64); // maximum permutations must be within 1/64th of the value range of an integer, adjusting this changes compression vs speed+reliability
         Character[] cst = cs.toArray(new Character[cs.size()]);
         charset = new char[cs.size()];
         for(int n=0;n<cs.size();++n)
           charset[n]=cst[n];
         len=0;
         int p=0;
         while(++len<in.length())
           if(Math.pow(charset.length,len)>perm)
           {
             --len;
             break;
           }
       
         System.out.println("len "+Integer.toString(len)+", perm: "+Integer.toString((int) Math.pow(charset.length,len)));
         int[] sections = new int[ceil((double)in.length()/len)];
         for(int n=0,i=-1; n<sections.length; ++n)
         {
           int ofs=n*len+len;
           sections[++i]=getSeed(Arrays.copyOfRange(ch,n*len,ofs>ch.length?ch.length:ofs));
         }
       
         System.out.println(decode(sections,in.length(),len));
       
         // ByteBuffer-lite, expands in set increments like a Vector and keeps track of filled space
         AutoByteArray out = new AutoByteArray(charset.length*wchar+sections.length*4+4,1);
         out.add(shortToBytes((short)charset.length)); // charset length
         out.add(len); // add length of each section
         for(int n=0;n<charset.length;++n)
           out.add(shortToBytes((short)charset[n])); // nobody cares about supplemental range right now, or at least i dont.
         out.add(shortToBytes((short)sections.length));
         for(int n=0; n<sections.length;++n)
           out.add(intToBytes(sections[n]));
         return out.getFilled();
       }
     
       // add methods for creating an environment with multiple strings
     
       private String decode(int[] sections, int length, int sectionlength)
       {
         StringBuilder s = new StringBuilder(length);
         for(int n=0,i=0; n<sections.length; ++n)
         {
           i+=sectionlength;
           if(length-i<0)
            s.append(decode(sections[n],sectionlength+(length-i)));
           else
             s.append(decode(sections[n],sectionlength));
         }
         return s.toString();
       }
     
       private String decode(int i, int ln)
       {
         char[] c = new char[ln];
         XorshiftRandom r = new XorshiftRandom();
         r.setSeed(i);
         for(int n=0;n<ln;++n)
           c[n]=charset[(r.nextInt()&0x7FFFFFFF)%charset.length];
         return new String(c);
       }
     
       private int getSeed(char[] c)
       {
         XorshiftRandom r = new XorshiftRandom();
       
         for(int n=Integer.MIN_VALUE;n<Integer.MAX_VALUE;++n)
         {
           boolean m=true;
           r.setSeed(n);
           for(int i=0;i<c.length;++i)
             if(charset[(r.nextInt()&0x7FFFFFFF)%charset.length]!=c[i])
               m=false;
           if(m)
            return n;
         }
         return 0;
       }
    }

     
    Incidentally it does not really do anything, and definitely cannot decode the returned value yet, although it would be fairly easy.