Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

/prog/ Challenge #9002

Name: Anonymous 2011-05-02 20:12

The task:

Print strings from "a" to "zzzzz" without using any loop or conditional statements. Don't just write all 1000 permutations out by hand. The output should look like this:
a
b
c
...
aa
ab
ac
...
zzzzx
zzzzy
zzzzz


inb4 lipthfags and dead dogs using some obscure functionality of their obscure languages.

Name: Anonymous 2011-05-02 20:14

lol its over nien tousand so randum xD lolol u so cool u call ppl fags xD

This is not /g/. Leave /prog/ and never come back.

Name: 1 2011-05-02 20:14

Don't just write all 1000 permutations out by hand.
Please ignore "1000", that shouldn't be there.
Don't just write all permutations out by hand.

Name: Anonymous 2011-05-02 20:16

>>2
I only named it 9002 because the last one was named 9001. I wanted to keep it chronological order, despite obviously not being the actual 9002nd challenge.

Name: Anonymous 2011-05-02 20:30

>>1
Go away.

Name: Anonymous 2011-05-02 20:50

>>5
Challenge too hard for you, /prog/rider?

Name: Anonymous 2011-05-02 20:52

This should print "aaaaa" -> "zzzzz", I was going to alter it to do "a" -> "zzzzz" after testing it, but I can't really test it as its been compiling for about 10 minutes now.


#include <iostream>

template<char a, char b, char c, char d, char e>
struct permutator
{
    static void print()
    {
        std::cout << a << b << c << d << e << std::endl;
        permutator<a, b, c, d, e+1>::print();
    }
};

template<char a, char b, char c, char d>
struct permutator<a, b, c, d, 'z'>
{
    static void print()
    {
        std::cout << a << b << c << d << 'z' << std::endl;
        permutator<a, b, c, d+1, 'a'>::print();
    }
};

template<char a, char b, char c>
struct permutator<a, b, c, 'z', 'z'>
{
    static void print()
    {
        std::cout << a << b << c << "zz" << std::endl;
        permutator<a, b, c+1, 'a', 'a'>::print();
    }
};

template<char a, char b>
struct permutator<a, b, 'z', 'z', 'z'>
{
    static void print()
    {
        std::cout << a << b << "zzz" << std::endl;
        permutator<a, b+1, 'a', 'a', 'a'>::print();
    }
};

template<char a>
struct permutator<a, 'z', 'z', 'z', 'z'>
{
    static void print()
    {
        std::cout << a << "zzzz" << std::endl;
        permutator<a+1, 'a', 'a', 'a', 'a'>::print();
    }
};

template<>
struct permutator<'z', 'z', 'z', 'z', 'z'>
{
    static void print()
    {
        std::cout << "zzzzz" << std::endl;
    }
};

int main()
{
    permutator<'a', 'a', 'a', 'a', 'a'>::print();
    std::cin.get();
}

Name: Anonymous 2011-05-02 20:53

import Data.List

let f = [""] ++ map (\x -> [x]) ['a'..'z'] in mapM_ print $ nub $ sort $ tail [a++b++c++d++e|a<-f,b<-f,c<-f,d<-f,e<-f]


No, it's not a loop.

Name: Anonymous 2011-05-02 20:56

>>8
Forgot my main =, I pasted that from ghci.

Name: Anonymous 2011-05-02 21:12

>>5
fuck you faggot

Name: Anonymous 2011-05-02 21:15

>>1
>The output should look like this:

ok

print """
a
b
c
...
aa
ab
ac
...
zzzzx
zzzzy
zzzzz
"""

Name: Anonymous 2011-05-02 21:18

>>11
Har har har.

Name: Anonymous 2011-05-02 21:52

>>8
[a++b++c++d++e|a<-f,b<-f,c<-f,d<-f,e<-f]
Which is just syntactic sugar for

do a <- f
   b <- f
   c <- f
   d <- f
   e <- f
   return a++b++c++d++e


Which is just syntactic sugar for
f >>= \a -> f >>= \b -> f >>= \c -> f >>= \d -> f >>= \e -> return a++b++c++d++e

Which, for the list monad, is equivalent to
concatMap (\a -> concatMap (\b -> concatMap (\c -> concatMap (\d -> concatMap (\e -> [a++b++c++d++e]) f) f) f) f) f)

