Advertisement
autid

AoC 2019 Day5 FORTRAN

Dec 5th, 2019
1,580
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. PROGRAM DAY5
  2.   TYPE OP
  3.      PROCEDURE(), POINTER, NOPASS :: OP
  4.      INTEGER :: NARGS
  5.   END TYPE OP
  6.   INTEGER :: I,N,IERR,MODES,OPCODE
  7.   CHARACTER(LEN=1) CHAR
  8.   INTEGER, ALLOCATABLE :: PROG(:)
  9.   TYPE(OP) :: OPS(8)
  10.  
  11.   OPS(1)%NARGS=3
  12.   OPS(1)%OP => ADD
  13.   OPS(2)%NARGS=3
  14.   OPS(2)%OP => MULTIPLY
  15.   OPS(3)%NARGS=1
  16.   OPS(3)%OP => INPUT
  17.   OPS(4)%NARGS=1
  18.   OPS(4)%OP => OUTPUT
  19.   OPS(5)%NARGS=2
  20.   OPS(5)%OP => JUMP_IF_TRUE
  21.   OPS(6)%NARGS=2
  22.   OPS(6)%OP => JUMP_IF_FALSE
  23.   OPS(7)%NARGS=3
  24.   OPS(7)%OP => LESS_THAN
  25.   OPS(8)%NARGS=3
  26.   OPS(8)%OP => EQUALS
  27.  
  28.   OPEN(1,FILE="input.txt")
  29.   N=1
  30.   DO
  31.      READ(1,'(A1)',IOSTAT=IERR,ADVANCE="NO")CHAR
  32.      IF(IERR.NE.0)EXIT
  33.      IF(CHAR.EQ.",")N=N+1
  34.   END DO
  35.   REWIND(1)
  36.   ALLOCATE(PROG(0:N-1))
  37.   READ(1,*)PROG
  38.  
  39.   I=0
  40.   DO
  41.      MODES=PROG(I)/100
  42.      OPCODE=MODULO(PROG(I),100)
  43.      IF(OPCODE.EQ.99)EXIT
  44.      CALL OPS(OPCODE)%OP(MODES,PROG(I+1:I+OPS(OPCODE)%NARGS),I)
  45.   END DO
  46.  
  47.  
  48.  
  49. CONTAINS
  50.   SUBROUTINE ADD(MODES,PARAMS,I)
  51.     INTEGER, INTENT(IN) :: MODES, PARAMS(3)
  52.     INTEGER :: A,B
  53.     INTEGER, INTENT(INOUT) :: I
  54.     I=I+4
  55.    
  56.     IF(MODULO(MODES,10).EQ.0)THEN
  57.        A=PROG(PARAMS(1))
  58.     ELSE
  59.        A=PARAMS(1)
  60.     END IF
  61.     IF(MODULO(MODES,100)/10.EQ.0)THEN
  62.        B=PROG(PARAMS(2))
  63.     ELSE
  64.        B=PARAMS(2)
  65.     END IF
  66.     PROG(PARAMS(3))=A+B
  67.   END SUBROUTINE ADD
  68.  
  69.   SUBROUTINE MULTIPLY(MODES,PARAMS,I)
  70.     INTEGER, INTENT(IN) :: MODES, PARAMS(3)
  71.     INTEGER :: A,B
  72.     INTEGER, INTENT(INOUT) :: I
  73.     I=I+4
  74.  
  75.     IF(MODULO(MODES,10).EQ.0)THEN    
  76.        A=PROG(PARAMS(1))
  77.     ELSE
  78.        A=PARAMS(1)
  79.     END IF
  80.     IF(MODULO(MODES,100)/10.EQ.0)THEN
  81.        B=PROG(PARAMS(2))
  82.     ELSE
  83.        B=PARAMS(2)
  84.     END IF
  85.     PROG(PARAMS(3))=A*B
  86.   END SUBROUTINE MULTIPLY
  87.  
  88.   SUBROUTINE INPUT(MODES,PARAMS,I)
  89.     INTEGER, INTENT(IN) :: MODES, PARAMS(3)
  90.     INTEGER :: A
  91.     INTEGER, INTENT(INOUT) :: I
  92.     I=I+2
  93.    
  94.     WRITE(*,'(A)',ADVANCE="NO") "Enter input: "
  95.     READ(*,*)A
  96.     PROG(PARAMS(1))=A
  97.   END SUBROUTINE INPUT
  98.  
  99.   SUBROUTINE OUTPUT(MODES,PARAMS,I)
  100.     INTEGER, INTENT(IN) :: MODES, PARAMS(3)
  101.     INTEGER :: A,B
  102.     INTEGER, INTENT(INOUT) :: I
  103.     I=I+2
  104.  
  105.     IF(MODULO(MODES,10).EQ.0)THEN
  106.        A=PROG(PARAMS(1))
  107.     ELSE
  108.        A=PARAMS(1)
  109.     END IF
  110.     IF(MODULO(MODES,100)/10.EQ.0)THEN
  111.        B=PROG(PARAMS(2))
  112.     ELSE
  113.        B=PARAMS(2)
  114.     END IF
  115.     WRITE(*,'(A,I0)') "Output: ", A
  116.   END SUBROUTINE OUTPUT
  117.  
  118.   SUBROUTINE JUMP_IF_TRUE(MODES,PARAMS,I)
  119.     INTEGER, INTENT(IN) :: MODES, PARAMS(2)
  120.     INTEGER :: A,B
  121.     INTEGER, INTENT(INOUT) :: I
  122.  
  123.     IF(MODULO(MODES,10).EQ.0)THEN
  124.        A=PROG(PARAMS(1))
  125.     ELSE
  126.        A=PARAMS(1)
  127.     END IF
  128.     IF(MODULO(MODES,100)/10.EQ.0)THEN
  129.        B=PROG(PARAMS(2))
  130.     ELSE
  131.        B=PARAMS(2)
  132.     END IF
  133.     IF(A.NE.0)THEN
  134.        I=B
  135.     ELSE
  136.        I=I+3
  137.     END IF
  138.   END SUBROUTINE JUMP_IF_TRUE
  139.  
  140.   SUBROUTINE JUMP_IF_FALSE(MODES,PARAMS,I)
  141.     INTEGER, INTENT(IN) :: MODES, PARAMS(2)
  142.     INTEGER :: A,B
  143.     INTEGER, INTENT(INOUT) :: I
  144.  
  145.     IF(MODULO(MODES,10).EQ.0)THEN
  146.        A=PROG(PARAMS(1))
  147.     ELSE
  148.        A=PARAMS(1)
  149.     END IF
  150.     IF(MODULO(MODES,100)/10.EQ.0)THEN
  151.        B=PROG(PARAMS(2))
  152.     ELSE
  153.        B=PARAMS(2)
  154.     END IF
  155.     IF(A.EQ.0)THEN
  156.        I=B
  157.     ELSE
  158.        I=I+3
  159.     END IF
  160.   END SUBROUTINE JUMP_IF_FALSE
  161.  
  162.   SUBROUTINE LESS_THAN(MODES,PARAMS,I)
  163.     INTEGER, INTENT(IN) :: MODES, PARAMS(3)
  164.     INTEGER :: A,B
  165.     INTEGER, INTENT(INOUT) :: I
  166.     I=I+4
  167.  
  168.     IF(MODULO(MODES,10).EQ.0)THEN    
  169.        A=PROG(PARAMS(1))
  170.     ELSE
  171.        A=PARAMS(1)
  172.     END IF
  173.     IF(MODULO(MODES,100)/10.EQ.0)THEN
  174.        B=PROG(PARAMS(2))
  175.     ELSE
  176.        B=PARAMS(2)
  177.     END IF
  178.     IF(A<B)THEN
  179.        PROG(PARAMS(3))=1
  180.     ELSE
  181.        PROG(PARAMS(3))=0
  182.     END IF
  183.   END SUBROUTINE LESS_THAN
  184.  
  185.   SUBROUTINE EQUALS(MODES,PARAMS,I)
  186.     INTEGER, INTENT(IN) :: MODES, PARAMS(3)
  187.     INTEGER :: A,B
  188.     INTEGER, INTENT(INOUT) :: I
  189.     I=I+4
  190.  
  191.     IF(MODULO(MODES,10).EQ.0)THEN    
  192.        A=PROG(PARAMS(1))
  193.     ELSE
  194.        A=PARAMS(1)
  195.     END IF
  196.     IF(MODULO(MODES,100)/10.EQ.0)THEN
  197.        B=PROG(PARAMS(2))
  198.     ELSE
  199.        B=PARAMS(2)
  200.     END IF
  201.     IF(A.EQ.B)THEN
  202.        PROG(PARAMS(3))=1
  203.     ELSE
  204.        PROG(PARAMS(3))=0
  205.     END IF
  206.   END SUBROUTINE EQUALS
  207.  
  208. END PROGRAM DAY5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement