2014-10-10 2 views
0

Я смог пересчитать до 97 бутылок пива, но у меня возникли проблемы с циклом отсчета до 1. Можно ли создать цикл с тем, что я написал? Вот что я до сих пор.Неисправность петли с 99 бутылками пива

all_beers = (99).to_s 
one_less = ((all_beers).to_i - 1).to_s 
puts '' + 
    all_beers + ' bottles of beer on the wall, ' + 
    all_beers + ' bottles of beer. You take one down you pass it around ' + 
    one_less + ', beers on the wall!' 

all_beers = one_less 
one_less = ((all_beers).to_i - 1).to_s 
puts '' + 
    all_beers + ' bottles of beer on the wall, ' + 
    all_beers + ' bottles of beer. You take one down you pass it around ' + 
    one_less + ', beers on the wall!' 

ответ

1

использование downto:

это будет цикл из числа вы хотите ДО номер, который вы хотите.

99.downto(1).each do |s| 
    all_beers = s 
    one_less = s - 1 
    puts '' + 
     all_beers.to_s + ' bottles of beer on the wall, ' + 
     all_beers.to_s + ' bottles of beer. You take one down you pass it around ' + 
     one_less.to_s + ', beers on the wall!' 
end 
0

Да, это конечно возможно. Это взято из 99 Bottles of Beer project:

# 
# Rubeer.rb 
# by Eric Budd, Jan. 2008 
# 
# Demonstrates adding functionality to a built-in class, optional method parameters, inline 
# conditionals, string replacement, alcohol aversion, and excessively fancy use of hashes. 
# 
# This borrows the hash from Daniel Straight's excellent implementation for the "wordalize" method 
# 

class Integer 
    NUMBER_WORDS = { 0 => "no", 1 => "one", 2 => "two", 3 => "three", 4 => "four", 5 => "five", 
        6 => "six", 7 => "seven", 8 => "eight", 9 => "nine", 

        10 => "ten", 11 => "eleven", 12 => "twelve", 13 => "thirteen", 
        14 => "fourteen", 15 => "fifteen", 16 => "sixteen", 17 => "seventeen", 
        18 => "eighteen", 19 => "nineteen", 

        20 => "twenty", 30 => "thirty", 40 => "forty", 50 => "fifty", 60 => "sixty", 
        70 => "seventy", 80 => "eighty", 90 => "ninety"} 

    def wordalize 
    raise "Invalid number to wordalize - should be in the range (0..99)" unless (0..99) === self 
    return NUMBER_WORDS[self] if self < 20 
    wordalized = NUMBER_WORDS[self - (self % 10)] 
    wordalized += '-' + NUMBER_WORDS[self % 10] unless (self % 10) == 0 
    return wordalized 
    end 

    def bottles 
    raise "Invalid number of bottles - should be in the range (0..99)" unless (0..99) === self 
    how_many_bottles = self.wordalize + ' bottle' 
    how_many_bottles += 's' unless self == 1 
    return how_many_bottles 
    end 

    alias :bottle :bottles # for grammar Nazis 
end 

def sing(number, teetotaller = false) 
    beverage = teetotaller ? 'coke' : 'beer' 

    puts "#{number.bottles.capitalize} of #{beverage} on the wall, #{number.bottles} of #{beverage}." 
    if number != 0 
    puts "Take one down, pass it around, #{(number - 1).bottles} of #{beverage} on the wall.\n\n" 
    else 
    puts "Go to the store and buy some more, 99 bottles of #{beverage} on the wall." 
    end 
end 

99.downto(0) { |number| sing(number) } 
# Uncomment the following for the alternative teetotaller version 
# 99.downto(0) { |number| sing(number, true) } 

Есть несколько версий Рубина загружено, но один по умолчанию является слишком сложной для начинающих. Это, однако, очень приятно, и вы должны понимать, что происходит.

Точка, которая должна отвечать на ваш вопрос, это бит с 99.downto(0) { |number| ... }. Это петля, которая будет повторять что-либо в фигурных скобках (в данном случае, sing(number)) сто раз, с number, идущим от 99 до 0.

Также обратите внимание, что он неэффективен (и неразборчив) для переноса числа в виде строки ((99).to_s) и конвертирует его обратно в целое, когда вам это нужно; скорее, он всегда будет целым числом и преобразует его в строку непосредственно перед тем, как вам понадобится его в виде строки, когда вы показываете (или конкатенация/интерполяция строк делают это автоматически, как в этом фрагменте кода).

Хотя Рубин имеет как for и while петли, они редко (while) или никогда (for) используется. Вместо этого рубисты обычно полагаются на итераторы и счетчики. Другие функции, такие как Integer#downto, - Integer#upto, Integer#times и почти все в самом удивительном Enumerable mixin.

0

Короткий ответ: да, вы можете сделать цикл, используя то, что вы написали, и есть много способов петли с рубином. Однако, поскольку это, по-видимому, связано с обучением программированию, учитывая, что вы не использовали никаких структур управления или интерполяции строк, не говоря уже о кастинге, который не имеет большого смысла, я бы рекомендовал Why's Poignant Guide to Ruby изучить концепции программирования при использовании рубина ,

Как Downto, вы могли бы сделать что-то вроде:

(1..99).reverse_each do |number| 
    bottle = number == 1 ? 'bottle' : 'bottles' 
    verse = "#{number} #{bottle} of beer on the wall, #{number} #{bottle} of beer. " 
    verse << "Take one down, pass it around, #{number-1} #{number-1 == 1 ? 'bottle' : 'bottles'} of beer on the wall" 
    puts verse 
end 
0

вещей вы можете использовать, чтобы сделать вашу жизнь проще: downto(), proc, тройная, если (--that - вещь ->:)

Мне очень понравилось это упражнение в первый раз, поэтому я немного нерешительно отношусь к предоставлению ответа здесь, но так оно и есть.

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

'downto()' также является прекрасным способом повторения этих 99 бутылок, так как это заставляет чувствовать, что вы читаете английский вместо кода.

num_at_start = 99 # You may change this number. 

num_bottles = proc { |n| "#{n} bottle#{ n == 1 ? '' : 's'}" } 

num_at_start.downto(1) do |num| 
    print "#{num_bottles.call(num)} of beer on the wall, " + 
     "#{num_bottles.call(num)} of beer!\n" + 
     "You take one down, pass it around, " 
    unless num == 1 
    puts "#{num_bottles.call(num - 1)} of beer on the wall!" 
    else 
    puts "No more bottles of beer on the wall!" 
    end 
end 

Источник: Учись программировать 2-е издание Крис Пайн (я изменил пару вещей, хотя)

+0

Вы имеете в виду, как используя printf? [printf] (http://ruby-doc.org/core-2.2.3/Kernel.html#method-i-printf) Вы можете форматировать printf с помощью этих символов типа поля: [спринт] (http: // ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf) –

0

Это исправление, я нашел на этот вопрос:

beer = 99 
    while beer > 0 

    puts beer.to_s + " bottles of beer on the wall. " + beer.to_s + 
    " bottles of beer." 

    (beer -= 1).to_s 

    puts "Take one down, pass it around. " + beer.to_s + 
    " bottles of beer on the wall." 
end 
Смежные вопросы