Advertisement
Oppaceted

OiU_3 second version

May 30th, 2023
432
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Fortran 12.34 KB | None | 0 0
  1. module OiU3
  2.     integer, parameter :: ASCII_const = 48
  3.     contains
  4.     !
  5.     subroutine numbers(array, n, y)
  6.         integer :: n, i, y
  7.         integer :: array(n)
  8.         write (0,fmt = '(a4$)') '| \ '
  9.         do i = 1,n,1
  10.             if (i==y) then
  11.                 write (0, fmt = '(a$)') '| '
  12.                 write (0, fmt='(a$)') achar(27)//'[4m'//achar(27)//'[91m'//&
  13.                 achar(ASCII_const + array(i))//':'//achar(27)//'[0m'
  14.             else
  15.                 write (0, fmt = '(a,i2,a$)') '|', array(i), ':'
  16.             end if
  17.             !write (0,fmt='(i2$)') array(i)
  18.         end do
  19.         write (0,fmt = '(a1)') '|'
  20.     end subroutine
  21.     !
  22.     subroutine cap(n)
  23.         integer :: n, i
  24.         do i =1,n
  25.             write (0,fmt = '(a$)') '+---'
  26.         end do
  27.         write (0,fmt = '(a)') '+'
  28.     end subroutine
  29.     !
  30.     subroutine write_array(stolbec_count,array,n)
  31.         integer :: n, i
  32.         integer :: array(n), stolbec_count(n)
  33.         write (0,*)
  34.         call cap(n+1)
  35.         call numbers(stolbec_count,n,0)
  36.         call cap(n+1)
  37.         write (0,fmt = '(a$)') '| / '
  38.         do i = 1,n
  39.             write (0,fmt = '(a,i2,a$)') '|', array(i),' '
  40.         end do
  41.         write (0,fmt = '(a)') '|'
  42.         call cap(n+1)
  43.         write (0,*)
  44.     end subroutine
  45.     !
  46.     subroutine write_matrix(matrix, stroka_count, stolbec_count, n, x, y)
  47.         integer :: n, x, y, k, l
  48.         integer :: matrix(n,n), stolbec_count(n), stroka_count(n)
  49.         !
  50.         call execute_command_line('')
  51.         write (0,*)
  52.         call cap(n+1)
  53.         call numbers(stolbec_count,n,y)
  54.         do k = 1,n
  55.             call cap(n+1)
  56.             if (k==x) then
  57.                 write (0, fmt='(a$)') '| '
  58.                 write (0, fmt='(a$)') achar(27)//'[4m'//achar(27)//'[91m'&
  59.                 //achar( ASCII_const + stroka_count(k) )//':'//achar(27)//'[0m'
  60.             else
  61.                 write (0, fmt='(a,i2,a$)') '|', stroka_count(k), ':'
  62.             end if
  63.             do l = 1,n
  64.                 if ( matrix(k,l)>10000 ) then
  65.                     if (k==x .or. l==y) then
  66.                         write (0,fmt = '(a$)') '|'
  67.                         write (0,fmt = '(a$)') achar(27)//'[4m'//achar(27)//'[91m'//'inf'//achar(27)//'[0m'
  68.                     else
  69.                         write (0, fmt = '(a$)') '|inf'
  70.                     end if
  71.                 else
  72.                     if (k==x .or. l==y) then
  73.                         write (0,fmt='(a$)') '|'
  74.                         write (0,fmt = '(1x,a$)') achar(27)//'[4m'//achar(27)//'[91m'//&
  75.                         achar(ASCII_const + (matrix(k,l)/10) )//&
  76.                         achar(ASCII_const + (matrix(k,l)-matrix(k,l)/10*10))//achar(27)//'[0m'
  77.                     else
  78.                         write (0,fmt='(a,i3$)') '|',matrix(k,l)
  79.                     end if
  80.                 end if
  81.             end do
  82.             write (0,fmt='(a)') '|'
  83.         end do
  84.         call cap(n+1)
  85.         write (0,*)
  86.     end subroutine
  87.     !
  88.     integer function minimum(array,n) result(res_index)
  89.         integer :: n, i
  90.         integer :: array(n)
  91.         res_index = 1
  92.         do i =1,n,1
  93.             if( array(i)<array(res_index) ) then
  94.                 res_index = i
  95.             end if
  96.         end do
  97.     end function
  98.     !
  99.     subroutine min_stroka(matrix,n,stroka_min)
  100.         integer :: n, i
  101.         integer :: matrix(n,n), stroka_min(n),temp_array(n)
  102.         do i =1,n
  103.             temp_array = matrix(i,:)
  104.             stroka_min(i) = matrix(i, minimum(temp_array,n))
  105.         end do
  106.     end subroutine
  107.     !
  108.     subroutine min_stolbec(matrix,n,stolbec_min)
  109.         integer :: n, i
  110.         integer :: matrix(n,n), stolbec_min(n),temp_array(n)
  111.         do i =1,n
  112.             temp_array = matrix(:,i)
  113.             stolbec_min(i) = matrix(minimum(temp_array,n), i)
  114.         end do
  115.     end subroutine
  116.     !
  117.     subroutine transform(matrix, n, summa)
  118.         integer :: n,i, summa_1, summa_2, summa
  119.         integer :: matrix(n,n), temp_matrix(n,n), stroka_min(n), stolbec_min(n)
  120.         ! 1 sequence of actions
  121.         temp_matrix = matrix
  122.         !
  123.         call min_stroka(temp_matrix,n,stroka_min)
  124.         !write (0,fmt = '(a$)') 'Massiv strok: '
  125.         do i = 1,n
  126.             temp_matrix(i,:) = temp_matrix(i,:) - stroka_min(i)
  127.         end do
  128.         call min_stolbec(temp_matrix,n,stolbec_min)
  129.         do i = 1,n
  130.             temp_matrix(:,i) = temp_matrix(:,i) - stolbec_min(i)
  131.         end do
  132.         !write (0,fmt = '(a$)') 'Massiv stolbcov: '
  133.         summa_1 = sum(stroka_min) + sum(stolbec_min)
  134.         ! 2 sequence of actions
  135.         temp_matrix = matrix
  136.         !
  137.         call min_stolbec(temp_matrix,n,stolbec_min)
  138.         do i = 1,n
  139.             temp_matrix(:,i) = temp_matrix(:,i) - stolbec_min(i)
  140.         end do
  141.         !write (0,fmt = '(a$)') 'Massiv stolbcov: '
  142.         call min_stroka(temp_matrix,n,stroka_min)
  143.         do i = 1,n
  144.             temp_matrix(i,:) = temp_matrix(i,:) - stroka_min(i)
  145.         end do
  146.         !write (0,fmt = '(a$)') 'Massiv strok: '
  147.         summa_2 = sum(stroka_min) + sum(stolbec_min)
  148.         !
  149.         write (0,fmt = '(a,i3)') 'Sum when stroki first then stolbcy:',summa_1
  150.         write (0,fmt = '(a,i3)') 'Sum when stolbcy first then stroki:',summa_2
  151.         if (summa_1>summa_2) then
  152.             summa = summa_1
  153.             !do i =1,n
  154.                 !temp_array = matrix(i,:)
  155.                 !stroka_min(i) = matrix(i, minimum(temp_array,n))
  156.             !end do
  157.             call min_stroka(matrix,n,stroka_min)
  158.             do i = 1,n
  159.                 matrix(i,:) = matrix(i,:) - stroka_min(i)
  160.             end do
  161.             call min_stolbec(matrix,n,stolbec_min)
  162.             do i = 1,n
  163.                 matrix(:,i) = matrix(:,i) - stolbec_min(i)
  164.             end do
  165.         else
  166.             summa = summa_2
  167.             call min_stolbec(matrix,n,stolbec_min)
  168.             do i = 1,n
  169.                 matrix(:,i) = matrix(:,i) - stolbec_min(i)
  170.             end do
  171.             call min_stroka(matrix,n,stroka_min)
  172.             do i = 1,n
  173.                 matrix(i,:) = matrix(i,:) - stroka_min(i)
  174.             end do
  175.         end if
  176.     end subroutine
  177.     !
  178.     integer function summ_of_minimums_in_zero(matrix,n,i,j)
  179.         integer :: i,j,n
  180.         integer :: matrix(n,n), stroka_min(n), stolbec_min(n)
  181.         integer :: copy(n,n)
  182.         copy = matrix
  183.         copy(i,j) = 100000
  184.         call min_stroka(copy,n,stroka_min)
  185.         call min_stolbec(copy,n,stolbec_min)
  186.         summ_of_minimums_in_zero = stroka_min(i) + stolbec_min(j)
  187.     end function
  188.     !
  189.     subroutine zero_choose(matrix,n,k,l)
  190.         integer :: i,j,n,k,l
  191.         integer :: matrix(n,n)
  192.         do i =1,n
  193.             do j =1,n
  194.                 if (matrix(i,j)==0) then
  195.                     k = i
  196.                     l = j
  197.                 end if
  198.             end do
  199.         end do
  200.         do i =1,n
  201.             do j =1,n
  202.                 if (matrix(i,j)==0) then
  203.                     if ( summ_of_minimums_in_zero(matrix,n,i,j) > summ_of_minimums_in_zero(matrix,n,k,l) )  then
  204.                         k = i
  205.                         l = j
  206.                     end if
  207.                 end if
  208.             end do
  209.         end do
  210.     end subroutine
  211.     !
  212.     subroutine matrix_rewrite(matrix_1,matrix_2,n,k,l)
  213.         integer :: n,k,l,i,j,x,y
  214.         integer :: matrix_1(n,n), matrix_2(n-1,n-1)
  215.         do i =1,n-1
  216.             do j = 1,n-1
  217.                 x = i
  218.                 y = j
  219.                 if (x >= k) then
  220.                     x = x + 1
  221.                 end if
  222.                 if (y >= l) then
  223.                     y = y + 1
  224.                 end if
  225.                 matrix_2(i,j) = matrix_1(x,y)
  226.             end do
  227.         end do
  228.     end subroutine
  229.     !
  230.     subroutine array_rewrite(array_1,array_2,n,m)
  231.         integer :: n,m,i,temp
  232.         integer :: array_1(n), array_2(n-1)
  233.         do i = 1,n-1
  234.             temp = i
  235.             if (temp >= m) then
  236.                 temp = temp + 1
  237.             end if
  238.             array_2(i) = array_1(temp)
  239.         end do
  240.     end subroutine
  241.     !
  242.     subroutine add_infinity(matrix,n)
  243.         integer :: n, i, j, x, y
  244.         integer :: matrix(n,n)
  245.         k = 0
  246.         l = 0
  247.         do i = 1, n
  248.             j = 1
  249.             do while ((j <= n) .and. (matrix(i, j)  <= 10000))
  250.                 if (j == n) then
  251.                     x = i
  252.                 end if
  253.                 j = j + 1
  254.             end do
  255.         end do
  256.         do j = 1, n
  257.             i = 1
  258.             do while ((i <= n) .and. (matrix(i, j)  <= 10000))
  259.                 if (i == n) then
  260.                     y = j
  261.                 end if
  262.                 i = i + 1
  263.             end do
  264.         end do
  265.         matrix(x,y) = 100000
  266.     end subroutine
  267. end module
  268. !
  269. !
  270. !
  271. !
  272. program main
  273.     use OiU3
  274.     implicit none
  275.     integer :: k, l, summa, n, j
  276.     integer, allocatable :: c(:,:), temp(:,:),roads(:,:),temp_2(:,:)
  277.     integer, allocatable :: stolbec_count(:), stroka_count(:), stolbec_count_temp(:), stroka_count_temp(:)
  278.     integer, parameter :: i = 10
  279.     !read (*,*) n
  280.     call execute_command_line('')
  281.     n = 7
  282.     summa = 0
  283.     allocate(c(n,n))
  284.     allocate(temp(n,n))
  285.     allocate(temp_2(n,n))
  286.     allocate(roads(2,n))
  287.     allocate(stolbec_count(n))
  288.     allocate(stroka_count(n))
  289.     allocate(stolbec_count_temp(n))
  290.     allocate(stroka_count_temp(n))
  291.     stolbec_count_temp = [(k, k =1,n)]
  292.     stroka_count_temp = [(k, k =1,n)]
  293.     stolbec_count = stolbec_count_temp
  294.     stroka_count = stroka_count_temp
  295.     do k = 1,n
  296.         do l = 1,n
  297.             if (k == l) then
  298.                 c(k,l) = 100000
  299.             else if ( mod( (i + 3*k + 5*l), 17) == 0 ) then
  300.                 c(k,l) = 17
  301.             else
  302.                 c(k,l) = mod( (i + 3*k + 5*l), 17)
  303.             end if
  304.         end do
  305.     end do
  306.     !stolbec_count = stolbec_count_temp
  307.     !stroka_count = stroka_count_temp
  308.     !stolbec_count(3) = 0
  309.     temp_2 = c
  310.     write (0,fmt='(a,i2)') 'Road 1 to 2: ',c(1,2)
  311.     write (0, fmt='(a$)') achar(27)//'[96m'//'First matrix:'//achar(27)//'[0m'
  312.     call write_matrix(c,stroka_count,stolbec_count,n,0,0)
  313.     write (0, fmt='(a)') achar(27)//'[96m'//'Enter the cycle: '//achar(27)//'[0m'
  314.     do j = n,3,-1
  315.         write (0, fmt='(/a/)') achar(27)//'[96m'//achar(ASCII_const + (n-j+1) )//achar(27)//'[0m'
  316.         deallocate(stolbec_count)
  317.         deallocate(stroka_count)
  318.         allocate(stolbec_count(j))
  319.         allocate(stroka_count(j))
  320.         stolbec_count = stolbec_count_temp
  321.         stroka_count = stroka_count_temp
  322.         deallocate(stolbec_count_temp)
  323.         deallocate(stroka_count_temp)
  324.         allocate(stolbec_count_temp(j-1))
  325.         allocate(stroka_count_temp(j-1))
  326.         !
  327.         deallocate(temp)
  328.         allocate(temp(j,j))
  329.         temp = temp_2
  330.         deallocate(temp_2)
  331.         allocate(temp_2(j-1,j-1))
  332.         !
  333.         call transform(temp, j, summa)
  334.         write (0, fmt='(/a)') achar(27)//'[96m'//'Write after transform:'//achar(27)//'[0m'
  335.         call write_matrix(temp, stroka_count, stolbec_count, j, 0, 0)
  336.         write (0,fmt = '(a,i3)') 'Then we choose better summa:', summa
  337.         call zero_choose(temp,j,k,l)
  338.         write (0,fmt = '(a,i1,/,a,i1,/,a,i10)') 'k:', stroka_count(k), 'l:', stolbec_count(l),&
  339.         'Summ in this zero:', summ_of_minimums_in_zero(temp,n,k,l)
  340.         call write_matrix(temp, stroka_count, stolbec_count, j, k, l)
  341.         !rewrite arrays and matrix, using k, l
  342.         write (0, fmt='(/a)') achar(27)//'[96m'//'Rewrite arrays and matrix, using k, l'//achar(27)//'[0m'
  343.         call matrix_rewrite(temp, temp_2, j, k, l)
  344.         call array_rewrite(stroka_count, stroka_count_temp, j, k)
  345.         call array_rewrite(stolbec_count, stolbec_count_temp, j, l)
  346.         call write_matrix(temp_2,stroka_count_temp,stolbec_count_temp, j-1,0,0)
  347.         !add infinity
  348.         !if ( (j-1) /= 2) then
  349.             write (0, fmt='(/a)') achar(27)//'[96m'//'Add infinity'//achar(27)//'[0m'
  350.             ! она добавляет бесконечность только один раз, а может быть случай, где их больше
  351.             call add_infinity(temp_2, j-1)
  352.             call write_matrix(temp_2,stroka_count_temp,stolbec_count_temp, j-1,0,0)
  353.         !end if
  354.     end do
  355.     !
  356.     !
  357.     deallocate(c)
  358.     deallocate(roads)
  359. end program main
  360.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement