autid

AoC 2019 Day6 FORTRAN

Dec 6th, 2019
1,617
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. PROGRAM DAY6
  2.   IMPLICIT NONE
  3.   TYPE OBJPTR
  4.      TYPE(OBJ), POINTER :: P
  5.   END TYPE OBJPTR
  6.   TYPE OBJ
  7.      TYPE(OBJPTR), ALLOCATABLE :: P(:)
  8.      CHARACTER(LEN=3) :: NAME
  9.   END TYPE OBJ
  10.   CHARACTER(LEN=7), ALLOCATABLE :: ORBITS(:)
  11.   CHARACTER(LEN=3), ALLOCATABLE :: ORBITED(:)
  12.   CHARACTER(LEN=3), ALLOCATABLE :: OBJECTNAMES(:)
  13.   TYPE(OBJ), ALLOCATABLE, TARGET :: OBJECTS(:)
  14.   INTEGER :: I,J,K,N,IERR,DEPTH,PART1,NORBS
  15.  
  16.   ! Input
  17.   OPEN(1,FILE="input.txt")
  18.   N=0
  19.   DO
  20.      READ(1,*,IOSTAT=IERR)
  21.      IF(IERR.NE.0)EXIT
  22.      N=N+1
  23.   END DO
  24.   ALLOCATE(ORBITS(N),ORBITED(N),OBJECTNAMES(0:N),OBJECTS(0:N))
  25.   REWIND(1)
  26.   READ(1,*)ORBITS
  27.   CLOSE(1)
  28.  
  29.   ! Setup tree
  30.   OBJECTNAMES(0)="COM"
  31.   DO I=1,N
  32.      OBJECTNAMES(I)=ORBITS(I)(5:)
  33.      ORBITED(I)=ORBITS(I)(1:3)
  34.   END DO
  35.   DO I=0,N
  36.      OBJECTS(I)%NAME=OBJECTNAMES(I)
  37.      NORBS=COUNT(ORBITED.EQ.OBJECTNAMES(I))
  38.      IF(NORBS>0)THEN
  39.         ALLOCATE(OBJECTS(I)%P(NORBS))
  40.         J=1
  41.         DO K=1,N
  42.            IF(ORBITED(K).EQ.OBJECTNAMES(I))THEN
  43.               OBJECTS(I)%P(J)%P => OBJECTS(K)
  44.               J=J+1
  45.            END IF
  46.         END DO
  47.      END IF
  48.   END DO
  49.  
  50.   WRITE(*,'("Part 1: ",I0)') COUNTORBS(OBJECTS(0),0)
  51.   WRITE(*,'("Part 2: ",I0)') DISTBETWEEN(OBJECTS(0),"YOU","SAN")
  52.  
  53. CONTAINS
  54.   RECURSIVE FUNCTION COUNTORBS(ORBITED, DEPTH) RESULT(PART1)
  55.     INTEGER :: DEPTH, PART1,I
  56.     TYPE(OBJ) :: ORBITED
  57.  
  58.     PART1=DEPTH
  59.     IF(ALLOCATED(ORBITED%P))THEN
  60.        DO I=1,SIZE(ORBITED%P)
  61.           PART1=PART1+COUNTORBS(ORBITED%P(I)%P,DEPTH+1)
  62.        END DO
  63.     END IF
  64.   END FUNCTION COUNTORBS
  65.  
  66.   RECURSIVE FUNCTION DISTTO(ORBITED, TARG) RESULT(DIST)
  67.     INTEGER :: DIST,I,J
  68.     TYPE(OBJ) :: ORBITED
  69.     CHARACTER(LEN=3) :: TARG
  70.  
  71.     DIST=-999
  72.     IF(ALLOCATED(ORBITED%P))THEN
  73.        DO I=1,SIZE(ORBITED%P)
  74.           IF(ORBITED%P(I)%P%NAME.EQ.TARG)THEN
  75.              DIST=0
  76.              RETURN
  77.           END IF
  78.           J=DISTTO(ORBITED%P(I)%P, TARG)
  79.           IF(J.GE.0)THEN
  80.              DIST=J+1
  81.              RETURN
  82.           END IF
  83.        END DO
  84.     END IF
  85.   END FUNCTION DISTTO
  86.  
  87.   RECURSIVE FUNCTION DISTBETWEEN(ORBITED, TARG1, TARG2) RESULT(PART2)
  88.     INTEGER :: PART2, I, J, K
  89.     TYPE(OBJ) :: ORBITED
  90.     CHARACTER(LEN=3) :: TARG1,TARG2
  91.  
  92.     PART2=-999
  93.    
  94.     IF(ALLOCATED(ORBITED%P))THEN
  95.        DO I=1,SIZE(ORBITED%P)
  96.           PART2=DISTBETWEEN(ORBITED%P(I)%P,TARG1,TARG2)
  97.           IF(PART2.GE.0)RETURN
  98.        END DO
  99.        J=DISTTO(ORBITED,TARG1)
  100.        K=DISTTO(ORBITED,TARG2)
  101.        IF(ANY((/J,K/).LT.0))RETURN
  102.        PART2=J+K
  103.     END IF
  104.   END FUNCTION DISTBETWEEN
  105. END PROGRAM DAY6
Advertisement
Add Comment
Please, Sign In to add comment