Advertisement
Oppaceted

OiU_3 first version

May 29th, 2023
879
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Fortran 12.24 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.         matrix(i,j) = 100000
  182.         call min_stroka(matrix,n,stroka_min)
  183.         call min_stolbec(matrix,n,stolbec_min)
  184.         summ_of_minimums_in_zero = stroka_min(i) + stolbec_min(j)
  185.         matrix(i,j) = 0
  186.     end function
  187.     !
  188.     subroutine zero_choose(matrix,n,k,l)
  189.         integer :: i,j,n,k,l
  190.         integer :: matrix(n,n)
  191.         do j =1,n
  192.             if (matrix(1,j)==0) then
  193.                 l = j
  194.             end if
  195.         end do
  196.         do i =1,n
  197.             do j =1,n
  198.                 if (matrix(i,j)==0) then
  199.                     if ( summ_of_minimums_in_zero(matrix,n,i,j) > summ_of_minimums_in_zero(matrix,n,k,l) )  then
  200.                         k = i
  201.                         l = j
  202.                     end if
  203.                 end if
  204.             end do
  205.         end do
  206.     end subroutine
  207.     !
  208.     subroutine matrix_rewrite(matrix_1,matrix_2,n,k,l)
  209.         integer :: n,k,l,i,j,x,y
  210.         integer :: matrix_1(n,n), matrix_2(n-1,n-1)
  211.         do i =1,n-1
  212.             do j = 1,n-1
  213.                 x = i
  214.                 y = j
  215.                 if (x >= k) then
  216.                     x = x + 1
  217.                 end if
  218.                 if (y >= l) then
  219.                     y = y + 1
  220.                 end if
  221.                 matrix_2(i,j) = matrix_1(x,y)
  222.             end do
  223.         end do
  224.     end subroutine
  225.     !
  226.     subroutine array_rewrite(array_1,array_2,n,m)
  227.         integer :: n,m,i,temp
  228.         integer :: array_1(n), array_2(n-1)
  229.         do i = 1,n-1
  230.             temp = i
  231.             if (temp >= m) then
  232.                 temp = temp + 1
  233.             end if
  234.             array_2(i) = array_1(temp)
  235.         end do
  236.     end subroutine
  237.     !
  238.     subroutine add_infinity(matrix,n)
  239.         integer :: n, i, j, x, y
  240.         integer :: matrix(n,n)
  241.         k = 0
  242.         l = 0
  243.         do i = 1, n
  244.             j = 1
  245.             do while ((j <= n) .and. (matrix(i, j)  <= 10000))
  246.                 if (j == n) then
  247.                     x = i
  248.                 end if
  249.                 j = j + 1
  250.             end do
  251.         end do
  252.         do j = 1, n
  253.             i = 1
  254.             do while ((i <= n) .and. (matrix(i, j)  <= 10000))
  255.                 if (i == n) then
  256.                     y = j
  257.                 end if
  258.                 i = i + 1
  259.             end do
  260.         end do
  261.         matrix(x,y) = 100000
  262.     end subroutine
  263. end module
  264.  
  265. !
  266. !
  267. !
  268. program main
  269.     use OiU3
  270.     implicit none
  271.     integer :: k, l, summa, n, j
  272.     integer, allocatable :: c(:,:), temp(:,:),roads(:,:),temp_2(:,:)
  273.     integer, allocatable :: stolbec_count(:), stroka_count(:), stolbec_count_temp(:), stroka_count_temp(:)
  274.     integer, parameter :: i = 10
  275.     !read (*,*) n
  276.     call execute_command_line('')
  277.     n = 7
  278.     summa = 0
  279.     allocate(c(n,n))
  280.     allocate(temp(n,n))
  281.     allocate(temp_2(n,n))
  282.     allocate(roads(2,n))
  283.     allocate(stolbec_count(n))
  284.     allocate(stroka_count(n))
  285.     allocate(stolbec_count_temp(n))
  286.     allocate(stroka_count_temp(n))
  287.     stolbec_count_temp = [(k, k =1,n)]
  288.     stroka_count_temp = [(k, k =1,n)]
  289.     stolbec_count = stolbec_count_temp
  290.     stroka_count = stroka_count_temp
  291.     do k = 1,n
  292.         do l = 1,n
  293.             if (k == l) then
  294.                 c(k,l) = 100000
  295.             else if ( mod( (i + 3*k + 5*l), 17) == 0 ) then
  296.                 c(k,l) = 17
  297.             else
  298.                 c(k,l) = mod( (i + 3*k + 5*l), 17)
  299.             end if
  300.         end do
  301.     end do
  302.     !stolbec_count = stolbec_count_temp
  303.     !stroka_count = stroka_count_temp
  304.     !stolbec_count(3) = 0
  305.     temp_2 = c
  306.     write (0,fmt='(a,i2)') 'Road 1 to 2: ',c(1,2)
  307.     write (0, fmt='(a$)') achar(27)//'[96m'//'First matrix:'//achar(27)//'[0m'
  308.     call write_matrix(c,stroka_count,stolbec_count,n,0,0)
  309.     write (0, fmt='(a)') achar(27)//'[96m'//'Enter the cycle: '//achar(27)//'[0m'
  310.     do j = n,3,-1
  311.         write (0, fmt='(/a/)') achar(27)//'[96m'//achar(ASCII_const + (n-j+1) )//achar(27)//'[0m'
  312.         deallocate(stolbec_count)
  313.         deallocate(stroka_count)
  314.         allocate(stolbec_count(j))
  315.         allocate(stroka_count(j))
  316.         stolbec_count = stolbec_count_temp
  317.         stroka_count = stroka_count_temp
  318.         deallocate(stolbec_count_temp)
  319.         deallocate(stroka_count_temp)
  320.         allocate(stolbec_count_temp(j-1))
  321.         allocate(stroka_count_temp(j-1))
  322.         !
  323.         deallocate(temp)
  324.         allocate(temp(j,j))
  325.         temp = temp_2
  326.         deallocate(temp_2)
  327.         allocate(temp_2(j-1,j-1))
  328.         !
  329.         call transform(temp, j, summa)
  330.         write (0, fmt='(/a)') achar(27)//'[96m'//'Write after transform:'//achar(27)//'[0m'
  331.         call write_matrix(temp, stroka_count, stolbec_count, j, 0, 0)
  332.         write (0,fmt = '(a,i3)') 'Then we choose better summa:', summa
  333.         call zero_choose(temp,j,k,l)
  334.         write (0,fmt = '(a,i1,/,a,i1,/,a,i10)') 'k:', stroka_count(k), 'l:', stolbec_count(l),&
  335.         'Summ in this zero:', summ_of_minimums_in_zero(temp,n,k,l)
  336.         call write_matrix(temp, stroka_count, stolbec_count, j, k, l)
  337.         !rewrite arrays and matrix, using k, l
  338.         write (0, fmt='(/a)') achar(27)//'[96m'//'Rewrite arrays and matrix, using k, l'//achar(27)//'[0m'
  339.         call matrix_rewrite(temp, temp_2, j, k, l)
  340.         call array_rewrite(stroka_count, stroka_count_temp, j, k)
  341.         call array_rewrite(stolbec_count, stolbec_count_temp, j, l)
  342.         call write_matrix(temp_2,stroka_count_temp,stolbec_count_temp, j-1,0,0)
  343.         !add infinity
  344.         if ( (j-1) /= 2) then
  345.             write (0, fmt='(/a)') achar(27)//'[96m'//'Add infinity'//achar(27)//'[0m'
  346.             ! она добавляет бесконечность только один раз, а может быть случай, где их больше
  347.             call add_infinity(temp_2, j-1)
  348.             call write_matrix(temp_2,stroka_count_temp,stolbec_count_temp, j-1,0,0)
  349.         end if
  350.     end do
  351.     !
  352.     !
  353.     deallocate(c)
  354.     deallocate(roads)
  355. end program main
  356.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement