Как мне написать это на Ruby / Python? Или вы можете перевести мой LINQ на Ruby / Python? - PullRequest
8 голосов
/ 23 сентября 2008

Вчера я задал этот вопрос и так и не получил ответа, которым был очень доволен. Я действительно хотел бы знать, как создать список из N уникальных случайных чисел, используя функциональный язык, такой как Ruby, без необходимости быть крайне обязательным в стиле.

Поскольку я не видел ничего, что мне действительно нравилось, я написал решение, которое искал в LINQ:


       static void Main(string[] args)
        {
            var temp = from q in GetRandomNumbers(100).Distinct().Take(5) select q;
        }

        private static IEnumerable GetRandomNumbers(int max)
        {
            Random r = new Random();
            while (true)
            {
                yield return r.Next(max);
            }
        }

Можете ли вы перевести мой LINQ на Ruby? Python? Любой другой функциональный язык программирования?

Примечание: Пожалуйста, старайтесь не использовать слишком много циклов и условных выражений - в противном случае решение будет тривиальным. Кроме того, я бы предпочел найти решение, в котором вам не нужно генерировать массив, намного больший, чем N, чтобы вы могли затем просто удалить дубликаты и обрезать его до N.

Я знаю, что я привередлив, но мне бы очень хотелось увидеть некоторые элегантные решения этой проблемы. Спасибо!

Edit:
Почему все отрицательные?

Первоначально мой пример кода имел функцию Distinct () после Take (), которая, как отмечали многие, могла оставить меня с пустым списком. Я изменил порядок, в котором эти методы вызываются, чтобы отразить то, что я имел в виду.

Апология:
Мне сказали, что этот пост показался мне довольно снобистским. Я не пытался сказать, что LINQ лучше Ruby / Python; или что мое решение намного лучше, чем у всех остальных. Я собираюсь научиться делать это (с некоторыми ограничениями) в Ruby. Извините, если я натолкнулся на этого.

Ответы [ 14 ]

0 голосов
/ 23 сентября 2008

Ну, во-первых, вы переписываете LINQ на Python. Тогда ваше решение однострочное:)

from random import randrange

def Distinct(items):
    set = {}
    for i in items:
        if not set.has_key(i):
            yield i
            set[i] = 1

def Take(num, items):
    for i in items:
        if num > 0:
            yield i
            num = num - 1
        else:
            break

def ToArray(items):
    return [i for i in items]

def GetRandomNumbers(max):
    while 1:
        yield randrange(max)

print ToArray(Take(5, Distinct(GetRandomNumbers(100))))

Если вы поместите все простые методы, описанные выше, в модуль LINQ.py, вы сможете произвести впечатление на своих друзей.

(Отказ от ответственности: конечно, это не на самом деле переписывание LINQ в Python. Люди ошибочно полагают, что LINQ - это просто набор простых методов расширения и некоторого нового синтаксиса. Действительно продвинутая часть LINQ, тем не менее, это автоматическая генерация SQL, так что когда вы запрашиваете базу данных, именно база данных реализует Distinct (), а не на стороне клиента.)

0 голосов
/ 23 сентября 2008
import random

def makeRand(n):
   rand = random.Random()
   while 1:
      yield rand.randint(0,n)
   yield rand.randint(0,n)      

gen = makeRand(100)      
terms = [ gen.next() for n in range(5) ]

print "raw list"
print terms
print "de-duped list"
print list(set(terms))

# produces output similar to this
#
# raw list
# [22, 11, 35, 55, 1]
# de-duped list
# [35, 11, 1, 22, 55]
0 голосов
/ 23 сентября 2008

Я действительно не могу прочитать ваш LINQ, но я думаю, что вы пытаетесь получить 5 случайных чисел до 100 и затем удалить дубликаты.

Вот решение для этого:

def random(max)
    (rand * max).to_i
end

# Get 5 random numbers between 0 and 100
a = (1..5).inject([]){|acc,i| acc << random( 100)}
# Remove Duplicates
a = a & a

Но, возможно, вы на самом деле ищете 5 различных случайных чисел от 0 до 100. В этом случае:

def random(max)
    (rand * max).to_i
end

a = []
while( a.size < 5)
    a << random( 100)
    a = a & a
end

Теперь, это может нарушить ваше чувство "не слишком много петель", но, вероятно, Take и Distinct просто скрывают петлю от вас. Было бы достаточно просто добавить методы в Enumerable, чтобы скрыть цикл while.

0 голосов
/ 23 сентября 2008

Python с числовым Python:

from numpy import *
a = random.random_integers(0, 100, 5)
b = unique(a)

Вуаля! Конечно, вы можете сделать что-то подобное в стиле функционального программирования, но ... почему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...