Advertisement
autid

AoC 2018 Day19 FORTRAN

Dec 19th, 2018
600
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. PROGRAM DAY19
  2.   IMPLICIT NONE
  3.   TYPE OP
  4.      PROCEDURE(), POINTER, NOPASS :: P
  5.      INTEGER :: ARGS(3)
  6.   END TYPE OP
  7.   INTEGER, TARGET :: REGISTERS(0:5)=0
  8.   INTEGER :: I,J,K,IERR
  9.   INTEGER, POINTER :: INSTRUCTION
  10.   CHARACTER(LEN=4) :: INLINE
  11.   TYPE(OP), ALLOCATABLE :: PROG(:)
  12.  
  13.   OPEN(1,FILE='input.txt')
  14.   I=-1
  15.   DO
  16.      READ(1,*,IOSTAT=IERR)
  17.      IF(IERR.NE.0)EXIT
  18.      I=I+1
  19.   END DO
  20.   REWIND(1)
  21.   READ(1,*)INLINE,J
  22.   INSTRUCTION=>REGISTERS(J)
  23.   ALLOCATE(PROG(0:I-1))
  24.   DO J=0,I-1
  25.      READ(1,*)INLINE,PROG(J)%ARGS
  26.      SELECT CASE(INLINE)
  27.      CASE('addr')
  28.         PROG(J)%P=>ADDR
  29.      CASE('addi')
  30.         PROG(J)%P=>ADDI
  31.      CASE('mulr')
  32.         PROG(J)%P=>MULR
  33.      CASE('muli')
  34.         PROG(J)%P=>MULI
  35.      CASE('banr')
  36.         PROG(J)%P=>BANR
  37.      CASE('bani')
  38.         PROG(J)%P=>BANI
  39.      CASE('borr')
  40.         PROG(J)%P=>BORR
  41.      CASE('bori')
  42.         PROG(J)%P=>BORI
  43.      CASE('setr')
  44.         PROG(J)%P=>SETR
  45.      CASE('seti')
  46.         PROG(J)%P=>SETI
  47.      CASE('gtir')
  48.         PROG(J)%P=>GTIR
  49.      CASE('gtri')
  50.         PROG(J)%P=>GTRI
  51.      CASE('gtrr')
  52.         PROG(J)%P=>GTRR
  53.      CASE('eqir')
  54.         PROG(J)%P=>EQIR
  55.      CASE('eqri')
  56.         PROG(J)%P=>EQRI
  57.      CASE('eqrr')
  58.         PROG(J)%P=>EQRR
  59.      END SELECT
  60.   END DO
  61.   REGISTERS=0
  62.   DO
  63.      IF((INSTRUCTION.LT.0).OR.(INSTRUCTION.GT.UBOUND(PROG,DIM=1)))EXIT
  64.      IF(INSTRUCTION.EQ.1)EXIT
  65.      CALL PROG(INSTRUCTION)%P(PROG(INSTRUCTION)%ARGS(1),PROG(INSTRUCTION)%ARGS(2),PROG(INSTRUCTION)%ARGS(3))
  66.      INSTRUCTION=INSTRUCTION+1
  67.   END DO
  68.   I=REGISTERS(PROG(4)%ARGS(2))
  69.   K=0
  70.   DO J=1,FLOOR(SQRT(REAL(I)))
  71.      IF(MODULO(I,J).EQ.0)K=K+J+I/J
  72.   END DO
  73.   WRITE(*,'("Part 1: ",i0)')K
  74.   REGISTERS=0
  75.   REGISTERS(0)=1
  76.   DO
  77.      IF((INSTRUCTION.LT.0).OR.(INSTRUCTION.GT.UBOUND(PROG,DIM=1)))EXIT
  78.      IF(INSTRUCTION.EQ.1)EXIT
  79.      CALL PROG(INSTRUCTION)%P(PROG(INSTRUCTION)%ARGS(1),PROG(INSTRUCTION)%ARGS(2),PROG(INSTRUCTION)%ARGS(3))
  80.      INSTRUCTION=INSTRUCTION+1
  81.   END DO
  82.   I=REGISTERS(PROG(4)%ARGS(2))
  83.   K=0
  84.   DO J=1,FLOOR(SQRT(REAL(I)))
  85.      IF(MODULO(I,J).EQ.0)K=K+J+I/J
  86.   END DO
  87.   WRITE(*,'("Part 2: ",i0)')K
  88. CONTAINS
  89.   SUBROUTINE ADDR(A,B,C)
  90.     INTEGER, INTENT(IN) :: A,B,C
  91.     REGISTERS(C)=REGISTERS(A)+REGISTERS(B)
  92.   END SUBROUTINE ADDR
  93.   SUBROUTINE ADDI(A,B,C)
  94.     INTEGER, INTENT(IN) :: A,B,C
  95.     REGISTERS(C)=REGISTERS(A)+B
  96.   END SUBROUTINE ADDI
  97.   SUBROUTINE MULR(A,B,C)
  98.     INTEGER, INTENT(IN) :: A,B,C
  99.     REGISTERS(C)=REGISTERS(A)*REGISTERS(B)
  100.   END SUBROUTINE MULR
  101.   SUBROUTINE MULI(A,B,C)
  102.     INTEGER, INTENT(IN) :: A,B,C
  103.     REGISTERS(C)=REGISTERS(A)*B
  104.   END SUBROUTINE MULI
  105.   SUBROUTINE BANR(A,B,C)
  106.     INTEGER, INTENT(IN) :: A,B,C
  107.     REGISTERS(C)=IAND(REGISTERS(A),REGISTERS(B))
  108.   END SUBROUTINE BANR
  109.   SUBROUTINE BANI(A,B,C)
  110.     INTEGER, INTENT(IN) :: A,B,C
  111.     REGISTERS(C)=IAND(REGISTERS(A),B)
  112.   END SUBROUTINE BANI
  113.   SUBROUTINE BORR(A,B,C)
  114.     INTEGER, INTENT(IN) :: A,B,C
  115.     REGISTERS(C)=IOR(REGISTERS(A),REGISTERS(B))
  116.   END SUBROUTINE BORR
  117.   SUBROUTINE BORI(A,B,C)
  118.     INTEGER, INTENT(IN) :: A,B,C
  119.     REGISTERS(C)=IOR(REGISTERS(A),B)
  120.   END SUBROUTINE BORI
  121.   SUBROUTINE SETR(A,B,C)
  122.     INTEGER, INTENT(IN) :: A,B,C
  123.     REGISTERS(C)=REGISTERS(A)
  124.   END SUBROUTINE SETR
  125.   SUBROUTINE SETI(A,B,C)
  126.     INTEGER, INTENT(IN) :: A,B,C
  127.     REGISTERS(C)=A
  128.   END SUBROUTINE SETI
  129.   SUBROUTINE GTIR(A,B,C)
  130.     INTEGER, INTENT(IN) :: A,B,C
  131.     IF(A>REGISTERS(B))THEN
  132.        REGISTERS(C)=1
  133.     ELSE
  134.        REGISTERS(C)=0
  135.     END IF
  136.   END SUBROUTINE GTIR
  137.   SUBROUTINE GTRI(A,B,C)
  138.     INTEGER, INTENT(IN) :: A,B,C
  139.     IF(REGISTERS(A)>B)THEN
  140.        REGISTERS(C)=1
  141.     ELSE
  142.        REGISTERS(C)=0
  143.     END IF
  144.   END SUBROUTINE GTRI
  145.   SUBROUTINE GTRR(A,B,C)
  146.     INTEGER, INTENT(IN) :: A,B,C
  147.     IF(REGISTERS(A)>REGISTERS(B))THEN
  148.        REGISTERS(C)=1
  149.     ELSE
  150.        REGISTERS(C)=0
  151.     END IF
  152.   END SUBROUTINE GTRR
  153.   SUBROUTINE EQIR(A,B,C)
  154.     INTEGER, INTENT(IN) :: A,B,C
  155.     IF(A.EQ.REGISTERS(B))THEN
  156.        REGISTERS(C)=1
  157.     ELSE
  158.        REGISTERS(C)=0
  159.     END IF
  160.   END SUBROUTINE EQIR
  161.   SUBROUTINE EQRI(A,B,C)
  162.     INTEGER, INTENT(IN) :: A,B,C
  163.     IF(REGISTERS(A).EQ.B)THEN
  164.        REGISTERS(C)=1
  165.     ELSE
  166.        REGISTERS(C)=0
  167.     END IF
  168.   END SUBROUTINE EQRI
  169.   SUBROUTINE EQRR(A,B,C)
  170.     INTEGER, INTENT(IN) :: A,B,C
  171.     IF(REGISTERS(A).EQ.REGISTERS(B))THEN
  172.        REGISTERS(C)=1
  173.     ELSE
  174.        REGISTERS(C)=0
  175.     END IF
  176.   END SUBROUTINE EQRR
  177. END PROGRAM DAY19
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement