102
\$\begingroup\$

Your task is to reverse the order in which some prints get executed.


Specs:
Your code will be in this form:

//some lines of code
/*code*/ print "Line1" /*code*/
/*code*/ print "Line2" /*code*/
/*code*/ print "Line3" /*code*/
/*code*/ print "Line4" /*code*/
//some lines of code

You will have to print (or echo, or write, or equivalent) those strings from the fourth to the first.

  • You decide which lines of your program must print the strings, but they must be adjacent;

  • Every line can contain only one print, and cannot exceed 60 bytes in length;

  • Since this is , be creative and avoid to write just a goto or a simple for(i){if(i=4)print"Line1";if(i=3)...}

  • The most upvoted answer in 2 weeks wins this.

  • Your output MUST be Line4 Line3 Line2 Line1 OR Line4Line3Line2Line1 OR Line4\nLine3\nLine2\nLine1(where \n is a newline), and it must be generated only by executing those prints backwards.

Happy coding!

UPDATE: Contest is over! Thank you all :)

\$\endgroup\$
  • 15
    \$\begingroup\$ Does Arabic count? : ) \$\endgroup\$ – user11739 Feb 13 '14 at 8:17
  • \$\begingroup\$ If you are able to meet the specs, of course :P \$\endgroup\$ – Vereos Feb 13 '14 at 10:34
  • \$\begingroup\$ Wanted to quickly clarify one rule... When you say "Every like can contain only one print", do you mean one text line in the code file or one LOC/statement? \$\endgroup\$ – Ruslan Feb 15 '14 at 8:54
  • \$\begingroup\$ Every line of code can contain only one print \$\endgroup\$ – Vereos Feb 15 '14 at 15:07
  • \$\begingroup\$ does it have to pass a code review - suitable for production code? \$\endgroup\$ – Lance Feb 17 '14 at 19:37

157 Answers 157

5
\$\begingroup\$

Python 3

Misusing keyword arguments

print('Line1', end=
print('Line2', end=
print('Line3', end=
print('Line4'))))
\$\endgroup\$
5
\$\begingroup\$

JavaScript

function golf() {
        /*
        console.log("Line1");
        console.log("Line2");
        console.log("Line3");
        console.log("Line4");
        */
        /\/\*(.+)\*\//.exec(golf.toString().replace(/\n/g,""))[1].split("; ").reverse().forEach(function(e){eval(e)});
    }

golf();

Explanation:
golf.toString().replace(/\n/g,"") returns the function's source on one line. The /\/\*(.+)\*\// regular expression matches the four console.log lines; it then separates them into an array, reverses the array, and uses forEach to eval each item in the array.

Edit: Removed the unnecessary var r =.

\$\endgroup\$
4
\$\begingroup\$

XQuery

As XQuery does not have any print statement (for those of you not familiar with XQuery, the result is simply outputted to the user) I defined a completely useless pseudo-print function, which does exactly nothing. This is just because you guys all have this nice and shiny print functions and I am trying to blend in.

declare function local:print($o) { $o };

fold-right((
  local:print("Line 1"),
  local:print("Line 2"),
  local:print("Line 3"),
  local:print("Line 4")
  ), (),
  function ($i, $r) { $r, $i }
)

You could also simply use reverse(), but how boring would that be? Instead it takes advantages of the powerful Higher-Order functions feature.

\$\endgroup\$
4
\$\begingroup\$

C++

#include <iostream>
#include <functional>

int main()
{
    std::function<void ()> a = [](){};
    a = [=](){ std::cout << "Line 1"; a(); };
    a = [=](){ std::cout << "Line 2"; a(); };
    a = [=](){ std::cout << "Line 3"; a(); };
    a = [=](){ std::cout << "Line 4"; a(); };
    a();
}

Note that this would behave very differently if I used [&] instead.

\$\endgroup\$
4
\$\begingroup\$

Rebol

