Модераторы: Alx, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VB/VBA] Получить "всегда True" 
:(
    Опции темы
Akina
Дата 19.3.2009, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



Постановка задачи:

Необходимо дописать программу так, чтобы она при запуске ВСЕГДА давала сообщение "True".
Программа должна состоять из двух модулей и запускаться процедурой Main().
Текст первого модуля дан, и его изменять нельзя.
Необходимо написать текст второго модуля.

В чём суть программы:

В программе создаётся массив элементов логического типа случайного (от 100 до 1000) размера. Он заполняется случайным образом. Затем процедуре (которую следует написать) сообщается количество элементов (нижняя и верхняя границы) и количество элементов True в массиве. Процедура может инвертировать любые элементы массива, но не может узнать значения элементов массива либо иные не переданные ей явно значения. В результате своей работы она должна вернуть место, где следует поделить массив (некоторые или все элементы которого ею инвертированы) на две части. В получившихся частях должно быть равно либо количество значений True (справа и слева одинаковое), либо количество значений False. В этом случае программа выводит сообщение "True". Если равенства нет, или сообщённая точка деления массива на части находится за границами массива, программа выводит "False".

Вот текст Module1.BAS
Код

' опции
Option Explicit ' переменные должны быть явно объявлены
Option Base 1   ' нижняя граница массива всегда равна 1
'=============================
' объявление общих переменных
' все переменные приватные, извне недоступны
Private Arr() As Boolean
Private i As Integer
Private Bound As Integer
'=============================
' главная процедура
' она приватная, извне недоступна
Private Sub Main()
' инициализируется генератор случайных чисел
Randomize Timer
' задаётся случайный размер массива - от 100 до 1000 элементов
ReDim Arr(100 + 900 * Rnd)
' массив заполняется случайными значениями
For i = LBound(Arr) To UBound(Arr)
    If Rnd < 0.5 Then
        Arr(i) = True
    Else
        Arr(i) = False
    End If
Next
' вызывается внешняя функция
' ей передаётся размер массива (min и max значения индекса)
' и количество элементов True в массиве
' функция возвращает место, где поделить массив на 2 части
Bound = GetBound(LBound(Arr), UBound(Arr), Check(LBound(Arr), UBound(Arr), True))
' если возвращена правильная точка деления массива на части, то
If CheckBounds(Bound) Then
' то проверить равенство в частях количества значений True либо значений False
    If (Check(LBound(Arr), Bound, True) - Check(Bound + 1, UBound(Arr), True)) * (Check(LBound(Arr), Bound, False) - Check(Bound + 1, UBound(Arr), False)) = 0 Then
' если хотя бы одно из значений встречается в обеих частях в одинаковом количестве
' сообщить об удаче
        MsgBox "True"
    Else
' иначе о неудаче
        MsgBox "False"
    End If
Else
' или сообщить, что вычисленная точка деления массива на части неверна
    MsgBox "False"
End If
' и закончить работу
End Sub
'=============================
' функция подсчитывает количество логических значений CheckValue
' среди элементов массива Arr от LowBound до HighBound
' она приватная, извне недоступна
Private Function Check(LowBound As Integer, HighBound As Integer, CheckValue As Boolean) As Integer
Check = 0
For i = LowBound To HighBound
    If Not (Arr(i) Xor CheckValue) Then
        Check = Check + 1
    End If
Next
End Function
'=============================
' функция проверяет, что Index не выходит за границы массива
' она приватная, извне недоступна
Private Function CheckBounds(Index As Integer) As Boolean
CheckBounds = ((Index - LBound(Arr)) * (UBound(Arr) - Index) > 0)
End Function
'=============================
' процедура инвертирует элемент массива с номером Index
' процедура доступна для вызова извне
Public Sub Invert(Index As Integer)
Arr(Index) = Not Arr(Index)
End Sub

Вот заготовка текста второго модуля Module2.BAS
Код

Public Function GetBound(Low As Integer, High As Integer, Count As Integer) As Integer
' в функцию передаётся нижняя (Low) и верхняя (High) границы массива
' и количество в нём элементов True (Count)

' Можно определить любое число необходимых для работы переменных
' Dim i As Integer

' Можно в процессе работы вызывать неограниченное число раз
' функцию Invert из первого модуля
'Call Invert(n)

' в конце работы следует передать обратно вычисленное значение
'GetBound = 1
End Function

' При необходимости можно создать необходимое число процедур, функций и переменных


Задача ориентирована на решение в среде VB6, но может быть решена и на VBA в любом Офисном приложении.

PS. Кратчайшее известное мне решение содержит 5 строк кода.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxdiver
Дата 21.3.2009, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 2
Всего: 18



1) зачем вообще VB? решение вообще от языка не зависит. для разнообразия что ле? smile
2) код местами довольно забавный: Not (Arr(i) Xor CheckValue) - а почему не просто = ?  smile
3) здесь, я так понимаю, варианты решения публиковать не надо, т.к. это разрушит интригу для других решателей?
PM MAIL WWW ICQ   Вверх
Akina
Дата 21.3.2009, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



1) В каком виде оно ко мне попало, в таком и выложил. Только дополнил несколько комментов.
2) См. п. 1.
3) Не знаю... кто-то же должен когда-нить запостить решение... 

PS. Решение в 5 строк кода я всё-таки нашёл... сам... не смотря в подсказку. 


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxdiver
Дата 27.3.2009, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 2
Всего: 18



Я не понял, заакцептил Akina моё решение или нет, но вроде есть в 4 строчки smile
PM MAIL WWW ICQ   Вверх
Akina
Дата 27.3.2009, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



Да, частично. Потому что у тебя в ответе использована не определённая переменная. Её определение даст пятую строку.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxdiver
Дата 27.3.2009, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 2
Всего: 18



Akina
Хм, а в VB обязательно объявлять переменные? В том Бейсике, который я изучал в дремучем детстве, переменные сами создавались при первом использовании smile
PM MAIL WWW ICQ   Вверх
Akina
Дата 27.3.2009, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



См. строку 2 первого модуля.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
LOD77
Дата 2.5.2009, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 2.5.2009

Репутация: нет
Всего: 1



Может быть я чего-то не понял, но это же классическая задача про фишки "реверси" на столе.
В таком случае получается 4 строки:

FOR i=Low TO Low+Count-1
    Call Invert(i)
NEXT i
GetBound = Low+Count-1

Вроде бы все. Массив делим на 2 части от эл-та Low до Low+Count-1 включительно и оставшаяся часть
от Low+Count до High

Или я чего-то недопонял?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Интересные и занимательные задачи по программированию | Следующая тема »


 




[ Время генерации скрипта: 0.1232 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.