Вновь здравствуйте! Возник вопрос и вопрос нехитро формулирующийся - стоит задача сгенерировать четырёхзначное целое число, состоящее из цифр 1,2,3 и 4. При этом в числе должны присутствовать все эти цифры по одной. Скажем, числа 1234, 3241, 2134 - это то, что надо. А числа 1122, 3132, 4443 не годятся. Как это сделать без использования цикла серии repeat-until ("генерировать число заново до тех пор, пока не совпадёт условие")? Премного благодарен )
Не зли других и сам не злись. Мы - гости в этом мире. И если что не так - смирись, Будь поумнее - улыбнись, Ведь в мире всё закономерно. Зло, излучённое тобой, К тебе вернётся непременно.
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)
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
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
Bru, Говоря о комбинаторике, нетрудно посчитать, что 4! = 24 различных варианта. А вот 10! = 3628800. Быстро растёт функция. Это решение не для общего случая, а для частного. Допустимо, учитывая то, что спрашивал я о частном случае)
Кристофер, Это идентично написанному Николасом варианту, но на словах) Так-то говоря, в этих решениях то плохо, что они требуют массивов и дополнительной памяти. Может, как-то можно повертеть через mod (остаток от деления)?
Не зли других и сам не злись. Мы - гости в этом мире. И если что не так - смирись, Будь поумнее - улыбнись, Ведь в мире всё закономерно. Зло, излучённое тобой, К тебе вернётся непременно.
Есть такая интересная теория, которая может обойтись без особенной индусятины, но в ней, похоже, закралась ошибка.
Задача - сгенерировать числа 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
Но работает она неверно. Почему?
Не зли других и сам не злись. Мы - гости в этом мире. И если что не так - смирись, Будь поумнее - улыбнись, Ведь в мире всё закономерно. Зло, излучённое тобой, К тебе вернётся непременно.
Duosora, ты знаешь язык Pascal? Если да, то переведешь на него? Я мб тогда помочь смогу.
"История нашего народа знает немало светлых страниц. Темных было тоже достаточно. И все с белыми пятнами. От белых пятен истории нужно избавляться, но нельзя же всё мазать черной краской!"(с) Рохан.
Кристофер, Знаю, но Паскаль это Паскаль, а Джасс - это Джасс. В Паскале есть div и mod, там это не проблема.
Не зли других и сам не злись. Мы - гости в этом мире. И если что не так - смирись, Будь поумнее - улыбнись, Ведь в мире всё закономерно. Зло, излучённое тобой, К тебе вернётся непременно.
Зачем тебе вообще это надо? Если хочешь максимальное быстродействие, бери вариант Srezi (только массив сделай глобальным). Если хочешь сэкономить на памяти WarCraft III (хоть это и довольно глупая затея) - пообъединяй свои массивы. Уверен, у тебя это много где можно сделать.
Код
//=========================================================================== // Calculate the modulus/remainder of (dividend) divided by (divisor). // Examples: 18 mod 5 = 3. 15 mod 5 = 0. -8 mod 5 = 2. // function ModuloInteger takes integer dividend, integer divisor returns integer local integer modulus = dividend - (dividend / divisor) * divisor
// If the dividend was negative, the above modulus calculation will // be negative, but within (-divisor..0). We can add (divisor) to // shift this result into the desired range of (0..divisor). if (modulus < 0) then set modulus = modulus + divisor endif
return modulus endfunction
Добавлено (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.
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
Не зли других и сам не злись. Мы - гости в этом мире. И если что не так - смирись, Будь поумнее - улыбнись, Ведь в мире всё закономерно. Зло, излучённое тобой, К тебе вернётся непременно.