do reverse [
    (print "Line1")
    (print "Line2")
    (print "Line3")
    (print "Line4")
]


An alternative option that doesn't use paren! blocks would be like this:

reverse2: func [
    "Reverse series/block in groups of 2 elements (modifies & returns)"
    s [block! series!]
  ][
    forskip s 2 [insert s take/last/part s 2]
    s
]

do reverse2 [
    print "Line1"
    print "Line2"
    print "Line3"
    print "Line4"
]


A little explanation

In Rebol, code is data and data is code...

four-lines: [
    print "Line1"
    print "Line2"
    print "Line3"
    print "Line4"
]

At this point four-lines is just a variable pointing to data. But we can assign it to a function like so:

print-4-lines: does four-lines

; or exactly same is

print-4-lines: func [] four-lines

Now the print-4-lines function will print the 4 lines as is. However if we do this...

print-4-lines: does reverse2 four-lines

then print-4-lines now prints in reverse order.

If you go into Rebol console (REPL) you will see that print-4-lines function code is reversed.

>> source print-4-lines
print-4-lines: make function! [[][
    print "Line4"
    print "Line3"
    print "Line2"
    print "Line1"
]]

>> print-4-lines
Line4
Line3
Line2
Line1
\$\endgroup\$
  • \$\begingroup\$ Edit submitted as you actually don't need the COMPOSE (since the parens are harmless in the DO evaluator in this case, unnecessary precedence grouping...) :-) \$\endgroup\$ – Dr. Rebmu Feb 13 '14 at 9:35
  • \$\begingroup\$ @Dr.Rebmu Of course! Thats much better thanks :) \$\endgroup\$ – draegtun Feb 13 '14 at 10:14
4
\$\begingroup\$

Java

Using instance initializers:

class L1 {{new L2();System.out.println("Line 1");}}
class L2 {{new L3();System.out.println("Line 2");}}
class L3 {{new L4();System.out.println("Line 3");}}
class L4 {{System.out.println("Line 4");}}
public class S {
    public static void main(String[] args) {
        new L1();
    }
}
\$\endgroup\$
  • \$\begingroup\$ nice work; and someone in PHP used the exact similar way to tackle this :P but still nice way to trololol the code order \$\endgroup\$ – masterX244 Feb 13 '14 at 15:22
4
\$\begingroup\$

Couldnt resist abusing overloaded System.out :P

import java.io.PrintStream;
import java.util.ArrayList;

class A
{
    public static void main(String[] arggxes)
    {
        CStream c = new CStream(System.out);
        System.setOut(c);
        System.out.println("Line 1");
        System.out.println("Line 2");
        System.out.println("Line 3");
        System.out.println("Line 4");
        c.done();
    }

}
class CStream extends PrintStream
    {
        ArrayList<String> bfr;
        public CStream(PrintStream ul) 
        {
            super(ul);
            bfr=new ArrayList<>();
        }
        @Override
        public void println(String x)
        {
            bfr.add(x);
        }
        public void done()
        {
            for (int i = bfr.size(); i > 0; i--)
            {
                super.println(bfr.get(i-1));
            }
        }
    }

variable string amount print() with string as return works, too :P; inspired by the printf c one and the rebol one

class pr
{
    public static void main (String[] args)
    {
        print("Line1",
        print("Line2",
        print("Line3",
        print("Line4"
                ))));
    }
    public static String print(String... in)
    {
        System.out.println(in[0]);
        return "";
    }
}
\$\endgroup\$
4
\$\begingroup\$

Bash and coreutils

Not very creative, I'm afraid, but gets the job done with the tac tool, which is built for this job:

{
    echo "Line1"
    echo "Line2"
    echo "Line3"
    echo "Line4"
} | tac
\$\endgroup\$
4
\$\begingroup\$

JavaScript

console.log("Line 1", 
(console.log("Line 2",
(console.log("Line 3", 
(console.log("Line 4"), "")), "")
  ), "")
)
\$\endgroup\$
4
\$\begingroup\$

Pseudo Code (will probably work in most languages with minor tweaks)

void printLine1() { print "Line 1"; }    
void printLine2() { print "Line 2"; }    
void printLine3() { print "Line 3"; }
void printLine4() { print "Line 4"; }

main
{
   printLine4();
   printLine3();
   printLine2();
   printLine1();
}
\$\endgroup\$
4
\$\begingroup\$

COBOL

The original of this I wrote some 30 years ago, so if the prize was for the oldest living, if brought-back-to-life, example of such a task... I re-wrote it about three years ago. After I had posted parts of it, parts appeared on some French web-site. This is the original and full working program, which I have posted some time last year on a LinkedIn group.

It still "works" today, and would have "worked" with the first COBOL compilers. GNU Cobol is readily available (SourgeForge) for anyone who would like to test the program...

The reason for writing it is mentioned in comments. Explanation follows the code. Enjoy :-)

   ID DIVISION.
   PROGRAM-ID. DEEPDOO.
  *REMARKS. THE PURPOSE OF THIS PROGRAM IS TO SHOW THAT, FAR
  *         FROM "THAT CAN'T BE THE PROBLEM, COBOL DOESN'T DO
  *         THAT", IT IS, AND IT DOES.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01  A1-FG PIC X VALUE SPACE.
   01  B1-FG PIC X VALUE SPACE.
   01  C1-FG PIC X VALUE SPACE.
   PROCEDURE DIVISION.
   OBLIGATORY-SECTION SECTION.
   OB-PARA.
       PERFORM A
       IF A1-FG EQUAL TO "Y"
           DISPLAY "DO"
           GO TO G6
       END-IF
       .
   G1.
       PERFORM B
       IF B1-FG EQUAL TO "Y"
           DISPLAY "DOO"
           GO TO G5
       END-IF
       .
   G2.
       PERFORM C
       IF C1-FG EQUAL TO "Y"
           DISPLAY "IN DEEP"
           GO TO G4
       END-IF
       .
   G3.
       GO TO C5
       .
   G4.
       GO TO B5
       .
   G5.
       GO TO A5
       .
   G6.
       MOVE +11 TO RETURN-CODE
       GOBACK
       .
   A SECTION.
   A0-PARA.
       GO TO G1
       .
   A5.
       MOVE "Y" TO A1-FG
       .
   A9.
       EXIT.
   B SECTION.
   B0-PARA.
       GO TO G2
       .
   B5.
       MOVE "Y" TO B1-FG
       .
   B9.
       EXIT.
   0A SECTION.
   0-PARA.
       DISPLAY "I WAS GOING ALONG QUIETLY AND NOW I'M"
       .
   C SECTION.
   C0-PARA.
       IF C1-FG NOT EQUAL TO "Y"
           GO TO G3
       ELSE
           GO TO C9
       END-IF
       .
   C5.
       MOVE "Y" TO C1-FG
       GO TO 0-PARA
       .
   C9.
       EXIT.
   Z-OBFUSCATION SECTION.
   Z-OB.
       DISPLAY "IT DOESN'T GET HERE, NOT IN A MILLION YEARS"
       STOP RUN. 

There, wasn't so bad, was it?

Output is:

I WAS GOING ALONG QUIETLY AND NOW I'M
IN DEEP
DOO
DO

Which is just a different way of spelling

Line4
Line3
Line2
Line1

When COBOL was designed, it was done such that a label (a paragraph or a SECTION) could be the target of a PERFORM or a GO TO or just "fallen into" sequentially, and even, though not explicitly stated, any combination for the same label.

The problem arises when the same label is already under the scope of a PERFORM, a GO TO (accidentally) comes out of the range of the PERFORM (leaving it still "active") and control later arrives at the same label. If progress is then smoothly to the end of the scope of the original PERFORM, then control will be returned to the statement after the original PERFORM, no matter what else has happened since (as long as an infinite loop has not been created).

Very, very, bad practice to knowingly make use of that. Very. Can't stress that enough. Very, very, bad.

However, carelessness in whirling chunks of code about in an editor can cause this unintentionally. It can also be deliberately coded, without realising the consequences (example on SO recently, but without causing this type of problem).

However, when it does happen, the consequences evident seem so unlikely that people do not believe it. Parts of a program appear to, and actually do, run out of their expected sequence.

Of course, the "expected sequence" is just wrong, not the actual sequence, until you know what to expect, and then everything is OK (except the program doesn't work).

After two people came to me within a week with this type of problem, and didn't believe what I told them (although that bit of their code worked after my pointing out the errant GO TOs) I wrote the program to show these and any future Doubting Thomases.

For fun I compiled it using GNU COBOL with the -debug switch, which lists each verb and label as they are encountered. Here is the output:

Program-Id: DEEPDOO          Statement: PERFORM                Line: 15
Program-Id: DEEPDOO          Section:   A                      Line: 48
Program-Id: DEEPDOO          Paragraph: A0-PARA                Line: 49
Program-Id: DEEPDOO          Statement: GO TO                  Line: 50
Program-Id: DEEPDOO          Paragraph: G1                     Line: 21
Program-Id: DEEPDOO          Statement: PERFORM                Line: 22
Program-Id: DEEPDOO          Section:   B                      Line: 57
Program-Id: DEEPDOO          Paragraph: B0-PARA                Line: 58
Program-Id: DEEPDOO          Statement: GO TO                  Line: 59
Program-Id: DEEPDOO          Paragraph: G2                     Line: 28
Program-Id: DEEPDOO          Statement: PERFORM                Line: 29
Program-Id: DEEPDOO          Section:   C                      Line: 70
Program-Id: DEEPDOO          Paragraph: C0-PARA                Line: 71
Program-Id: DEEPDOO          Statement: IF                     Line: 72
Program-Id: DEEPDOO          Statement: GO TO                  Line: 73
Program-Id: DEEPDOO          Paragraph: G3                     Line: 35
Program-Id: DEEPDOO          Statement: GO TO                  Line: 36
Program-Id: DEEPDOO          Paragraph: C5                     Line: 78
Program-Id: DEEPDOO          Statement: MOVE                   Line: 79
Program-Id: DEEPDOO          Statement: GO TO                  Line: 80
Program-Id: DEEPDOO          Paragraph: 0-PARA                 Line: 67
Program-Id: DEEPDOO          Statement: DISPLAY                Line: 68
I WAS GOING ALONG QUIETLY AND NOW I'M
Program-Id: DEEPDOO          Section:   C                      Line: 70
Program-Id: DEEPDOO          Paragraph: C0-PARA                Line: 71
Program-Id: DEEPDOO          Statement: IF                     Line: 72
Program-Id: DEEPDOO          Statement: GO TO                  Line: 75
Program-Id: DEEPDOO          Paragraph: C9                     Line: 82
Program-Id: DEEPDOO          Statement: EXIT                   Line: 83
Program-Id: DEEPDOO          Statement: IF                     Line: 30
Program-Id: DEEPDOO          Statement: DISPLAY                Line: 31
IN DEEP
Program-Id: DEEPDOO          Statement: GO TO                  Line: 32
Program-Id: DEEPDOO          Paragraph: G4                     Line: 38
Program-Id: DEEPDOO          Statement: GO TO                  Line: 39
Program-Id: DEEPDOO          Paragraph: B5                     Line: 61
Program-Id: DEEPDOO          Statement: MOVE                   Line: 62
Program-Id: DEEPDOO          Paragraph: B9                     Line: 64
Program-Id: DEEPDOO          Statement: EXIT                   Line: 65
Program-Id: DEEPDOO          Statement: IF                     Line: 23
Program-Id: DEEPDOO          Statement: DISPLAY                Line: 24
DOO
Program-Id: DEEPDOO          Statement: GO TO                  Line: 25
Program-Id: DEEPDOO          Paragraph: G5                     Line: 41
Program-Id: DEEPDOO          Statement: GO TO                  Line: 42
Program-Id: DEEPDOO          Paragraph: A5                     Line: 52
Program-Id: DEEPDOO          Statement: MOVE                   Line: 53
Program-Id: DEEPDOO          Paragraph: A9                     Line: 55
Program-Id: DEEPDOO          Statement: EXIT                   Line: 56
Program-Id: DEEPDOO          Statement: IF                     Line: 16
Program-Id: DEEPDOO          Statement: DISPLAY                Line: 17
DO
Program-Id: DEEPDOO          Statement: GO TO                  Line: 18
Program-Id: DEEPDOO          Paragraph: G6                     Line: 44
Program-Id: DEEPDOO          Statement: MOVE                   Line: 45
Program-Id: DEEPDOO          Statement: GOBACK                 Line: 46
Program-Id: DEEPDOO          Exit:      DEEPDOO

Line: 80 is what causes the unwinding of the PERFORMs to start, as control will "fall through" from the target of that GO TO into the following SECTION.

This mimics the situation where a SECTION in the program has been copied, modified, but the "GO TO the named paragraph which happens to be the end of the PERFORM range has not been changed - so it GO TOs the end of the wrong SECTION, and "falls through" into the next SECTION and continues falling until it stumbles across a PERFORM-range which is still active, or it gets into a Big Fat Loop or the end of the program is reached.

There are COBOL programmers who feel it is OK to use GO TO to get to the last paragraph of a PERFORM-range (I'm not one). If doing this, and using SECTIONs, it is best to name the final paragraph in each SECTION identically. The compiler will then automatically "qualify" that paragraph-reference in the GO TO to being the one in the current SECTION.

\$\endgroup\$
  • \$\begingroup\$ Never seen such beautiful code before... \$\endgroup\$ – ceased to turn counterclockwis Feb 15 '14 at 13:05
  • \$\begingroup\$ @leftaroundabout Thanks. I've never had this program described as beautiful. Updated with -debug results, if interested to see it flying around... \$\endgroup\$ – Bill Woodger Feb 15 '14 at 15:03
  • \$\begingroup\$ This is absolutely amazing. \$\endgroup\$ – cat Dec 30 '15 at 16:18
3
\$\begingroup\$

Postscript

{
    currentfile 
    60 string readline 
        { cvx }
        { pop count { exec } repeat exit } 
    ifelse 
} loop
(Line1\n) print
(Line2\n) print
(Line3\n) print
(Line4\n) print

and

gs -q -dBATCH print_backwards.ps
Line4
Line3
Line2
Line1

P.S. Oh, and if, I see, there should be some code after our print "LineX", it can be modified easily:

4 {
    currentfile 
    60 string readline pop cvx
} repeat
(Line1\n) print
(Line2\n) print
(Line3\n) print
(Line4\n) print
count { exec } repeat
(And that's all!\n) print

and

gs -q -dBATCH print_backwards.ps
Line4
Line3
Line2
Line1
And that's all!
\$\endgroup\$
3
\$\begingroup\$

C++11 using UDL and abusing RAII.

#include <iostream>

class wrapper
{
public:
  const char *s_;
  wrapper(const char *s) : s_(s) {}
  ~wrapper() { std::cout << s_ << std::endl;}

};

wrapper operator "" _print(const char *str, long unsigned int)
{
  return wrapper(str);
}

int     main()
{
  wrapper test[] = {
    "Line 1"_print,
    "Line 2"_print,
    "Line 3"_print,
    "Line 4"_print,
  };
}
\$\endgroup\$
3
\$\begingroup\$

Here is my attempt in Befunge:

"4"21p"3"22p"2"23p"1"24pv
" 1eniL",,,,,,   v      >
" 2eniL",,,,,,  v>
" 3eniL",,,,,, v>
" 4eniL",,,,,,@>

" 1eniL",,,,,, is a print statement; it prints Line1.

This works by modifying the code, overwriting the numbers in the print statements before they are executed.

Output:

Line4 Line3 Line2 Line1 

However, since it unfortunately looks like that is not allowed (it is not executing the statements in reverse order, but modifying them), this works:

 v
" 1eniL",,,,,,@>
" 2eniL",,,,,, ^>
" 3eniL",,,,,,  ^>
" 4eniL",,,,,,   ^>
 >                ^
\$\endgroup\$
  • \$\begingroup\$ “[Your output] must be generated only by executing those prints backwards.” Your first solution doesn't execute anything backwards. \$\endgroup\$ – svick Feb 12 '14 at 18:47
  • \$\begingroup\$ The first solution is not bending the rules, it's breaking them: it's clearly stated that Your code will have this form: //some lines of code /*code*/ print "Line1" /*code*/ /*code*/ print "Line2" /*code*/ /*code*/ print "Line3" /*code*/ /*code*/ print "Line4" /*code*/ //some lines of code This means that you must code them in this order but execute them in the opposite way. \$\endgroup\$ – Vereos Feb 13 '14 at 7:54
  • \$\begingroup\$ Still not good, I'm sorry. As I stated in another comment, the contest is not about printing the strings, but executing the commands in the reverse way (like the title says). You are not actually executing those last three prints since they're comments. \$\endgroup\$ – Vereos Feb 13 '14 at 8:40
  • \$\begingroup\$ @Quincunx No, you are executing another print command that has the same arg, written before the comment. You cannot run a comment. \$\endgroup\$ – Vereos Feb 13 '14 at 8:47
  • \$\begingroup\$ let us continue this discussion in chat \$\endgroup\$ – Justin Feb 13 '14 at 8:48
3
\$\begingroup\$

OCaml

Since lists are created starting from the tail prepending elements in front of it, these print statements end up executing backwards.

[print_string "Line1";
print_string "Line2";
print_string "Line3";
print_string "Line4"]

output is

Line4Line3Line2Line1

(you can try it here)

\$\endgroup\$
3
\$\begingroup\$

Python

After a little setup, you can get reversed printing from nearly unaltered Python code. (You do need parens around your print arguments).

from __future__ import print_function
import atexit
stack=[]
def done():
    stack.reverse()
    for a,k in stack: __builtins__.print(*a,**k)
atexit.register(done)
def print(*args,**kwargs):
    stack.append((args,kwargs))

#normal code from here down.

print('Line1')
print('Line2')
print('Line3')
print('Line4')
\$\endgroup\$
  • \$\begingroup\$ nice way :) seems that ya got inspired by my modified output stream in java :) +1 \$\endgroup\$ – masterX244 Feb 13 '14 at 19:19
3
\$\begingroup\$

Bash

This one abusing process substitution and redirects:

< <(< <(< <(< <(
1>&2 echo "Line1")
1>&2 echo "Line2")
1>&2 echo "Line3")
1>&2 echo "Line4")
\$\endgroup\$
3
\$\begingroup\$

Perl 5

use 5.010;

!say "Line 1",
!say "Line 2",
!say "Line 3",
!say "Line 4";

This works basically the same way as bwoebi's PHP answer: the return value of each of the say commands is given as an argument to the previous one, so the interpreter must evaluate them from last to first. The negation operator ! maps the return values from 1 to an empty string, keeping them from interfering with the output.

\$\endgroup\$
3
\$\begingroup\$
#include <stdio.h>
#include <stdlib.h>

void line1() { printf("line1\n"); }
void line2() { printf("line2\n"); }
void line3() { printf("line3\n"); }
void line4() { printf("line4\n"); }

int main() {
  atexit(line1);
  atexit(line2);
  atexit(line3);
  atexit(line4);
}
\$\endgroup\$
3
\$\begingroup\$

Haskell

(<<)=flip(>>)
main=putStrLn "Line1" <<
     putStrLn "Line2" <<
     putStrLn "Line3" <<
     putStrLn "Line4"
\$\endgroup\$
3
\$\begingroup\$

Coldfusion


anything not in a coldfusion tag is written to the output webpage, Coldfusion also lets you treat pretty much any string as a list and loop over a list in an output tag where things in #'s are evaluated

<cfsavecontent variable="output">
    Line 1
    Line 2
    Line 3
    Line 4
</cfsavecontent>

<cfset output = ListSort(output,'text','desc',chr(13))>

<cfloop index="i" list="#output#" delimiters="#chr(13)#">
    <cfoutput>#i#</cfoutput>
</cfloop>
\$\endgroup\$
3
\$\begingroup\$

Python 2.7

The great thing about dynamic languages is that you can override anything. Also, finalizers are the future.

import sys
class StdOut(object):
    text = ""
    def __init__(self):
        self.stdout = sys.stdout
    def write(self, text):
        self.text = text + self.text
    def __del__(self):
        self.stdout.write(self.text)
sys.stdout = StdOut()

print "Line1"
print "Line2"
print "Line3"
print "Line4"

Note that we haven't overridden print - we're using the stock print function that comes with Python.

\$\endgroup\$
2
\$\begingroup\$

F#

Pretty much like the Michael's JS and C++ entry.

[(fun () -> printfn "Line 1");
 (fun () -> printfn "Line 2");
 (fun () -> printfn "Line 3");
 (fun () -> printfn "Line 4")]
|> List.rev |> List.iter(fun u-> u())
\$\endgroup\$
2
\$\begingroup\$

PHP

<?php
ob_start();print 'Line 1';$a=ob_get_clean();
ob_start();print 'Line 2';$a=ob_get_clean().$a;
ob_start();print 'Line 3';$a=ob_get_clean().$a;
ob_start();print 'Line 4';$a=ob_get_clean().$a;
fwrite(STDOUT, $a);

i'm not sure if it actually qualifies, as the prints are executed in order

\$\endgroup\$
  • \$\begingroup\$ It works but the print statements need \n. \$\endgroup\$ – Boann Feb 12 '14 at 22:40
  • 1
    \$\begingroup\$ @Boann where? i'm using the second output style from the specs \$\endgroup\$ – Einacio Feb 13 '14 at 16:09
  • \$\begingroup\$ ‍@Einacio Oh I see. Okay. \$\endgroup\$ – Boann Feb 13 '14 at 16:36
2
\$\begingroup\$

Tcl

Inspired by histocrat's Ruby solution.
Just demonstrates that any proc can be renamed and/or re-declared in Tcl.

rename puts stup

proc puts {{arg ""}} {
  global buffer
  if {$arg == ""} {
    stup [lreverse $buffer]
  } else {
    lappend buffer $arg
  }
}

puts Line1
puts Line2
puts Line3
puts Line4
puts

Sample run:

bash-4.2$ tclsh reverseputs.tcl
Line4 Line3 Line2 Line1

Tcl

Inspired by all those looping solutions.
Just demonstrates that no eval is needed, as everything is a string.

foreach {line puts} [lreverse {
  puts Line1
  puts Line2
  puts Line3
  puts Line4
}] {
  $puts $line
}

Sample output:

bash-4.2$ tclsh reverseputs.tcl
Line4
Line3
Line2
Line1

Tcl

Minimal version.

puts Line1[
puts Line2[
puts Line3[
puts Line4]]]

Sample output:

bash-4.2$ tclsh reverseputs.tcl
Line4
Line3
Line2
Line1
\$\endgroup\$
  • \$\begingroup\$ My upvote was for the last one. \$\endgroup\$ – sergiol Mar 30 '17 at 0:47
2
\$\begingroup\$

PHP

Based on a sleepsort

<?php
if (!pcntl_fork()) { sleep(4); echo 'Line 1'; die;}
if (!pcntl_fork()) { sleep(3); echo 'Line 2'; die;}
if (!pcntl_fork()) { sleep(2); echo 'Line 3'; die;}
if (!pcntl_fork()) { sleep(1); echo 'Line 4'; die;}
\$\endgroup\$
2
\$\begingroup\$

Perl

$_->() for reverse
  sub { print "Line1\n" },
  sub { print "Line2\n" },
  sub { print "Line3\n" },
  sub { print "Line4\n" };
\$\endgroup\$
  • \$\begingroup\$ @Quincunx There's a few moving parts here but the key point is that Perl has first class functions. Above uses a list of 4 anonymous functions (sub), it reverses this list then iterates over the list (for), this for usage is postfix so works on the $_->() that precedes. The $_ is Perl's it (context) variable which for aliases to with each iteration. Finally the ->() runs (calls) the anonymous functions that $_ points to. \$\endgroup\$ – draegtun Feb 12 '14 at 18:42
2
\$\begingroup\$

C#

using System;
using System.Linq;

class P
{
    static void Main()
    {
        new Action[] { 
            () => Console.WriteLine("Line 1"),
            () => Console.WriteLine("Line 2"),
            () => Console.WriteLine("Line 3"),
            () => Console.WriteLine("Line 4"),
        }.Reverse().ToList().ForEach(a => a.Invoke());
    }
}

or:

using System;
using System.Linq;

class P
{
    static void Main()
    {
        foreach (var a in new Action[] { 
                () => Console.WriteLine("Line 1"),
                () => Console.WriteLine("Line 2"),
                () => Console.WriteLine("Line 3"),
                () => Console.WriteLine("Line 4"),
            }.Reverse())
            a.Invoke();
    }
}

Or:

using System;
using System.Collections.Generic;

class P
{
    static void Main()
    {
        var t = new Stack<Action>(new Action[] { 
                () => Console.WriteLine("Line 1"),
                () => Console.WriteLine("Line 2"),
                () => Console.WriteLine("Line 3"),
                () => Console.WriteLine("Line 4"),
            });
        while (t.Count > 0)
            t.Pop().Invoke();
    }
}
\$\endgroup\$
  • \$\begingroup\$ Why a.Invoke() when you can just a()? \$\endgroup\$ – svick Feb 12 '14 at 18:13
  • \$\begingroup\$ Habit I guess :P I think Invoke() more clearly conveys what's happening, but you are correct. However, since it's not a "shorter == better" contest I think I'll leave it this way. \$\endgroup\$ – RobIII Feb 12 '14 at 18:21
2
\$\begingroup\$

JavaScript

Kinda wanted to avoid using eval() or strings, so I gave each Line a separate function.

.reverse() makes it still too easy. :9

var cg = [
  function() {console.log('Line one')},
  function() {console.log('Line two')},
  function() {console.log('Line three')},
  function() {console.log('Line four')}
];
for(i in cg.reverse()) {cg[i]()}

Output:

Line four
Line three
Line two
Line one

Guess I could replace the loop with

for(i in cg) {cg[cg.length-++i]()}

to make it more interesting. Doesn't make it prettier, though.

\$\endgroup\$
2
\$\begingroup\$

SQL

(mySQL 5.6)

SELECT 'Line1' UNION
SELECT 'Line2' UNION
SELECT 'Line3' UNION
SELECT 'Line4' 
ORDER BY Line1 DESC;

If you count SELECTing a literal as equivalent to a print statement anyway.

mySQL defaults to including the column name and adding fancy table formatting, but if you're at the cli they can be turned off if you do something like:

mysql --skip-column-names -B -e "SELECT 'Line1' ... etc ...;"

Output:

Line4
Line3
Line2
Line1
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.