Which is equivalent to
concat $ map (\a -> concat $ map (\b -> concat $ map (\c -> concat $ map (\d -> concat $ map (\e -> [a++b++c++d++e]) f) f) f) f)

Where concat is

concat [] ys = ys
concat [x:xs] ys = x : (concat xs ys)

and map is

map _ [] = []
map f [x:xs] = (f x) : (map f xs)


Both are clearly loops.

Name: Anonymous 2011-05-02 22:24

If that's syntactic sugar then I'm syntactic diabetic.

Name: Anonymous 2011-05-02 22:50

>>13
I like how you typed out that whole thing to prove that I was using map, even though I also used it explicitly.

Name: Anonymous 2011-05-02 23:11

([X~] (['a'..'z'], ['a'..'z', ''] xx 4))>>.fmt('%5s').sort.uniq>>.say;

Name: Anonymous 2011-05-03 1:22

Pretty sure this uses absolutely no loops or conditionals... But it requires a huge stack to run without crashing. I haven't run it to the end so I'm not even sure if a stack size of 100,000,000 is big enough.


#pragma comment(linker, "/stack:100000000")

#include <iostream>
#include <cstdlib>

template<typename T>
struct true_define
{
    typedef T (*is_true)(T);
};

template<typename T>
T is_true1(T x)
{
    return x;
}

template<typename T>
T is_true2(T x)
{
    return 1;
}

template<typename T, int I>
struct check_bits
{
    static T check(T x, T cur, typename true_define<T>::is_true tests[2])
    {
        cur = tests[cur]((x >> I) & 1);
        return check_bits<T, I-1>::check(x, cur, tests);
    }
};

template<typename T>
struct check_bits<T, 0>
{
    static T check(T x, T cur, typename true_define<T>::is_true tests[2])
    {
        cur = tests[cur](x & 1);
        return cur;
    }
};

template<typename T>
T set_true(T x)
{
    true_define<T>::is_true tests[2];
    tests[0] = is_true1;
    tests[1] = is_true2;
    return check_bits<T, (sizeof(T)*8)-1>::check(x, 0, tests);
}

class if_object;

void call_then_(if_object* obj);
void call_else_(if_object* obj);

class if_object
{
public:
    friend void call_then_(if_object*);
    friend void call_else_(if_object*);

    if_object()
    {
        calls[0] = call_else_;
        calls[1] = call_then_;
    }

    template<typename T>
    void if_(T x)
    {
        calls[set_true(x)](this);
    }
protected:
    virtual void then_() = 0;
    virtual void else_() = 0;
private:
    typedef void (*if_call)(if_object*);
    if_call calls[2];
};

void call_then_(if_object* obj)
{
    obj->then_();
}

void call_else_(if_object* obj)
{
    obj->else_();
}

class exit_if_not : public if_object
{
public:
    template<typename T>
    exit_if_not(T x)
    {
        this->if_(x);
    }
private:
    void then_()
    {
    }

    void else_()
    {
        std::cin.get();
        exit(0);
    }
};

class incrementer2 : public if_object
{
public:
    incrementer2(char* c_) : c(c_) {}
private:
    void then_()
    {
        ++(*c);
    }
    void else_()
    {
        *c = 'a';
    }
    char* c;
};

class incrementer : public if_object
{
public:
    incrementer(char* c_, int depth_, int* fin_) : c(c_), depth(depth_), fin(fin_) {}
private:
    void then_()
    {
        exit_if_not ex(depth);
        *c = 'a';
        incrementer inc(c-1, depth-1, fin);
        inc.if_(*(c-1) / 'z');
    }

    void else_()
    {
        exit_if_not ex(depth);
        incrementer2 inc2(c);
        inc2.if_(*c);
    }

    char* c;
    int depth;
    int* fin;
};

class string_printer : public if_object
{
public:
    string_printer(char c_) : c(c_)
    {
        this->if_(c);
    }
private:
    void then_()
    {
        std::cout << c;
    }

    void else_()
    {
    }

    char c;
};

void print_string(char* s)
{
    string_printer s1(s[0]);
    string_printer s2(s[1]);
    string_printer s3(s[2]);
    string_printer s4(s[3]);
    string_printer s5(s[4]);
    std::cout << std::endl;
}

inline void recursive_increment(char* p)
{
    int fin = 0;
    incrementer inc(p+4, 5, &fin);
    inc.if_(p[4] / 'z');
    print_string(p);
    recursive_increment(p);
}

int main()
{
    char sbegin[5];
    sbegin[0] = 0;
    sbegin[1] = 0;
    sbegin[2] = 0;
    sbegin[3] = 0;
    sbegin[4] = 0;
    recursive_increment(sbegin);
}

Name: 17 2011-05-03 1:23

>>17
Ignore that variable called fin, I forgot to take it out.

Name: Anonymous 2011-05-03 2:13

ENTERPRISE

Name: vivi 2011-05-03 2:41

Name: Anonymous 2011-05-03 4:40

ENTERPRISE QUALITY
it's not reaching the end, though...
at least i'm not using preprocessor tricks or some fag language

#include <stdio.h>

char c0 = 0, c1 = -1, c2 = -1, c3 = -1, c4 = -1;

int main()
{
 start:
 printf("%c%c%c%c%c\n",
        (c4 + 'a') & ((c4 >= 0) * 255),
        (c3 + 'a') & ((c3 >= 0) * 255),
        (c2 + 'a') & ((c2 >= 0) * 255),
        (c1 + 'a') & ((c1 >= 0) * 255),
        (c0 + 'a'));
 c0++;
 c1 += c0 > 25;
 c2 += c1 > 25;
 c3 += c2 > 25;
 c4 += c3 > 25;
 c0 %= 26;
 c1 %= 26;
 c2 %= 26;
 c3 %= 26;
 c4 %= 26;
 goto start;
 /* never reached... :-{ */
 printf("DONE!!\n");
 return 0;
}

Name: Anonymous 2011-05-03 6:55

>>21
By connecting SIGFPE to an exit function and dividing some dummy volatile value with ('z' - c0) + ('z' - c1) + ('z' - c2) + ('z' - c3) + ('z' - c4), you could make it terminate at the right time.

Name: Anonymous 2011-05-03 7:17

>>21

goto is a loop.

Name: 17 2011-05-03 7:54

This runs for me without any stack overflows on my machine.


#include <iostream>
#include <cstdlib>

template<typename T>
struct true_define
{
    typedef T (*is_true)(T);
};

template<typename T>
T is_true1(T x)
{
    return x;
}

template<typename T>
T is_true2(T x)
{
    return 1;
}

template<typename T, int I>
struct check_bits
{
    static T check(T x, T cur, typename true_define<T>::is_true tests[2])
    {
        cur = tests[cur]((x >> I) & 1);
        return check_bits<T, I-1>::check(x, cur, tests);
    }
};

template<typename T>
struct check_bits<T, 0>
{
    static T check(T x, T cur, typename true_define<T>::is_true tests[2])
    {
        cur = tests[cur](x & 1);
        return cur;
    }
};

template<typename T>
T set_true(T x)
{
    true_define<T>::is_true tests[2];
    tests[0] = is_true1;
    tests[1] = is_true2;
    return check_bits<T, (sizeof(T)*8)-1>::check(x, 0, tests);
}

class if_object;

void call_then_(if_object* obj);
void call_else_(if_object* obj);

class if_object
{
public:
    friend void call_then_(if_object*);
    friend void call_else_(if_object*);

    if_object()
    {
        calls[0] = call_else_;
        calls[1] = call_then_;
    }

    template<typename T>
    void if_(T x)
    {
        calls[set_true(x)](this);
    }
protected:
    virtual void then_() = 0;
    virtual void else_() = 0;
private:
    typedef void (*if_call)(if_object*);
    if_call calls[2];
};

void call_then_(if_object* obj)
{
    obj->then_();
}

void call_else_(if_object* obj)
{
    obj->else_();
}

class exit_if_not : public if_object
{
public:
    template<typename T>
    exit_if_not(T x)
    {
        this->if_(x);
    }
private:
    void then_()
    {
    }

    void else_()
    {
        std::cin.get();
        exit(0);
    }
};

class incrementer2 : public if_object
{
public:
    incrementer2(char* c_) : c(c_) {}
private:
    void then_()
    {
        ++(*c);
    }
    void else_()
    {
        *c = 'a';
    }
    char* c;
};

class incrementer : public if_object
{
public:
    incrementer(char* c_, int depth_) : c(c_), depth(depth_) {}
private:
    void then_()
    {
        exit_if_not ex(depth);
        *c = 'a';
        incrementer inc(c-1, depth-1);
        inc.if_(*(c-1) / 'z');
    }

    void else_()
    {
        exit_if_not ex(depth);
        incrementer2 inc2(c);
        inc2.if_(*c);
    }

    char* c;
    int depth;
};

class string_printer : public if_object
{
public:
    string_printer(char c_) : c(c_)
    {
        this->if_(c);
    }
private:
    void then_()
    {
        std::cout << c;
    }

    void else_()
    {
    }

    char c;
};

void print_string(char* s)
{
    string_printer s1(s[0]);
    string_printer s2(s[1]);
    string_printer s3(s[2]);
    string_printer s4(s[3]);
    string_printer s5(s[4]);
    std::cout << std::endl;
}

void recursive_increment(char* p)
{
    incrementer inc(p+4, 5);
    inc.if_(p[4] / 'z');
    print_string(p);
    __asm {
        pop eax;
        pop eax;
        pop eax;
        pop eax;
        pop eax;
        pop eax;
        pop eax;
        pop eax;
    }
    recursive_increment(p);
}

int main()
{
    char sbegin[5];
    sbegin[0] = 0;
    sbegin[1] = 0;
    sbegin[2] = 0;
    sbegin[3] = 0;
    sbegin[4] = 0;
    recursive_increment(sbegin);
}

Name: Anonymous 2011-05-03 7:57

>>23
I have to admit that you might be correct here. I could have also used a recursion with main() (or rather a separate function) instead of the goto here, though, which, by definition, is not a loop, but gets unstable on my machine and quits after ~37000 loops, so I'd rather use the goto.

Anyways, both most likely create a JMP in asm, anyway. I'm not even sure if this is possible without, since we're basically talking about a looping/repeating behaviour (PRINT(X) Y TIMES)...

>>22
>By connecting SIGFPE to an exit function
If you tell me how, I'll do it :3
Breaking out by causing a div by zero is working but getting a runtime error isn't so nice.

Name: Anonymous 2011-05-03 8:07

>>25
Recursion on main() will generate a call in asm.

If you want to make it not crash, do what >>24 did in his recursive function.

Name: Anonymous 2011-05-04 6:09

you're all niggers

Name: Anonymous 2011-05-04 7:57


(defmacro meta (&body body)
  (let ((m (gensym)))
    `(macrolet ((,m () ,@body))
       (,m))))

(defun integer->base-n-list (i n &optional append-on)
  (if (zerop i) (or append-on (list 0))
      (multiple-value-bind (div mod) (truncate i n)
        (integer->base-n-list div n (cons mod append-on)))))

(defun base-n-list->integer (list n)
  (reduce #'(lambda (i next) (+ (* n i) next)) list :initial-value 0))

;; this would be fast if most CL compilers didn't suck at
;; numbered ecases (unless you make a macro that properly writes a jumptable using an array or hashtable)
(defun integer->letter (i)
  (meta
    `(ecase i
       ,@(loop for x from 0 to 25 collect
              `(,x ,(code-char (+ x (char-code #\a))))))))

;; so I write this instead
(defun integer->letter (i)
  (if (<= 0 i 25)
      (code-char (+ (char-code #\a) i))
      (error "Character out of range")))

(defun letter->integer (char)
  (let ((n (- (char-code char) (char-code #\a))))
    (if (<= 0 n 25) n (error "Character out of range"))))

(defun integer->base26a (i) 
  (map 'string #'integer->letter (integer->base-n-list i 26)))
(defun base26a->integer (string)
  (base-n-list->integer (map 'list #'letter->integer string) 26))

(defun all-letter-permutations (&key (start "a") (end "zzzzz"))
  (let ((start-n (base26a->integer start))
        (end-n   (base26a->integer end)))
    (loop for i from start-n to end-n collect (integer->base26a i))))

;; this will obviously generate a huge function and waste lots of memory
;; like: (progn (format t "~A~&" "a") ... (format t "~A~&" "a"))
(meta
  `(progn ,@(mapcar #'(lambda (s) `(format t "~A~&" ,s))
                    (all-letter-permutations))))

;; so let's make something cleaner which
;; just does (princ *hugestringwithallpermutations*)
(meta
  `(princ
    ,(with-output-to-string (stream)
       (dolist (x (all-letter-permutations))
         (princ x stream)
         (terpri stream)))))

Half the code here is redundant, but it does the job.
It generates the output at compile time then generates the code which prints it.
I'm not writing a C and x86 assembly version this time around, even though it wouldn't be hard at all.

Name: >>28 2011-05-04 8:00

Oops, those defun's need to be wrapped in an eval-when if you plan on compiling the file as a whole (not needed if you do enter it at the REPL).

Name: Anonymous 2011-05-04 13:23

>>25
You can install a signal handler. I wrote an example in the other thread.

Name: Anonymous 2011-05-04 20:44


' ' :: ['a'..'z'] |> List.iter (fun c1 ->
    ' ' :: ['a'..'z'] |> List.iter (fun c2 ->
        ' ' :: ['a'..'z'] |> List.iter (fun c3 ->
            ' ' :: ['a'..'z'] |> List.iter (fun c4 ->
                ['a'..'z'] |> List.iter (fun c5 -> System.Console.WriteLine((string(c1) + string(c2) + string(c3) + string(c4) + string(c5)).Trim()))))))

Name: Anonymous 2011-05-04 23:23

>>31 Fixed:

' ' :: ['a'..'z'] |> List.iter (fun c1 ->
    ' ' :: ['a'..'z'] |> List.iter (fun c2 ->
        ' ' :: ['a'..'z'] |> List.iter (fun c3 ->
            ' ' :: ['a'..'z'] |> List.iter (fun c4 ->
                ['a'..'z']
                |> List.filter (fun c5 -> (string(c1) + string(c2) + string(c3) + string(c4) + string(c5)).Trim().Contains(" ") = false)
                |> List.iter (fun c5 -> System.Console.WriteLine((string(c1) + string(c2) + string(c3) + string(c4) + string(c5)).Trim()))))))

Name: Anonymous 2011-05-05 0:44

>>22
>>23
>>26
>>30
Ok, thanks for all your tips but I did it somewhat different now. Hers's the new code, with cheap ASM, function pointing and actual spaces instead of null characters:
#include <stdio.h>

char c0 = 0, c1 = -1, c2 = -1, c3 = -1, c4 = -1, done;
unsigned long t;
void (*f)();
void p(), x();

void p()
{
 printf("%c%c%c%c%c\n",
        ((c4 + 'a') & ((c4 >= 0) * 0xFF)) | (' ' & ((c4 < 0) * 0xFF)),
        ((c3 + 'a') & ((c3 >= 0) * 0xFF)) | (' ' & ((c3 < 0) * 0xFF)),
        ((c2 + 'a') & ((c2 >= 0) * 0xFF)) | (' ' & ((c2 < 0) * 0xFF)),
        ((c1 + 'a') & ((c1 >= 0) * 0xFF)) | (' ' & ((c1 < 0) * 0xFF)),
        (c0 + 'a'));
 c0++;
 c1 += c0 > 25;
 c2 += c1 > 25;
 c3 += c2 > 25;
 c4 += c3 > 25;
 done = (c0 > 25) & (c1 > 25) & (c2 > 25) & (c3 > 25) & (c4 > 25);
 c0 %= 26;
 c1 %= 26;
 c2 %= 26;
 c3 %= 26;
 c4 %= 26;
 f = (void*) ((p & ((1 - done) * 0xFFFFFFFF)) | (x & (done * 0xFFFFFFFF)));
 asm("movl %0, %%esp\n" : : "r"(t));
 f();
}

void x()
{
 /* YES, it's reached now. Feels good to return zero. */
 printf("DONE!!\n");
 exit(0);
}

int main(void)
{
 asm("movl %%esp, %0\n" : "r"(t) : );
 p();
}


...yes, this compiles for me. I'm using TCC/Win32 for compiling, so ASM is in GAS/AT&T format. The function pointing didn't work like this for me in GCC, though.
I also removed the return statement, since this might be interpreted as a jump/loop/whatever. Only calls now, no JMPs.

Name: Anonymous 2011-05-05 9:34

Name: Anonymous 2011-05-05 22:03

>>34
I question your optimization. Why is >>22-23 preferable to >>22,23 ?

Name: Anonymous 2011-05-05 22:27

>>35
>>22,23 shows the first post, >>22-23 does not. In >>22-23,26 there already is a comma, so it's just matter of habit.

Name: Anonymous 2011-05-07 4:24

so who won

Name: Anonymous 2011-05-07 5:37

>>37
my anus.

Name: fusianasan 2011-05-07 5:50

Perl:

print join "\n" => (a .. zzzzz)

not cheating because it doesn't loop anywhere :)

Name: Anonymous 2012-01-15 5:58

nigger

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List