Generate all halting Smallfuck programs of length n

6

1

Your task is to write a program that, given a number n, returns a list of all valid, halting Smallfuck programs of length n, in any order.

Actually, we're using a variation of Smallfuck called F2, which is just Smallfuck with a right-unbounded tape. For the purposes of this challenge, a program that moves left from the start of the tape is considered invalid, as is one with unbalanced brackets.

Scoring

Since solving this for every n is impossible (as it would require you to solve the halting problem), your submission's score will be the lowest n for which it returns an incorrect answer.

Each submission must be, at most, 1000 bytes (though you are encouraged to provide an ungolfed version as well). In the event of a tie, the earlier answer wins.

Test Cases

n = 1:

+ >

n = 2:

++ +> >+ >< >> []

n = 3:

+++ ++> +>+ +>< +>> >++ >+< >+> ><+ ><> >>+ >>< >>> >[] [+] [<] [>] []+ []>

n = 4:

++++ +++> ++>+ ++>< ++>> +>++ +>+< +>+> +><+ +><> +>>+ +>>< +>>> >+++ >++< >++> >+<+ >+<> >+>+ >+>< >+>> ><++ ><+> ><>+ ><>< ><>> >>++ >>+< >>+> >><+ >><< >><> >>>+ >>>< >>>> [][] ++[] +>[] ><[] >>[] [++] [+<] [+>] [<+] [<<] [<>] [>+] [><] [>>] []++ []+> []>+ []>< []>> +[+] +[>] >[+] >[<] >[>] >[]+ >[]< >[]> [+]+ [+]> [<]+ [<]> [>]+ [>]> [[]]

Please inform me if there are any more that I have forgotten to add.

Esolanging Fruit

Posted 2017-06-06T01:35:52.373

Reputation: 13 542

Comments are not for extended discussion; this conversation has been moved to chat.

– Dennis – 2017-06-08T14:10:40.900

For n=3 assuming 2-way unbounded tape, we get <[] as well. – user75200 – 2018-01-13T18:03:43.493

@user75200 "For the purposes of this challenge, a program that moves left from the start of the tape is considered invalid." – Esolanging Fruit – 2018-01-15T00:42:28.960

This challenge is effectively just "write a Smallfuck implementation and find all programs that halt after at least G steps, where G is the largest constant you can fit under 1000 bytes." – Esolanging Fruit – 2018-06-20T07:14:27.600

Answers

6

Java (OpenJDK 8), Score: ???

This clocks in at 980 bytes, since I had so much to work with I decided to make it a little more readable. Basically I'm generating all the possible programs for length n and iterating them n^x times for some x. x is currently 3 but it can be modified arbitrarily to any size, limited only by the limitation of the JVM's precission. This will work for arbitrarily large input values if x is increased, but I have it set to 3 for tio.

import java.util.*;
public class Main{
    public static void main(String[] args){
        int i = new Scanner(System.in).nextInt();
        int x = 3;
        l:for(int j=0;j<Math.pow(5, i);j++){
            try {
                String s="";
                for(int k=j;s.length()<i;k/=5)
                    s="+<>][".charAt(k%5)+s;
                Stack<Integer>y=new Stack<Integer>();
                Map<Integer,Integer>f=new HashMap<>(),b=new HashMap<>();
                for(int m=0; m<s.length();m++){
                    char c=s.charAt(m);
                    if(c=='[')y.push(m);
                    if(c==']'){int n=y.pop();f.put(n, m);b.put(m, n);}
                }
                if(y.size()>0)
                    continue;
                boolean[] t= new boolean[s.length()];
                int l=0,n=0;
                for(long m=0;l<s.length()&m<Math.pow(i,x);l++,m++){
                    switch(s.charAt(l)){
                    case'+':t[n]=!t[n];break;
                    case'>':n++;break;
                    case'<':n--; if(n < 0)continue l;break;
                    case'[':if(!t[n])l=f.get(l);break;
                    case']':l=b.get(l)-1;break;
                    }
                }
                if(l>=s.length()){
                    System.out.println(s);
                }
            } catch(Exception e){continue;}
        }
    }
}

Try it online!

PunPun1000

Posted 2017-06-06T01:35:52.373

Reputation: 973

My guess is that the first program that breaks this will be some sort of counting-in-binary program. I'm not sure exactly how long that would be, though. – None – 2017-06-06T18:30:00.923

I did the same thing in Python, but just had no way of proving anything. It amused me how difficult the proof felt compared to the actual code. – nmjcman101 – 2017-06-06T19:08:46.453

>>>>>>>>+[[<]+>>>>>>>>+[+<<<<<<<[+>]]<+] is a program that SHOULD do binary counting (I don't know if that part works correctly), is 40 characters long (4040=1600), and takes 4451 steps to run. I don't think it's the minimum program that takes longer than `nn` steps to run, just an example. – nmjcman101 – 2017-06-07T12:34:47.870

@nmjcman101 Thanks for the input, I've updated the code to do n*n*n but set a variable x to allow it to arbitrarily be increased. I'm not sure what the score would be at x=3,4,5... and I don't know how I would begin calculating it, so I'm just going to leave it unknown – PunPun1000 – 2017-06-07T13:05:56.510

@PunPun1000 per the halting problem, there is no x such that this algorithm can determine if an arbitrary F2 program halts - indeed, we could then just convert any problem to F2 and solve the halting problem with your algorithm. – Sanchises – 2017-06-08T06:34:53.397

@Sanchises I know. That's why I said that you could increase x for arbitrary score, not that there was any x which for which there was infinite score – PunPun1000 – 2017-06-08T10:38:00.153

@PunPun1000 It's impossible to calculate the score as a function of x in general- it turns out that that is equivalent to solving the halting problem :p There is a maximum score that you can provably achieve by increasing x (though my inclination is that this maximum is itself not computable) – Chris – 2017-06-14T00:07:58.567

1

Braingolf, Score: 3

1-?"++ +> >+ >< >> []":"+ >"|&@

Start things off nice and easy, hardcodes the correct answer for 1 and 2, outputs + > if n = 1, and ++ +> >+ >< >> [] otherwise

Skidsdev

Posted 2017-06-06T01:35:52.373

Reputation: 9 656

Also add [] for another length-2 testcase. – Esolanging Fruit – 2017-06-06T16:44:26.653