[QUIZ] Count and Say (#138)

R

Ruby Quiz

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion. Please reply to the original quiz message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

by Martin DeMello

Conway's "Look and Say" sequence
(http://en.wikipedia.org/wiki/Look-and-say_sequence) is a sequence of numbers in
which each term "reads aloud" the digits of the previous term. For instance, the
canonical L&S sequence starts off 1, 11, 21, 1211, 111221, ..., because:

* 1 is read off as "one 1" or 11.
* 11 is read off as "two 1's" or 21.
* 21 is read off as "one 2, then one 1" or 1211.
* 1211 is read off as "one 1, then one 2, then two 1's" or 111221.
* 111221 is read off as "three 1, then two 2, then one 1" or 312211.

Over on rec.puzzles, Eric A. proposed a variant in which the letters of a
sentence are grouped, then "counted aloud", omitting the "s"s for the plural
form. Thus, seeding the sequence with "LOOK AND SAY", we get:

0. LOOK AND SAY
1. TWO A ONE D ONE K ONE L ONE N TWO O ONE S ONE Y
2. ONE A ONE D SIX E ONE K ONE L SEVEN N NINE O ONE S TWO T TWO W ONE Y
3. ONE A ONE D TEN E TWO I ONE K ONE L TEN N NINE O THREE S THREE T ONE V
THREE W ONE X ONE Y

and so on. (Note the difference between this and the L&S sequence--the letters
are counted rather than read in order). Eric wants to know when the sequence
enters a cycle, and how long that cycle is. Well?
 
P

Phrogz

Ruby said:
0. LOOK AND SAY
1. TWO A ONE D ONE K ONE L ONE N TWO O ONE S ONE Y
2. ONE A ONE D SIX E ONE K ONE L SEVEN N NINE O ONE S TWO T TWO W ONE Y
3. ONE A ONE D TEN E TWO I ONE K ONE L TEN N NINE O THREE S THREE T ONE V
THREE W ONE X ONE Y

and so on. (Note the difference between this and the L&S sequence--the letters
are counted rather than read in order). Eric wants to know when the sequence
enters a cycle, and how long that cycle is. Well?

In case the string gets quite long, what is the canonical English
representation (for this quiz) of:
101 - "One hundred one" or "One hundred and one"? (Not "One Oh One", I
suppose.)

(From that answer I suppose I can extrapolate the answer for similar
edge cases, largely involving the presence of absence of the word
'and'.)
 
A

Alex LeDonne

In case the string gets quite long, what is the canonical English
representation (for this quiz) of:
101 - "One hundred one" or "One hundred and one"? (Not "One Oh One", I
suppose.)

(From that answer I suppose I can extrapolate the answer for similar
edge cases, largely involving the presence of absence of the word
'and'.)

I was taught in the US that "and" in a spelled out number designates
the decimal point. So, "ONE HUNDRED ONE" would be 101, while "ONE
HUNDRED AND ONE TENTH" would be 100.1 - "ONE HUNDRED AND ONE" would
then be considered an incorrect designation. I think this is based on
check-writing/banking standards.

But I have heard that others learned by other standards both in the US
and elsewhere.

-A
 
M

Martin DeMello

In case the string gets quite long, what is the canonical English
representation (for this quiz) of:
101 - "One hundred one" or "One hundred and one"? (Not "One Oh One", I
suppose.)

I'd say "ONE HUNDRED AND ONE", but you could always add it as a parameter

martin
 
C

Chris Shea

In case the string gets quite long, what is the canonical English
representation (for this quiz) of:
101 - "One hundred one" or "One hundred and one"? (Not "One Oh One", I
suppose.)

I've always felt that the answer to the question "What is the smallest
positive integer spelled with the letter 'a'?" is 1,000.

Chris
 
J

James Edward Gray II

In case the string gets quite long, what is the canonical English
representation (for this quiz) of:
101 - "One hundred one" or "One hundred and one"? (Not "One Oh One", I
suppose.)

(From that answer I suppose I can extrapolate the answer for similar
edge cases, largely involving the presence of absence of the word
'and'.)

This has come up in past quizzes. Here's a line of thought from and
oldy but goody:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/135449

James Edward Gray II
 
W

werner

Il Thu, 6 Sep 2007 21:00:20 +0900, Ruby Quiz ha scritto:
The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

I hope what I'm writing doesn't break this rule ^^

A couple of newbie questions: I understand that Ruby hashes copy both the
key and the value in their internal table, is this right? And if it is, is
there a way to avoid copying that key, especially if the key is a String
(or a library that implements a different hash system?)

Second question: is the value always stored as a pointer to the existing
object, or is a new object also created for the hash table?

And third... (now you are all going to realize what kind of languages I
used to program in ^^;;) I understand that the object_id is somehow
connected to the pointer to the actual structure holding object data, if it
isn't the pointer itself. Is there a way to use it as an actual object
pointer? (I guess there isn't, but....)


Thanks in advance
 
J

James Edward Gray II

Hehe... I used that for Integer#to_english. That made solving this
Ruby Quiz fairly easy. Can I post my solution now?

Sure can.

James Edward Gray II
 
J

Josef 'Jupp' Schugt

--Sig_AnIJjWoroPpZQ=6HS_rUPc6
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable


Seems as if something got broken 8-|
On Thu, 6 Sep 2007 21:00:20 +0900 Ruby Quiz wrote:
=20
Over on rec.puzzles, Eric A. proposed a variant in which the letters of= a
sentence are grouped, then "counted aloud", omitting the "s"s for the p= lural
form. =20
=20
Here is my solution. The idea is as follows:
=20
1. Add an instance method "count" to "String" that builds a hash assigning
each letter present in the string its frequency.
=20
2. Add an instance method "say" to Fixnum and Hash that 'says' a number o= r a
hashes of the abovementioned structure.
=20
3. Push what is said until what is currently said has been said before.
=20
Saying numbers is only implemented for values from 0 through 999_999_999 = and
without the use of "and". The latter is because I personally do not use an
"and". The former is because starting with 1_000_000_000 all hell breaks = loose
and a crore of different ways to read the numbers enter the scene.
=20
#########################################################################= ######
# Ruby Quiz 138, Josef 'Jupp' Schugt
#########################################################################= ######
=20
# String#count creates a hash where the keys are the letters 'a'
# through 'z' and the values are the frequencies of these letters.
=20
class String
def count
a =3D Hash.new(0)
self.each_byte{|i| a[i.chr] +=3D 1 if ('a'..'z').member?(i.chr)}
a
end
end
=20
# Hash#say "reads the hash aloud"
=20
class Hash
def say
self.sort.map{|n,c| "#{c.say} #{n}"}.join(' ')
end
end
=20
# Fixnum#say "reads the number aloud"
=20
class Fixnum
=20
# Lookup table for numbers from zero to nineteen
@@to20 =3D [ 'zero', 'one', 'two', 'three', 'four', 'five', 'six',
'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve',
'thirteen', 'fourteen', 'fivteen', 'sixteen',
'seventeen', 'eighteen', 'nineteen' ]
=20
# Looup table for tens with the first two values only being fillers.
@@tens =3D [ nil, nil, 'twenty', 'thirty', 'forty', 'fifty', 'sixty',
'seventy', 'eighty', 'ninety' ]
=20
def say
name =3D=20
case self
when 0...20:
@@to20[self]
when 20...100:
@@tens[self / 10 ] + '-' + @@to20[self % 10]
when 100...1000:
(self / 100).say + ' hundred ' + (self % 100).say
when 1000...1_000_000:
(self / 1000).say + ' thousand ' + (self % 1000).say
when 1_000_000...1_000_000_000:
(self / 1_000_000).say + ' million ' + (self % 1_000_000).say
else
raise ArgumentError, 'Only numbers from 0 to 999_999_999 are
supported' end
/[- ]zero$/.match(name) ? $~.pre_match : name
end
end
=20
puts <<EOF
=20
PLEASE ENTER A STRING TO START WITH AND NOTE THAT:
=20
1. No output will be shown until processing is done.
2. The string will be first downcased.
3. All whitespace will be collapsed to single spaces.
4. All characters except 'a' through 'z' and space are removed.
=20
EOF
=20
print "? "
s =3D gets.chomp.downcase.gsub(/\s+/, ' ').gsub(/[^a-z ]/, '')
=20
arr =3D Array.new
=20
until arr.member?(s)
arr.push s
s =3D s.count.say
end
=20
puts <<EOF
=20
VALUES BEFORE FIRST CYCLE
=20
#{(0...arr.index(s)).map {|i| "#{i}:\t#{arr}" }.join("\n")}
=20
VALUES OF FIRST CYCLE
=20
#{(arr.index(s)...arr.length).map {|i| "#{i}:\t#{arr}" }.join("\n")}
=20
SUMMARY
=20
Initial value (step #{0}) is '#{arr.first}'
=20
First cycle:
=20
\tFirst step:\t#{arr.index(s)}
\tLast step:\t#{arr.length - 1}
\tPeriod (steps):\t#{arr.length - arr.index(s)}
=20
EOF
=20
=20
Josef 'Jupp' Schugt


Josef 'Jupp' Schugt
--=20
Blog available at http://www.mynetcologne.de/~nc-schugtjo/blog/
PGP key with id 6CC6574F available at http://wwwkeys.de.pgp.net/

--Sig_AnIJjWoroPpZQ=6HS_rUPc6
Content-Type: application/pgp-signature; name=signature.asc
Content-Disposition: attachment; filename=signature.asc

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQFG48ZWrhv7B2zGV08RAtdcAKDh5K12s/C00Z+thueKRMB7vpru6ACcD23Q
t0u6tXfZn4hXO1swfDGnu2k=
=PsBu
-----END PGP SIGNATURE-----

--Sig_AnIJjWoroPpZQ=6HS_rUPc6--
 
E

Eugene Kalenkovich

by Martin DeMello

I decided not to miss all the fun, and implemented my own spelling not
lookong in prior quuiz solutions. BTW, the full-fledged spelling is not
necessary, as the biggest number to spell for this quiz I found was 37
(bigger input texts will require more), but - fun is fun. Interesting facts
(hope I did not make any typos, they would screw up all statistics):
Worst (or one of) word in unix dictionary is 'SYMPATHIZED' - 303 hops before
entering loop of 885 iterations;
Best - surprise! - 'ERROR' - only 7+5

################## spelling part ##########################
TOTEENS=[nil, 'one two three four five six seven eight nine ten eleven
twelve thirteen fourteen fifteen sixteen seventeen eighteen
nineteen'.split].flatten
TENS=[nil, nil, 'twenty thirty forty fifty sixty seventy eighty
ninety'.split].flatten
EXPS_US=[nil,'thousand million billion trillion quadrillion quintillion
sextillion septillion octillion nonillion decillion undecillion duodecillion
tredecillion quattuordecillion quindecillion sexdecillion septendecillion
octodecillion novemdecillion vigintillion'.split].flatten
EXPS_NON_US=[nil,'million billion trillion quadrillion quintillion
sextillion septillion octillion nonillion decillion'.split].flatten

class Integer
def spell(us=true)
return 'zero' if self==0
self<0 ? 'minus '+(-self).spell_unsign(us) : self.spell_unsign(us)
end

def spell_unsign(us=true)
size=us ? 3 : 6
res=[]
self.to_s.reverse.scan(%r"\d{1,#{size}}").each_with_index {|s, i|
n=s.reverse.to_i
if n>0
sp=us ? n.spell_small : n.spell(true)
sp.gsub!('thousand','milliard') if i==1 && !us
sc=us ? EXPS_US : EXPS_NON_US
res << sc if sc
res << sp
end
}
res.compact.reverse.join(' ')
end

def spell_small
res=[]
hundred=TOTEENS[self/100]
res << hundred << 'hundred' if hundred
res << TENS[self%100/10] << (self<20 ? TOTEENS[self%100] :
TOTEENS[self%10])
res.compact.join(' ')
end
end
################## actial quiz part ##########################
def count_and_say str
h=str.split(//).inject(Hash.new(0)){|h,c|h[c]+=1; h}
h.delete(' ')
res=''
h.keys.sort.each {|k|
res << ' ' unless res.empty?
res << h[k].spell << ' ' << k
}
res
end

it=start=0
hres={(orig=last=ARGV[0].downcase.delete("^a-z"))=>it}
while true
puts now=count_and_say(last)
it+=1
key=now.delete(' ') # slight optimization, gives ~10% on 'sympathized'
break if start=hres[key]
hres[key],last=it,key
end
puts "#{start} + #{it-start}"
 
P

Phrogz

# Solution to Ruby Quiz #138 by Gavin Kistner
SEED = "LOOK AND SAY"

module Enumerable
def item_counts
inject( Hash.new(0) ){ |counts, item|
counts[ item ] += 1
counts
}
end
end

class String
def look_and_say
counts = upcase.scan( /[A-Z]/ ).item_counts
counts.keys.sort.map{ |letter|
"#{counts[letter].to_english.upcase} #{letter}"
}.join( ' ' )
end
end

# Code courtesy of Glenn Parker in Ruby Quiz #25
class Integer
Ones = %w[ zero one two three four five six seven eight nine ]
Teen = %w[ ten eleven twelve thirteen fourteen fifteen sixteen
seventeen eighteen nineteen ]
Tens = %w[ zero ten twenty thirty forty fifty sixty seventy eighty
ninety ]
Mega = %w[ none thousand million billion trillion quadrillion
quintillion sextillion septillion octillion ]
def to_english
places = to_s.split(//).collect {|s| s.to_i}.reverse
name = []
((places.length + 2) / 3).times do |p|
strings = Integer.trio(places[p * 3, 3])
name.push(Mega[p]) if strings.length > 0 and p > 0
name += strings
end
name.push(Ones[0]) unless name.length > 0
name.reverse.join(" ")
end
private
def Integer.trio(places)
strings = []
if places[1] == 1
strings.push(Teen[places[0]])
elsif places[1] and places[1] > 0
strings.push(places[0] == 0 ? Tens[places[1]] :
"#{Tens[places[1]]}-#{Ones[places[0]]}")
elsif places[0] > 0
strings.push(Ones[places[0]])
end
if places[2] and places[2] > 0
strings.push("hundred", Ones[places[2]])
end
strings
end
end

str = SEED
strs_seen = {}
0.upto( 9999 ){ |i|
puts "%4d. %s" % [ i, str ]
if last_seen_on = strs_seen[ str ]
print "Cycle from #{i-1} back to #{last_seen_on}"
puts " (#{i - last_seen_on} lines in cycle)"
break
else
strs_seen[ str ] = i
end
str = str.look_and_say
}
 
P

Phrogz

For fun, I thought I'd see what it looked like to implement the
integer-based algorithm that this quiz is based on. Here's what I came
up with. (I'm a big fan of monkeypatching. :)


class Integer
def each_digit
to_s.each_byte{ |b| yield( b - ?0 ) }
end
def look_and_say
digits, counts = [], []
each_digit{ |d|
if digits.last == d
counts[ counts.size - 1 ] += 1
else
digits << d
counts << 1
end
}
counts.zip( digits ).join.to_i
end
end

n = 1
12.times{ p n; n = n.look_and_say }
#=> 1
#=> 11
#=> 21
#=> 1211
#=> 111221
#=> 312211
#=> 13112221
#=> 1113213211
#=> 31131211131221
#=> 13211311123113112211
#=> 11131221133112132113212221
#=> 3113112221232112111312211312113211
 
P

Phrogz

Interesting facts
(hope I did not make any typos, they would screw up all statistics):
Worst (or one of) word in unix dictionary is 'SYMPATHIZED' - 303 hops before
entering loop of 885 iterations;
Best - surprise! - 'ERROR' - only 7+5

Hey, thanks for providing this! I was wondering about that best case,
and tried random words seeing how they played out, but didn't think to
run the full dictionary against it. :)
 
K

Krishna Dole

# Krishna Dole's solution to Ruby Quiz 138.
# I followed Glenn Parker's reasoning on naming numbers, but didn't
look at his code.

class CountSay

def initialize(str)
@str = str
end

def succ
letters = @str.scan(/\w/)
@str = letters.uniq.sort.map do |l|
[letters.select{ |e| e == l }.size.to_words, l]
end.join(" ").upcase
end

def each(limit = nil)
if limit.nil?
while true
yield succ
end
else
limit.times { yield succ }
end
end

end

class Integer
NUMS_0_19 = %w(zero one two three four five six seven eight nine ten
eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen
nineteen)
NUMS_TENS = [nil, nil] + %w(twenty thirty forty fifty sixty seventy
eighty ninety)
NUMS_TRIPLETS = [nil] + %w(thousand million billion trillion)

# Return the english words representing the number,
# so long as it is smaller than 10**15.
# The specifications for this method follow the reasoning in:
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/135449
# though I wrote the code without seeing Glenn's.
def to_words
case self
when 0..19
NUMS_0_19[self]
when 20..99
a, b = self.divmod(10)
[NUMS_TENS[a], NUMS_0_19].reject { |w| w == "zero" }.join("-")
when 100..999
a, b = self.divmod(100)
"#{NUMS_0_19[a]} hundred#{b == 0 ? '' : ' ' + b.to_words}"
else
raise "Too lazy to write numbers >= 10**15" if self >= 10**15
triplet = (self.to_s.size - 1) / 3 # find out if we are in
thousands, millions, etc
a, b = self.divmod(10**(3 * triplet))
"#{a.to_words} #{NUMS_TRIPLETS[triplet]}#{b == 0 ? '' : ' ' +
b.to_words}"
end
end

end

class SimpleCycleDetector

# Expects an object that responds to #each.
# Returns an array containing the number of
# iterations before the cycle started, the length
# of the cycle, and the repeated element.
def self.detect(obj)
results = []
obj.each do |e|
if i = results.index(e)
return [i, results.size - i, e]
else
results << e
end
end
end

end



unless ARGV[0] == "-test"

seed = if ARGV.empty?
"LOOK AND SAY"
else
ARGV.join(' ').upcase
end

puts "Seeding CountSay with '#{seed}'"
cs = CountSay.new(seed)
initial, period, phrase = SimpleCycleDetector.detect(cs)
puts "Repeated phrase '#{phrase}.' Started cycle of length #{period}
after #{initial} iterations."

else
require "test/unit"

class TestToWords < Test::Unit::TestCase

def test_to_words_0_19
assert_equal("zero", 0.to_words)
assert_equal("nine", 9.to_words)
assert_equal("eleven", 11.to_words)
assert_equal("nineteen", 19.to_words)
end

def test_to_words_20_99
assert_equal("twenty", 20.to_words)
assert_equal("twenty-one", 21.to_words)
assert_equal("forty-two", 42.to_words)
assert_equal("seventy-seven", 77.to_words)
assert_equal("ninety-nine", 99.to_words)
end

def test_to_words_100_999
assert_equal("one hundred", 100.to_words)
assert_equal("nine hundred three", 903.to_words)
assert_equal("two hundred fifty-six", 256.to_words)
end

def test_to_words_999_and_up
assert_equal("one thousand", 1000.to_words)
assert_equal("one thousand one hundred one", 1101.to_words)
assert_equal("twenty-two thousand", 22_000.to_words)
assert_equal("one million", (10**6).to_words)
assert_equal("twenty-two million nine hundred thousand four
hundred fifty-six", 22_900_456.to_words)
assert_equal("nine hundred ninety-nine trillion twenty-two
million four thousand one", 999_000_022_004_001.to_words)
assert_equal("nine hundred ninety-nine trillion nine hundred
ninety-nine billion nine hundred ninety-nine million nine hundred
ninety-nine thousand nine hundred ninety-nine",
999_999_999_999_999.to_words)
end

def test_error_on_big_number
assert_raise(RuntimeError) { (10**15).to_words }
assert_nothing_raised(RuntimeError) { ((10**15) - 1).to_words }
end

end

class TestSimpleCyleDetector < Test::Unit::TestCase
def setup
@nums = [1,2,3,1,2,3]
@letters = %w( x y a b c d a e f )
end

def test_detect
assert_equal([0, 3, 1], SimpleCycleDetector.detect(@nums))
assert_equal([2, 4, 'a'], SimpleCycleDetector.detect(@letters))
end
end

class TestCountSay < Test::Unit::TestCase

def setup
@output = <<END_OUTPUT
0. LOOK AND SAY
1. TWO A ONE D ONE K ONE L ONE N TWO O ONE S ONE Y
2. ONE A ONE D SIX E ONE K ONE L SEVEN N NINE O ONE S TWO T TWO W ONE Y
3. ONE A ONE D TEN E TWO I ONE K ONE L TEN N NINE O THREE S THREE T
ONE V THREE W ONE X ONE Y
END_OUTPUT

@lines = @output.to_a.map { |l| l[3..-2] } # without leading
number or newline
@cs = CountSay.new(@lines.first)
end

def test_succ
@lines[1..-1].each do |line|
assert_equal(line, @cs.succ)
end
end

def test_each_with_limit
@lines.shift
@cs.each(3) do |str|
assert_equal(@lines.shift, str)
end
end

end
end
 
S

Simon Kröger

Phrogz said:
For fun, I thought I'd see what it looked like to implement the
integer-based algorithm that this quiz is based on. Here's what I came
up with. (I'm a big fan of monkeypatching. :)

Another monkeypatchingversion (i like reopening classes,
i'm not realy a fan of the term 'monkeypatching')

--------------------------------------------
class String
def look_and_say
gsub(/(.)\1*/){|s| "#{s.size}#{s[0,1]}"}
end
end

s = '1'
12.times {p s; s = s.look_and_say}
 
J

James Edward Gray II

TOTEENS=[nil, 'one two three four five six seven eight nine ten eleven
twelve thirteen fourteen fifteen sixteen seventeen eighteen
nineteen'.split].flatten

A small suggestion:
=> ["one", "two", "three", "..."]

James Edward Gray II
 
P

Phrogz

TOTEENS=[nil, 'one two three four five six seven eight nine ten eleven
twelve thirteen fourteen fifteen sixteen seventeen eighteen
nineteen'.split].flatten

A small suggestion:
=> ["one", "two", "three", "..."]

Moreover:
irb(main):001:0> [ nil, *%w| two three | ]
=> [nil, "two", "three"]

No need to flatten.
 
P

Phrogz

class String
def look_and_say
gsub(/(.)\1*/){|s| "#{s.size}#{s[0,1]}"}
end
end

Dude, that's elegant. Thanks for sharing. I particularly like keeping
it as a String, avoiding the performance issues of Bignum for the
truly large.

Your solution scales much, much better than mine after a few
iterations:

user system total real
Simon up to 30 0.203000 0.000000 0.203000 ( 0.219000)
Gavin up to 30 0.500000 0.000000 0.500000 ( 0.531000)

Simon up to 32 0.390000 0.000000 0.390000 ( 0.407000)
Gavin up to 32 0.672000 0.000000 0.672000 ( 0.672000)

Simon up to 34 0.485000 0.000000 0.485000 ( 0.484000)
Gavin up to 34 1.578000 0.000000 1.578000 ( 1.579000)

Simon up to 36 0.750000 0.016000 0.766000 ( 0.765000)
Gavin up to 36 4.000000 0.000000 4.000000 ( 4.032000)

Simon up to 38 1.328000 0.000000 1.328000 ( 1.328000)
Gavin up to 38 10.312000 0.094000 10.406000 ( 10.471000)

Simon up to 40 2.500000 0.015000 2.515000 ( 2.531000)
Gavin up to 40 28.016000 0.031000 28.047000 ( 28.270000)

Simon up to 42 4.375000 0.079000 4.454000 ( 4.485000)
Gavin up to 42 80.219000 0.046000 80.265000 ( 81.029000)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top