Advertisement
autid

AoC 2018 Day24 FORTRAN

Dec 24th, 2018
688
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. PROGRAM DAY24
  2.   IMPLICIT NONE
  3.   TYPE GROUP
  4.      INTEGER :: INITIATIVE,HEALTH,NUMBER,DAMAGE
  5.      CHARACTER(LEN=20) :: DAMAGETYPE
  6.      LOGICAL :: WEAK(5)=.FALSE.,IMMUNE(5)=.FALSE.
  7.   END TYPE GROUP
  8.   TYPE(GROUP), ALLOCATABLE :: IMMUNE(:),INFECTION(:)
  9.   INTEGER, ALLOCATABLE :: IMTARGETS(:),IMEFFECTIVE(:),INTARGETS(:),INEFFECTIVE(:),ORDER(:),IMDAMAGE(:),INDAMAGE(:)
  10.   INTEGER, ALLOCATABLE :: IMNUMBERS(:),INNUMBERS(:),BIMNUMBERS(:),BINNUMBERS(:)
  11.   LOGICAL,ALLOCATABLE :: ORDERTYPE(:),IMCHOSEN(:),INCHOSEN(:)
  12.   INTEGER :: I,J,K,L,M,N,O,IERR,BOOST
  13.   CHARACTER(LEN=500) :: INLINE,THING
  14.   CHARACTER(LEN=20) :: TYPES(5)=(/'bludgeoning','slashing','radiation','cold','fire'/)
  15.   OPEN(1,FILE='input.txt')
  16.   M=0
  17.   READ(1,'(A)')INLINE
  18.   DO
  19.      READ(1,'(A)')INLINE
  20.      IF(TRIM(INLINE).EQ.'')EXIT
  21.      M=M+1
  22.   END DO
  23.   N=0
  24.   READ(1,'(A)')INLINE
  25.   DO
  26.      READ(1,'(A)',IOSTAT=IERR)INLINE
  27.      IF(IERR.NE.0)EXIT
  28.      N=N+1
  29.   END DO
  30.   ALLOCATE(IMMUNE(M),INFECTION(N))
  31.   ALLOCATE(IMTARGETS(M),IMEFFECTIVE(M),INTARGETS(N),INEFFECTIVE(N),ORDER(M+N),ORDERTYPE(M+N),IMDAMAGE(N),INDAMAGE(M))
  32.   ALLOCATE(IMCHOSEN(M),INCHOSEN(N),IMNUMBERS(M),INNUMBERS(N),BIMNUMBERS(M),BINNUMBERS(N))
  33.   REWIND(1)
  34.   READ(1,'(A)')INLINE
  35.   DO I=1,M
  36.      READ(1,'(A)')INLINE
  37.      J=SCAN(INLINE,' ')
  38.      READ(INLINE(1:J-1),*)IMMUNE(I)%NUMBER
  39.      IMNUMBERS(I)=IMMUNE(I)%NUMBER
  40.      DO L=1,3
  41.         J=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  42.      END DO
  43.      K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  44.      READ(INLINE(J+1:K-1),*)IMMUNE(I)%HEALTH
  45.      IF(SCAN(INLINE,'(').NE.0)THEN
  46.         J=SCAN(INLINE,'(')
  47.         DO
  48.            K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  49.            THING=INLINE(J+1:K-1)
  50.            IF(TRIM(THING).EQ.'immune')THEN
  51.               J=K+SCAN(INLINE(K+1:LEN_TRIM(INLINE)),' ')
  52.               DO
  53.                  K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  54.                  THING=INLINE(J+1:K-2)
  55.                  IMMUNE(I)%IMMUNE=IMMUNE(I)%IMMUNE.OR.((/(TRIM(TYPES(I)).EQ.THING,I=1,5)/))
  56.                  J=K
  57.                  IF(SCAN(INLINE(K-1:K-1),';)').NE.0)EXIT
  58.               END DO
  59.            ELSE
  60.               J=K+SCAN(INLINE(K+1:LEN_TRIM(INLINE)),' ')
  61.               DO
  62.                  K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  63.                  THING=INLINE(J+1:K-2)
  64.                  IMMUNE(I)%WEAK=IMMUNE(I)%WEAK.OR.((/(TRIM(TYPES(I)).EQ.THING,I=1,5)/))
  65.                  J=K
  66.                  IF(SCAN(INLINE(K-1:K-1),';)').NE.0)EXIT
  67.               END DO
  68.            END IF
  69.            IF(INLINE(J-1:J-1).EQ.')')EXIT
  70.         END DO
  71.      END IF
  72.      J=SCAN(TRIM(INLINE),' ',.TRUE.)
  73.      READ(INLINE(J+1:LEN_TRIM(INLINE)),*)IMMUNE(I)%INITIATIVE
  74.      DO L=1,4
  75.         J=SCAN(INLINE(1:J-1),' ',.TRUE.)
  76.      END DO
  77.      K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  78.      READ(INLINE(J+1:K-1),'(A)')IMMUNE(I)%DAMAGETYPE
  79.      K=SCAN(INLINE(1:J-1),' ',.TRUE.)
  80.      READ(INLINE(K+1:J-1),*)IMMUNE(I)%DAMAGE
  81.   END DO
  82.   READ(1,'(A)')INLINE
  83.   READ(1,'(A)')INLINE
  84.   DO I=1,N
  85.      READ(1,'(A)')INLINE
  86.      J=SCAN(INLINE,' ')
  87.      READ(INLINE(1:J-1),*)INFECTION(I)%NUMBER
  88.      INNUMBERS(I)=INFECTION(I)%NUMBER
  89.      DO L=1,3
  90.         J=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  91.      END DO
  92.      K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  93.      READ(INLINE(J+1:K-1),*)INFECTION(I)%HEALTH
  94.      IF(SCAN(INLINE,'(').NE.0)THEN
  95.         J=SCAN(INLINE,'(')
  96.         DO
  97.            K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  98.            THING=INLINE(J+1:K-1)
  99.            IF(TRIM(THING).EQ.'immune')THEN
  100.               J=K+SCAN(INLINE(K+1:LEN_TRIM(INLINE)),' ')
  101.               DO
  102.                  K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  103.                  THING=INLINE(J+1:K-2)
  104.                  INFECTION(I)%IMMUNE=INFECTION(I)%IMMUNE.OR.((/(TRIM(TYPES(I)).EQ.THING,I=1,5)/))
  105.                  J=K
  106.                  IF(SCAN(INLINE(K-1:K-1),';)').NE.0)EXIT
  107.               END DO
  108.            ELSE
  109.               J=K+SCAN(INLINE(K+1:LEN_TRIM(INLINE)),' ')
  110.               DO
  111.                  K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  112.                  THING=INLINE(J+1:K-2)
  113.                  INFECTION(I)%WEAK=INFECTION(I)%WEAK.OR.((/(TRIM(TYPES(I)).EQ.THING,I=1,5)/))
  114.                  J=K
  115.                  IF(SCAN(INLINE(K-1:K-1),';)').NE.0)EXIT
  116.               END DO
  117.            END IF
  118.            IF(INLINE(J-1:J-1).EQ.')')EXIT
  119.         END DO
  120.      END IF
  121.      J=SCAN(TRIM(INLINE),' ',.TRUE.)
  122.      READ(INLINE(J+1:LEN_TRIM(INLINE)),*)INFECTION(I)%INITIATIVE
  123.      DO L=1,4
  124.         J=SCAN(INLINE(1:J-1),' ',.TRUE.)
  125.      END DO
  126.      K=J+SCAN(INLINE(J+1:LEN_TRIM(INLINE)),' ')
  127.      READ(INLINE(J+1:K-1),'(A)')INFECTION(I)%DAMAGETYPE
  128.      K=SCAN(INLINE(1:J-1),' ',.TRUE.)
  129.      READ(INLINE(K+1:J-1),*)INFECTION(I)%DAMAGE
  130.   END DO
  131.   CLOSE(1)
  132.   J=1
  133.   IMEFFECTIVE=IMMUNE%INITIATIVE
  134.   INEFFECTIVE=INFECTION%INITIATIVE
  135.   IMCHOSEN=.TRUE.
  136.   INCHOSEN=.TRUE.
  137.   ORDER=0
  138.   DO
  139.      K=MAXVAL((/IMEFFECTIVE,INEFFECTIVE/),MASK=(/IMCHOSEN,INCHOSEN/))
  140.      IF(ANY(IMEFFECTIVE.EQ.K))THEN
  141.         ORDERTYPE(J)=.TRUE.
  142.         ORDER(J)=MAXLOC(IMEFFECTIVE,MASK=IMEFFECTIVE.EQ.K,DIM=1)
  143.         IMCHOSEN(ORDER(J))=.FALSE.
  144.      ELSE
  145.         ORDERTYPE(J)=.FALSE.
  146.         ORDER(J)=MAXLOC(INEFFECTIVE,MASK=INEFFECTIVE.EQ.K,DIM=1)
  147.         INCHOSEN(ORDER(J))=.FALSE.
  148.      END IF
  149.      J=J+1
  150.      IF(J.GT.M+N)EXIT
  151.   END DO
  152.  
  153.   BOOST=-1
  154.   OUTER:DO
  155.      BOOST=BOOST+1
  156.      IMMUNE%NUMBER=IMNUMBERS
  157.      INFECTION%NUMBER=INNUMBERS
  158.      DO
  159.         BIMNUMBERS=IMMUNE%NUMBER
  160.         BINNUMBERS=INFECTION%NUMBER
  161.         IF(ALL(IMMUNE%NUMBER.EQ.0).OR.ALL(INFECTION%NUMBER.EQ.0))EXIT
  162.         IMEFFECTIVE=IMMUNE%NUMBER*(IMMUNE%DAMAGE+BOOST)*1000+IMMUNE%INITIATIVE
  163.         INEFFECTIVE=INFECTION%NUMBER*INFECTION%DAMAGE*1000+INFECTION%INITIATIVE
  164.         IMCHOSEN=.FALSE.
  165.         INCHOSEN=.FALSE.
  166.         IMTARGETS=0
  167.         K=MAXVAL(IMEFFECTIVE)+1
  168.         DO
  169.            IF(K.EQ.MINVAL(IMEFFECTIVE))EXIT
  170.            IF(MAXVAL(IMEFFECTIVE,MASK=IMEFFECTIVE<K).LT.1000)EXIT
  171.            J=MAXLOC(IMEFFECTIVE,MASK=IMEFFECTIVE<K,DIM=1)
  172.            K=IMEFFECTIVE(J)
  173.            IMDAMAGE=0
  174.            DO I=1,N
  175.               IF(INCHOSEN(I))CYCLE
  176.               IF(INFECTION(I)%NUMBER.EQ.0)CYCLE
  177.               IF(ANY(INFECTION(I)%IMMUNE.AND.((/(TRIM(TYPES(L)).EQ.TRIM(IMMUNE(J)%DAMAGETYPE),L=1,5)/))))CYCLE
  178.               IMDAMAGE(I)=IMMUNE(J)%NUMBER*(IMMUNE(J)%DAMAGE+BOOST)
  179.               IF(COUNT(INFECTION(I)%WEAK.AND.(/(TRIM(TYPES(L)).EQ.TRIM(IMMUNE(J)%DAMAGETYPE),L=1,5)/)).GT.0)THEN
  180.                  IMDAMAGE(I)=IMDAMAGE(I)*2
  181.               END IF
  182.            END DO
  183.            IF(MAXVAL(IMDAMAGE).EQ.0)CYCLE
  184.            IMTARGETS(J)=MAXLOC(INEFFECTIVE,MASK=IMDAMAGE.EQ.MAXVAL(IMDAMAGE),DIM=1)
  185.            INCHOSEN(IMTARGETS(J))=.TRUE.
  186.         END DO
  187.         INTARGETS=0
  188.         K=MAXVAL(INEFFECTIVE)+1
  189.         DO
  190.            IF(K.EQ.MINVAL(INEFFECTIVE))EXIT
  191.            IF(MAXVAL(INEFFECTIVE,MASK=INEFFECTIVE<K).LT.1000)EXIT
  192.            J=MAXLOC(INEFFECTIVE,MASK=INEFFECTIVE<K,DIM=1)
  193.            K=INEFFECTIVE(J)
  194.            INDAMAGE=0
  195.            DO I=1,M
  196.               IF(IMCHOSEN(I))CYCLE
  197.               IF(IMMUNE(I)%NUMBER.EQ.0)CYCLE
  198.               IF(ANY(IMMUNE(I)%IMMUNE.AND.((/(TRIM(TYPES(L)).EQ.TRIM(INFECTION(J)%DAMAGETYPE),L=1,5)/))))CYCLE
  199.               INDAMAGE(I)=INFECTION(J)%NUMBER*INFECTION(J)%DAMAGE
  200.               IF(COUNT(IMMUNE(I)%WEAK.AND.(/(TRIM(TYPES(L)).EQ.TRIM(INFECTION(J)%DAMAGETYPE),L=1,5)/)).GT.0)THEN
  201.                  INDAMAGE(I)=INDAMAGE(I)*2
  202.               END IF
  203.            END DO
  204.            IF(MAXVAL(INDAMAGE).EQ.0)CYCLE
  205.            INTARGETS(J)=MAXLOC(IMEFFECTIVE,MASK=INDAMAGE.EQ.MAXVAL(INDAMAGE),DIM=1)
  206.            IMCHOSEN(INTARGETS(J))=.TRUE.
  207.         END DO
  208.         DO I=1,M+N
  209.            IF(ORDERTYPE(I))THEN
  210.               IF(IMTARGETS(ORDER(I)).EQ.0)CYCLE
  211.               J=ORDER(I)
  212.               IF(IMMUNE(J)%NUMBER.EQ.0)CYCLE
  213.               L=IMMUNE(J)%NUMBER*(IMMUNE(J)%DAMAGE+BOOST)
  214.               K=IMTARGETS(J)
  215.               IF(ANY(INFECTION(K)%WEAK.AND.(/(TRIM(TYPES(O)).EQ.TRIM(IMMUNE(J)%DAMAGETYPE),O=1,5)/)))THEN
  216.                  L=L*2
  217.               END IF
  218.               INFECTION(K)%NUMBER=MAX(0,INFECTION(K)%NUMBER-L/INFECTION(K)%HEALTH)
  219.            ELSE
  220.               IF(INTARGETS(ORDER(I)).EQ.0)CYCLE
  221.               J=ORDER(I)
  222.               IF(INFECTION(J)%NUMBER.EQ.0)EXIT
  223.               L=INFECTION(J)%NUMBER*INFECTION(J)%DAMAGE
  224.               K=INTARGETS(J)
  225.               IF(ANY(IMMUNE(K)%WEAK.AND.(/(TRIM(TYPES(O)).EQ.TRIM(INFECTION(J)%DAMAGETYPE),O=1,5)/)))THEN
  226.                  L=L*2
  227.               END IF
  228.               IMMUNE(K)%NUMBER=MAX(0,IMMUNE(K)%NUMBER-L/IMMUNE(K)%HEALTH)
  229.            END IF
  230.         END DO
  231.         IF(ALL(BIMNUMBERS.EQ.IMMUNE%NUMBER).AND.ALL(BINNUMBERS.EQ.INFECTION%NUMBER))CYCLE OUTER
  232.      END DO
  233.      IF(BOOST.EQ.0)WRITE(*,'("Part 1: ",I0)')MAX(SUM(INFECTION%NUMBER),SUM(IMMUNE%NUMBER))
  234.      IF(SUM(IMMUNE%NUMBER).GT.0)EXIT OUTER
  235.   END DO OUTER
  236.   WRITE(*,'("Part 2: ",I0)')SUM(IMMUNE%NUMBER)
  237. END PROGRAM DAY24
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement