Сейчас 13:43:59 Пятница, 29 марта, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » Вопросы по картостроению » Генерация случайного четырёхзначного числа (да, опять без циклов)
Генерация случайного четырёхзначного числа
DuosoraДата: Пятница, 13 Марта 2015, 00:31:58 | Сообщение # 1
The cats never sleep...
Группа: Ветераны
Сообщений: 6734
Награды: 10
Репутация: 2161
Блокировки:
Вновь здравствуйте!
Возник вопрос и вопрос нехитро формулирующийся - стоит задача сгенерировать четырёхзначное целое число, состоящее из цифр 1,2,3 и 4. При этом в числе должны присутствовать все эти цифры по одной. Скажем, числа 1234, 3241, 2134 - это то, что надо. А числа 1122, 3132, 4443 не годятся.
Как это сделать без использования цикла серии repeat-until ("генерировать число заново до тех пор, пока не совпадёт условие")?
Премного благодарен )


Не зли других и сам не злись.
Мы - гости в этом мире.
И если что не так - смирись,
Будь поумнее - улыбнись,
Ведь в мире всё закономерно.
Зло, излучённое тобой,
К тебе вернётся непременно.
 

SirNikolasДата: Пятница, 13 Марта 2015, 01:02:50 | Сообщение # 2
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
alphabet = { 1, 2, 3, 4 }; n = 4; result = 0
do {
n--; x = GetRandomInt(0, n); result = result * 10 + alphabet[x]; alphabet[x] = alphabet[n]
} while (n)


 

ExtrematorДата: Пятница, 13 Марта 2015, 09:45:27 | Сообщение # 3
10 уровень
Группа: Проверенные
Сообщений: 3199
Награды: 0
Репутация: 1018
Блокировки:
Код
function TEST_0001 takes nothing returns nothing
     local integer i; local integer l; local string S;
     local integer M = 4; local integer array I;
     set l = 0; loop
         set l = l + 1; set I[l] = l; exitwhen l == M;
     endloop
     set l = 0; loop
         set l = l + 1; set i = GetRandomInt(1,M); set S = S + I2S(i);
         set I[i] = I[M]; set M = M - 1; exitwhen l >= 4 or M <= 0;
     endloop
     // =====
     call BJDebugMsg(S);
endfunction


я канеш давно не практиковал ._. можт чо напутал


Сообщение отредактировал Extremator - Пятница, 13 Марта 2015, 09:47:04
 

BruДата: Пятница, 13 Марта 2015, 13:46:10 | Сообщение # 4
i<3bo4k@
Группа: Акулы
Сообщений: 4750
Награды: 2
Репутация: 1950
Блокировки:
Цитата SirNikolas ()
while (n)

Цитата Duosora ()
без использования цикла серии repeat-until

Разве это не тождественные по своей сути понятия?
 

SreziДата: Пятница, 13 Марта 2015, 14:00:55 | Сообщение # 5
7 уровень
Группа: Проверенные
Сообщений: 414
Награды: 0
Репутация: 116
Блокировки:
function 1 takes nothing returns integer
local integer array ms

set ms[1]=1234
set ms[2]=4321
set ms[3]=2134
set ms[n]=......

return ms[GetRandomInt(1,n)]
endfunction


Нет места чести на войне,
Враг церемониться не будет,
Убей его любым путём,
Ведь победителей не судят.
 

BruДата: Пятница, 13 Марта 2015, 14:06:23 | Сообщение # 6
i<3bo4k@
Группа: Акулы
Сообщений: 4750
Награды: 2
Репутация: 1950
Блокировки:
Цитата Srezi ()
function 1 takes nothing returns integer
local integer array ms

set ms[1]=1234
set ms[2]=4321
set ms[3]=2134
set ms[n]=......

return ms[GetRandomInt(1,n)]
endfunction

Как-то это совсем некрасиво.
А что если это будет 10значное число?
 

SreziДата: Пятница, 13 Марта 2015, 14:09:12 | Сообщение # 7
7 уровень
Группа: Проверенные
Сообщений: 414
Награды: 0
Репутация: 116
Блокировки:
Цитата Bru ()
Как-то это совсем некрасиво.
А что если это будет 10значное число?


Это первое, что пришло в голову без "цикла" и ему нужно было 4-значное.


Нет места чести на войне,
Враг церемониться не будет,
Убей его любым путём,
Ведь победителей не судят.
 

КристоферДата: Пятница, 13 Марта 2015, 14:33:35 | Сообщение # 8
7 уровень
Группа: Проверенные
Сообщений: 401
Награды: 0
Репутация: 338
Блокировки:
Duosora, предлагаю такой вариант:
e=1;
f=2;
g=3;
h=4;
Пока "abcd" является буквенным выражением:
От i="а" до "d":
Если i не равно 0, то:
Присвоить i рандомное значение от e до f;
Присвоенное значение приравнять к 0;
Конец If-а;
Конец цикла;
Конец цикла;
Вывести на экран abcd;
Конец программы.

P.S. Джассом не владею, написал словами. Могу составить программу на Паскале, если так будет легче понять.)


"История нашего народа знает немало светлых страниц. Темных было тоже достаточно. И все с белыми пятнами. От белых пятен истории нужно избавляться, но нельзя же всё мазать черной краской!"(с) Рохан.


Сообщение отредактировал Кристофер - Пятница, 13 Марта 2015, 14:34:10
 

DuosoraДата: Пятница, 13 Марта 2015, 14:54:24 | Сообщение # 9
The cats never sleep...
Группа: Ветераны
Сообщений: 6734
Награды: 10
Репутация: 2161
Блокировки:
Bru,
Говоря о комбинаторике, нетрудно посчитать, что 4! = 24 различных варианта.
А вот 10! = 3628800. Быстро растёт функция.
Это решение не для общего случая, а для частного. Допустимо, учитывая то, что спрашивал я о частном случае)

Кристофер,
Это идентично написанному Николасом варианту, но на словах)
Так-то говоря, в этих решениях то плохо, что они требуют массивов и дополнительной памяти. Может, как-то можно повертеть через mod (остаток от деления)?


Не зли других и сам не злись.
Мы - гости в этом мире.
И если что не так - смирись,
Будь поумнее - улыбнись,
Ведь в мире всё закономерно.
Зло, излучённое тобой,
К тебе вернётся непременно.
 

BruДата: Пятница, 13 Марта 2015, 15:25:41 | Сообщение # 10
i<3bo4k@
Группа: Акулы
Сообщений: 4750
Награды: 2
Репутация: 1950
Блокировки:
Цитата Duosora ()
Это решение не для общего случая, а для частного. Допустимо, учитывая то, что спрашивал я о частном случае)

Такой я человек, вообще не люблю решений для частных случаев.
 

SirNikolasДата: Пятница, 13 Марта 2015, 18:38:55 | Сообщение # 11
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Если без циклов и без массивов, получается индусский код. Два варианта, один хуже другого:
Код
int GetRandom4Permutation() {
     int n = GetRandomInt(0, 23);
     int sorted0, sorted1, sorted2;

     int digit0 = n / 6;
     n -= digit0 * 6;

     int digit1 = n / 2;
     if digit1 >= digit0 {
         digit1++;
         sorted0 = digit0;
         sorted1 = digit1;
     } else {
         sorted0 = digit1;
         sorted1 = digit0;
     }

     int digit2 = n - (digit1 + digit1);
     if digit2 >= sorted0 {
         digit2++;
         if digit2 >= sorted1 {
             digit2++;
             sorted2 = digit2;
         } else {
             sorted2 = sorted1;
             sorted1 = digit2;
         }
     } else {
         sorted2 = sorted1;
         sorted1 = sorted0;
         sorted0 = digit2;
     }

     int digit3 = 0;
     if digit3 >= sorted0 {
         digit3++;
         if digit3 >= sorted1 {
             digit3++;
             if digit3 >= sorted2 {
                 digit3++;
             }
         }
     }

     return digit0 * 1000 + digit1 * 100 + digit2 * 10 + digit3 + 1111;
}
Код
int GetRandom4Permutation() {
     int n = GetRandomInt(0, 23);
     if n < 12 {
         if n < 6 {
             if n < 3 {
                 if n == 0 {
                     return 1234;
                 } elseif n == 1 {
                     return 1243;
                 }
                 return 1324;
             } elseif n == 3 {
                 return 1342;
             } elseif n == 4 {
                 return 1423;
             }
             return 1432;
         } elseif n < 9 {
             if n == 6 {
                 return 2134;
             } elseif n == 7 {
                 return 2143;
             }
             return 2314;
         } elseif n == 9 {
             return 2341;
         } elseif n == 10 {
             return 2413;
         }
         return 2431;
     } elseif n < 18 {
         if n < 15 {
             if n == 12 {
                 return 3124;
             } elseif n == 13 {
                 return 3142;
             }
             return 3214;
         } elseif n == 15 {
             return 3241;
         } elseif n == 16 {
             return 3412;
         }
         return 3421;
     } elseif n < 21 {
         if n == 18 {
             return 4123;
         } elseif n == 19 {
             return 4132;
         }
         return 4213;
     } elseif n == 21 {
         return 4231;
     } elseif n == 22 {
         return 4312;
     }
     return 4321;
}


 

DuosoraДата: Пятница, 13 Марта 2015, 19:47:11 | Сообщение # 12
The cats never sleep...
Группа: Ветераны
Сообщений: 6734
Награды: 10
Репутация: 2161
Блокировки:
Есть такая интересная теория, которая может обойтись без особенной индусятины, но в ней, похоже, закралась ошибка.

Задача - сгенерировать числа 1,2,3 и 4 в случайном порядке.

Для этого была использована вспомогательная функция получения остатка от деления Mod (аналог a%b в C++):
Код
function Mod takes real a, real b returns integer
     return R2I((a/b-R2I(a/b))*b)
endfunction

function GetRandomPattern takes nothing returns integer
                     local integer x = GetRandomInt(1,3)
                     local integer a = GetRandomInt(1,4)
                     local integer b = Mod(a+x,4)
                     local integer c = Mod(a+Mod(x+GetRandomInt(1,2),3),4)
                     local integer d = 10-a-b-c

                     return d*1000+c*100+b*10+a
endfunction


Но работает она неверно. Почему?


Не зли других и сам не злись.
Мы - гости в этом мире.
И если что не так - смирись,
Будь поумнее - улыбнись,
Ведь в мире всё закономерно.
Зло, излучённое тобой,
К тебе вернётся непременно.
 

КристоферДата: Пятница, 13 Марта 2015, 19:58:20 | Сообщение # 13
7 уровень
Группа: Проверенные
Сообщений: 401
Награды: 0
Репутация: 338
Блокировки:
Duosora, ты знаешь язык Pascal? Если да, то переведешь на него? Я мб тогда помочь смогу.

"История нашего народа знает немало светлых страниц. Темных было тоже достаточно. И все с белыми пятнами. От белых пятен истории нужно избавляться, но нельзя же всё мазать черной краской!"(с) Рохан.
 

DuosoraДата: Пятница, 13 Марта 2015, 20:02:34 | Сообщение # 14
The cats never sleep...
Группа: Ветераны
Сообщений: 6734
Награды: 10
Репутация: 2161
Блокировки:
Кристофер,
Знаю, но Паскаль это Паскаль, а Джасс - это Джасс. В Паскале есть div и mod, там это не проблема.


Не зли других и сам не злись.
Мы - гости в этом мире.
И если что не так - смирись,
Будь поумнее - улыбнись,
Ведь в мире всё закономерно.
Зло, излучённое тобой,
К тебе вернётся непременно.
 

SirNikolasДата: Пятница, 13 Марта 2015, 20:18:32 | Сообщение # 15
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Я не понимаю, почему она должна работать.

Зачем тебе вообще это надо? Если хочешь максимальное быстродействие, бери вариант Srezi (только массив сделай глобальным). Если хочешь сэкономить на памяти WarCraft III (хоть это и довольно глупая затея) - пообъединяй свои массивы. Уверен, у тебя это много где можно сделать.

Добавлено (13 Марта 2015, 20:18:32)
---------------------------------------------

Код
var
     x, a, b, c, d: integer;

begin
     Randomize;
     x := Random(3) + 1;
     a := Random(4) + 1;
     b := (a + x) mod 4;
     c := (a + (x + Random(2) + 1) mod 3) mod 4;
     d := 10 - a - b - c;
     Write(a, b, c, d);
end.


 

DuosoraДата: Пятница, 13 Марта 2015, 22:46:27 | Сообщение # 16
The cats never sleep...
Группа: Ветераны
Сообщений: 6734
Награды: 10
Репутация: 2161
Блокировки:
SirNikolas,
Просьба тему пока не закрывать, так как, возможно, скоро пришлю работающий вариант моей функции.

Добавлено (13 Марта 2015, 22:46:27)
---------------------------------------------
upd.
Вуу! Рабочая начинка моей функции.)

Код
                    local integer x = GetRandomInt(0,2)
                     local integer a = GetRandomInt(0,3)
                     local integer b = Mod(a+x+1,4)
                     local integer c = Mod(a+Mod(x+GetRandomInt(0,1)+1,3)+1,4)
                     local integer d = 6-a-b-c
                      
                     set a = a + 1
                     set b = b + 1
                     set c = c + 1
                     set d = d + 1

                     return d*1000+c*100+b*10+a


Не зли других и сам не злись.
Мы - гости в этом мире.
И если что не так - смирись,
Будь поумнее - улыбнись,
Ведь в мире всё закономерно.
Зло, излучённое тобой,
К тебе вернётся непременно.
 

Форум о Warcraft 3 » Раздел для картостроителей » Вопросы по картостроению » Генерация случайного четырёхзначного числа (да, опять без циклов)
  • Страница 1 из 1
  • 1
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz