2018-04-11

Fortran puzzle!

And the puzzle is not "why does anyone use Fortran", because that's unfair. Via James, from Rolf, is the excellent:

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
       PROGRAM OBFUSCATE
        CONSTANT = 5.
          INVERSE = 1./CONSTANT
              photo1 = 5.*INVERSE + 5.
                  pH = CONSTANT + 3.
                  X = photo1 * pH
C         strange combination of pH and photolysis...
     GOTO      1
                  X = X + 17.
   1      CONTINUE
        IF (X .LT. 60.) THEN X = X + 7.
      PRINT *,'RESULT=',X
            STOP 
        END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

Hopefully the formatting comes out OK; consult the original if in doubt. The question, of course, is what does the code print, and more importantly exactly why? I'm off to the Lakes for a few days to get rained on, so unless you can work out the answer for yourselves, you'll have to wait till I come back.

Obviously, C would never do anything so odd.

Answer


And the answer, as EFS found, comes in three parts:

1. The easy one is that without IMPLICIT NONE, any variable starting with I (to N) is implicitly an integer, so INVERSE is 0, not 0.2.

2. The first amusing one is that any non-blank character in column 6 is a continuation marker. Comments are discarded, so we have:
      X = photo1 * pH
          OTO      1
and since spaces are also discarded, we actually have
      X = photo1 * pHOTO1
So (since case is also discarded) after that X is 25. To which we add 17, getting 42, of course.

3. Then, lastly, Fortran has a block IF, but also a single-line IF, and
      IF (X .LT. 60.) THEN X = X + 7
can't be a block IF (despite the formatting trying to make the end-of-code "END" look like it's closing), so it's actually
      IF (X .LT. 60.) THENX = X + 7
And so we end up with a variable called THENX with value 49, and X with value 42.


9 comments:

Everett F Sargent said...

42.

X = photo1 * pHOTO1 (basically the G in GOTO! is read as a continuation of the previous statement)
(G in GOTO! occupies the 6th character position which is the default position for a FORTRAN continuation statement)

X = photo1 * pH
GOTO 1


X = 25.

X = 25. + 17. = 42.

The FORTRAN compiler ignores case/spaces everywhere (by default, if there are no 'normal' FORTRAN syntax errors), thus spaces or tabs upper/lower case are ignored and thus ...
X = photo1 * pH
GOTO 1
... is actually ...
X = P h O t O 1
x = photo1

Everett F Sargent said...

"GOTO!"

... should read ...

"GOTO1" (I held down the shift key when typing "1")

Everett F Sargent said...

Still messed it up (via online formatting, x=photo1*photo1=25,x=x+17=42), but I know the answer.

Everett F Sargent said...

INVERSE is an integer by default, thus inverse=1/5=0 (default F77 is 6 characters, but doesn't matter here due to revisions to the FORTRAN standard). I normally follow the F&& standard except when I don't, which is often, thus all my codes are wrong but always give me my preferred answers.

THE CLIMATE WARS said...

It's Greek to me.

https://vvattsupwiththat.blogspot.com/2016/01/the-climate-of-gods.html

William M. Connolley said...

EFS: nearly. You've missed the last trick though.

Everett F Sargent said...

if you mean that ...
IF (X .LT. 60.) THEN X = X + 7.

... is ...

IF(X.LT.60.)THENX=X+7. (which isn't printed out)

Otherwise, I'm still missing the last trick?

Everett F Sargent said...

Yup.

I use the Intel FORTRAN compiler ,,,
https://software.intel.com/en-us/node/679437

"NOTE
No additional statement can be placed after the IF THEN statement in a block IF construct. For example, the following statement is invalid in the block IF construct:

IF (e) THEN I = J
This statement is translated as the following logical IF statement:

IF (e) THENI = J"

If I thought that that if then construct was even valid, I would have said so (and the answer would have been 49 instead of 42). But then I already knew that it wasn't, didn't think it was of any value, since it does nothing relative to the 'RESULT=',X statement. And no, I just looked it up like 10 seconds ago (but I already knew it was not a proper if/then construct and that it will still get through the compiler anyways).

I go back with that particular compiler to when DEC owned it (very early 1983 is when I 1st used it).

Everett F Sargent said...

BTW, I 1st learned FORTRAN in the fall of 1975 (IBM 360 with little donuts for memory). I 1st learned BASIC in the fall of 1972 (self taught 18 years old Dartmouth timeshare while at VTC). There were no computer courses at the time I went to HS (I only did NC punched tape in technical drafting, that would take me back to circa 1970).